diff --git a/webapp/channels/src/components/post_emoji/post_emoji.test.tsx b/webapp/channels/src/components/post_emoji/post_emoji.test.tsx index a8a4b24b60..a0f0da9d26 100644 --- a/webapp/channels/src/components/post_emoji/post_emoji.test.tsx +++ b/webapp/channels/src/components/post_emoji/post_emoji.test.tsx @@ -9,6 +9,7 @@ import PostEmoji from './post_emoji'; describe('PostEmoji', () => { const baseProps = { + children: ':emoji:', imageUrl: '/api/v4/emoji/1234/image', name: 'emoji', }; @@ -26,7 +27,7 @@ describe('PostEmoji', () => { expect(screen.queryByTestId('postEmoji.:' + baseProps.name + ':')).toHaveTextContent(`:${baseProps.name}:`); }); - test('should render original text when imageUrl is empty', () => { + test('should render children as fallback when imageUrl is empty', () => { const props = { ...baseProps, imageUrl: '', diff --git a/webapp/channels/src/components/post_emoji/post_emoji.tsx b/webapp/channels/src/components/post_emoji/post_emoji.tsx index e32adec457..8cafdcbb1e 100644 --- a/webapp/channels/src/components/post_emoji/post_emoji.tsx +++ b/webapp/channels/src/components/post_emoji/post_emoji.tsx @@ -5,7 +5,8 @@ import React from 'react'; import WithTooltip from 'components/with_tooltip'; -interface Props { +export interface Props { + children: React.ReactNode; name: string; imageUrl: string; } @@ -15,12 +16,12 @@ declare module 'react' { } } -const PostEmoji = ({name, imageUrl}: Props) => { +const PostEmoji = ({children, name, imageUrl}: Props) => { const emojiText = `:${name}:`; const backgroundImageUrl = `url(${imageUrl})`; if (!imageUrl) { - return <>{emojiText}; + return <>{children}; } return ( @@ -37,7 +38,7 @@ const PostEmoji = ({name, imageUrl}: Props) => { data-testid={`postEmoji.${emojiText}`} style={{backgroundImage: backgroundImageUrl}} > - {emojiText} + {children} ); diff --git a/webapp/channels/src/utils/emoticons.tsx b/webapp/channels/src/utils/emoticons.tsx index 46280cd7e8..92fe50e14e 100644 --- a/webapp/channels/src/utils/emoticons.tsx +++ b/webapp/channels/src/utils/emoticons.tsx @@ -90,5 +90,5 @@ export function handleEmoticons( } export function renderEmoji(name: string, matchText: string): string { - return `${matchText.toLowerCase()}`; + return `${matchText}`; } diff --git a/webapp/channels/src/utils/message_html_to_component.test.tsx b/webapp/channels/src/utils/message_html_to_component.test.tsx index 1bfccf5fd1..7a093d8cbb 100644 --- a/webapp/channels/src/utils/message_html_to_component.test.tsx +++ b/webapp/channels/src/utils/message_html_to_component.test.tsx @@ -6,6 +6,7 @@ import {shallow} from 'enzyme'; import AtMention from 'components/at_mention'; import MarkdownImage from 'components/markdown_image'; +import {renderWithContext, screen} from 'tests/react_testing_utils'; import Constants from 'utils/constants'; import EmojiMap from 'utils/emoji_map'; import messageHtmlToComponent from 'utils/message_html_to_component'; @@ -146,4 +147,43 @@ const myFunction = () => { expect(messageHtmlToComponent(html)).toMatchSnapshot(); }); + + describe('emojis', () => { + test('should render valid named emojis as spans with background images', () => { + const input = 'These are emojis: :taco: :astronaut:'; + + const {container} = renderWithContext(messageHtmlToComponent(TextFormatting.formatText(input, {}, emptyEmojiMap))); + + expect(screen.getByTestId('postEmoji.:taco:')).toBeInTheDocument(); + expect(screen.getByTestId('postEmoji.:taco:').getAttribute('style')).toContain('background-image'); + expect(screen.getByTestId('postEmoji.:astronaut:')).toBeInTheDocument(); + expect(screen.getByTestId('postEmoji.:astronaut:').getAttribute('style')).toContain('background-image'); + + expect(container).toHaveTextContent('These are emojis: :taco: :astronaut:'); + }); + + test('should render invalid named emojis as spans with background images', () => { + const input = 'These are emojis: :fake: :notAnEmoji:'; + + const {container} = renderWithContext(messageHtmlToComponent(TextFormatting.formatText(input, {}, emptyEmojiMap))); + + expect(screen.queryByTestId('postEmoji.:taco:')).not.toBeInTheDocument(); + expect(screen.queryByTestId('postEmoji.:astronaut:')).not.toBeInTheDocument(); + + expect(container).toHaveTextContent('These are emojis: :fake: :notAnEmoji:'); + }); + + test('should render supported unicode emojis as spans with background images', () => { + const input = 'These are emojis: 🌮 🧑‍🚀'; + + const {container} = renderWithContext(messageHtmlToComponent(TextFormatting.formatText(input, {}, emptyEmojiMap))); + + expect(screen.getByTestId('postEmoji.:taco:')).toBeInTheDocument(); + expect(screen.getByTestId('postEmoji.:taco:').getAttribute('style')).toContain('background-image'); + expect(screen.getByTestId('postEmoji.:astronaut:')).toBeInTheDocument(); + expect(screen.getByTestId('postEmoji.:astronaut:').getAttribute('style')).toContain('background-image'); + + expect(container).toHaveTextContent('These are emojis: 🌮 🧑‍🚀'); + }); + }); }); diff --git a/webapp/channels/src/utils/message_html_to_component.tsx b/webapp/channels/src/utils/message_html_to_component.tsx index bc3b557661..6c74b5e089 100644 --- a/webapp/channels/src/utils/message_html_to_component.tsx +++ b/webapp/channels/src/utils/message_html_to_component.tsx @@ -181,10 +181,10 @@ export function messageHtmlToComponent(html: string, options: Options = {}) { processingInstructions.push({ replaceChildren: true, shouldProcessNode: (node: any) => node.attribs && node.attribs[emojiAttrib], - processNode: (node: any) => { + processNode: (node: any, children: any) => { const emojiName = node.attribs[emojiAttrib]; - return ; + return {children}; }, }); }