diff options
Diffstat (limited to 'spec/frontend/content_editor/services/track_input_rules_and_shortcuts_spec.js')
-rw-r--r-- | spec/frontend/content_editor/services/track_input_rules_and_shortcuts_spec.js | 108 |
1 files changed, 108 insertions, 0 deletions
diff --git a/spec/frontend/content_editor/services/track_input_rules_and_shortcuts_spec.js b/spec/frontend/content_editor/services/track_input_rules_and_shortcuts_spec.js new file mode 100644 index 00000000000..437714ba938 --- /dev/null +++ b/spec/frontend/content_editor/services/track_input_rules_and_shortcuts_spec.js @@ -0,0 +1,108 @@ +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, EditorContent } from '@tiptap/vue-2'; +import { mount } from '@vue/test-utils'; +import { nextTick } from 'vue'; +import { mockTracking } from 'helpers/tracking_helper'; +import { extendedWrapper } from 'helpers/vue_test_utils_helper'; +import { + KEYBOARD_SHORTCUT_TRACKING_ACTION, + INPUT_RULE_TRACKING_ACTION, + CONTENT_EDITOR_TRACKING_LABEL, +} from '~/content_editor/constants'; +import trackInputRulesAndShortcuts from '~/content_editor/services/track_input_rules_and_shortcuts'; +import { ENTER_KEY, BACKSPACE_KEY } from '~/lib/utils/keys'; + +describe('content_editor/services/track_input_rules_and_shortcuts', () => { + let wrapper; + let trackingSpy; + let editor; + const HEADING_TEXT = 'Heading text'; + + const buildWrapper = () => { + wrapper = extendedWrapper( + mount(EditorContent, { + propsData: { + editor, + }, + }), + ); + }; + + beforeEach(() => { + trackingSpy = mockTracking(undefined, null, jest.spyOn); + }); + + afterEach(() => { + wrapper.destroy(); + }); + + describe('given the heading extension is instrumented', () => { + beforeEach(() => { + editor = new Editor({ + extensions: [ + Document, + Paragraph, + Text, + Heading, + CodeBlockLowlight, + BulletList, + ListItem, + ].map(trackInputRulesAndShortcuts), + }); + }); + + beforeEach(async () => { + buildWrapper(); + await nextTick(); + }); + + describe('when creating a heading using an keyboard shortcut', () => { + it('sends a tracking event indicating that a heading was created using an input rule', async () => { + const shortcuts = Heading.config.addKeyboardShortcuts.call(Heading); + const [firstShortcut] = Object.keys(shortcuts); + const nodeName = Heading.name; + + editor.chain().keyboardShortcut(firstShortcut).insertContent(HEADING_TEXT).run(); + + expect(trackingSpy).toHaveBeenCalledWith(undefined, KEYBOARD_SHORTCUT_TRACKING_ACTION, { + label: CONTENT_EDITOR_TRACKING_LABEL, + property: `${nodeName}.${firstShortcut}`, + }); + }); + }); + + it.each` + extension | shortcut + ${ListItem.name} | ${ENTER_KEY} + ${CodeBlockLowlight.name} | ${BACKSPACE_KEY} + `('does not track $shortcut shortcut for $extension extension', ({ shortcut }) => { + editor.chain().keyboardShortcut(shortcut).run(); + + expect(trackingSpy).not.toHaveBeenCalled(); + }); + + describe('when creating a heading using an input rule', () => { + it('sends a tracking event indicating that a heading was created using an input rule', async () => { + const nodeName = Heading.name; + const { view } = editor; + const { selection } = view.state; + + // Triggers the event handler that input rules listen to + view.someProp('handleTextInput', (f) => f(view, selection.from, selection.to, '## ')); + + editor.chain().insertContent(HEADING_TEXT).run(); + + expect(trackingSpy).toHaveBeenCalledWith(undefined, INPUT_RULE_TRACKING_ACTION, { + label: CONTENT_EDITOR_TRACKING_LABEL, + property: `${nodeName}`, + }); + }); + }); + }); +}); |