# Groups Integration Tests Integration tests for the groups module. Each file targets a specific feature area — add new tests to the matching file, or create a new file if the feature area doesn't exist yet. ## File Map | File | Feature area covered | |------|---------------------| | `groups.test.ts` | Group CRUD (create, edit, archive, delete), member listing, approval policy, backoffice operations | | `groupsListing.test.ts` | Group list/explore, red bubble unread counts, ordering by last activity | | `groupMembers.test.ts` | Membership requests (accept/reject/bulk), add/remove members, roles, `membersCanLeave` policy | | `groupPosts.test.ts` | Post scheduling, approval/edit requests, post summary, pin/unpin, poll answers, key updates listing, user group posts listing | | `groupPostsCRUDOperations.test.ts` | Post creation/deletion/edit (CRUD), pagination, metadata (SHARE_POST_ID), viewCount, listing filters (e.g. deleted users) | | `groupPostsCommentsAndReactions.test.ts` | Comments (create/edit/delete/pagination/ordering), reactions on posts and comments, `commentsEnabled` toggle | | `groupPostEvents.test.ts` | SQS event handler messages emitted on post/comment/reaction created/deleted | | `groupPostLivestreamStats.test.ts` | Livestream viewer stats, viewers list, stats report download | | `groupLivestreams.test.ts` | Livestream poll answers (vote, duplicate vote prevention, active/ended poll fetch) | | `groupStats.test.ts` | Most active members (last 28 days), stats summary, most active members report | | `groupsCDCService.test.ts` | Kafka CDC: user create/update/delete sync to `GroupsUsers`, group delete cascade, red bubble invalidation | | `multiCompanyGroup.test.ts` | Multi-company group creation, member management across instances, join requests, privacy permissions | | `multiCompanyGroupPost.test.ts` | Multi-company posts, reactions, comments, polls, key updates, cursor-paginated feed mixing group types | ## Available Commands Groups-specific commands are in `commands/groups/` — documented in [`commands/groups/AGENTS.md`](../../../commands/groups/AGENTS.md). Check that file before writing a raw `apiGet`/`apiPost` call — the command likely already exists. Some tests also need commands from other modules (e.g. creating a user, adding capabilities, enabling a community feature). Those live in their own folder under `commands/{module}/`. Browse the relevant folder if you need to set up prerequisites from another domain. ## Where to Add New Tests - **New scenario for an existing feature** → add an `it` block inside the matching file's `describe`. - **New feature area with no matching file** → create a new `groupPostsXxx.test.ts` or `groupXxx.test.ts` file following the bootstrap pattern below. - **Listing/filter behavior** (e.g. filtering by author status, approval state) → `groupPostsCRUDOperations.test.ts`. ## Avoiding Flaky Tests Tests run in parallel across 14 workers sharing the same database. Any test that creates, modifies, or deletes data can break other tests or be broken by them if not properly isolated. **Before writing a test that creates or deletes elements, ask:** - Could another test running in parallel create data that interferes with mine? - Could my deletions or mutations affect data that another test depends on? **Rules:** - **Create a dedicated group per test** using `createRandomGroup(...)`. Never reuse a group across `it` blocks that mutate state — a deleted post or changed role in one test will bleed into another. - **Create a dedicated user per test** (via `createUserSession`) when the test mutates user state (e.g. marks user as deleted, changes role). Mutating `community.user1` or `community.user2` in one `it` will corrupt every other `it` that relies on them. - **Never assert on total counts** without scoping by your test's `groupId`, `instanceId`, or `userId`. - **Never DELETE or UPDATE without a WHERE clause** scoped to your own data. - **Restore mutated state in `afterAll`** if you had no choice but to reuse a shared resource (e.g. re-set `deleted = false` after setting it to `true`). ## Bootstrap Pattern Every test file must set up its own isolated community and populate `GroupsUsers`: ```typescript describe('My Feature', () => { let community: Community; beforeAll(async () => { community = await CreateCommunity.new({ instanceCapabilities: [GenerallyAvailableInstanceCapabilityNames.VIEW_GROUPS], }); await runExecuteQueryOnMainDb( `INSERT INTO "GroupsUsers" (id, "firstName", "lastName", email, "profilePicture", "instanceId", deleted) SELECT id, "firstName", "lastName", "email", "profilePicture", "instanceId", case when "deletedAt" is null then false else true end FROM "Users" WHERE "instanceId" = $1 ON CONFLICT DO NOTHING`, community.instance.id, ); }); it('...', async () => { const group = await createRandomGroup(community.adminSession, [community.user1.id, community.user2.id]); // ... }); }); ``` **`GroupsUsers` must be populated** before any test that touches post listing or member lookups — the query that lists group posts joins against this table.