diff options
Diffstat (limited to 'spec/frontend/content_editor/extensions')
5 files changed, 80 insertions, 44 deletions
diff --git a/spec/frontend/content_editor/extensions/attachment_spec.js b/spec/frontend/content_editor/extensions/attachment_spec.js index d3c42104e47..d528096be34 100644 --- a/spec/frontend/content_editor/extensions/attachment_spec.js +++ b/spec/frontend/content_editor/extensions/attachment_spec.js @@ -11,32 +11,12 @@ import { VARIANT_DANGER } from '~/flash'; import httpStatus from '~/lib/utils/http_status'; import eventHubFactory from '~/helpers/event_hub_factory'; import { createTestEditor, createDocBuilder } from '../test_utils'; - -const PROJECT_WIKI_ATTACHMENT_IMAGE_HTML = `<p data-sourcepos="1:1-1:27" dir="auto"> - <a class="no-attachment-icon" href="/group1/project1/-/wikis/test-file.png" target="_blank" rel="noopener noreferrer" data-canonical-src="test-file.png"> - <img alt="test-file" class="lazy" data-src="/group1/project1/-/wikis/test-file.png" data-canonical-src="test-file.png"> - </a> -</p>`; - -const PROJECT_WIKI_ATTACHMENT_VIDEO_HTML = `<p data-sourcepos="1:1-1:132" dir="auto"> - <span class="media-container video-container"> - <video src="/group1/project1/-/wikis/test-file.mp4" controls="true" data-setup="{}" data-title="test-file" width="400" preload="metadata" data-canonical-src="test-file.mp4"> - </video> - <a href="/himkp/test/-/wikis/test-file.mp4" target="_blank" rel="noopener noreferrer" title="Download 'test-file'" data-canonical-src="test-file.mp4">test-file</a> - </span> -</p>`; - -const PROJECT_WIKI_ATTACHMENT_AUDIO_HTML = `<p data-sourcepos="3:1-3:74" dir="auto"> - <span class="media-container audio-container"> - <audio src="/himkp/test/-/wikis/test-file.mp3" controls="true" data-setup="{}" data-title="test-file" data-canonical-src="test-file.mp3"> - </audio> - <a href="/himkp/test/-/wikis/test-file.mp3" target="_blank" rel="noopener noreferrer" title="Download 'test-file'" data-canonical-src="test-file.mp3">test-file</a> - </span> -</p>`; - -const PROJECT_WIKI_ATTACHMENT_LINK_HTML = `<p data-sourcepos="1:1-1:26" dir="auto"> - <a href="/group1/project1/-/wikis/test-file.zip" data-canonical-src="test-file.zip">test-file</a> -</p>`; +import { + PROJECT_WIKI_ATTACHMENT_IMAGE_HTML, + PROJECT_WIKI_ATTACHMENT_AUDIO_HTML, + PROJECT_WIKI_ATTACHMENT_VIDEO_HTML, + PROJECT_WIKI_ATTACHMENT_LINK_HTML, +} from '../test_constants'; describe('content_editor/extensions/attachment', () => { let tiptapEditor; diff --git a/spec/frontend/content_editor/extensions/code_block_highlight_spec.js b/spec/frontend/content_editor/extensions/code_block_highlight_spec.js index 02e5b1dc271..fc8460c7f84 100644 --- a/spec/frontend/content_editor/extensions/code_block_highlight_spec.js +++ b/spec/frontend/content_editor/extensions/code_block_highlight_spec.js @@ -1,4 +1,5 @@ import CodeBlockHighlight from '~/content_editor/extensions/code_block_highlight'; +import languageLoader from '~/content_editor/services/code_block_language_loader'; import { createTestEditor, createDocBuilder, triggerNodeInputRule } from '../test_utils'; const CODE_BLOCK_HTML = `<pre class="code highlight js-syntax-highlight language-javascript" lang="javascript" v-pre="true"> @@ -9,20 +10,20 @@ const CODE_BLOCK_HTML = `<pre class="code highlight js-syntax-highlight language </code> </pre>`; +jest.mock('~/content_editor/services/code_block_language_loader'); + describe('content_editor/extensions/code_block_highlight', () => { let parsedCodeBlockHtmlFixture; let tiptapEditor; let doc; let codeBlock; - let languageLoader; const parseHTML = (html) => new DOMParser().parseFromString(html, 'text/html'); const preElement = () => parsedCodeBlockHtmlFixture.querySelector('pre'); beforeEach(() => { - languageLoader = { loadLanguages: jest.fn() }; tiptapEditor = createTestEditor({ - extensions: [CodeBlockHighlight.configure({ languageLoader })], + extensions: [CodeBlockHighlight], }); ({ @@ -70,6 +71,8 @@ describe('content_editor/extensions/code_block_highlight', () => { const language = 'javascript'; beforeEach(() => { + languageLoader.loadLanguageFromInputRule.mockReturnValueOnce({ language }); + triggerNodeInputRule({ tiptapEditor, inputRuleText: `${inputRule}${language} `, @@ -83,7 +86,9 @@ describe('content_editor/extensions/code_block_highlight', () => { }); it('loads language when language loader is available', () => { - expect(languageLoader.loadLanguages).toHaveBeenCalledWith([language]); + expect(languageLoader.loadLanguageFromInputRule).toHaveBeenCalledWith( + expect.arrayContaining([`${inputRule}${language} `, language]), + ); }); }); }); diff --git a/spec/frontend/content_editor/extensions/diagram_spec.js b/spec/frontend/content_editor/extensions/diagram_spec.js new file mode 100644 index 00000000000..b8d9e0b5aeb --- /dev/null +++ b/spec/frontend/content_editor/extensions/diagram_spec.js @@ -0,0 +1,16 @@ +import Diagram from '~/content_editor/extensions/diagram'; +import CodeBlockHighlight from '~/content_editor/extensions/code_block_highlight'; + +describe('content_editor/extensions/diagram', () => { + it('inherits from code block highlight extension', () => { + expect(Diagram.parent).toBe(CodeBlockHighlight); + }); + + it('sets isDiagram attribute to true by default', () => { + expect(Diagram.config.addAttributes()).toEqual( + expect.objectContaining({ + isDiagram: { default: true }, + }), + ); + }); +}); diff --git a/spec/frontend/content_editor/extensions/frontmatter_spec.js b/spec/frontend/content_editor/extensions/frontmatter_spec.js index 4f80c2cb81a..9bd29070858 100644 --- a/spec/frontend/content_editor/extensions/frontmatter_spec.js +++ b/spec/frontend/content_editor/extensions/frontmatter_spec.js @@ -22,6 +22,10 @@ describe('content_editor/extensions/frontmatter', () => { })); }); + it('inherits from code block highlight extension', () => { + expect(Frontmatter.parent).toBe(CodeBlockHighlight); + }); + it('does not insert a frontmatter block when executing code block input rule', () => { const expectedDoc = doc(codeBlock({ language: 'plaintext' }, '')); const inputRuleText = '``` '; @@ -31,6 +35,14 @@ describe('content_editor/extensions/frontmatter', () => { expect(tiptapEditor.getJSON()).toEqual(expectedDoc.toJSON()); }); + it('sets isFrontmatter attribute to true by default', () => { + expect(Frontmatter.config.addAttributes()).toEqual( + expect.objectContaining({ + isFrontmatter: { default: true }, + }), + ); + }); + it.each` command | result | resultDesc ${'toggleCodeBlock'} | ${() => doc(codeBlock(''))} | ${'code block element'} diff --git a/spec/frontend/content_editor/extensions/paste_markdown_spec.js b/spec/frontend/content_editor/extensions/paste_markdown_spec.js index 8f734c7dabc..5d46c2c0650 100644 --- a/spec/frontend/content_editor/extensions/paste_markdown_spec.js +++ b/spec/frontend/content_editor/extensions/paste_markdown_spec.js @@ -1,4 +1,7 @@ import PasteMarkdown from '~/content_editor/extensions/paste_markdown'; +import CodeBlockHighlight from '~/content_editor/extensions/code_block_highlight'; +import Diagram from '~/content_editor/extensions/diagram'; +import Frontmatter from '~/content_editor/extensions/frontmatter'; import Bold from '~/content_editor/extensions/bold'; import { VARIANT_DANGER } from '~/flash'; import eventHubFactory from '~/helpers/event_hub_factory'; @@ -11,6 +14,12 @@ import { import waitForPromises from 'helpers/wait_for_promises'; import { createTestEditor, createDocBuilder, waitUntilNextDocTransaction } from '../test_utils'; +const CODE_BLOCK_HTML = '<pre lang="javascript">var a = 2;</pre>'; +const DIAGRAM_HTML = + '<img data-diagram="nomnoml" data-diagram-src="data:text/plain;base64,WzxmcmFtZT5EZWNvcmF0b3IgcGF0dGVybl0=">'; +const FRONTMATTER_HTML = '<pre lang="yaml" data-lang-params="frontmatter">key: value</pre>'; +const PARAGRAPH_HTML = '<p>Just a regular paragraph</p>'; + describe('content_editor/extensions/paste_markdown', () => { let tiptapEditor; let doc; @@ -27,7 +36,13 @@ describe('content_editor/extensions/paste_markdown', () => { jest.spyOn(eventHub, '$emit'); tiptapEditor = createTestEditor({ - extensions: [PasteMarkdown.configure({ renderMarkdown, eventHub }), Bold], + extensions: [ + Bold, + CodeBlockHighlight, + Diagram, + Frontmatter, + PasteMarkdown.configure({ renderMarkdown, eventHub }), + ], }); ({ @@ -35,7 +50,7 @@ describe('content_editor/extensions/paste_markdown', () => { } = createDocBuilder({ tiptapEditor, names: { - Bold: { markType: Bold.name }, + bold: { markType: Bold.name }, }, })); }); @@ -47,13 +62,11 @@ describe('content_editor/extensions/paste_markdown', () => { }; const triggerPasteEventHandler = (event) => { - let handled = false; - - tiptapEditor.view.someProp('handlePaste', (eventHandler) => { - handled = eventHandler(tiptapEditor.view, event); + return new Promise((resolve) => { + tiptapEditor.view.someProp('handlePaste', (eventHandler) => { + resolve(eventHandler(tiptapEditor.view, event)); + }); }); - - return handled; }; const triggerPasteEventHandlerAndWaitForTransaction = (event) => { @@ -73,8 +86,20 @@ describe('content_editor/extensions/paste_markdown', () => { ${['text/plain', 'text/html']} | ${{}} | ${false} | ${'doesn’t handle html format'} ${['text/plain', 'text/html', 'vscode-editor-data']} | ${{ 'vscode-editor-data': '{ "mode": "markdown" }' }} | ${true} | ${'handles vscode markdown'} ${['text/plain', 'text/html', 'vscode-editor-data']} | ${{ 'vscode-editor-data': '{ "mode": "ruby" }' }} | ${false} | ${'doesn’t vscode code snippet'} - `('$desc', ({ types, handled, data }) => { - expect(triggerPasteEventHandler(buildClipboardEvent({ types, data }))).toBe(handled); + `('$desc', async ({ types, handled, data }) => { + expect(await triggerPasteEventHandler(buildClipboardEvent({ types, data }))).toBe(handled); + }); + + it.each` + nodeType | html | handled | desc + ${'codeBlock'} | ${CODE_BLOCK_HTML} | ${false} | ${'does not handle'} + ${'diagram'} | ${DIAGRAM_HTML} | ${false} | ${'does not handle'} + ${'frontmatter'} | ${FRONTMATTER_HTML} | ${false} | ${'does not handle'} + ${'paragraph'} | ${PARAGRAPH_HTML} | ${true} | ${'handles'} + `('$desc paste if currently a `$nodeType` is in focus', async ({ html, handled }) => { + tiptapEditor.commands.insertContent(html); + + expect(await triggerPasteEventHandler(buildClipboardEvent())).toBe(handled); }); describe('when pasting raw markdown source', () => { @@ -105,16 +130,14 @@ describe('content_editor/extensions/paste_markdown', () => { }); it(`triggers ${LOADING_ERROR_EVENT} event`, async () => { - triggerPasteEventHandler(buildClipboardEvent()); - + await triggerPasteEventHandler(buildClipboardEvent()); await waitForPromises(); expect(eventHub.$emit).toHaveBeenCalledWith(LOADING_ERROR_EVENT); }); it(`triggers ${ALERT_EVENT} event`, async () => { - triggerPasteEventHandler(buildClipboardEvent()); - + await triggerPasteEventHandler(buildClipboardEvent()); await waitForPromises(); expect(eventHub.$emit).toHaveBeenCalledWith(ALERT_EVENT, { |