Skip to content

Conversation

@dougfabris
Copy link
Member

@dougfabris dougfabris commented Nov 7, 2025

Proposed changes (including videos or screenshots)

Kapture 2025-11-10 at 16 38 15

Issue(s)

Steps to test or reproduce

Further comments

CORE-1429

Summary by CodeRabbit

  • Bug Fixes

    • Custom status now updates and clears immediately; presence updates reliably reflect empty or changed statuses.
    • Presence notifications consistently include the status text field so updates display predictably.
  • User Experience

    • Toasts are dismissed after saving a custom status for a smoother profile interaction.
  • Tests

    • Enhanced end-to-end tests for custom status flows (dynamic generation, updating, clearing, and verification).

✏️ Tip: You can customize this high-level summary in your review settings.

@dionisio-bot
Copy link
Contributor

dionisio-bot bot commented Nov 7, 2025

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

  • This PR is targeting the wrong base branch. It should target 7.14.0, but it targets 7.13.0

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 Nov 7, 2025

🦋 Changeset detected

Latest commit: 71763ab

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 41 packages
Name Type
@rocket.chat/meteor Patch
@rocket.chat/core-typings Patch
@rocket.chat/rest-typings Patch
@rocket.chat/uikit-playground Patch
@rocket.chat/api-client Patch
@rocket.chat/apps Patch
@rocket.chat/core-services Patch
@rocket.chat/cron Patch
@rocket.chat/ddp-client Patch
@rocket.chat/freeswitch Patch
@rocket.chat/fuselage-ui-kit Patch
@rocket.chat/gazzodown Patch
@rocket.chat/http-router Patch
@rocket.chat/livechat Patch
@rocket.chat/model-typings Patch
@rocket.chat/ui-avatar Patch
@rocket.chat/ui-client Patch
@rocket.chat/ui-contexts Patch
@rocket.chat/web-ui-registration Patch
@rocket.chat/account-service Patch
@rocket.chat/authorization-service Patch
@rocket.chat/ddp-streamer Patch
@rocket.chat/omnichannel-transcript Patch
@rocket.chat/presence-service Patch
@rocket.chat/queue-worker Patch
@rocket.chat/stream-hub-service Patch
@rocket.chat/federation-matrix Patch
@rocket.chat/license Patch
@rocket.chat/media-calls Patch
@rocket.chat/omnichannel-services Patch
@rocket.chat/pdf-worker Patch
@rocket.chat/presence Patch
rocketchat-services Patch
@rocket.chat/models Patch
@rocket.chat/network-broker Patch
@rocket.chat/omni-core-ee Patch
@rocket.chat/mock-providers Patch
@rocket.chat/ui-video-conf Patch
@rocket.chat/ui-voip Patch
@rocket.chat/instance-status Patch
@rocket.chat/omni-core Patch

Not sure what this means? Click here to learn what changesets are.

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

@dougfabris dougfabris added this to the 7.13.0 milestone Nov 7, 2025
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Nov 7, 2025

Walkthrough

Always include statusText in presence diffs (may be undefined); changeStatus/setStatus flow updated to control broadcasts and persist cleared status; E2E helpers and tests updated to set and clear custom status and to dismiss toasts.

Changes

Cohort / File(s) Summary
Changeset
\.changeset/grumpy-colts-collect.md
Adds a changeset entry for @rocket.chat/meteor (patch) documenting bug fix for custom status not updating immediately when cleared.
Presence listener
apps/meteor/server/modules/listeners/listeners.module.ts
Ensure presence diffs always include a statusText property (may be undefined) in the diff payload.
Users API / status route
apps/meteor/app/api/server/v1/users.ts
Destructure status/statusText, update DB with status/statusDefault together, avoid immediate in-block broadcast, emit a final presence broadcast including statusText, status, and previousStatus.
setStatusText implementation
apps/meteor/app/lib/server/functions/setStatusText.ts, apps/meteor/app/lib/server/functions/saveUser/saveUser.ts
Change _setStatusText signature to accept options object { updater, session, emit = true }; normalize/truncate statusText; make broadcasting conditional on emit; update callers to pass options object (saveUser).
E2E spec
apps/meteor/tests/e2e/presence.spec.ts
Replace hardcoded status with faker-generated value; use new HomeSidenav.changeUserCustomStatus API; add step to clear custom status ('') and assert empty status is persisted/cleared in UI.
Page-objects — Home sidenav
apps/meteor/tests/e2e/page-objects/fragments/home-sidenav.ts
Add async changeUserCustomStatus(text: string): Promise<void> that opens profile, selects Custom Status, and delegates to EditStatusModal.changeStatusMessage.
Page-objects — Edit status modal & toasts
apps/meteor/tests/e2e/page-objects/fragments/edit-status-modal.ts, apps/meteor/tests/e2e/page-objects/fragments/toast-messages.ts
Remove stored page field from EditStatusModal; add/import ToastMessages, initialize it, and dismiss toast after saving status.

Sequence Diagram(s)

sequenceDiagram
  participant Test as E2E Test
  participant Sidenav as HomeSidenav / EditStatusModal
  participant API as Meteor API (users.setStatus / setStatusText)
  participant Listener as Presence Listener
  participant Clients as Other Clients

  Note over Test,Sidenav: Test triggers set or clear custom status
  Test->>Sidenav: changeUserCustomStatus(text)
  Sidenav->>Sidenav: open EditStatusModal, changeStatusMessage(text), dismiss toast
  Sidenav->>API: POST users.setStatus (status?, statusText?)
  API->>API: validate, update DB (status + statusText)
  API->>Listener: build presence diff (status, statusText always present)
  Listener->>Clients: broadcast presence diff
  Clients->>Clients: render presence (show or clear custom status)
  Note over Test: E2E asserts UI reflects update or cleared status
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

  • Review attention:
    • Callers of setStatusText updated to use the options object (e.g., saveUser).
    • Broadcast timing/shape changes in users.setStatus and the presence listener (clients may expect omitted vs. undefined statusText).
    • E2E changes: toast dismissal and new HomeSidenav API usage; verify test stability with faker-driven values.

Possibly related PRs

Suggested labels

stat: ready to merge, stat: QA assured

Suggested reviewers

  • ricardogarim
  • MartinSchoeler

Poem

🐇 I nibbled through code where the status once clung,
Now statusText travels — defined or unsung.
I cleared all the words and dismissed every toast,
Tests hop and they pass, the bug is the ghost.
Carrots for CI — cheer from the host!

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and specifically describes the bug fix: preventing custom status from failing to update immediately when set to an empty value.
Linked Issues check ✅ Passed Code changes comprehensively address CORE-1429 requirements: backend handles empty statusText properly [users.ts, setStatusText.ts], frontend updates status immediately via new API [home-sidenav.ts], and E2E tests verify empty status persists [presence.spec.ts].
Out of Scope Changes check ✅ Passed All code changes relate directly to fixing the custom status empty value update issue. Infrastructure changes (toast dismissal in EditStatusModal, conditional broadcast logic) are necessary to support the fix and remain in scope.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch fix/statusText-reactivity

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.

@codecov
Copy link

codecov bot commented Nov 7, 2025

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 68.82%. Comparing base (355d26d) to head (71763ab).
⚠️ Report is 47 commits behind head on develop.

Additional details and impacted files

Impacted file tree graph

@@             Coverage Diff             @@
##           develop   #37443      +/-   ##
===========================================
+ Coverage    68.79%   68.82%   +0.02%     
===========================================
  Files         3361     3362       +1     
  Lines       114201   114214      +13     
  Branches     20619    20660      +41     
===========================================
+ Hits         78563    78604      +41     
+ Misses       33543    33515      -28     
  Partials      2095     2095              
Flag Coverage Δ
e2e 57.34% <ø> (+0.09%) ⬆️
e2e-api 42.19% <100.00%> (-0.06%) ⬇️

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.

@dougfabris dougfabris force-pushed the fix/statusText-reactivity branch from 81f03d2 to fef4820 Compare November 10, 2025 19:42
@dougfabris dougfabris marked this pull request as ready for review November 10, 2025 19:43
@dougfabris dougfabris requested review from a team as code owners November 10, 2025 19:43
cardoso
cardoso previously approved these changes Nov 12, 2025
Copy link
Member

@cardoso cardoso left a comment

Choose a reason for hiding this comment

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

LGTM!

@cardoso
Copy link
Member

cardoso commented Nov 12, 2025

It looks like this test is flaky :

await test.step('user1 custom status should be empty', async () => {
await poHomeChannel.sidenav.openChat('user1');
await expect(poHomeChannel.content.channelHeader).not.toContainText('new status');
});

I think the status text should be generated using faker. And it actually isn't testing whether the status is empty, just that it doesn't contain "new status".

@dougfabris
Copy link
Member Author

dougfabris commented Nov 12, 2025

It looks like this test is flaky :

I know, I'm trying to figure out why

I think the status text should be generated using faker.

why ?

And it actually isn't testing whether the status is empty, just that it doesn't contain "new status".

if the menu doesn't contain the status text that it used to have previously, I think we achieve the result we want. Don't we?

@cardoso
Copy link
Member

cardoso commented Nov 12, 2025

why ?

If the test relies on a fixed string like "new status", another test or a retry of the same test can break that expectation, causing flakyness.

if the menu doesn't contain the status text that it used to have previously, I think we achieve the result we want. Don't we?

Maybe, but it's better to target exactly the status if possible:

    Expected string: not "new status"
    Received string: "rocketchat.internal.admin.testnew statusStatusonlineawaybusyofflineCustom StatusNew voice callAccountProfilePreferencesAccessibility & appearance❪Logout"

Ideally this would be:

    Expected string: not "new status"
    Received string: "new status"

@dougfabris
Copy link
Member Author

dougfabris commented Nov 12, 2025

If the test relies on a fixed string like "new status", another test or a retry of the same test can break that expectation, causing flakyness.

I think its difficult, but yet, possible

Maybe, but it's better to target exactly the status if possible:

I'm afraid its not since Im looking for plain text, no semantic tag besides the menu.
Changing for a random faker will fix a possible problem, though

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Nitpick comments (1)
apps/meteor/tests/e2e/page-objects/fragments/home-sidenav.ts (1)

256-262: Good Page Object abstraction, but consider stable selectors for menu options.

The method correctly encapsulates the custom status change flow and follows the Page Object Model pattern. The delegation to EditStatusModal promotes reusability.

However, Line 260 uses the localized string 'Custom Status' to identify the menu option. If the application supports multiple languages or the menu text changes, this test will break. Consider using a stable selector like a data-qa attribute instead.

Based on learnings

Example refactor if a data-qa attribute is available:

-		await this.getUserProfileMenuOption('Custom Status').click();
+		await this.userProfileMenu.getByRole('menuitemcheckbox', { name: '', exact: true }).locator('[data-qa="custom-status-option"]').click();

Note: This pattern also applies to existing menu interactions in this file (e.g., lines 102, 106, 110), which could be addressed in a follow-up refactor.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

Disabled knowledge base sources:

  • Jira integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between fef4820 and 625f0cf.

📒 Files selected for processing (3)
  • apps/meteor/tests/e2e/page-objects/fragments/edit-status-modal.ts (0 hunks)
  • apps/meteor/tests/e2e/page-objects/fragments/home-sidenav.ts (2 hunks)
  • apps/meteor/tests/e2e/presence.spec.ts (2 hunks)
💤 Files with no reviewable changes (1)
  • apps/meteor/tests/e2e/page-objects/fragments/edit-status-modal.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • apps/meteor/tests/e2e/presence.spec.ts
🧰 Additional context used
📓 Path-based instructions (3)
apps/meteor/tests/e2e/page-objects/**/*.ts

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

Utilize and place Page Object implementations under apps/meteor/tests/e2e/page-objects/

Files:

  • apps/meteor/tests/e2e/page-objects/fragments/home-sidenav.ts
apps/meteor/tests/e2e/**/*.{ts,tsx,js,jsx}

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

apps/meteor/tests/e2e/**/*.{ts,tsx,js,jsx}: Write concise, technical TypeScript/JavaScript with accurate typing
Follow DRY by extracting reusable logic into helper functions or page objects
Avoid code comments in the implementation

Files:

  • apps/meteor/tests/e2e/page-objects/fragments/home-sidenav.ts
apps/meteor/tests/e2e/**/*.{ts,tsx}

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

apps/meteor/tests/e2e/**/*.{ts,tsx}: Avoid using page.locator(); prefer semantic locators like page.getByRole, page.getByLabel, page.getByText, and page.getByTitle
Store commonly used locators in variables/constants for reuse
Use page.waitFor() with specific conditions and avoid hardcoded timeouts
Implement proper wait strategies for dynamic content
Follow the Page Object Model pattern consistently

Files:

  • apps/meteor/tests/e2e/page-objects/fragments/home-sidenav.ts
🧠 Learnings (12)
📚 Learning: 2025-09-16T22:08:51.490Z
Learnt from: CR
Repo: RocketChat/Rocket.Chat PR: 0
File: .cursor/rules/playwright.mdc:0-0
Timestamp: 2025-09-16T22:08:51.490Z
Learning: Applies to apps/meteor/tests/e2e/**/*.spec.ts : Use descriptive test names that clearly communicate expected behavior

Applied to files:

  • apps/meteor/tests/e2e/page-objects/fragments/home-sidenav.ts
📚 Learning: 2025-09-16T22:08:51.490Z
Learnt from: CR
Repo: RocketChat/Rocket.Chat PR: 0
File: .cursor/rules/playwright.mdc:0-0
Timestamp: 2025-09-16T22:08:51.490Z
Learning: Applies to apps/meteor/tests/e2e/page-objects/**/*.ts : Utilize and place Page Object implementations under apps/meteor/tests/e2e/page-objects/

Applied to files:

  • apps/meteor/tests/e2e/page-objects/fragments/home-sidenav.ts
📚 Learning: 2025-09-16T22:08:51.490Z
Learnt from: CR
Repo: RocketChat/Rocket.Chat PR: 0
File: .cursor/rules/playwright.mdc:0-0
Timestamp: 2025-09-16T22:08:51.490Z
Learning: Applies to apps/meteor/tests/e2e/**/*.{ts,tsx} : Follow the Page Object Model pattern consistently

Applied to files:

  • apps/meteor/tests/e2e/page-objects/fragments/home-sidenav.ts
📚 Learning: 2025-09-16T22:08:51.490Z
Learnt from: CR
Repo: RocketChat/Rocket.Chat PR: 0
File: .cursor/rules/playwright.mdc:0-0
Timestamp: 2025-09-16T22:08:51.490Z
Learning: Applies to apps/meteor/tests/e2e/**/*.spec.ts : Prefer web-first assertions (e.g., toBeVisible, toHaveText)

Applied to files:

  • apps/meteor/tests/e2e/page-objects/fragments/home-sidenav.ts
📚 Learning: 2025-09-16T22:08:51.490Z
Learnt from: CR
Repo: RocketChat/Rocket.Chat PR: 0
File: .cursor/rules/playwright.mdc:0-0
Timestamp: 2025-09-16T22:08:51.490Z
Learning: Applies to apps/meteor/tests/e2e/**/*.spec.ts : Utilize Playwright fixtures (test, page, expect) consistently

Applied to files:

  • apps/meteor/tests/e2e/page-objects/fragments/home-sidenav.ts
📚 Learning: 2025-09-16T22:08:51.490Z
Learnt from: CR
Repo: RocketChat/Rocket.Chat PR: 0
File: .cursor/rules/playwright.mdc:0-0
Timestamp: 2025-09-16T22:08:51.490Z
Learning: Applies to apps/meteor/tests/e2e/**/*.{ts,tsx} : Implement proper wait strategies for dynamic content

Applied to files:

  • apps/meteor/tests/e2e/page-objects/fragments/home-sidenav.ts
📚 Learning: 2025-09-16T22:08:51.490Z
Learnt from: CR
Repo: RocketChat/Rocket.Chat PR: 0
File: .cursor/rules/playwright.mdc:0-0
Timestamp: 2025-09-16T22:08:51.490Z
Learning: Applies to apps/meteor/tests/e2e/**/*.{ts,tsx} : Store commonly used locators in variables/constants for reuse

Applied to files:

  • apps/meteor/tests/e2e/page-objects/fragments/home-sidenav.ts
📚 Learning: 2025-09-16T22:08:51.490Z
Learnt from: CR
Repo: RocketChat/Rocket.Chat PR: 0
File: .cursor/rules/playwright.mdc:0-0
Timestamp: 2025-09-16T22:08:51.490Z
Learning: Applies to apps/meteor/tests/e2e/**/*.{ts,tsx} : Avoid using page.locator(); prefer semantic locators like page.getByRole, page.getByLabel, page.getByText, and page.getByTitle

Applied to files:

  • apps/meteor/tests/e2e/page-objects/fragments/home-sidenav.ts
📚 Learning: 2025-09-16T22:08:51.490Z
Learnt from: CR
Repo: RocketChat/Rocket.Chat PR: 0
File: .cursor/rules/playwright.mdc:0-0
Timestamp: 2025-09-16T22:08:51.490Z
Learning: Applies to apps/meteor/tests/e2e/**/*.{ts,tsx,js,jsx} : Follow DRY by extracting reusable logic into helper functions or page objects

Applied to files:

  • apps/meteor/tests/e2e/page-objects/fragments/home-sidenav.ts
📚 Learning: 2025-09-16T22:08:51.490Z
Learnt from: CR
Repo: RocketChat/Rocket.Chat PR: 0
File: .cursor/rules/playwright.mdc:0-0
Timestamp: 2025-09-16T22:08:51.490Z
Learning: Applies to apps/meteor/tests/e2e/**/*.{ts,tsx} : Use page.waitFor() with specific conditions and avoid hardcoded timeouts

Applied to files:

  • apps/meteor/tests/e2e/page-objects/fragments/home-sidenav.ts
📚 Learning: 2025-09-16T22:08:51.490Z
Learnt from: CR
Repo: RocketChat/Rocket.Chat PR: 0
File: .cursor/rules/playwright.mdc:0-0
Timestamp: 2025-09-16T22:08:51.490Z
Learning: Applies to apps/meteor/tests/e2e/**/*.spec.ts : All Playwright test files must be located under apps/meteor/tests/e2e/ and use the .spec.ts extension (e.g., login.spec.ts)

Applied to files:

  • apps/meteor/tests/e2e/page-objects/fragments/home-sidenav.ts
📚 Learning: 2025-09-23T19:22:59.217Z
Learnt from: dougfabris
Repo: RocketChat/Rocket.Chat PR: 36987
File: apps/meteor/tests/e2e/page-objects/fragments/room-toolbar.ts:10-20
Timestamp: 2025-09-23T19:22:59.217Z
Learning: In Playwright e2e tests, prefer stable selectors like data-qa-id attributes over localized text in getByRole() or getByText() calls to prevent test failures when UI language changes. Test translations separately by validating actual text content after ensuring UI interactions work with stable selectors.

Applied to files:

  • apps/meteor/tests/e2e/page-objects/fragments/home-sidenav.ts
🧬 Code graph analysis (1)
apps/meteor/tests/e2e/page-objects/fragments/home-sidenav.ts (1)
apps/meteor/tests/e2e/page-objects/fragments/edit-status-modal.ts (1)
  • EditStatusModal (5-18)
⏰ 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). (3)
  • GitHub Check: 📦 Build Packages
  • GitHub Check: CodeQL-Build
  • GitHub Check: CodeQL-Build

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Nitpick comments (1)
apps/meteor/tests/e2e/page-objects/fragments/edit-status-modal.ts (1)

18-22: Consider waiting for toast visibility before dismissing.

The method dismisses the toast immediately after saving without waiting for it to appear or verifying save success. This could introduce a race condition where dismissToast() is called before the toast is visible, or mask failures if an error toast appears instead.

Consider adding explicit wait for toast visibility:

 async changeStatusMessage(statusMessage: string): Promise<void> {
   await this.statusMessageInput.fill(statusMessage);
   await this.save();
+  await this.toastMessages.waitForDisplay({ type: 'success' });
   await this.toastMessages.dismissToast();
 }

Alternatively, if error cases are expected, consider handling both success and error toasts based on the operation result.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

Disabled knowledge base sources:

  • Jira integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 625f0cf and 5b842c9.

📒 Files selected for processing (1)
  • apps/meteor/tests/e2e/page-objects/fragments/edit-status-modal.ts (2 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
apps/meteor/tests/e2e/page-objects/fragments/edit-status-modal.ts (1)
apps/meteor/tests/e2e/page-objects/fragments/toast-messages.ts (1)
  • ToastMessages (5-29)
⏰ 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). (3)
  • GitHub Check: 📦 Build Packages
  • GitHub Check: CodeQL-Build
  • GitHub Check: CodeQL-Build
🔇 Additional comments (1)
apps/meteor/tests/e2e/page-objects/fragments/edit-status-modal.ts (1)

4-4: LGTM: Clean integration of ToastMessages.

The import, field declaration, and initialization follow proper patterns and support the new toast-handling behavior.

Also applies to: 7-7, 11-11

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Nitpick comments (1)
apps/meteor/app/api/server/v1/users.ts (1)

1347-1352: Technical debt acknowledged: double user update.

The TODO comment correctly identifies that updating the user twice (once in setStatusText and again for status/statusDefault) is suboptimal. This creates two separate database writes and potential race conditions.

However, the empty string handling on line 1350 properly addresses the PR's core objective—allowing custom status text to be cleared immediately.

Consider consolidating both updates into a single database write in a future refactor to improve performance and eliminate race conditions. This could be done by:

  1. Building a complete update object that includes both statusText and status changes
  2. Performing a single Users.updateOne() call
  3. Broadcasting once with all changed fields
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

Disabled knowledge base sources:

  • Jira integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 5b842c9 and 6eea0dc.

📒 Files selected for processing (1)
  • apps/meteor/app/api/server/v1/users.ts (2 hunks)
⏰ 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). (3)
  • GitHub Check: 📦 Build Packages
  • GitHub Check: CodeQL-Build
  • GitHub Check: CodeQL-Build
🔇 Additional comments (2)
apps/meteor/app/api/server/v1/users.ts (2)

1354-1386: Good optimization: guard prevents unnecessary status updates.

The guard condition status !== this.bodyParams.status (line 1354) properly prevents unnecessary database writes and broadcasts when the status hasn't actually changed. This improves performance and reduces noise in the presence system.

The logic correctly handles:

  • Status validation against allowed values
  • Permission check for invisible status
  • Database update with both status and statusDefault
  • Cancellation of upcoming calendar status changes

1376-1376: Verification complete—statusText broadcast mechanism is working correctly.

The removal of statusText from line 1376 is intentional and correct. When setStatusText is called, it:

  1. Updates the user document in the database
  2. Explicitly broadcasts a presence.status event that includes statusText
  3. The listeners module (apps/meteor/server/modules/listeners/listeners.module.ts) receives this event and broadcasts statusText through multiple notification paths (userData, user-status, and sendPresence())

This represents a clean separation: line 1376 broadcasts status changes (online/away/busy/offline), while statusText changes flow through the dedicated presence event listener architecture. The PR's objective—ensuring empty status text updates are reflected immediately—is properly satisfied through this mechanism.

@dougfabris dougfabris force-pushed the fix/statusText-reactivity branch from 532fb00 to c9c9a79 Compare November 13, 2025 18:16
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Nitpick comments (1)
apps/meteor/app/lib/server/functions/setStatusText.ts (1)

29-29: Replace deprecated substr with slice.

The substr method is deprecated. Use slice or substring instead.

Apply this diff:

-	statusText = statusText.trim().substr(0, 120);
+	statusText = statusText.trim().slice(0, 120);
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

Disabled knowledge base sources:

  • Jira integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 6eea0dc and c9c9a79.

📒 Files selected for processing (4)
  • apps/meteor/app/api/server/v1/users.ts (2 hunks)
  • apps/meteor/app/lib/server/functions/saveUser/saveUser.ts (1 hunks)
  • apps/meteor/app/lib/server/functions/setStatusText.ts (2 hunks)
  • apps/meteor/tests/e2e/presence.spec.ts (2 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • apps/meteor/app/api/server/v1/users.ts
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: 2025-10-06T20:30:45.540Z
Learnt from: d-gubert
Repo: RocketChat/Rocket.Chat PR: 37152
File: packages/apps-engine/tests/test-data/storage/storage.ts:101-122
Timestamp: 2025-10-06T20:30:45.540Z
Learning: In `packages/apps-engine/tests/test-data/storage/storage.ts`, the stub methods (updatePartialAndReturnDocument, updateStatus, updateSetting, updateAppInfo, updateMarketplaceInfo) intentionally throw "Method not implemented." Tests using these methods must stub them using `SpyOn` from the test library rather than relying on actual implementations.

Applied to files:

  • apps/meteor/tests/e2e/presence.spec.ts
🧬 Code graph analysis (3)
apps/meteor/tests/e2e/presence.spec.ts (1)
apps/meteor/tests/e2e/page-objects/home-channel.ts (1)
  • HomeChannel (6-120)
apps/meteor/app/lib/server/functions/setStatusText.ts (2)
packages/models/src/index.ts (1)
  • Updater (138-138)
packages/core-typings/src/IUser.ts (1)
  • IUser (186-255)
apps/meteor/app/lib/server/functions/saveUser/saveUser.ts (1)
apps/meteor/app/lib/server/functions/setStatusText.ts (1)
  • setStatusText (63-69)
⏰ 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). (3)
  • GitHub Check: 📦 Build Packages
  • GitHub Check: CodeQL-Build
  • GitHub Check: CodeQL-Build
🔇 Additional comments (5)
apps/meteor/tests/e2e/presence.spec.ts (2)

1-1: Good addition - addresses test flakiness.

Using faker to generate dynamic status text prevents test interference when tests run concurrently or are retried, directly addressing the flakiness concerns raised in the PR comments.

Also applies to: 40-40


66-76: LGTM - test validates the bug fix.

This test correctly validates that custom status can be cleared by passing an empty string. The use of toPass() on line 75 properly handles potential timing issues with reactivity updates.

apps/meteor/app/lib/server/functions/saveUser/saveUser.ts (1)

128-128: LGTM - signature change aligns with updated API.

The call to setStatusText correctly uses the new options object signature, maintaining the same parameters (updater and session) in the new format.

apps/meteor/app/lib/server/functions/setStatusText.ts (2)

12-24: LGTM - cleaner signature with options object.

The refactored signature using an options object improves readability and extensibility. The emit flag with a default value of true maintains backward compatibility while allowing callers to control broadcast timing.


50-58: LGTM - conditional broadcasting enables immediate updates.

The emit flag allows callers to control when presence updates are broadcast, and including statusText in the broadcast payload (line 54) enables immediate UI updates. The normalized statusText value from line 29 is correctly used in the broadcast.

@dougfabris dougfabris removed this from the 7.13.0 milestone Nov 14, 2025
@dougfabris dougfabris marked this pull request as draft November 16, 2025 14:43
@dougfabris dougfabris added this to the 7.14.0 milestone Dec 3, 2025
@github-actions
Copy link
Contributor

github-actions bot commented Dec 3, 2025

📦 Docker Image Size Report

📈 Changes

Service Current Baseline Change Percent
sum of all images 1.2GiB 1.2GiB +12MiB
rocketchat 359MiB 348MiB +12MiB
omnichannel-transcript-service 132MiB 132MiB -726B
queue-worker-service 132MiB 132MiB -439B
ddp-streamer-service 126MiB 126MiB -220B
account-service 113MiB 113MiB -1.7KiB
stream-hub-service 111MiB 111MiB -634B
authorization-service 111MiB 111MiB -360B
presence-service 111MiB 111MiB -411B

📊 Historical Trend

---
config:
  theme: "dark"
  xyChart:
    width: 900
    height: 400
---
xychart
  title "Image Size Evolution by Service (Last 30 Days + This PR)"
  x-axis ["11/15 22:28", "11/16 01:28", "11/17 23:50", "11/18 22:53", "11/19 23:02", "11/21 16:49", "11/24 17:34", "11/27 22:32", "11/28 19:05", "12/01 23:01", "12/02 21:57", "12/03 21:00", "12/04 18:17", "12/05 18:59", "12/05 19:28 (PR)"]
  y-axis "Size (GB)" 0 --> 0.5
  line "account-service" [0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11]
  line "authorization-service" [0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11]
  line "ddp-streamer-service" [0.12, 0.12, 0.12, 0.12, 0.12, 0.12, 0.12, 0.12, 0.12, 0.12, 0.12, 0.12, 0.12, 0.12, 0.12]
  line "omnichannel-transcript-service" [0.14, 0.14, 0.14, 0.14, 0.14, 0.13, 0.13, 0.13, 0.13, 0.13, 0.13, 0.13, 0.13, 0.13, 0.13]
  line "presence-service" [0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11]
  line "queue-worker-service" [0.14, 0.14, 0.14, 0.14, 0.14, 0.13, 0.13, 0.13, 0.13, 0.13, 0.13, 0.13, 0.13, 0.13, 0.13]
  line "rocketchat" [0.36, 0.36, 0.35, 0.35, 0.35, 0.34, 0.34, 0.34, 0.34, 0.34, 0.34, 0.34, 0.34, 0.34, 0.35]
  line "stream-hub-service" [0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11]
Loading

Statistics (last 14 days):

  • 📊 Average: 1.5GiB
  • ⬇️ Minimum: 1.2GiB
  • ⬆️ Maximum: 1.6GiB
  • 🎯 Current PR: 1.2GiB
ℹ️ About this report

This report compares Docker image sizes from this build against the develop baseline.

  • Tag: pr-37443
  • Baseline: develop
  • Timestamp: 2025-12-05 19:28:50 UTC
  • Historical data points: 14

Updated: Fri, 05 Dec 2025 19:28:51 GMT

@dougfabris dougfabris force-pushed the fix/statusText-reactivity branch 2 times, most recently from 271422d to 877dbb7 Compare December 4, 2025 17:38
@dougfabris dougfabris force-pushed the fix/statusText-reactivity branch from 877dbb7 to c50714d Compare December 5, 2025 12:32
@dougfabris dougfabris marked this pull request as ready for review December 5, 2025 20:03
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Nitpick comments (1)
apps/meteor/app/lib/server/functions/setStatusText.ts (1)

12-24: Options bag + emit flag look good; all callers validate statusText as string

The new { updater, session, emit = true } options bag keeps call sites cleaner and the default preserves previous behavior. All three call sites (setUserStatus, saveUser, users API) validate statusText as a string before calling—via check(statusText, String), typeof guard, and Match.Maybe(String) respectively—so the statusText.trim().substr(0, 120) normalization at line 29 will not throw. The emit flag correctly gates the broadcast (lines 50-58), preserving behavior when emit: false is used in the API endpoint. For cleaner reuse across call sites, consider hoisting the inline options type to a shared SetStatusTextOptions type alias.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

Disabled knowledge base sources:

  • Jira integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between c9c9a79 and 71763ab.

📒 Files selected for processing (2)
  • apps/meteor/app/api/server/v1/users.ts (2 hunks)
  • apps/meteor/app/lib/server/functions/setStatusText.ts (2 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • apps/meteor/app/api/server/v1/users.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/app/lib/server/functions/setStatusText.ts
🔇 Additional comments (1)
apps/meteor/app/lib/server/functions/setStatusText.ts (1)

50-58: Emit gating on presence broadcast is correct; call sites properly handle the parameter

All three server-side call sites of setStatusText correctly handle the emit parameter. The default emit: true preserves the broadcast behavior for the two sites that rely on it (setUserStatus and saveUser), and the API endpoint explicitly passes emit: false when avoiding the broadcast. The RateLimiter wrapper is compatible with this pattern.

@dougfabris dougfabris added the stat: QA assured Means it has been tested and approved by a company insider label Dec 5, 2025
@dionisio-bot dionisio-bot bot added the stat: ready to merge PR tested and approved waiting for merge label Dec 5, 2025
@ggazzo ggazzo merged commit 4186121 into develop Dec 8, 2025
53 checks passed
@ggazzo ggazzo deleted the fix/statusText-reactivity branch December 8, 2025 11:31
@dougfabris dougfabris modified the milestones: 7.14.0, 8.0.0 Jan 19, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

stat: QA assured Means it has been tested and approved by a company insider stat: ready to merge PR tested and approved waiting for merge

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants