diff options
Diffstat (limited to 'spec/frontend_integration/content_editor/content_editor_integration_spec.js')
-rw-r--r-- | spec/frontend_integration/content_editor/content_editor_integration_spec.js | 111 |
1 files changed, 77 insertions, 34 deletions
diff --git a/spec/frontend_integration/content_editor/content_editor_integration_spec.js b/spec/frontend_integration/content_editor/content_editor_integration_spec.js index 12cd6dcad83..c0c6b5e5dc8 100644 --- a/spec/frontend_integration/content_editor/content_editor_integration_spec.js +++ b/spec/frontend_integration/content_editor/content_editor_integration_spec.js @@ -1,6 +1,7 @@ import { nextTick } from 'vue'; import { mountExtended } from 'helpers/vue_test_utils_helper'; import { ContentEditor } from '~/content_editor'; +import waitForPromises from 'helpers/wait_for_promises'; /** * This spec exercises some workflows in the Content Editor without mocking @@ -10,32 +11,38 @@ import { ContentEditor } from '~/content_editor'; describe('content_editor', () => { let wrapper; let renderMarkdown; - let contentEditorService; - const buildWrapper = () => { - renderMarkdown = jest.fn(); + const buildWrapper = ({ markdown = '' } = {}) => { wrapper = mountExtended(ContentEditor, { propsData: { renderMarkdown, uploadsPath: '/', - }, - listeners: { - initialized(contentEditor) { - contentEditorService = contentEditor; - }, + markdown, }, }); }; + const waitUntilContentIsLoaded = async () => { + await waitForPromises(); + await nextTick(); + }; + + const mockRenderMarkdownResponse = (response) => { + renderMarkdown.mockImplementation((markdown) => (markdown ? response : null)); + }; + + beforeEach(() => { + renderMarkdown = jest.fn(); + }); + describe('when loading initial content', () => { describe('when the initial content is empty', () => { it('still hides the loading indicator', async () => { - buildWrapper(); + mockRenderMarkdownResponse(''); - renderMarkdown.mockResolvedValue(''); + buildWrapper(); - await contentEditorService.setSerializedContent(''); - await nextTick(); + await waitUntilContentIsLoaded(); expect(wrapper.findByTestId('content-editor-loading-indicator').exists()).toBe(false); }); @@ -44,14 +51,15 @@ describe('content_editor', () => { describe('when the initial content is not empty', () => { const initialContent = '<p><strong>bold text</strong></p>'; beforeEach(async () => { - buildWrapper(); + mockRenderMarkdownResponse(initialContent); - renderMarkdown.mockResolvedValue(initialContent); + buildWrapper({ + markdown: '**bold text**', + }); - await contentEditorService.setSerializedContent('**bold text**'); - await nextTick(); + await waitUntilContentIsLoaded(); }); - it('hides the loading indicator', async () => { + it('hides the loading indicator', () => { expect(wrapper.findByTestId('content-editor-loading-indicator').exists()).toBe(false); }); @@ -70,27 +78,29 @@ describe('content_editor', () => { }); it('processes and renders footnote ids alongside the footnote definition', async () => { - buildWrapper(); - - await contentEditorService.setSerializedContent(` + buildWrapper({ + markdown: ` This reference tag is a mix of letters and numbers [^footnote]. [^footnote]: This is another footnote. - `); - await nextTick(); + `, + }); + + await waitUntilContentIsLoaded(); expect(wrapper.text()).toContain('footnote: This is another footnote'); }); it('processes and displays reference definitions', async () => { - buildWrapper(); - - await contentEditorService.setSerializedContent(` + buildWrapper({ + markdown: ` [GitLab][gitlab] [gitlab]: https://gitlab.com - `); - await nextTick(); + `, + }); + + await waitUntilContentIsLoaded(); expect(wrapper.find('pre').text()).toContain('[gitlab]: https://gitlab.com'); }); @@ -99,9 +109,7 @@ This reference tag is a mix of letters and numbers [^footnote]. it('renders table of contents', async () => { jest.useFakeTimers(); - buildWrapper(); - - renderMarkdown.mockResolvedValue(` + renderMarkdown.mockResolvedValueOnce(` <ul class="section-nav"> </ul> <h1 dir="auto" data-sourcepos="3:1-3:11"> @@ -112,18 +120,53 @@ This reference tag is a mix of letters and numbers [^footnote]. </h2> `); - await contentEditorService.setSerializedContent(` + buildWrapper({ + markdown: ` [TOC] # Heading 1 ## Heading 2 - `); + `, + }); - await nextTick(); - jest.runAllTimers(); + await waitUntilContentIsLoaded(); expect(wrapper.findByTestId('table-of-contents').text()).toContain('Heading 1'); expect(wrapper.findByTestId('table-of-contents').text()).toContain('Heading 2'); }); + + describe('when pasting content', () => { + const buildClipboardData = (data = {}) => ({ + clipboardData: { + getData(mimeType) { + return data[mimeType]; + }, + types: Object.keys(data), + }, + }); + + describe('when the clipboard does not contain text/html data', () => { + it('processes the clipboard content as markdown', async () => { + const processedMarkdown = '<strong>bold text</strong>'; + + buildWrapper(); + + await waitUntilContentIsLoaded(); + + mockRenderMarkdownResponse(processedMarkdown); + + wrapper.find('[contenteditable]').trigger( + 'paste', + buildClipboardData({ + 'text/plain': '**bold text**', + }), + ); + + await waitUntilContentIsLoaded(); + + expect(wrapper.find('[contenteditable]').html()).toContain(processedMarkdown); + }); + }); + }); }); |