diff options
Diffstat (limited to 'spec/frontend/content_editor')
-rw-r--r-- | spec/frontend/content_editor/components/__snapshots__/toolbar_link_button_spec.js.snap | 8 | ||||
-rw-r--r-- | spec/frontend/content_editor/components/content_editor_spec.js | 19 | ||||
-rw-r--r-- | spec/frontend/content_editor/components/formatting_toolbar_spec.js (renamed from spec/frontend/content_editor/components/top_toolbar_spec.js) | 4 | ||||
-rw-r--r-- | spec/frontend/content_editor/extensions/comment_spec.js | 30 | ||||
-rw-r--r-- | spec/frontend/content_editor/services/gl_api_markdown_deserializer_spec.js | 12 | ||||
-rw-r--r-- | spec/frontend/content_editor/services/markdown_serializer_spec.js | 53 | ||||
-rw-r--r-- | spec/frontend/content_editor/test_utils.js | 4 |
7 files changed, 116 insertions, 14 deletions
diff --git a/spec/frontend/content_editor/components/__snapshots__/toolbar_link_button_spec.js.snap b/spec/frontend/content_editor/components/__snapshots__/toolbar_link_button_spec.js.snap index 6ad8a9de8d3..331a0a474a3 100644 --- a/spec/frontend/content_editor/components/__snapshots__/toolbar_link_button_spec.js.snap +++ b/spec/frontend/content_editor/components/__snapshots__/toolbar_link_button_spec.js.snap @@ -14,15 +14,15 @@ exports[`content_editor/components/toolbar_link_button renders dropdown componen </div> </form> </li> - <li role=\\"presentation\\" class=\\"gl-new-dropdown-divider\\"> + <li role=\\"presentation\\" class=\\"gl-dropdown-divider\\"> <hr role=\\"separator\\" aria-orientation=\\"horizontal\\" class=\\"dropdown-divider\\"> </li> - <li role=\\"presentation\\" class=\\"gl-new-dropdown-item\\"><button role=\\"menuitem\\" type=\\"button\\" class=\\"dropdown-item\\"> + <li role=\\"presentation\\" class=\\"gl-dropdown-item\\"><button role=\\"menuitem\\" type=\\"button\\" class=\\"dropdown-item\\"> <!----> <!----> <!----> - <div class=\\"gl-new-dropdown-item-text-wrapper\\"> - <p class=\\"gl-new-dropdown-item-text-primary\\"> + <div class=\\"gl-dropdown-item-text-wrapper\\"> + <p class=\\"gl-dropdown-item-text-primary\\"> Upload file </p> <!----> diff --git a/spec/frontend/content_editor/components/content_editor_spec.js b/spec/frontend/content_editor/components/content_editor_spec.js index c1c2a125515..1a3cd36a8bb 100644 --- a/spec/frontend/content_editor/components/content_editor_spec.js +++ b/spec/frontend/content_editor/components/content_editor_spec.js @@ -10,7 +10,7 @@ import FormattingBubbleMenu from '~/content_editor/components/bubble_menus/forma import CodeBlockBubbleMenu from '~/content_editor/components/bubble_menus/code_block_bubble_menu.vue'; import LinkBubbleMenu from '~/content_editor/components/bubble_menus/link_bubble_menu.vue'; import MediaBubbleMenu from '~/content_editor/components/bubble_menus/media_bubble_menu.vue'; -import TopToolbar from '~/content_editor/components/top_toolbar.vue'; +import FormattingToolbar from '~/content_editor/components/formatting_toolbar.vue'; import LoadingIndicator from '~/content_editor/components/loading_indicator.vue'; import waitForPromises from 'helpers/wait_for_promises'; import { KEYDOWN_EVENT } from '~/content_editor/constants'; @@ -27,13 +27,14 @@ describe('ContentEditor', () => { const findEditorStateObserver = () => wrapper.findComponent(EditorStateObserver); const findLoadingIndicator = () => wrapper.findComponent(LoadingIndicator); const findContentEditorAlert = () => wrapper.findComponent(ContentEditorAlert); - const createWrapper = ({ markdown, autofocus } = {}) => { + const createWrapper = ({ markdown, autofocus, useBottomToolbar } = {}) => { wrapper = shallowMountExtended(ContentEditor, { propsData: { renderMarkdown, uploadsPath, markdown, autofocus, + useBottomToolbar, }, stubs: { EditorStateObserver, @@ -89,7 +90,19 @@ describe('ContentEditor', () => { it('renders top toolbar component', () => { createWrapper(); - expect(wrapper.findComponent(TopToolbar).exists()).toBe(true); + expect(wrapper.findComponent(FormattingToolbar).exists()).toBe(true); + expect(wrapper.findComponent(FormattingToolbar).classes('gl-border-t')).toBe(false); + expect(wrapper.findComponent(FormattingToolbar).classes('gl-border-b')).toBe(true); + }); + + it('renders bottom toolbar component', () => { + createWrapper({ + useBottomToolbar: true, + }); + + expect(wrapper.findComponent(FormattingToolbar).exists()).toBe(true); + expect(wrapper.findComponent(FormattingToolbar).classes('gl-border-t')).toBe(true); + expect(wrapper.findComponent(FormattingToolbar).classes('gl-border-b')).toBe(false); }); describe('when setting initial content', () => { diff --git a/spec/frontend/content_editor/components/top_toolbar_spec.js b/spec/frontend/content_editor/components/formatting_toolbar_spec.js index 8f194ff32e2..c4bf21ba813 100644 --- a/spec/frontend/content_editor/components/top_toolbar_spec.js +++ b/spec/frontend/content_editor/components/formatting_toolbar_spec.js @@ -1,6 +1,6 @@ import { mockTracking } from 'helpers/tracking_helper'; import { shallowMountExtended } from 'helpers/vue_test_utils_helper'; -import TopToolbar from '~/content_editor/components/top_toolbar.vue'; +import FormattingToolbar from '~/content_editor/components/formatting_toolbar.vue'; import { TOOLBAR_CONTROL_TRACKING_ACTION, CONTENT_EDITOR_TRACKING_LABEL, @@ -11,7 +11,7 @@ describe('content_editor/components/top_toolbar', () => { let trackingSpy; const buildWrapper = () => { - wrapper = shallowMountExtended(TopToolbar); + wrapper = shallowMountExtended(FormattingToolbar); }; beforeEach(() => { diff --git a/spec/frontend/content_editor/extensions/comment_spec.js b/spec/frontend/content_editor/extensions/comment_spec.js new file mode 100644 index 00000000000..7d8ff28e4d7 --- /dev/null +++ b/spec/frontend/content_editor/extensions/comment_spec.js @@ -0,0 +1,30 @@ +import Comment from '~/content_editor/extensions/comment'; +import { createTestEditor, createDocBuilder, triggerNodeInputRule } from '../test_utils'; + +describe('content_editor/extensions/comment', () => { + let tiptapEditor; + let doc; + let comment; + + beforeEach(() => { + tiptapEditor = createTestEditor({ extensions: [Comment] }); + ({ + builders: { doc, comment }, + } = createDocBuilder({ + tiptapEditor, + names: { + comment: { nodeType: Comment.name }, + }, + })); + }); + + describe('when typing the comment input rule', () => { + it('inserts a comment node', () => { + const expectedDoc = doc(comment()); + + triggerNodeInputRule({ tiptapEditor, inputRuleText: '<!-- ' }); + + expect(tiptapEditor.getJSON()).toEqual(expectedDoc.toJSON()); + }); + }); +}); diff --git a/spec/frontend/content_editor/services/gl_api_markdown_deserializer_spec.js b/spec/frontend/content_editor/services/gl_api_markdown_deserializer_spec.js index 5458a42532f..90d83820c70 100644 --- a/spec/frontend/content_editor/services/gl_api_markdown_deserializer_spec.js +++ b/spec/frontend/content_editor/services/gl_api_markdown_deserializer_spec.js @@ -1,5 +1,6 @@ import createMarkdownDeserializer from '~/content_editor/services/gl_api_markdown_deserializer'; import Bold from '~/content_editor/extensions/bold'; +import Comment from '~/content_editor/extensions/comment'; import { createTestEditor, createDocBuilder } from '../test_utils'; describe('content_editor/services/gl_api_markdown_deserializer', () => { @@ -7,19 +8,21 @@ describe('content_editor/services/gl_api_markdown_deserializer', () => { let doc; let p; let bold; + let comment; let tiptapEditor; beforeEach(() => { tiptapEditor = createTestEditor({ - extensions: [Bold], + extensions: [Bold, Comment], }); ({ - builders: { doc, p, bold }, + builders: { doc, p, bold, comment }, } = createDocBuilder({ tiptapEditor, names: { bold: { markType: Bold.name }, + comment: { nodeType: Comment.name }, }, })); renderMarkdown = jest.fn(); @@ -33,7 +36,7 @@ describe('content_editor/services/gl_api_markdown_deserializer', () => { const deserializer = createMarkdownDeserializer({ render: renderMarkdown }); renderMarkdown.mockResolvedValueOnce( - `<p><strong>${text}</strong></p><pre lang="javascript"></pre>`, + `<p><strong>${text}</strong></p><pre lang="javascript"></pre><!-- some comment -->`, ); result = await deserializer.deserialize({ @@ -41,8 +44,9 @@ describe('content_editor/services/gl_api_markdown_deserializer', () => { schema: tiptapEditor.schema, }); }); + it('transforms HTML returned by render function to a ProseMirror document', async () => { - const document = doc(p(bold(text))); + const document = doc(p(bold(text)), comment(' some comment ')); expect(result.document.toJSON()).toEqual(document.toJSON()); }); diff --git a/spec/frontend/content_editor/services/markdown_serializer_spec.js b/spec/frontend/content_editor/services/markdown_serializer_spec.js index 1bf23415052..2cd8b8a0d6f 100644 --- a/spec/frontend/content_editor/services/markdown_serializer_spec.js +++ b/spec/frontend/content_editor/services/markdown_serializer_spec.js @@ -3,6 +3,7 @@ import Bold from '~/content_editor/extensions/bold'; import BulletList from '~/content_editor/extensions/bullet_list'; import Code from '~/content_editor/extensions/code'; import CodeBlockHighlight from '~/content_editor/extensions/code_block_highlight'; +import Comment from '~/content_editor/extensions/comment'; import DescriptionItem from '~/content_editor/extensions/description_item'; import DescriptionList from '~/content_editor/extensions/description_list'; import Details from '~/content_editor/extensions/details'; @@ -50,6 +51,7 @@ const { bulletList, code, codeBlock, + comment, details, detailsContent, div, @@ -89,6 +91,7 @@ const { bulletList: { nodeType: BulletList.name }, code: { markType: Code.name }, codeBlock: { nodeType: CodeBlockHighlight.name }, + comment: { nodeType: Comment.name }, details: { nodeType: Details.name }, detailsContent: { nodeType: DetailsContent.name }, descriptionItem: { nodeType: DescriptionItem.name }, @@ -169,6 +172,17 @@ describe('markdownSerializer', () => { ); }); + it('correctly serializes a comment node', () => { + expect(serialize(paragraph('hi'), comment(' this is a\ncomment '))).toBe( + ` +hi + +<!-- this is a +comment --> + `.trim(), + ); + }); + it('correctly serializes a line break', () => { expect(serialize(paragraph('hello', hardBreak(), 'world'))).toBe('hello\\\nworld'); }); @@ -304,7 +318,7 @@ var y = 10; expect( serialize( codeBlock( - { language: 'json' }, + { language: 'json', langParams: '' }, 'this is not really json but just trying out whether this case works or not', ), ), @@ -317,6 +331,23 @@ this is not really json but just trying out whether this case works or not ); }); + it('correctly serializes a code block with language parameters', () => { + expect( + serialize( + codeBlock( + { language: 'json', langParams: 'table' }, + 'this is not really json:table but just trying out whether this case works or not', + ), + ), + ).toBe( + ` +\`\`\`json:table +this is not really json:table but just trying out whether this case works or not +\`\`\` + `.trim(), + ); + }); + it('correctly serializes emoji', () => { expect(serialize(paragraph(emoji({ name: 'dog' })))).toBe(':dog:'); }); @@ -366,6 +397,26 @@ this is not really json but just trying out whether this case works or not ); }); + it.each` + width | height | outputAttributes + ${300} | ${undefined} | ${'width=300'} + ${undefined} | ${300} | ${'height=300'} + ${300} | ${300} | ${'width=300 height=300'} + ${'300%'} | ${'300px'} | ${'width="300%" height="300px"'} + `( + 'correctly serializes an image with width and height attributes', + ({ width, height, outputAttributes }) => { + const imageAttrs = { src: 'img.jpg', alt: 'foo bar' }; + + if (width) imageAttrs.width = width; + if (height) imageAttrs.height = height; + + expect(serialize(paragraph(image(imageAttrs)))).toBe( + `![foo bar](img.jpg){${outputAttributes}}`, + ); + }, + ); + it('does not serialize an image when src and canonicalSrc are empty', () => { expect(serialize(paragraph(image({})))).toBe(''); }); diff --git a/spec/frontend/content_editor/test_utils.js b/spec/frontend/content_editor/test_utils.js index 0768fa6e8df..0fa0e65cd26 100644 --- a/spec/frontend/content_editor/test_utils.js +++ b/spec/frontend/content_editor/test_utils.js @@ -11,10 +11,12 @@ import Bold from '~/content_editor/extensions/bold'; import BulletList from '~/content_editor/extensions/bullet_list'; import Code from '~/content_editor/extensions/code'; import CodeBlockHighlight from '~/content_editor/extensions/code_block_highlight'; +import Comment from '~/content_editor/extensions/comment'; import DescriptionItem from '~/content_editor/extensions/description_item'; import DescriptionList from '~/content_editor/extensions/description_list'; import Details from '~/content_editor/extensions/details'; import DetailsContent from '~/content_editor/extensions/details_content'; +import Diagram from '~/content_editor/extensions/diagram'; import Emoji from '~/content_editor/extensions/emoji'; import FootnoteDefinition from '~/content_editor/extensions/footnote_definition'; import FootnoteReference from '~/content_editor/extensions/footnote_reference'; @@ -211,10 +213,12 @@ export const createTiptapEditor = (extensions = []) => BulletList, Code, CodeBlockHighlight, + Comment, DescriptionItem, DescriptionList, Details, DetailsContent, + Diagram, Emoji, FootnoteDefinition, FootnoteReference, |