Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2021-07-29 12:08:46 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2021-07-29 12:08:46 +0300
commitf931527bc5120097db15737f8594a431bcad9116 (patch)
tree9f222683bb0ee7b88e3f7c0e02362a530e3c98a6 /spec/frontend/content_editor
parentfd3d0d4c2c5ecac651fdeff92a1f2e4c927e05e0 (diff)
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'spec/frontend/content_editor')
-rw-r--r--spec/frontend/content_editor/components/content_editor_spec.js4
-rw-r--r--spec/frontend/content_editor/components/editor_state_observer_spec.js75
-rw-r--r--spec/frontend/content_editor/components/toolbar_button_spec.js28
-rw-r--r--spec/frontend/content_editor/components/toolbar_image_button_spec.js2
-rw-r--r--spec/frontend/content_editor/components/toolbar_link_button_spec.js10
-rw-r--r--spec/frontend/content_editor/components/toolbar_table_button_spec.js2
-rw-r--r--spec/frontend/content_editor/components/toolbar_text_style_dropdown_spec.js16
-rw-r--r--spec/frontend/content_editor/components/top_toolbar_spec.js18
-rw-r--r--spec/frontend/content_editor/test_utils.js7
9 files changed, 123 insertions, 39 deletions
diff --git a/spec/frontend/content_editor/components/content_editor_spec.js b/spec/frontend/content_editor/components/content_editor_spec.js
index 563e80e04c1..c52fc395487 100644
--- a/spec/frontend/content_editor/components/content_editor_spec.js
+++ b/spec/frontend/content_editor/components/content_editor_spec.js
@@ -38,10 +38,10 @@ describe('ContentEditor', () => {
expect(editorContent.classes()).toContain('md');
});
- it('renders top toolbar component and attaches editor instance', () => {
+ it('renders top toolbar component', () => {
createWrapper(editor);
- expect(wrapper.findComponent(TopToolbar).props().contentEditor).toBe(editor);
+ expect(wrapper.findComponent(TopToolbar).exists()).toBe(true);
});
it.each`
diff --git a/spec/frontend/content_editor/components/editor_state_observer_spec.js b/spec/frontend/content_editor/components/editor_state_observer_spec.js
new file mode 100644
index 00000000000..5e4bb348e1f
--- /dev/null
+++ b/spec/frontend/content_editor/components/editor_state_observer_spec.js
@@ -0,0 +1,75 @@
+import { shallowMount } from '@vue/test-utils';
+import { each } from 'lodash';
+import EditorStateObserver, {
+ tiptapToComponentMap,
+} from '~/content_editor/components/editor_state_observer.vue';
+import { createTestEditor } from '../test_utils';
+
+describe('content_editor/components/editor_state_observer', () => {
+ let tiptapEditor;
+ let wrapper;
+ let onDocUpdateListener;
+ let onSelectionUpdateListener;
+ let onTransactionListener;
+
+ const buildEditor = () => {
+ tiptapEditor = createTestEditor();
+ jest.spyOn(tiptapEditor, 'on');
+ };
+
+ const buildWrapper = () => {
+ wrapper = shallowMount(EditorStateObserver, {
+ provide: { tiptapEditor },
+ listeners: {
+ docUpdate: onDocUpdateListener,
+ selectionUpdate: onSelectionUpdateListener,
+ transaction: onTransactionListener,
+ },
+ });
+ };
+
+ beforeEach(() => {
+ onDocUpdateListener = jest.fn();
+ onSelectionUpdateListener = jest.fn();
+ onTransactionListener = jest.fn();
+ buildEditor();
+ buildWrapper();
+ });
+
+ afterEach(() => {
+ wrapper.destroy();
+ });
+
+ describe('when editor content changes', () => {
+ it('emits update, selectionUpdate, and transaction events', () => {
+ const content = '<p>My paragraph</p>';
+
+ tiptapEditor.commands.insertContent(content);
+
+ expect(onDocUpdateListener).toHaveBeenCalledWith(
+ expect.objectContaining({ editor: tiptapEditor }),
+ );
+ expect(onSelectionUpdateListener).toHaveBeenCalledWith(
+ expect.objectContaining({ editor: tiptapEditor }),
+ );
+ expect(onSelectionUpdateListener).toHaveBeenCalledWith(
+ expect.objectContaining({ editor: tiptapEditor }),
+ );
+ });
+ });
+
+ describe('when component is destroyed', () => {
+ it('removes onTiptapDocUpdate and onTiptapSelectionUpdate hooks', () => {
+ jest.spyOn(tiptapEditor, 'off');
+
+ wrapper.destroy();
+
+ each(tiptapToComponentMap, (_, tiptapEvent) => {
+ expect(tiptapEditor.off).toHaveBeenCalledWith(
+ tiptapEvent,
+ tiptapEditor.on.mock.calls.find(([eventName]) => eventName === tiptapEvent)[1],
+ );
+ });
+ });
+ });
+});
diff --git a/spec/frontend/content_editor/components/toolbar_button_spec.js b/spec/frontend/content_editor/components/toolbar_button_spec.js
index d848adcbff8..da32f308481 100644
--- a/spec/frontend/content_editor/components/toolbar_button_spec.js
+++ b/spec/frontend/content_editor/components/toolbar_button_spec.js
@@ -1,7 +1,8 @@
import { GlButton } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils';
+import EditorStateObserver from '~/content_editor/components/editor_state_observer.vue';
import ToolbarButton from '~/content_editor/components/toolbar_button.vue';
-import { createTestEditor, mockChainedCommands } from '../test_utils';
+import { createTestEditor, mockChainedCommands, emitEditorEvent } from '../test_utils';
describe('content_editor/components/toolbar_button', () => {
let wrapper;
@@ -20,9 +21,12 @@ describe('content_editor/components/toolbar_button', () => {
wrapper = shallowMount(ToolbarButton, {
stubs: {
GlButton,
+ EditorStateObserver,
},
- propsData: {
+ provide: {
tiptapEditor,
+ },
+ propsData: {
contentType: CONTENT_TYPE,
iconName: ICON_NAME,
label: LABEL,
@@ -51,14 +55,20 @@ describe('content_editor/components/toolbar_button', () => {
${{ isActive: true, isFocused: true }} | ${'button is active'} | ${true}
${{ isActive: false, isFocused: true }} | ${'button is not active'} | ${false}
${{ isActive: true, isFocused: false }} | ${'button is not active '} | ${false}
- `('$outcomeDescription when when editor state is $editorState', ({ editorState, outcome }) => {
- tiptapEditor.isActive.mockReturnValueOnce(editorState.isActive);
- tiptapEditor.isFocused = editorState.isFocused;
- buildWrapper();
+ `(
+ '$outcomeDescription when when editor state is $editorState',
+ async ({ editorState, outcome }) => {
+ tiptapEditor.isActive.mockReturnValueOnce(editorState.isActive);
+ tiptapEditor.isFocused = editorState.isFocused;
- expect(findButton().classes().includes('active')).toBe(outcome);
- expect(tiptapEditor.isActive).toHaveBeenCalledWith(CONTENT_TYPE);
- });
+ buildWrapper();
+
+ await emitEditorEvent({ event: 'transaction', tiptapEditor });
+
+ expect(findButton().classes().includes('active')).toBe(outcome);
+ expect(tiptapEditor.isActive).toHaveBeenCalledWith(CONTENT_TYPE);
+ },
+ );
describe('when button is clicked', () => {
it('executes the content type command when executeCommand = true', async () => {
diff --git a/spec/frontend/content_editor/components/toolbar_image_button_spec.js b/spec/frontend/content_editor/components/toolbar_image_button_spec.js
index 6553d8fd357..bf744d5d385 100644
--- a/spec/frontend/content_editor/components/toolbar_image_button_spec.js
+++ b/spec/frontend/content_editor/components/toolbar_image_button_spec.js
@@ -10,7 +10,7 @@ describe('content_editor/components/toolbar_image_button', () => {
const buildWrapper = () => {
wrapper = mountExtended(ToolbarImageButton, {
- propsData: {
+ provide: {
tiptapEditor: editor,
},
});
diff --git a/spec/frontend/content_editor/components/toolbar_link_button_spec.js b/spec/frontend/content_editor/components/toolbar_link_button_spec.js
index 89a40c42590..405213d0487 100644
--- a/spec/frontend/content_editor/components/toolbar_link_button_spec.js
+++ b/spec/frontend/content_editor/components/toolbar_link_button_spec.js
@@ -3,7 +3,7 @@ import { mountExtended } from 'helpers/vue_test_utils_helper';
import ToolbarLinkButton from '~/content_editor/components/toolbar_link_button.vue';
import Link from '~/content_editor/extensions/link';
import { hasSelection } from '~/content_editor/services/utils';
-import { createTestEditor, mockChainedCommands } from '../test_utils';
+import { createTestEditor, mockChainedCommands, emitEditorEvent } from '../test_utils';
jest.mock('~/content_editor/services/utils');
@@ -13,7 +13,7 @@ describe('content_editor/components/toolbar_link_button', () => {
const buildWrapper = () => {
wrapper = mountExtended(ToolbarLinkButton, {
- propsData: {
+ provide: {
tiptapEditor: editor,
},
});
@@ -43,6 +43,8 @@ describe('content_editor/components/toolbar_link_button', () => {
beforeEach(async () => {
jest.spyOn(editor, 'isActive').mockReturnValueOnce(true);
buildWrapper();
+
+ await emitEditorEvent({ event: 'transaction', tiptapEditor: editor });
});
it('sets dropdown as active when link extension is active', () => {
@@ -88,7 +90,7 @@ describe('content_editor/components/toolbar_link_button', () => {
href: '/username/my-project/uploads/abcdefgh133535/my-file.zip',
});
- await editor.emit('selectionUpdate', { editor });
+ await emitEditorEvent({ event: 'transaction', tiptapEditor: editor });
expect(findLinkURLInput().element.value).toEqual('uploads/my-file.zip');
});
@@ -98,7 +100,7 @@ describe('content_editor/components/toolbar_link_button', () => {
href: 'https://gitlab.com',
});
- await editor.emit('selectionUpdate', { editor });
+ await emitEditorEvent({ event: 'transaction', tiptapEditor: editor });
expect(findLinkURLInput().element.value).toEqual('https://gitlab.com');
});
diff --git a/spec/frontend/content_editor/components/toolbar_table_button_spec.js b/spec/frontend/content_editor/components/toolbar_table_button_spec.js
index fe5212cfe3c..336391f9b63 100644
--- a/spec/frontend/content_editor/components/toolbar_table_button_spec.js
+++ b/spec/frontend/content_editor/components/toolbar_table_button_spec.js
@@ -9,7 +9,7 @@ describe('content_editor/components/toolbar_table_button', () => {
const buildWrapper = () => {
wrapper = mountExtended(ToolbarTableButton, {
- propsData: {
+ provide: {
tiptapEditor: editor,
},
});
diff --git a/spec/frontend/content_editor/components/toolbar_text_style_dropdown_spec.js b/spec/frontend/content_editor/components/toolbar_text_style_dropdown_spec.js
index 8c98fe95bd4..65c1c8c8310 100644
--- a/spec/frontend/content_editor/components/toolbar_text_style_dropdown_spec.js
+++ b/spec/frontend/content_editor/components/toolbar_text_style_dropdown_spec.js
@@ -1,11 +1,12 @@
import { GlDropdown, GlDropdownItem } from '@gitlab/ui';
import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
+import EditorStateObserver from '~/content_editor/components/editor_state_observer.vue';
import ToolbarTextStyleDropdown from '~/content_editor/components/toolbar_text_style_dropdown.vue';
import { TEXT_STYLE_DROPDOWN_ITEMS } from '~/content_editor/constants';
import Heading from '~/content_editor/extensions/heading';
-import { createTestEditor, mockChainedCommands } from '../test_utils';
+import { createTestEditor, mockChainedCommands, emitEditorEvent } from '../test_utils';
-describe('content_editor/components/toolbar_headings_dropdown', () => {
+describe('content_editor/components/toolbar_text_style_dropdown', () => {
let wrapper;
let tiptapEditor;
@@ -22,9 +23,12 @@ describe('content_editor/components/toolbar_headings_dropdown', () => {
stubs: {
GlDropdown,
GlDropdownItem,
+ EditorStateObserver,
},
- propsData: {
+ provide: {
tiptapEditor,
+ },
+ propsData: {
...propsData,
},
});
@@ -50,7 +54,7 @@ describe('content_editor/components/toolbar_headings_dropdown', () => {
describe('when there is an active item ', () => {
let activeTextStyle;
- beforeEach(() => {
+ beforeEach(async () => {
[, activeTextStyle] = TEXT_STYLE_DROPDOWN_ITEMS;
tiptapEditor.isActive.mockImplementation(
@@ -59,6 +63,7 @@ describe('content_editor/components/toolbar_headings_dropdown', () => {
);
buildWrapper();
+ await emitEditorEvent({ event: 'transaction', tiptapEditor });
});
it('displays the active text style label as the dropdown toggle text ', () => {
@@ -79,9 +84,10 @@ describe('content_editor/components/toolbar_headings_dropdown', () => {
});
describe('when there isn’t an active item', () => {
- beforeEach(() => {
+ beforeEach(async () => {
tiptapEditor.isActive.mockReturnValue(false);
buildWrapper();
+ await emitEditorEvent({ event: 'transaction', tiptapEditor });
});
it('sets dropdown as disabled', () => {
diff --git a/spec/frontend/content_editor/components/top_toolbar_spec.js b/spec/frontend/content_editor/components/top_toolbar_spec.js
index 5411793cd5e..18faf1930e7 100644
--- a/spec/frontend/content_editor/components/top_toolbar_spec.js
+++ b/spec/frontend/content_editor/components/top_toolbar_spec.js
@@ -6,34 +6,19 @@ import {
TOOLBAR_CONTROL_TRACKING_ACTION,
CONTENT_EDITOR_TRACKING_LABEL,
} from '~/content_editor/constants';
-import { createContentEditor } from '~/content_editor/services/create_content_editor';
describe('content_editor/components/top_toolbar', () => {
let wrapper;
- let contentEditor;
let trackingSpy;
- const buildEditor = () => {
- contentEditor = createContentEditor({ renderMarkdown: () => true });
- };
const buildWrapper = () => {
- wrapper = extendedWrapper(
- shallowMount(TopToolbar, {
- propsData: {
- contentEditor,
- },
- }),
- );
+ wrapper = extendedWrapper(shallowMount(TopToolbar));
};
beforeEach(() => {
trackingSpy = mockTracking(undefined, null, jest.spyOn);
});
- beforeEach(() => {
- buildEditor();
- });
-
afterEach(() => {
wrapper.destroy();
});
@@ -60,7 +45,6 @@ describe('content_editor/components/top_toolbar', () => {
it('renders the toolbar control with the provided properties', () => {
expect(wrapper.findByTestId(testId).props()).toEqual({
...controlProps,
- tiptapEditor: contentEditor.tiptapEditor,
});
});
diff --git a/spec/frontend/content_editor/test_utils.js b/spec/frontend/content_editor/test_utils.js
index 090e1d92218..b5a2abc2389 100644
--- a/spec/frontend/content_editor/test_utils.js
+++ b/spec/frontend/content_editor/test_utils.js
@@ -4,6 +4,7 @@ import { Paragraph } from '@tiptap/extension-paragraph';
import { Text } from '@tiptap/extension-text';
import { Editor } from '@tiptap/vue-2';
import { builders, eq } from 'prosemirror-test-builder';
+import { nextTick } from 'vue';
export const createDocBuilder = ({ tiptapEditor, names = {} }) => {
const docBuilders = builders(tiptapEditor.schema, {
@@ -14,6 +15,12 @@ export const createDocBuilder = ({ tiptapEditor, names = {} }) => {
return { eq, builders: docBuilders };
};
+export const emitEditorEvent = ({ tiptapEditor, event, params = {} }) => {
+ tiptapEditor.emit(event, { editor: tiptapEditor, ...params });
+
+ return nextTick();
+};
+
/**
* Creates an instance of the Tiptap Editor class
* with a minimal configuration for testing purposes.