Skip to content

Conversation

@thisisamir98
Copy link
Contributor

@thisisamir98 thisisamir98 commented Dec 30, 2025

TaskWPB-15705 [Web] Messages replies

Pull Request

Summary

  • What did I change and why?
    This PR adds support for multipart message replies, extending the existing quote/reply functionality to handle multipart messages (messages with text and attachments). The implementation mirrors the existing single-part message reply handling by adding parallel code paths for multipart messages throughout the quote processing pipeline.

  • Adds quote support to MultipartMessageAddEvent type definition

  • Extends reply/quote middleware to handle multipart messages alongside regular messages

  • Updates event service filters to find replies in both message types

  • Added e2e test for replying to multipart message TC-8787

  • Risks and how to roll out / roll back (e.g. feature flags):
    none.


Security Checklist (required)

  • External inputs are validated & sanitized on client and/or server where applicable.
  • API responses are validated; unexpected shapes are handled safely (fallbacks or errors).
  • No unsafe HTML is rendered; if unavoidable, sanitization is applied and documented where it happens.
  • Injection risks (XSS/SQL/command) are prevented via safe APIs and/or escaping.

Accessibility (required)

Standards Acknowledgement (required)

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 PR adds support for multipart message replies, extending the existing quote/reply functionality to handle multipart messages (messages with text and attachments). The implementation mirrors the existing single-part message reply handling by adding parallel code paths for multipart messages throughout the quote processing pipeline.

  • Adds quote support to MultipartMessageAddEvent type definition
  • Extends reply/quote middleware to handle multipart messages alongside regular messages
  • Updates event service filters to find replies in both message types

Reviewed changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated 8 comments.

Show a summary per file
File Description
RepliesUpdaterMiddleware.ts Adds multipart message edit event handling and updates reply invalidation/update logic to support both message types
QuoteDecoderMiddleware.ts Implements quote decoding for multipart messages with new handlers for add and edit events
EventService.ts Updates event filters to search for quotes in both regular and multipart message structures
EventBuilder.ts Extends MultipartMessageAddEvent type to include quote property and associated metadata fields
MessageHasher.ts Adds hash generation support for multipart message content

@codecov
Copy link

codecov bot commented Dec 30, 2025

Codecov Report

❌ Patch coverage is 11.94030% with 59 lines in your changes missing coverage. Please review.
✅ Project coverage is 44.54%. Comparing base (5e51801) to head (f70bccf).
⚠️ Report is 29 commits behind head on dev.

Additional details and impacted files
@@            Coverage Diff             @@
##              dev   #19953      +/-   ##
==========================================
- Coverage   44.62%   44.54%   -0.08%     
==========================================
  Files        1311     1311              
  Lines       33029    33086      +57     
  Branches     7315     7334      +19     
==========================================
- Hits        14739    14738       -1     
- Misses      16539    16591      +52     
- Partials     1751     1757       +6     
🚀 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.

@github-actions
Copy link
Contributor

github-actions bot commented Dec 30, 2025

🔗 Download Full Report Artifact

🧪 Playwright Test Summary

  • Passed: 100
  • Failed: 14
  • Skipped: 11
  • 🔁 Flaky: 5
  • 📊 Total: 130
  • Total Runtime: 365.0s (~ 6 min 5 sec)
specs/Accessibility/Accessibility.spec.ts (❌ 1 failed, ⚠️ 1 flaky)
  • ❌ Accessibility > I should not lose a drafted message when switching between conversations in collapsed view (tags: TC-51, regression)
  • ⚠️ Accessibility > I want to see collapsed view when app is narrow (tags: TC-48, regression)
specs/AccountSettingsSpecs/accountSettings.spec.ts (❌ 1 failed, ⚠️ 1 flaky)
  • ❌ account settings > I should not be able to change email of user managed by SCIM (tags: TC-60, regression)
  • ⚠️ account settings > Edit Profile (tags: TC-8770, regression)
specs/AppLock/AppLock.spec.ts (❌ 1 failed, ⚠️ 0 flaky)
  • ❌ AppLock > Web: App should not lock if I switch back to webapp tab in time (during inactivity timeout) (tags: TC-2752, TC-2753, regression)
specs/ArchiveSpecs/archive.spec.ts (❌ 0 failed, ⚠️ 1 flaky)
  • ⚠️ Accessibility > I want to archive the 1on1 conversation from conversation details (tags: TC-105, regression)
specs/Authentication/authentication.spec.ts (❌ 2 failed, ⚠️ 0 flaky)
  • ❌ Authentication > Verify current browser is set as temporary device (tags: TC-3460, regression)
  • ❌ Authentication > Make sure user does not see data of user of previous sessions on same browser (tags: TC-1311, regression)
specs/Block/block.spec.ts (❌ 1 failed, ⚠️ 0 flaky)
  • ❌ Block: User A and User B are NOT in the same team > Verify you still receive messages from blocked person in a group chat (tags: TC-141, regression)
specs/ClearConversationContent/clearConversationContent.spec.ts (❌ 0 failed, ⚠️ 1 flaky)
  • ⚠️ Clear Conversation Content > I want to clear the group conversation content from conversation details options (tags: TC-424, regression)
specs/CriticalFlow/accountManagement-TC-8639.spec.ts (❌ 1 failed, ⚠️ 0 flaky)
  • ❌ Account Management (tags: TC-8639, crit-flow-web)
specs/CriticalFlow/Cells/replyingToMultipartMessage-TC-8787.spec.ts (❌ 1 failed, ⚠️ 0 flaky)
  • ❌ Replying to multipart message in a group conversation (tags: crit-flow-cells, regression, TC-8787)
specs/CriticalFlow/Cells/uploadingFileInGroupConversation.spec.ts (❌ 1 failed, ⚠️ 0 flaky)
  • ❌ Uploading an file in a group conversation (tags: crit-flow-cells, regression)
specs/CriticalFlow/oneOnOneCall-TC-8754.spec.ts (❌ 1 failed, ⚠️ 0 flaky)
  • ❌ 1:1 Video call with device switch and screenshare (tags: TC-8754, crit-flow-web)
specs/CriticalFlow/personalAccountLifecycle-TC-8638.spec.ts (❌ 0 failed, ⚠️ 1 flaky)
  • ⚠️ Personal Account Lifecycle (tags: TC-8638, crit-flow-web)
specs/LoginSpecs/login.spec.ts (❌ 1 failed, ⚠️ 0 flaky)
  • ❌ Verify you can sign in by email (tags: TC-3461, regression)
specs/RegressionSpecs/archive.spec.ts (❌ 1 failed, ⚠️ 0 flaky)
  • ❌ Archive status of conversation should only change by user explicitly changing it (tags: TC-97, TC-99, TC-104, TC-105, regression)
specs/RegressionSpecs/block-messages.spec.ts (❌ 1 failed, ⚠️ 0 flaky)
  • ❌ Block specs (tags: TC-141, regression)
specs/Reply/reply.spec.ts (❌ 1 failed, ⚠️ 0 flaky)
  • ❌ Reply > I should not be able to send a reply after I got removed from the conversation (tags: TC-3014, regression)

Copilot AI review requested due to automatic review settings December 31, 2025 11:47
@sonarqubecloud
Copy link

Quality Gate Failed Quality Gate failed

Failed conditions
16.7% Duplication on New Code (required ≤ 5%)

See analysis details on SonarQube Cloud

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

Copilot reviewed 9 out of 9 changed files in this pull request and generated 6 comments.

Comment on lines +117 to 128
/**
* will update the message ID of all the replies to an edited multipart message
*/
private async handleMultipartEditEvent(event: MultipartMessageAddEvent, originalMessageId: string) {
const {originalEvent, replies} = await this.findRepliesToMessage(event.conversation, originalMessageId, event.id);
if (!originalEvent || !event.id) {
return event;
}

this.logger.info(`Updating '${replies.length}' replies to updated multipart message '${originalMessageId}'`);
await this.updateRepliesToEditedMessage(replies, event.id);
return event;
Copy link

Copilot AI Dec 31, 2025

Choose a reason for hiding this comment

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

The handleEditEvent and handleMultipartEditEvent methods have identical implementations. Consider refactoring to eliminate this duplication by making a single method that accepts MessageAddEvent | MultipartMessageAddEvent as its parameter type.

Copilot uses AI. Check for mistakes.
? originalEvent.data.text.quote
: originalEvent.data.quote;

const decoratedData = {...event.data, text: {...event.data.text, quote: originalQuote} as any};
Copy link

Copilot AI Dec 31, 2025

Choose a reason for hiding this comment

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

The 'as any' type assertion circumvents TypeScript's type safety. The issue appears to be that MultiPartContent['text'] doesn't natively include a 'quote' property. Consider updating the type definition of MultiPartContent in the wireapp/core library to properly include quote support, or create a local type that extends MultiPartContent['text'] with the quote property to maintain type safety.

Copilot uses AI. Check for mistakes.
},
};

const decoratedData = {...event.data, text: {...event.data.text, quote: quoteData} as any};
Copy link

Copilot AI Dec 31, 2025

Choose a reason for hiding this comment

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

The 'as any' type assertion circumvents TypeScript's type safety. Consider creating a properly typed interface that extends MultiPartContent['text'] to include the quote property, maintaining type safety throughout the codebase.

Copilot uses AI. Check for mistakes.
hash: quote.quotedMessageSha256,
};

const decoratedData = {...event.data, text: {...event.data.text, quote: quoteData} as any};
Copy link

Copilot AI Dec 31, 2025

Choose a reason for hiding this comment

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

The 'as any' type assertion circumvents TypeScript's type safety. Consider creating a properly typed interface that extends MultiPartContent['text'] to include the quote property, maintaining type safety throughout the codebase.

Copilot uses AI. Check for mistakes.
if (reply.type === ClientEvent.CONVERSATION.MESSAGE_ADD) {
reply.data.quote = {error: {type: QuoteEntity.ERROR.MESSAGE_NOT_FOUND}};
} else if (reply.type === ClientEvent.CONVERSATION.MULTIPART_MESSAGE_ADD && reply.data.text) {
reply.data.text.quote = {error: {type: QuoteEntity.ERROR.MESSAGE_NOT_FOUND}} as any;
Copy link

Copilot AI Dec 31, 2025

Choose a reason for hiding this comment

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

The 'as any' type assertion circumvents TypeScript's type safety. Consider creating a properly typed interface that extends the text quote property to maintain type safety.

Suggested change
reply.data.text.quote = {error: {type: QuoteEntity.ERROR.MESSAGE_NOT_FOUND}} as any;
type TextQuote = NonNullable<NonNullable<typeof reply.data.text>['quote']>;
const messageNotFoundQuote: TextQuote = {error: {type: QuoteEntity.ERROR.MESSAGE_NOT_FOUND}};
reply.data.text.quote = messageNotFoundQuote;

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants