-
Notifications
You must be signed in to change notification settings - Fork 13k
refactor: use chat.update endpoint instead of updateMessage method #37138
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
|
Looks like this PR is not ready to merge, because of the following issues:
Please fix the issues and try again If you have any trouble, please check the PR guidelines |
|
WalkthroughAdds schema-validated /v1/chat.update supporting text or encrypted content (with e2eMentions), migrates web client from Meteor method to REST, expands server updateMessage types to accept content-shaped payloads, updates REST typings/schema, adds E2E tests for encrypted edits, and centralizes fixture path helper. Changes
Sequence Diagram(s)sequenceDiagram
autonumber
participant Client as Web Client
participant API as REST /v1/chat.update
participant Auth as AuthN/AuthZ
participant Schema as isChatUpdateProps
participant Service as executeUpdateMessage
participant DB as Messages Store
Client->>API: POST /v1/chat.update { roomId, msgId, text | content, ... }
API->>Auth: validate session & permissions
Auth-->>API: OK
API->>Schema: validate oneOf (text OR encrypted)
Schema-->>API: Valid
alt Text update
API->>Service: uid, { msg, customFields?, previewUrls? }
else Encrypted update
API->>Service: uid, { content, e2eMentions? }
end
Service->>DB: apply update
DB-->>Service: updated message
Service-->>API: normalized message
API-->>Client: { success: true, message }
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Possibly related PRs
Suggested labels
Poem
Pre-merge checks and finishing touches❌ Failed checks (2 warnings)
✅ Passed checks (3 passed)
✨ Finishing touches
🧪 Generate unit tests (beta)
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. Comment |
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## develop #37138 +/- ##
========================================
Coverage 67.37% 67.38%
========================================
Files 3288 3288
Lines 111814 111815 +1
Branches 20419 20439 +20
========================================
+ Hits 75335 75342 +7
+ Misses 33789 33785 -4
+ Partials 2690 2688 -2
Flags with carried forward coverage won't be shown. Click here to find out more. 🚀 New features to boost your workflow:
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 4
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
apps/meteor/app/lib/server/methods/updateMessage.ts (1)
16-40: Fix early-return logic to handle content-based updates correctly.The early-return logic at lines 37-39 assumes
message.msgexists:const msgText = originalMessage?.attachments?.[0]?.description ?? originalMessage.msg; if (msgText === message.msg && !previewUrls && !message.customFields) { return; }For content-based updates (where
message.msgis undefined), this comparison will incorrectly trigger the early return whenmsgTextis defined butmessage.msgisundefined, preventing legitimate content updates.Apply this diff to fix the logic:
const msgText = originalMessage?.attachments?.[0]?.description ?? originalMessage.msg; - if (msgText === message.msg && !previewUrls && !message.customFields) { + if ('content' in message || (msgText === message.msg && !previewUrls && !message.customFields)) { - return; + if ('content' in message) { + // Content-based updates should always proceed + } else { + return; + } }Or more simply:
const msgText = originalMessage?.attachments?.[0]?.description ?? originalMessage.msg; - if (msgText === message.msg && !previewUrls && !message.customFields) { + if (!('content' in message) && msgText === message.msg && !previewUrls && !message.customFields) { return; }
🧹 Nitpick comments (1)
apps/meteor/tests/e2e/page-objects/fragments/home-content.ts (1)
2-2: Consider using absolute paths for robustness.The current implementation uses
relative(process.cwd(), ...)to create paths relative to the working directory. While this works if tests always run from the repository root, it's fragile and could break if the working directory changes.For more reliable path resolution, use absolute paths directly:
-import { resolve, join, relative } from 'node:path'; +import { resolve, join } from 'node:path'; -const FIXTURES_PATH = relative(process.cwd(), resolve(__dirname, '../../fixtures/files')); +const FIXTURES_PATH = resolve(__dirname, '../../fixtures/files');This eliminates dependency on the working directory and works regardless of where tests are executed from. Both
fs.readFile()and Playwright'ssetInputFiles()handle absolute paths reliably.Also applies to: 8-12
📜 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.
📒 Files selected for processing (11)
apps/meteor/app/api/server/v1/chat.ts(4 hunks)apps/meteor/app/lib/server/functions/updateMessage.ts(1 hunks)apps/meteor/app/lib/server/methods/updateMessage.ts(1 hunks)apps/meteor/client/lib/chats/data.ts(1 hunks)apps/meteor/client/startup/useRedirectToSetupWizard.ts(1 hunks)apps/meteor/tests/e2e/e2e-encryption/e2ee-encrypted-channels.spec.ts(1 hunks)apps/meteor/tests/e2e/messaging.spec.ts(2 hunks)apps/meteor/tests/e2e/page-objects/fragments/home-content.ts(5 hunks)packages/ddp-client/src/legacy/RocketchatSDKLegacy.ts(2 hunks)packages/ddp-client/src/legacy/types/SDKLegacy.ts(2 hunks)packages/rest-typings/src/v1/chat.ts(0 hunks)
💤 Files with no reviewable changes (1)
- packages/rest-typings/src/v1/chat.ts
🧰 Additional context used
📓 Path-based instructions (4)
apps/meteor/tests/e2e/**/*.spec.ts
📄 CodeRabbit inference engine (.cursor/rules/playwright.mdc)
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)
Use descriptive test names that clearly communicate expected behavior
Use test.beforeAll() and test.afterAll() for setup and teardown
Use test.step() to organize complex test scenarios
Group related tests in the same file
Utilize Playwright fixtures (test, page, expect) consistently
Prefer web-first assertions (e.g., toBeVisible, toHaveText)
Use expect matchers (toEqual, toContain, toBeTruthy, toHaveLength, etc.) instead of assert statements
Maintain test isolation between test cases
Ensure a clean state for each test execution
Ensure tests run reliably in parallel without shared state conflicts
Files:
apps/meteor/tests/e2e/messaging.spec.tsapps/meteor/tests/e2e/e2e-encryption/e2ee-encrypted-channels.spec.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/messaging.spec.tsapps/meteor/tests/e2e/page-objects/fragments/home-content.tsapps/meteor/tests/e2e/e2e-encryption/e2ee-encrypted-channels.spec.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/messaging.spec.tsapps/meteor/tests/e2e/page-objects/fragments/home-content.tsapps/meteor/tests/e2e/e2e-encryption/e2ee-encrypted-channels.spec.ts
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-content.ts
🧠 Learnings (6)
📚 Learning: 2025-09-16T22:08:51.490Z
Learnt from: CR
PR: RocketChat/Rocket.Chat#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/messaging.spec.ts
📚 Learning: 2025-09-16T22:08:51.490Z
Learnt from: CR
PR: RocketChat/Rocket.Chat#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-content.ts
📚 Learning: 2025-09-16T22:08:51.490Z
Learnt from: CR
PR: RocketChat/Rocket.Chat#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-content.ts
📚 Learning: 2025-09-16T22:08:51.490Z
Learnt from: CR
PR: RocketChat/Rocket.Chat#0
File: .cursor/rules/playwright.mdc:0-0
Timestamp: 2025-09-16T22:08:51.490Z
Learning: Applies to apps/meteor/tests/e2e/**/*.spec.ts : Group related tests in the same file
Applied to files:
apps/meteor/tests/e2e/page-objects/fragments/home-content.ts
📚 Learning: 2025-09-16T22:08:51.490Z
Learnt from: CR
PR: RocketChat/Rocket.Chat#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-content.ts
📚 Learning: 2025-09-16T22:08:51.490Z
Learnt from: CR
PR: RocketChat/Rocket.Chat#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-content.ts
🧬 Code graph analysis (4)
apps/meteor/app/lib/server/methods/updateMessage.ts (1)
packages/core-typings/src/IMessage/IMessage.ts (1)
IMessage(138-239)
apps/meteor/app/lib/server/functions/updateMessage.ts (1)
packages/core-typings/src/IMessage/IMessage.ts (1)
IMessage(138-239)
apps/meteor/client/lib/chats/data.ts (2)
packages/core-typings/src/IMessage/IMessage.ts (1)
IEditedMessage(259-262)apps/meteor/app/utils/client/lib/SDKClient.ts (1)
sdk(271-271)
apps/meteor/app/api/server/v1/chat.ts (3)
packages/core-typings/src/IRoom.ts (1)
IRoom(21-95)packages/core-typings/src/IMessage/IMessage.ts (1)
IMessage(138-239)apps/meteor/app/lib/server/methods/updateMessage.ts (1)
executeUpdateMessage(16-99)
🔇 Additional comments (8)
apps/meteor/tests/e2e/e2e-encryption/e2ee-encrypted-channels.spec.ts (2)
323-345: LGTM! Well-structured test for encrypted message editing.The test properly verifies the encrypted message editing flow:
- Creates an isolated test environment with a unique channel
- Verifies encryption state before and after editing
- Uses web-first assertions and semantic locators
- Follows the existing page object pattern consistently
347-381: LGTM! Comprehensive test for editing encrypted messages with mentions.The test effectively verifies mention handling in edited encrypted messages:
- Distinguishes between input format (
@user1,#general) and displayed format (user1,general)- Validates both user and channel mention rendering using semantic locators
- Maintains proper test isolation and follows established patterns
apps/meteor/tests/e2e/page-objects/fragments/home-content.ts (1)
389-389: Good refactor for DRY compliance.Extracting the fixture path construction into the
getFilePath()helper centralizes path management and makes the code more maintainable. This follows the coding guideline to extract reusable logic into helper functions.Based on coding guidelines
Also applies to: 405-405, 421-421, 437-437
packages/ddp-client/src/legacy/types/SDKLegacy.ts (1)
2-2: Verify/v1/chat.updatetypings in@rocket.chat/rest-typings
No references tochat.updateorOperationParams<...chat.update>were found in the REST-typings package. Confirm the endpoint typings weren’t removed unintentionally—if they’re missing, restore or update the import and method signature in SDKLegacy.ts to keep strong typing.apps/meteor/tests/e2e/messaging.spec.ts (1)
176-176: LGTM! Test endpoints correctly updated for chat.update migration.The test assertions have been updated to expect calls to
/api/v1/chat.updateinstead of/api/v1/method.call/updateMessage, correctly reflecting the migration from Meteor methods to the REST endpoint.As per coding guidelines
Also applies to: 187-187
apps/meteor/app/api/server/v1/chat.ts (1)
405-446: LGTM! Route implementation correctly handles both update variants.The route correctly:
- Validates the request body using the schema
- Fetches and validates the message exists
- Checks roomId matches
- Constructs appropriate updateData based on whether
contentis present- Calls executeUpdateMessage with proper parameters
- Normalizes the response message
The conditional payload construction at lines 419-435 properly handles both text-based and content-based updates, passing the correct fields to
executeUpdateMessage.apps/meteor/client/lib/chats/data.ts (1)
178-196: No changes needed: payload construction is safe
IMessage.msg is non-optional and content is optional, so the!message.contentbranch always has a definedmsgand the branches enforce mutual exclusivity.Likely an incorrect or invalid review comment.
apps/meteor/app/lib/server/functions/updateMessage.ts (1)
13-18: Ensure URL parsing and pre-save hooks support content-only messages.
- Confirm
parseUrlsInMessagecorrectly processesmessage.contentwhenmsgis undefined.- Verify
Message.beforeSavehandles thecontentfield variant and persists it.- Check that the
if (!editedMessage.msg) delete editedMessage.mdlogic safely applies only to content-based updates.
|
@ggazzo can you confirm if I needed to make the changes to rest-typings and ddp-client? I remember it being necessary at some point to use the new pattern, but maybe that was solved and I can reduce the diff here. |
a419a18 to
b863031
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 2
📜 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.
📒 Files selected for processing (2)
apps/meteor/app/api/server/v1/chat.ts(1 hunks)packages/rest-typings/src/v1/chat.ts(1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
- apps/meteor/app/api/server/v1/chat.ts
🧰 Additional context used
🧬 Code graph analysis (1)
packages/rest-typings/src/v1/chat.ts (2)
packages/core-typings/src/IRoom.ts (1)
IRoom(21-95)packages/core-typings/src/IMessage/IMessage.ts (1)
IMessage(138-239)
⏰ 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). (2)
- GitHub Check: CodeQL-Build
- GitHub Check: CodeQL-Build
🔇 Additional comments (3)
packages/rest-typings/src/v1/chat.ts (3)
449-449: LGTM!The union type correctly enforces mutual exclusivity between text-based and encrypted message updates at the TypeScript level, matching the oneOf schema structure.
503-520: LGTM!The
e2eMentionsstructure correctly mirrors the optional and nullable nature of mentions in encrypted messages, allowing flexibility for messages with no mentions, user mentions only, channel mentions only, or both.
1019-1023: LGTM!The endpoint definition correctly uses the union type for request validation and maintains a clean response contract.
yash-rajpal
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe also add another test for editing attachment description on encrypted message.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
📜 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.
📒 Files selected for processing (2)
apps/meteor/app/api/server/v1/chat.ts(1 hunks)apps/meteor/tests/end-to-end/api/chat.ts(1 hunks)
🧰 Additional context used
🧬 Code graph analysis (2)
apps/meteor/tests/end-to-end/api/chat.ts (1)
apps/meteor/tests/data/api-data.ts (3)
request(10-10)api(46-48)credentials(39-42)
apps/meteor/app/api/server/v1/chat.ts (4)
packages/rest-typings/src/v1/chat.ts (1)
isChatUpdateProps(528-528)packages/rest-typings/src/v1/Ajv.ts (3)
validateBadRequestErrorResponse(46-46)validateUnauthorizedErrorResponse(69-69)ajv(23-23)packages/core-typings/src/IMessage/IMessage.ts (1)
IMessage(138-239)apps/meteor/app/lib/server/methods/updateMessage.ts (1)
executeUpdateMessage(16-99)
⏰ 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 (3)
apps/meteor/app/api/server/v1/chat.ts (3)
308-326: LGTM! Validation logic correctly checks encrypted message type.The implementation properly addresses the concern raised in previous reviews by checking the message type from the database (
msg.t !== 'e2e') to ensure only encrypted messages can have content updates. The validation flow is clear and follows the PR objectives.
328-344: LGTM! Update payload construction correctly handles both variants.The code properly constructs different update payloads based on the message type:
- Encrypted messages: includes
contentand optionale2eMentions- Plain text messages: includes
msg(text) and optionalcustomFieldsThe type safety with
Parameters<typeof executeUpdateMessage>ensures the payload matches the expected function signature.
349-354: ```markdownVerify and handle missing
updatedMessage
Inapps/meteor/app/api/server/v1/chat.ts:349-354, ifMessages.findOneById(msg._id)can returnnull,normalizeMessagesForUser([])yieldsmessage === undefined. Add an explicit null check to return an error (e.g.API.v1.failure) or document why falling back toundefinedis acceptable.</blockquote></details> </blockquote></details> </details> <!-- This is an auto-generated comment by CodeRabbit for review status -->
Editing attachment description isn't possible right now, so the test should be added in a separate PR.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
📜 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.
📒 Files selected for processing (1)
apps/meteor/client/lib/chats/data.ts(2 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
apps/meteor/client/lib/chats/data.ts (1)
packages/core-typings/src/IMessage/IMessage.ts (2)
IEditedMessage(259-262)isEncryptedMessageContent(248-253)
⏰ 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/client/lib/chats/data.ts (2)
2-2: LGTM! Correctly imports the encryption helper.The import of
isEncryptedMessageContentaddresses the past review comment and is necessary for determining the payload shape.
180-197: Verify type guard narrowing and backend e2eMentions handling
Couldn’t locateEncryptedMessageContentor the/v1/chat.updateschema in this repo. Please confirm that
isEncryptedMessageContentproperly narrowsIEditedMessageto includecontentande2eMentions- the backend gracefully handles
e2eMentionswhen it’s omitted orundefined
The current
/v1/chat.updateREST API endpoint only supports updating messages via the text parameter, but it doesn't support the content parameter needed for End-to-End Encrypted (E2EE) messages or the e2eMentions parameter for encrypted mentions.This limitation affects mobile clients that need to:
e2eMentions)Currently, mobile clients cannot properly edit encrypted messages because:
textparameter, notcontent.e2eMentionsparameter./v1/method.call/updateMessage) in mobile is not an option as the team is moving away from Meteor methods.Proposed changes (including videos or screenshots)
Current Behavior
/v1/method.call/updateMessageMeteor method (supports bothmsgandcontent)./v1/chat.updateREST API (only supportstext, notcontent).text,roomId,msgId,previewUrls, andcustomFields.Desired Behavior
Update the
/v1/chat.updateendpoint to support both traditional and encrypted message formats.Issue(s)
https://rocketchat.atlassian.net/browse/ESH-39
Steps to test or reproduce
Try editing a message in an encrypted channel on mobile to include a channel or user mention. It will not process or display the mentions.
Further comments
Summary by CodeRabbit
New Features
Refactor
Bug Fixes
Tests