Commit 40e059af authored by Natalia Tepluhina's avatar Natalia Tepluhina

Merge branch 'refactor-use-test-utils-content-editor' into 'master'

Use consistent approach to create TipTap editor in tests

See merge request gitlab-org/gitlab!64298
parents dd963a33 a2d4cb8e
import { GlButton } from '@gitlab/ui'; import { GlButton } from '@gitlab/ui';
import { Extension } from '@tiptap/core';
import { shallowMount } from '@vue/test-utils'; import { shallowMount } from '@vue/test-utils';
import ToolbarButton from '~/content_editor/components/toolbar_button.vue'; import ToolbarButton from '~/content_editor/components/toolbar_button.vue';
import { createContentEditor } from '~/content_editor/services/create_content_editor'; import { createTestEditor, mockChainedCommands } from '../test_utils';
describe('content_editor/components/toolbar_button', () => { describe('content_editor/components/toolbar_button', () => {
let wrapper; let wrapper;
let tiptapEditor; let tiptapEditor;
let toggleFooSpy;
const CONTENT_TYPE = 'bold'; const CONTENT_TYPE = 'bold';
const ICON_NAME = 'bold'; const ICON_NAME = 'bold';
const LABEL = 'Bold'; const LABEL = 'Bold';
const buildEditor = () => { const buildEditor = () => {
toggleFooSpy = jest.fn(); tiptapEditor = createTestEditor();
tiptapEditor = createContentEditor({
extensions: [
{
tiptapExtension: Extension.create({
addCommands() {
return {
toggleFoo: () => toggleFooSpy,
};
},
}),
},
],
renderMarkdown: () => true,
}).tiptapEditor;
jest.spyOn(tiptapEditor, 'isActive'); jest.spyOn(tiptapEditor, 'isActive');
}; };
...@@ -78,20 +62,28 @@ describe('content_editor/components/toolbar_button', () => { ...@@ -78,20 +62,28 @@ describe('content_editor/components/toolbar_button', () => {
describe('when button is clicked', () => { describe('when button is clicked', () => {
it('executes the content type command when executeCommand = true', async () => { it('executes the content type command when executeCommand = true', async () => {
buildWrapper({ editorCommand: 'toggleFoo' }); const editorCommand = 'toggleFoo';
const mockCommands = mockChainedCommands(tiptapEditor, [editorCommand, 'focus', 'run']);
buildWrapper({ editorCommand });
await findButton().trigger('click'); await findButton().trigger('click');
expect(toggleFooSpy).toHaveBeenCalled(); expect(mockCommands[editorCommand]).toHaveBeenCalled();
expect(mockCommands.focus).toHaveBeenCalled();
expect(mockCommands.run).toHaveBeenCalled();
expect(wrapper.emitted().execute).toHaveLength(1); expect(wrapper.emitted().execute).toHaveLength(1);
}); });
it('does not executes the content type command when executeCommand = false', async () => { it('does not executes the content type command when executeCommand = false', async () => {
const editorCommand = 'toggleFoo';
const mockCommands = mockChainedCommands(tiptapEditor, [editorCommand, 'run']);
buildWrapper(); buildWrapper();
await findButton().trigger('click'); await findButton().trigger('click');
expect(toggleFooSpy).not.toHaveBeenCalled(); expect(mockCommands[editorCommand]).not.toHaveBeenCalled();
expect(wrapper.emitted().execute).toHaveLength(1); expect(wrapper.emitted().execute).toHaveLength(1);
}); });
}); });
......
...@@ -2,21 +2,16 @@ import { GlDropdown, GlDropdownItem } from '@gitlab/ui'; ...@@ -2,21 +2,16 @@ import { GlDropdown, GlDropdownItem } from '@gitlab/ui';
import { shallowMountExtended } from 'helpers/vue_test_utils_helper'; import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
import ToolbarTextStyleDropdown from '~/content_editor/components/toolbar_text_style_dropdown.vue'; import ToolbarTextStyleDropdown from '~/content_editor/components/toolbar_text_style_dropdown.vue';
import { TEXT_STYLE_DROPDOWN_ITEMS } from '~/content_editor/constants'; import { TEXT_STYLE_DROPDOWN_ITEMS } from '~/content_editor/constants';
import { createTestContentEditorExtension, createTestEditor } from '../test_utils'; import { tiptapExtension as Heading } from '~/content_editor/extensions/heading';
import { createTestEditor, mockChainedCommands } from '../test_utils';
describe('content_editor/components/toolbar_headings_dropdown', () => { describe('content_editor/components/toolbar_headings_dropdown', () => {
let wrapper; let wrapper;
let tiptapEditor; let tiptapEditor;
let commandMocks;
const buildEditor = () => { const buildEditor = () => {
const testExtension = createTestContentEditorExtension({
commands: TEXT_STYLE_DROPDOWN_ITEMS.map((item) => item.editorCommand),
});
commandMocks = testExtension.commandMocks;
tiptapEditor = createTestEditor({ tiptapEditor = createTestEditor({
extensions: [testExtension.tiptapExtension], extensions: [Heading],
}); });
jest.spyOn(tiptapEditor, 'isActive'); jest.spyOn(tiptapEditor, 'isActive');
...@@ -104,9 +99,12 @@ describe('content_editor/components/toolbar_headings_dropdown', () => { ...@@ -104,9 +99,12 @@ describe('content_editor/components/toolbar_headings_dropdown', () => {
TEXT_STYLE_DROPDOWN_ITEMS.forEach((textStyle, index) => { TEXT_STYLE_DROPDOWN_ITEMS.forEach((textStyle, index) => {
const { editorCommand, commandParams } = textStyle; const { editorCommand, commandParams } = textStyle;
const commands = mockChainedCommands(tiptapEditor, [editorCommand, 'focus', 'run']);
wrapper.findAllComponents(GlDropdownItem).at(index).vm.$emit('click'); wrapper.findAllComponents(GlDropdownItem).at(index).vm.$emit('click');
expect(commandMocks[editorCommand]).toHaveBeenCalledWith(commandParams || {}); expect(commands[editorCommand]).toHaveBeenCalledWith(commandParams || {});
expect(commands.focus).toHaveBeenCalled();
expect(commands.run).toHaveBeenCalled();
}); });
}); });
......
import { BulletList } from '@tiptap/extension-bullet-list';
import { CodeBlockLowlight } from '@tiptap/extension-code-block-lowlight';
import { Document } from '@tiptap/extension-document';
import { Heading } from '@tiptap/extension-heading';
import { ListItem } from '@tiptap/extension-list-item';
import { Paragraph } from '@tiptap/extension-paragraph';
import { Text } from '@tiptap/extension-text';
import { Editor } from '@tiptap/vue-2';
import { mockTracking } from 'helpers/tracking_helper'; import { mockTracking } from 'helpers/tracking_helper';
import { import {
KEYBOARD_SHORTCUT_TRACKING_ACTION, KEYBOARD_SHORTCUT_TRACKING_ACTION,
INPUT_RULE_TRACKING_ACTION, INPUT_RULE_TRACKING_ACTION,
CONTENT_EDITOR_TRACKING_LABEL, CONTENT_EDITOR_TRACKING_LABEL,
} from '~/content_editor/constants'; } from '~/content_editor/constants';
import { tiptapExtension as BulletList } from '~/content_editor/extensions/bullet_list';
import { tiptapExtension as CodeBlockLowlight } from '~/content_editor/extensions/code_block_highlight';
import { tiptapExtension as Heading } from '~/content_editor/extensions/heading';
import { tiptapExtension as ListItem } from '~/content_editor/extensions/list_item';
import trackInputRulesAndShortcuts from '~/content_editor/services/track_input_rules_and_shortcuts'; import trackInputRulesAndShortcuts from '~/content_editor/services/track_input_rules_and_shortcuts';
import { ENTER_KEY, BACKSPACE_KEY } from '~/lib/utils/keys'; import { ENTER_KEY, BACKSPACE_KEY } from '~/lib/utils/keys';
import { createTestEditor } from '../test_utils';
describe('content_editor/services/track_input_rules_and_shortcuts', () => { describe('content_editor/services/track_input_rules_and_shortcuts', () => {
let trackingSpy; let trackingSpy;
let editor; let editor;
let trackedExtensions; let trackedExtensions;
const HEADING_TEXT = 'Heading text'; const HEADING_TEXT = 'Heading text';
const extensions = [Document, Paragraph, Text, Heading, CodeBlockLowlight, BulletList, ListItem]; const extensions = [Heading, CodeBlockLowlight, BulletList, ListItem];
beforeEach(() => { beforeEach(() => {
trackingSpy = mockTracking(undefined, null, jest.spyOn); trackingSpy = mockTracking(undefined, null, jest.spyOn);
...@@ -29,7 +26,7 @@ describe('content_editor/services/track_input_rules_and_shortcuts', () => { ...@@ -29,7 +26,7 @@ describe('content_editor/services/track_input_rules_and_shortcuts', () => {
describe('given the heading extension is instrumented', () => { describe('given the heading extension is instrumented', () => {
beforeEach(() => { beforeEach(() => {
trackedExtensions = extensions.map(trackInputRulesAndShortcuts); trackedExtensions = extensions.map(trackInputRulesAndShortcuts);
editor = new Editor({ editor = createTestEditor({
extensions: extensions.map(trackInputRulesAndShortcuts), extensions: extensions.map(trackInputRulesAndShortcuts),
}); });
}); });
......
...@@ -15,7 +15,7 @@ import { Editor } from '@tiptap/vue-2'; ...@@ -15,7 +15,7 @@ import { Editor } from '@tiptap/vue-2';
* include in the editor * include in the editor
* @returns An instance of a Tiptap’s Editor class * @returns An instance of a Tiptap’s Editor class
*/ */
export const createTestEditor = ({ extensions = [] }) => { export const createTestEditor = ({ extensions = [] } = {}) => {
return new Editor({ return new Editor({
extensions: [Document, Text, Paragraph, ...extensions], extensions: [Document, Text, Paragraph, ...extensions],
}); });
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment