Skip to content

fix(team): await default-room assignments when adding team members#38701

Open
Shreyas2004wagh wants to merge 2 commits intoRocketChat:developfrom
Shreyas2004wagh:fix/team-default-rooms-await
Open

fix(team): await default-room assignments when adding team members#38701
Shreyas2004wagh wants to merge 2 commits intoRocketChat:developfrom
Shreyas2004wagh:fix/team-default-rooms-await

Conversation

@Shreyas2004wagh
Copy link
Contributor

@Shreyas2004wagh Shreyas2004wagh commented Feb 15, 2026

Summary

  • await all async default-room membership operations in \TeamService.addMembersToDefaultRooms\
  • ensure failures from \�ddUserToRoom\ are propagated to the caller
  • add regression tests covering completion semantics and error propagation

Testing

  • yarn --cwd apps/meteor mocha --no-config --require tsx --require ./tests/setup/chaiPlugins.ts tests/unit/server/services/team/service.tests.ts --exit
  • yarn --cwd apps/meteor mocha --no-config --require tsx --require ./tests/setup/chaiPlugins.ts tests/unit/definition/rest/v1/teams/TeamsAddMembersProps.spec.ts tests/unit/definition/rest/v1/teams/TeamsUpdateMemberProps.spec.ts --exit

Fixes #38700

Summary by CodeRabbit

  • Bug Fixes

    • Fixed an issue where users were not being properly added to default team rooms. The system now ensures all user additions complete successfully before proceeding.
  • Tests

    • Added unit tests to verify team member addition process functions correctly and handles errors appropriately.

Copilot AI review requested due to automatic review settings February 15, 2026 04:41
@Shreyas2004wagh Shreyas2004wagh requested a review from a team as a code owner February 15, 2026 04:41
@dionisio-bot
Copy link
Contributor

dionisio-bot bot commented Feb 15, 2026

Looks like this PR is not ready to merge, because of the following issues:

  • This PR is missing the 'stat: QA assured' label
  • This PR is missing the required milestone or project

Please fix the issues and try again

If you have any trouble, please check the PR guidelines

@changeset-bot
Copy link

changeset-bot bot commented Feb 15, 2026

⚠️ No Changeset found

Latest commit: 7f5e06f

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Feb 15, 2026

Walkthrough

Modified TeamService's addMembersToDefaultRooms to properly await completion of all async operations using Promise.all instead of non-awaited map calls. Users are added sequentially per room. Comprehensive unit tests were added to verify proper awaiting and error propagation.

Changes

Cohort / File(s) Summary
Service Implementation
apps/meteor/server/services/team/service.ts
Wrapped defaultRooms.map() with Promise.all to ensure all async room operations await completion before function returns. Changed inner user iteration from for-await to for-of loop for sequential processing per room. Total: +9 lines, -7 lines.
Unit Tests
apps/meteor/tests/unit/server/services/team/service.tests.ts
Added 135 lines of comprehensive tests covering addMembersToDefaultRooms behavior including proper awaiting of concurrent room operations and error propagation from addUserToRoom failures.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Poem

🐰 Hop, hop, awaiting the way,
No more promises left to stray,
Promise.all brings order true,
Users added, fresh and new,
Async bugs are bid adieu! 🎉

🚥 Pre-merge checks | ✅ 6
✅ Passed checks (6 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the main fix: awaiting default-room assignments in the team service when adding members.
Linked Issues check ✅ Passed The PR addresses all coding requirements from issue #38700: awaiting async operations in addMembersToDefaultRooms, propagating errors, and adding regression tests.
Out of Scope Changes check ✅ Passed All changes are scoped to fixing the identified issue: modifying TeamService.addMembersToDefaultRooms and adding corresponding unit tests.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Merge Conflict Detection ✅ Passed ✅ No merge conflicts detected when merging into develop

✏️ Tip: You can configure your own custom pre-merge checks in the settings.


No actionable comments were generated in the recent review. 🎉

🧹 Recent nitpick comments
apps/meteor/server/services/team/service.ts (1)

1003-1006: Remove inline code comments.

Lines 1003 and 1005 introduce implementation comments. As per coding guidelines, **/*.{ts,tsx,js} files should avoid code comments in the implementation.

Proposed fix
 		await Promise.all(
 			defaultRooms.map(async (room) => {
-				// at this point, users are already part of the team so we won't check for membership
 				for (const user of users) {
-					// add each user to the default room
 					await addUserToRoom(room._id, user, inviter, { skipSystemMessage: false });
 				}
 			}),
 		);
apps/meteor/tests/unit/server/services/team/service.tests.ts (1)

6-10: flushMicrotasks is fragile — consider documenting the assumption.

The triple Promise.resolve() drains a fixed number of microtask ticks. If the implementation of addMembersToDefaultRooms gains additional await points in the future, this helper may silently become insufficient and cause flaky tests. Consider adding a brief note about why three ticks are sufficient, or switching to a small polling loop with a timeout for more robustness.

📜 Recent review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 11e1c51 and 160a2d3.

📒 Files selected for processing (2)
  • apps/meteor/server/services/team/service.ts
  • apps/meteor/tests/unit/server/services/team/service.tests.ts
🧰 Additional context used
📓 Path-based instructions (1)
**/*.{ts,tsx,js}

📄 CodeRabbit inference engine (.cursor/rules/playwright.mdc)

**/*.{ts,tsx,js}: Write concise, technical TypeScript/JavaScript with accurate typing in Playwright tests
Avoid code comments in the implementation

Files:

  • apps/meteor/server/services/team/service.ts
  • apps/meteor/tests/unit/server/services/team/service.tests.ts
🧠 Learnings (12)
📚 Learning: 2025-09-25T09:59:26.461Z
Learnt from: Dnouv
Repo: RocketChat/Rocket.Chat PR: 37057
File: packages/apps-engine/src/definition/accessors/IUserRead.ts:23-27
Timestamp: 2025-09-25T09:59:26.461Z
Learning: AppUserBridge.getUserRoomIds in apps/meteor/app/apps/server/bridges/users.ts always returns an array of strings by mapping subscription documents to room IDs, never undefined, even when user has no room subscriptions.

Applied to files:

  • apps/meteor/server/services/team/service.ts
📚 Learning: 2025-09-25T09:59:26.461Z
Learnt from: Dnouv
Repo: RocketChat/Rocket.Chat PR: 37057
File: packages/apps-engine/src/definition/accessors/IUserRead.ts:23-27
Timestamp: 2025-09-25T09:59:26.461Z
Learning: AppUserBridge.getUserRoomIds in apps/meteor/app/apps/server/bridges/users.ts always returns an array of strings (mapping subscription documents to room IDs), never undefined, even when user has no room subscriptions.

Applied to files:

  • apps/meteor/server/services/team/service.ts
📚 Learning: 2025-10-28T16:53:42.761Z
Learnt from: ricardogarim
Repo: RocketChat/Rocket.Chat PR: 37205
File: ee/packages/federation-matrix/src/FederationMatrix.ts:296-301
Timestamp: 2025-10-28T16:53:42.761Z
Learning: In the Rocket.Chat federation-matrix integration (ee/packages/federation-matrix/), the createRoom method from rocket.chat/federation-sdk will support a 4-argument signature (userId, roomName, visibility, displayName) in newer versions. Code using this 4-argument call is forward-compatible with planned library updates and should not be flagged as an error.

Applied to files:

  • apps/meteor/server/services/team/service.ts
📚 Learning: 2025-11-24T17:08:17.065Z
Learnt from: CR
Repo: RocketChat/Rocket.Chat PR: 0
File: .cursor/rules/playwright.mdc:0-0
Timestamp: 2025-11-24T17:08:17.065Z
Learning: Applies to apps/meteor/tests/e2e/**/*.spec.ts : Ensure tests run reliably in parallel without shared state conflicts

Applied to files:

  • apps/meteor/server/services/team/service.ts
  • apps/meteor/tests/unit/server/services/team/service.tests.ts
📚 Learning: 2025-11-27T17:56:26.050Z
Learnt from: MartinSchoeler
Repo: RocketChat/Rocket.Chat PR: 37557
File: apps/meteor/client/views/admin/ABAC/AdminABACRooms.tsx:115-116
Timestamp: 2025-11-27T17:56:26.050Z
Learning: In Rocket.Chat, the GET /v1/abac/rooms endpoint (implemented in ee/packages/abac/src/index.ts) only returns rooms where abacAttributes exists and is not an empty array (query: { abacAttributes: { $exists: true, $ne: [] } }). Therefore, in components consuming this endpoint (like AdminABACRooms.tsx), room.abacAttributes is guaranteed to be defined for all returned rooms, and optional chaining before calling array methods like .join() is sufficient without additional null coalescing.

Applied to files:

  • apps/meteor/server/services/team/service.ts
📚 Learning: 2026-01-17T01:51:47.764Z
Learnt from: tassoevan
Repo: RocketChat/Rocket.Chat PR: 38219
File: packages/core-typings/src/cloud/Announcement.ts:5-6
Timestamp: 2026-01-17T01:51:47.764Z
Learning: In packages/core-typings/src/cloud/Announcement.ts, the AnnouncementSchema.createdBy field intentionally overrides IBannerSchema.createdBy (object with _id and optional username) with a string enum ['cloud', 'system'] to match existing runtime behavior. This is documented as technical debt with a FIXME comment at apps/meteor/app/cloud/server/functions/syncWorkspace/handleCommsSync.ts:53 and should not be flagged as an error until the runtime behavior is corrected.

Applied to files:

  • apps/meteor/server/services/team/service.ts
📚 Learning: 2025-09-25T09:59:26.461Z
Learnt from: Dnouv
Repo: RocketChat/Rocket.Chat PR: 37057
File: packages/apps-engine/src/definition/accessors/IUserRead.ts:23-27
Timestamp: 2025-09-25T09:59:26.461Z
Learning: UserBridge.doGetUserRoomIds in packages/apps-engine/src/server/bridges/UserBridge.ts has a bug where it implicitly returns undefined when the app lacks read permission (missing return statement in the else case of the permission check).

Applied to files:

  • apps/meteor/server/services/team/service.ts
📚 Learning: 2025-11-24T17:08:17.065Z
Learnt from: CR
Repo: RocketChat/Rocket.Chat PR: 0
File: .cursor/rules/playwright.mdc:0-0
Timestamp: 2025-11-24T17:08:17.065Z
Learning: Applies to apps/meteor/tests/e2e/**/*.spec.ts : Group related tests in the same file

Applied to files:

  • apps/meteor/tests/unit/server/services/team/service.tests.ts
📚 Learning: 2025-11-24T17:08:17.065Z
Learnt from: CR
Repo: RocketChat/Rocket.Chat PR: 0
File: .cursor/rules/playwright.mdc:0-0
Timestamp: 2025-11-24T17:08:17.065Z
Learning: Applies to apps/meteor/tests/e2e/**/*.spec.ts : Utilize Playwright fixtures (`test`, `page`, `expect`) for consistency in test files

Applied to files:

  • apps/meteor/tests/unit/server/services/team/service.tests.ts
📚 Learning: 2025-11-24T17:08:17.065Z
Learnt from: CR
Repo: RocketChat/Rocket.Chat PR: 0
File: .cursor/rules/playwright.mdc:0-0
Timestamp: 2025-11-24T17:08:17.065Z
Learning: Applies to apps/meteor/tests/e2e/**/*.spec.ts : Maintain test isolation between test cases in Playwright tests

Applied to files:

  • apps/meteor/tests/unit/server/services/team/service.tests.ts
📚 Learning: 2025-11-24T17:08:17.065Z
Learnt from: CR
Repo: RocketChat/Rocket.Chat PR: 0
File: .cursor/rules/playwright.mdc:0-0
Timestamp: 2025-11-24T17:08:17.065Z
Learning: Applies to apps/meteor/tests/e2e/**/*.spec.ts : All test files must be created in `apps/meteor/tests/e2e/` directory

Applied to files:

  • apps/meteor/tests/unit/server/services/team/service.tests.ts
📚 Learning: 2025-11-24T17:08:17.065Z
Learnt from: CR
Repo: RocketChat/Rocket.Chat PR: 0
File: .cursor/rules/playwright.mdc:0-0
Timestamp: 2025-11-24T17:08:17.065Z
Learning: Applies to apps/meteor/tests/e2e/**/*.spec.ts : Use `expect` matchers for assertions (`toEqual`, `toContain`, `toBeTruthy`, `toHaveLength`, etc.) instead of `assert` statements in Playwright tests

Applied to files:

  • apps/meteor/tests/unit/server/services/team/service.tests.ts
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (4)
  • GitHub Check: 📦 Build Packages
  • GitHub Check: Agent
  • GitHub Check: cubic · AI code reviewer
  • GitHub Check: CodeQL-Build
🔇 Additional comments (4)
apps/meteor/server/services/team/service.ts (1)

1001-1009: Good fix — properly awaits all default-room assignments.

The await Promise.all(...) wrapper correctly ensures the function doesn't resolve until every addUserToRoom call completes, and rejections now propagate to the caller. This directly addresses the issue.

One minor note: Promise.all short-circuits on the first rejection, so if adding a user to one default room fails, remaining rooms may be skipped. If partial completion is undesirable, Promise.allSettled would attempt all rooms before surfacing errors. This may or may not be the desired behavior—worth confirming.

apps/meteor/tests/unit/server/services/team/service.tests.ts (3)

12-59: Clean test helper setup.

The createTeamService factory with proxyquire.noCallThru() properly isolates the unit under test. All required module dependencies are stubbed.


62-105: Good test for completion semantics.

The deferred-promise pattern correctly verifies that addMembersToDefaultRooms doesn't resolve prematurely—exactly the regression described in issue #38700.


107-134: Solid error-propagation test.

Correctly asserts that addUserToRoom rejections surface to the caller. The try/catch approach is clear and readable.

✏️ Tip: You can disable this entire section by setting review_details to false in your review settings.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This pull request fixes a critical bug in TeamService.addMembersToDefaultRooms where async operations were not properly awaited, causing the function to return before users were actually added to default team rooms and silently dropping errors.

Changes:

  • Wrapped async room processing operations with Promise.all() to ensure completion before function returns
  • Changed for await to for for iterating over regular arrays
  • Added comprehensive unit tests to verify completion semantics and error propagation

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated no comments.

File Description
apps/meteor/server/services/team/service.ts Fixed addMembersToDefaultRooms to properly await all async default-room membership operations using Promise.all()
apps/meteor/tests/unit/server/services/team/service.tests.ts Added new test file with two regression tests: one verifying completion semantics and another verifying error propagation

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

resolved = true;
});

await flushMicrotasks();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I’m using flushMicrotasks() here because resolved is set inside operation.then(...), and that callback only runs once the microtask queue is processed ,Without yeilding to microtasks first, resolved could still be false simply because the .then() hasn’t executed yet — not because addMembersToDefaultRooms() is actually still pending

Flushing microtasks makes the assertion meaningful, and after that point, if resolved is still false, it confirms the function is waiting for the second addUserToRoom promise to resolve, which is the behavior the test is validating.

Copy link
Contributor

@cubic-dev-ai cubic-dev-ai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No issues found across 2 files

@codecov
Copy link

codecov bot commented Feb 15, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 70.59%. Comparing base (11e1c51) to head (7f5e06f).
⚠️ Report is 1 commits behind head on develop.

Additional details and impacted files

Impacted file tree graph

@@             Coverage Diff             @@
##           develop   #38701      +/-   ##
===========================================
+ Coverage    70.49%   70.59%   +0.10%     
===========================================
  Files         3175     3176       +1     
  Lines       111094   111153      +59     
  Branches     20045    20039       -6     
===========================================
+ Hits         78311    78464     +153     
+ Misses       30738    30652      -86     
+ Partials      2045     2037       -8     
Flag Coverage Δ
unit 71.14% <100.00%> (-0.34%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

TeamService.addMembersToDefaultRooms resolves before default-room membership completes

2 participants