From b9aeb629be642c2ba82d7992c7bfd769fa53700a Mon Sep 17 00:00:00 2001 From: Ben Schumacher Date: Thu, 19 Mar 2026 11:33:16 +0100 Subject: [PATCH] [MM-67905] Allow full Markdown rendering in message attachment footer (#35570) Co-authored-by: Claude Opus 4.6 --- .../attachment_footer_markdown_spec.ts | 94 +++++++++++++++++++ .../message_attachment.test.tsx.snap | 21 +++-- .../message_attachment/message_attachment.tsx | 6 +- 3 files changed, 111 insertions(+), 10 deletions(-) create mode 100644 e2e-tests/cypress/tests/integration/channels/integrations/incoming_webhook/attachment_footer_markdown_spec.ts diff --git a/e2e-tests/cypress/tests/integration/channels/integrations/incoming_webhook/attachment_footer_markdown_spec.ts b/e2e-tests/cypress/tests/integration/channels/integrations/incoming_webhook/attachment_footer_markdown_spec.ts new file mode 100644 index 00000000000..055a05045fd --- /dev/null +++ b/e2e-tests/cypress/tests/integration/channels/integrations/incoming_webhook/attachment_footer_markdown_spec.ts @@ -0,0 +1,94 @@ +// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. +// See LICENSE.txt for license information. + +// *************************************************************** +// - [#] indicates a test step (e.g. # Go to a page) +// - [*] indicates an assertion (e.g. * Check the title) +// - Use element ID when selecting an element. Create one if none. +// *************************************************************** + +// Group: @channels @incoming_webhook + +describe('Integrations/Incoming Webhook', () => { + let incomingWebhook; + let testTeam; + let testChannel; + + before(() => { + // # Create and visit new channel and create incoming webhook + cy.apiInitSetup().then(({team, channel}) => { + testTeam = team; + testChannel = channel; + + const newIncomingHook = { + channel_id: channel.id, + channel_locked: true, + description: 'Incoming webhook - attachment footer markdown', + display_name: 'attachment-footer-markdown', + }; + + cy.apiCreateWebhook(newIncomingHook).then((hook) => { + incomingWebhook = hook; + }); + }); + }); + + beforeEach(() => { + cy.visit(`/${testTeam.name}/channels/${testChannel.name}`); + }); + + it('MM-67905 Attachment footer renders bold and italic markdown', () => { + const payload = { + channel: testChannel.name, + attachments: [{ + text: 'Attachment with markdown footer', + footer: 'Footer with **bold** and _italic_ text', + }], + }; + + cy.postIncomingWebhook({url: incomingWebhook.url, data: payload}); + + cy.getLastPost().within(() => { + cy.get('.attachment__footer-container').within(() => { + cy.get('strong').should('have.text', 'bold'); + cy.get('em').should('have.text', 'italic'); + }); + }); + }); + + it('MM-67905 Attachment footer renders links in markdown', () => { + const payload = { + channel: testChannel.name, + attachments: [{ + text: 'Attachment with link in footer', + footer: 'Visit [Mattermost](https://mattermost.com) for more info', + }], + }; + + cy.postIncomingWebhook({url: incomingWebhook.url, data: payload}); + + cy.getLastPost().within(() => { + cy.get('.attachment__footer-container').within(() => { + cy.get('a.markdown__link[href="https://mattermost.com"]').should('have.text', 'Mattermost'); + }); + }); + }); + + it('MM-67905 Attachment footer renders emoji in markdown', () => { + const payload = { + channel: testChannel.name, + attachments: [{ + text: 'Attachment with emoji in footer', + footer: 'All good :white_check_mark:', + }], + }; + + cy.postIncomingWebhook({url: incomingWebhook.url, data: payload}); + + cy.getLastPost().within(() => { + cy.get('.attachment__footer-container').within(() => { + cy.get('span[data-emoticon="white_check_mark"]').should('exist'); + }); + }); + }); +}); diff --git a/webapp/channels/src/components/post_view/message_attachments/message_attachment/__snapshots__/message_attachment.test.tsx.snap b/webapp/channels/src/components/post_view/message_attachments/message_attachment/__snapshots__/message_attachment.test.tsx.snap index 23e58be3c62..b0e498b2c54 100644 --- a/webapp/channels/src/components/post_view/message_attachments/message_attachment/__snapshots__/message_attachment.test.tsx.snap +++ b/webapp/channels/src/components/post_view/message_attachments/message_attachment/__snapshots__/message_attachment.test.tsx.snap @@ -97,9 +97,10 @@ exports[`components/post_view/MessageAttachment should call actions.doPostAction > - - footer - +
- - footer - +
- - aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa… - +
footer = (
{footerIcon} - {truncate(attachment.footer, {length: Constants.MAX_ATTACHMENT_FOOTER_LENGTH, omission: '…'})} +
); }