diff --git a/webapp/channels/src/components/code_block/__snapshots__/code_block.test.tsx.snap b/webapp/channels/src/components/code_block/__snapshots__/code_block.test.tsx.snap deleted file mode 100644 index f21ebbbe17..0000000000 --- a/webapp/channels/src/components/code_block/__snapshots__/code_block.test.tsx.snap +++ /dev/null @@ -1,1105 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`codeBlock should render html code block with proper indentation after syntax highlighting 1`] = ` - - - -
-
- - - - - } - placement="top" - shouldUpdatePosition={true} - trigger={ - Array [ - "hover", - "focus", - ] - } - > - - - - } - placement="top" - shouldUpdatePosition={true} - trigger={ - Array [ - "hover", - "focus", - ] - } - > - - - - - - - - HTML, XML - -
-
-
- 1 -2 -3 -4 -5 -6 -
- <div className='myClass'> - <a href='https://randomgibberishurl.com'>ClickMe</a> -</div> -\`\`\` -", - } - } - /> -
-
-
-
-
-`; - -exports[`codeBlock should render html code block with proper indentation before syntax highlighting 1`] = ` - - - -
-
- - - - - } - placement="top" - shouldUpdatePosition={true} - trigger={ - Array [ - "hover", - "focus", - ] - } - > - - - - } - placement="top" - shouldUpdatePosition={true} - trigger={ - Array [ - "hover", - "focus", - ] - } - > - - - - - - - - HTML, XML - -
-
-
- 1 -2 -3 -4 -5 -6 -
- <div className='myClass'> - <a href='https://randomgibberishurl.com'>ClickMe</a> -</div> -\`\`\` -", - } - } - /> -
-
-
-
-
-`; - -exports[`codeBlock should render typescript code block after syntax highlighting 1`] = ` - - - -
-
- - - - - } - placement="top" - shouldUpdatePosition={true} - trigger={ - Array [ - "hover", - "focus", - ] - } - > - - - - } - placement="top" - shouldUpdatePosition={true} - trigger={ - Array [ - "hover", - "focus", - ] - } - > - - - - - - - - TypeScript - -
-
-
- 1 -2 -3 -4 -5 -6 -
- \`\`\`typescript -const myFunction = () => { - console.log('This is a meaningful function'); -}; -\`\`\` -", - } - } - /> -
-
-
-
-
-`; - -exports[`codeBlock should render typescript code block before syntax highlighting 1`] = ` - - - -
-
- - - - - } - placement="top" - shouldUpdatePosition={true} - trigger={ - Array [ - "hover", - "focus", - ] - } - > - - - - } - placement="top" - shouldUpdatePosition={true} - trigger={ - Array [ - "hover", - "focus", - ] - } - > - - - - - - - - TypeScript - -
-
-
- 1 -2 -3 -4 -5 -6 -
- \`\`\`typescript -const myFunction = () => { - console.log('This is a meaningful function'); -}; -\`\`\` -", - } - } - /> -
-
-
-
-
-`; - -exports[`codeBlock should render unknown language after syntax highlighting 1`] = ` - - - -
-
- - - - - } - placement="top" - shouldUpdatePosition={true} - trigger={ - Array [ - "hover", - "focus", - ] - } - > - - - - } - placement="top" - shouldUpdatePosition={true} - trigger={ - Array [ - "hover", - "focus", - ] - } - > - - - - - - -
-
- -
-
-
-
-
-`; - -exports[`codeBlock should render unknown language before syntax highlighting 1`] = ` - - - -
-
- - - - - } - placement="top" - shouldUpdatePosition={true} - trigger={ - Array [ - "hover", - "focus", - ] - } - > - - - - } - placement="top" - shouldUpdatePosition={true} - trigger={ - Array [ - "hover", - "focus", - ] - } - > - - - - - - -
-
- -
-
-
-
-
-`; diff --git a/webapp/channels/src/components/code_block/code_block.test.tsx b/webapp/channels/src/components/code_block/code_block.test.tsx index 677d08ded7..948bb2f476 100644 --- a/webapp/channels/src/components/code_block/code_block.test.tsx +++ b/webapp/channels/src/components/code_block/code_block.test.tsx @@ -1,205 +1,94 @@ // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. // See LICENSE.txt for license information. -import type {ReactWrapper} from 'enzyme'; -import {mount} from 'enzyme'; import React from 'react'; -import {act} from 'react-dom/test-utils'; -import {IntlProvider} from 'react-intl'; -import {Provider as ReduxProvider} from 'react-redux'; -import mockStore from 'tests/test_store'; +import {act, renderWithContext, screen} from 'tests/react_testing_utils'; import CodeBlock from './code_block'; -const actImmediate = (wrapper: ReactWrapper) => +const actImmediate = () => act( () => new Promise((resolve) => { setImmediate(() => { - wrapper.update(); resolve(); }); }), ); describe('codeBlock', () => { - const state = { - plugins: {components: {CodeBlockAction: []}}, - }; - const store = mockStore(state); - - test('should render typescript code block before syntax highlighting', async () => { + test('should render typescript code block with syntax highlighting', async () => { const language = 'typescript'; - const input = `\`\`\`${language} -const myFunction = () => { + const input = `const myFunction = () => { console.log('This is a meaningful function'); -}; -\`\`\` -`; +};`; - const wrapper = mount( - - - - - , + const {container} = renderWithContext( + , ); - await actImmediate(wrapper); - const languageHeader = wrapper.find('span.post-code__language').text(); - const lineNumbersDiv = wrapper.find('.post-code__line-numbers').exists(); + expect(screen.getByText('TypeScript')).toBeInTheDocument(); + expect(container.querySelector('.post-code__line-numbers')).toBeInTheDocument(); - expect(languageHeader).toEqual('TypeScript'); - expect(lineNumbersDiv).toBeTruthy(); + expect(container.querySelector('.hljs-keyword')).not.toBeInTheDocument(); - expect(wrapper).toMatchSnapshot(); - }); + // Wait for highlight.js to finish loading + await actImmediate(); - test('should render typescript code block after syntax highlighting', async () => { - const language = 'typescript'; - const input = `\`\`\`${language} -const myFunction = () => { - console.log('This is a meaningful function'); -}; -\`\`\` -`; + expect(screen.getByText('TypeScript')).toBeInTheDocument(); + expect(container.querySelector('.post-code__line-numbers')).toBeInTheDocument(); - const wrapper = mount( - - - - - , - ); - await actImmediate(wrapper); - - const languageHeader = wrapper.find('span.post-code__language').text(); - const lineNumbersDiv = wrapper.find('.post-code__line-numbers').exists(); - - expect(languageHeader).toEqual('TypeScript'); - expect(lineNumbersDiv).toBeTruthy(); - - expect(wrapper).toMatchSnapshot(); - }); - - test('should render html code block with proper indentation before syntax highlighting', async () => { - const language = 'html'; - const input = `\`\`\`${language} -
- ClickMe -
-\`\`\` -`; - - const wrapper = mount( - - - - - , - ); - await actImmediate(wrapper); - - const languageHeader = wrapper.find('span.post-code__language').text(); - const lineNumbersDiv = wrapper.find('.post-code__line-numbers').exists(); - - expect(languageHeader).toEqual('HTML, XML'); - expect(lineNumbersDiv).toBeTruthy(); - expect(wrapper).toMatchSnapshot(); - }); - - test('should render html code block with proper indentation after syntax highlighting', async () => { - const language = 'html'; - const input = `\`\`\`${language} -
- ClickMe -
-\`\`\` -`; - - const wrapper = mount( - - - - - , - ); - await actImmediate(wrapper); - - const languageHeader = wrapper.find('span.post-code__language').text(); - const lineNumbersDiv = wrapper.find('.post-code__line-numbers').exists(); - - expect(languageHeader).toEqual('HTML, XML'); - expect(lineNumbersDiv).toBeTruthy(); - expect(wrapper).toMatchSnapshot(); + expect(container.querySelector('.hljs-keyword')).toBeInTheDocument(); }); test('should render unknown language before syntax highlighting', async () => { const language = 'unknownLanguage'; - const input = `\`\`\`${language} -this is my unknown language -it shouldn't highlight, it's just garbage -\`\`\` -`; + const input = `this is my unknown language +it shouldn't highlight, it's just garbage`; - const wrapper = mount( - - - - - , + const {container} = renderWithContext( + , ); - await actImmediate(wrapper); - const languageHeader = wrapper.find('span.post-code__language').exists(); - const lineNumbersDiv = wrapper.find('.post-code__line-numbers').exists(); + expect(screen.queryByText('unknownLanguage')).toBeFalsy(); + expect(container.querySelector('.post-code__line-numbers')).toBeFalsy(); - expect(languageHeader).toBeFalsy(); - expect(lineNumbersDiv).toBeFalsy(); - expect(wrapper).toMatchSnapshot(); + // Wait for highlight.js to finish loading + await actImmediate(); + + expect(screen.queryByText('unknownLanguage')).toBeFalsy(); + expect(container.querySelector('.post-code__line-numbers')).toBeFalsy(); }); - test('should render unknown language after syntax highlighting', async () => { - const language = 'unknownLanguage'; - const input = `\`\`\`${language} -this is my unknown language -it shouldn't highlight, it's just garbage -\`\`\` -`; + test('MM-54468 should not add an extra space before highlighted code in search results', async () => { + const language = ''; + const input = 'foo foo foo foo'; + const searchedInput = 'foo foo ' + + 'foo foo'; - const wrapper = mount( - - - - - , + const {container} = renderWithContext( + , ); - await actImmediate(wrapper); - const languageHeader = wrapper.find('span.post-code__language').exists(); - const lineNumbersDiv = wrapper.find('.post-code__line-numbers').exists(); + // There shouldn't be a space between the overlay with search highlighting and the code below + expect(container.querySelector('code')).toHaveTextContent('foo foo foo foofoo foo foo foo'); + expect(container.querySelector('code')).not.toHaveTextContent('foo foo foo foo foo foo foo foo'); - expect(languageHeader).toBeFalsy(); - expect(lineNumbersDiv).toBeFalsy(); - expect(wrapper).toMatchSnapshot(); + // Wait for highlight.js to finish loading + await actImmediate(); + + expect(container.querySelector('code')).toHaveTextContent('foo foo foo foofoo foo foo foo'); + expect(container.querySelector('code')).not.toHaveTextContent('foo foo foo foo foo foo foo foo'); }); }); diff --git a/webapp/channels/src/components/code_block/code_block.tsx b/webapp/channels/src/components/code_block/code_block.tsx index 88e2297ac1..d1fb5774ca 100644 --- a/webapp/channels/src/components/code_block/code_block.tsx +++ b/webapp/channels/src/components/code_block/code_block.tsx @@ -66,7 +66,7 @@ const CodeBlock: React.FC = ({code, language, searchedContent}: Props) => let htmlContent = content; if (searchedContent) { - htmlContent = `${searchedContent} ${content}`; + htmlContent = searchedContent + content; } const codeBlockActions = useSelector((state: GlobalState) => state.plugins.components.CodeBlockAction);