diff options
Diffstat (limited to 'spec/frontend/pages/shared/wikis/components/wiki_form_spec.js')
-rw-r--r-- | spec/frontend/pages/shared/wikis/components/wiki_form_spec.js | 291 |
1 files changed, 60 insertions, 231 deletions
diff --git a/spec/frontend/pages/shared/wikis/components/wiki_form_spec.js b/spec/frontend/pages/shared/wikis/components/wiki_form_spec.js index b37d2f06191..0f947e84e0f 100644 --- a/spec/frontend/pages/shared/wikis/components/wiki_form_spec.js +++ b/spec/frontend/pages/shared/wikis/components/wiki_form_spec.js @@ -1,15 +1,12 @@ import { nextTick } from 'vue'; -import { GlAlert, GlButton, GlFormInput, GlFormGroup, GlSegmentedControl } from '@gitlab/ui'; +import { GlAlert, GlButton, GlFormInput, GlFormGroup } from '@gitlab/ui'; import { mount, shallowMount } from '@vue/test-utils'; import axios from 'axios'; import MockAdapter from 'axios-mock-adapter'; import { mockTracking } from 'helpers/tracking_helper'; -import { stubComponent } from 'helpers/stub_component'; import { extendedWrapper } from 'helpers/vue_test_utils_helper'; -import waitForPromises from 'helpers/wait_for_promises'; -import ContentEditor from '~/content_editor/components/content_editor.vue'; -import LocalStorageSync from '~/vue_shared/components/local_storage_sync.vue'; import WikiForm from '~/pages/shared/wikis/components/wiki_form.vue'; +import MarkdownEditor from '~/vue_shared/components/markdown/markdown_editor.vue'; import { CONTENT_EDITOR_LOADED_ACTION, SAVED_USING_CONTENT_EDITOR_ACTION, @@ -18,8 +15,6 @@ import { WIKI_FORMAT_UPDATED_ACTION, } from '~/pages/shared/wikis/constants'; -import MarkdownField from '~/vue_shared/components/markdown/field.vue'; - jest.mock('~/emoji'); describe('WikiForm', () => { @@ -30,16 +25,12 @@ describe('WikiForm', () => { const findForm = () => wrapper.find('form'); const findTitle = () => wrapper.find('#wiki_title'); const findFormat = () => wrapper.find('#wiki_format'); - const findContent = () => wrapper.find('#wiki_content'); const findMessage = () => wrapper.find('#wiki_message'); + const findMarkdownEditor = () => wrapper.findComponent(MarkdownEditor); const findSubmitButton = () => wrapper.findByTestId('wiki-submit-button'); const findCancelButton = () => wrapper.findByTestId('wiki-cancel-button'); - const findToggleEditingModeButton = () => wrapper.findByTestId('toggle-editing-mode-button'); const findTitleHelpLink = () => wrapper.findByText('Learn more.'); const findMarkdownHelpLink = () => wrapper.findByTestId('wiki-markdown-help-link'); - const findContentEditor = () => wrapper.findComponent(ContentEditor); - const findClassicEditor = () => wrapper.findComponent(MarkdownField); - const findLocalStorageSync = () => wrapper.findComponent(LocalStorageSync); const setFormat = (value) => { const format = findFormat(); @@ -53,13 +44,6 @@ describe('WikiForm', () => { await nextTick(); }; - const dispatchBeforeUnload = () => { - const e = new Event('beforeunload'); - jest.spyOn(e, 'preventDefault'); - window.dispatchEvent(e); - return e; - }; - const pageInfoNew = { persisted: false, uploadsPath: '/project/path/-/wikis/attachments', @@ -103,11 +87,8 @@ describe('WikiForm', () => { }, }, stubs: { - MarkdownField, GlAlert, GlButton, - GlSegmentedControl, - LocalStorageSync: stubComponent(LocalStorageSync), GlFormInput, GlFormGroup, }, @@ -126,6 +107,22 @@ describe('WikiForm', () => { wrapper = null; }); + it('displays markdown editor', () => { + createWrapper({ persisted: true }); + + expect(findMarkdownEditor().props()).toEqual( + expect.objectContaining({ + value: pageInfoPersisted.content, + renderMarkdownPath: pageInfoPersisted.markdownPreviewPath, + markdownDocsPath: pageInfoPersisted.markdownHelpPath, + uploadsPath: pageInfoPersisted.uploadsPath, + initOnAutofocus: pageInfoPersisted.persisted, + formFieldId: 'wiki_content', + formFieldName: 'wiki[content]', + }), + ); + }); + it.each` title | persisted | message ${'my page'} | ${false} | ${'Create my page'} @@ -154,7 +151,7 @@ describe('WikiForm', () => { it('does not trim page content by default', () => { createWrapper({ persisted: true }); - expect(findContent().element.value).toBe(' My page content '); + expect(findMarkdownEditor().props().value).toBe(' My page content '); }); it.each` @@ -168,7 +165,9 @@ describe('WikiForm', () => { await setFormat(format); - expect(findClassicEditor().props('enablePreview')).toBe(enabled); + nextTick(); + + expect(findMarkdownEditor().props('enablePreview')).toBe(enabled); }); it.each` @@ -185,14 +184,6 @@ describe('WikiForm', () => { expect(wrapper.text()).toContain(text); }); - it('starts with no unload warning', () => { - createWrapper(); - - const e = dispatchBeforeUnload(); - expect(typeof e.returnValue).not.toBe('string'); - expect(e.preventDefault).not.toHaveBeenCalled(); - }); - it.each` persisted | titleHelpText | titleHelpLink ${true} | ${'You can move this page by adding the path to the beginning of the title.'} | ${'/help/user/project/wiki/index#move-a-wiki-page'} @@ -219,15 +210,7 @@ describe('WikiForm', () => { beforeEach(async () => { createWrapper({ mountFn: mount, persisted: true }); - const input = findContent(); - - await input.setValue(' Lorem ipsum dolar sit! '); - }); - - it('sets before unload warning', () => { - const e = dispatchBeforeUnload(); - - expect(e.preventDefault).toHaveBeenCalledTimes(1); + await findMarkdownEditor().vm.$emit('input', ' Lorem ipsum dolar sit! '); }); describe('form submit', () => { @@ -235,17 +218,12 @@ describe('WikiForm', () => { await triggerFormSubmit(); }); - it('when form submitted, unsets before unload warning', () => { - const e = dispatchBeforeUnload(); - expect(e.preventDefault).not.toHaveBeenCalled(); - }); - it('triggers wiki format tracking event', () => { expect(trackingSpy).toHaveBeenCalledTimes(1); }); it('does not trim page content', () => { - expect(findContent().element.value).toBe(' Lorem ipsum dolar sit! '); + expect(findMarkdownEditor().props().value).toBe(' Lorem ipsum dolar sit! '); }); }); }); @@ -264,7 +242,7 @@ describe('WikiForm', () => { createWrapper({ mountFn: mount }); await findTitle().setValue(title); - await findContent().setValue(content); + await findMarkdownEditor().vm.$emit('input', content); expect(findSubmitButton().props().disabled).toBe(disabledAttr); }, @@ -296,208 +274,59 @@ describe('WikiForm', () => { ); }); - describe('toggle editing mode control', () => { - beforeEach(() => { - createWrapper({ mountFn: mount }); - }); + it.each` + format | enabled | action + ${'markdown'} | ${true} | ${'enables'} + ${'rdoc'} | ${false} | ${'disables'} + ${'asciidoc'} | ${false} | ${'disables'} + ${'org'} | ${false} | ${'disables'} + `('$action content editor when format is $format', async ({ format, enabled }) => { + createWrapper({ mountFn: mount }); - it.each` - format | exists | action - ${'markdown'} | ${true} | ${'displays'} - ${'rdoc'} | ${false} | ${'hides'} - ${'asciidoc'} | ${false} | ${'hides'} - ${'org'} | ${false} | ${'hides'} - `('$action toggle editing mode button when format is $format', async ({ format, exists }) => { - await setFormat(format); - - expect(findToggleEditingModeButton().exists()).toBe(exists); - }); + setFormat(format); - describe('when content editor is not active', () => { - it('displays "Source" label in the toggle editing mode button', () => { - expect(findToggleEditingModeButton().props().checked).toBe('source'); - }); + await nextTick(); - describe('when clicking the toggle editing mode button', () => { - beforeEach(async () => { - await findToggleEditingModeButton().vm.$emit('input', 'richText'); - }); + expect(findMarkdownEditor().props().enableContentEditor).toBe(enabled); + }); - it('hides the classic editor', () => { - expect(findClassicEditor().exists()).toBe(false); - }); + describe('when markdown editor activates the content editor', () => { + beforeEach(async () => { + createWrapper({ mountFn: mount, persisted: true }); - it('shows the content editor', () => { - expect(findContentEditor().exists()).toBe(true); - }); - }); + await findMarkdownEditor().vm.$emit('contentEditor'); }); - describe('markdown editor type persistance', () => { - it('loads content editor by default if it is persisted in local storage', async () => { - expect(findClassicEditor().exists()).toBe(true); - expect(findContentEditor().exists()).toBe(false); - - // enable content editor - await findLocalStorageSync().vm.$emit('input', 'richText'); - - expect(findContentEditor().exists()).toBe(true); - expect(findClassicEditor().exists()).toBe(false); - }); + it('disables the format dropdown', () => { + expect(findFormat().element.getAttribute('disabled')).toBeDefined(); }); - describe('when content editor is active', () => { - beforeEach(() => { - createWrapper(); - findToggleEditingModeButton().vm.$emit('input', 'richText'); - }); - - it('displays "Edit Rich" label in the toggle editing mode button', () => { - expect(findToggleEditingModeButton().props().checked).toBe('richText'); - }); - - describe('when clicking the toggle editing mode button', () => { - beforeEach(async () => { - await findToggleEditingModeButton().vm.$emit('input', 'source'); - await nextTick(); - }); - - it('hides the content editor', () => { - expect(findContentEditor().exists()).toBe(false); - }); - - it('displays the classic editor', () => { - expect(findClassicEditor().exists()).toBe(true); - }); - }); - - describe('when content editor is loading', () => { - beforeEach(async () => { - findContentEditor().vm.$emit('loading'); - - await nextTick(); - }); - - it('disables toggle editing mode button', () => { - expect(findToggleEditingModeButton().attributes().disabled).toBe('true'); - }); - - describe('when content editor loads successfully', () => { - it('enables toggle editing mode button', async () => { - findContentEditor().vm.$emit('loadingSuccess'); - - await nextTick(); - - expect(findToggleEditingModeButton().attributes().disabled).not.toBeDefined(); - }); - }); - - describe('when content editor fails to load', () => { - it('enables toggle editing mode button', async () => { - findContentEditor().vm.$emit('loadingError'); - - await nextTick(); - - expect(findToggleEditingModeButton().attributes().disabled).not.toBeDefined(); - }); - }); + it('sends tracking event when editor loads', async () => { + expect(trackingSpy).toHaveBeenCalledWith(undefined, CONTENT_EDITOR_LOADED_ACTION, { + label: WIKI_CONTENT_EDITOR_TRACKING_LABEL, }); }); - }); - - describe('wiki content editor', () => { - describe('clicking "Edit rich text": editor fails to load', () => { - beforeEach(async () => { - createWrapper({ mountFn: mount }); - mock.onPost(/preview-markdown/).reply(400); - - await findToggleEditingModeButton().vm.$emit('input', 'richText'); - - // try waiting for content editor to load (but it will never actually load) - await waitForPromises(); - }); - - it('disables the submit button', () => { - expect(findSubmitButton().props('disabled')).toBe(true); - }); - - describe('toggling editing modes to the classic editor', () => { - beforeEach(() => { - return findToggleEditingModeButton().vm.$emit('input', 'source'); - }); - it('switches to classic editor', () => { - expect(findContentEditor().exists()).toBe(false); - expect(findClassicEditor().exists()).toBe(true); - }); - }); - }); + describe('when triggering form submit', () => { + const updatedMarkdown = 'hello **world**'; - describe('clicking "Edit rich text": editor loads successfully', () => { beforeEach(async () => { - createWrapper({ persisted: true, mountFn: mount }); - - mock.onPost(/preview-markdown/).reply(200, { body: '<p>hello <strong>world</strong></p>' }); - - await findToggleEditingModeButton().vm.$emit('input', 'richText'); - await waitForPromises(); - }); - - it('shows the rich text editor when loading finishes', async () => { - expect(findContentEditor().exists()).toBe(true); + findMarkdownEditor().vm.$emit('input', updatedMarkdown); + await triggerFormSubmit(); }); - it('sends tracking event when editor loads', async () => { - expect(trackingSpy).toHaveBeenCalledWith(undefined, CONTENT_EDITOR_LOADED_ACTION, { + it('triggers tracking events on form submit', async () => { + expect(trackingSpy).toHaveBeenCalledWith(undefined, SAVED_USING_CONTENT_EDITOR_ACTION, { label: WIKI_CONTENT_EDITOR_TRACKING_LABEL, }); - }); - - it('disables the format dropdown', () => { - expect(findFormat().element.getAttribute('disabled')).toBeDefined(); - }); - describe('when wiki content is updated', () => { - const updatedMarkdown = 'hello **world**'; - - beforeEach(() => { - findContentEditor().vm.$emit('change', { - empty: false, - changed: true, - markdown: updatedMarkdown, - }); - }); - - it('sets before unload warning', () => { - const e = dispatchBeforeUnload(); - expect(e.preventDefault).toHaveBeenCalledTimes(1); - }); - - it('unsets before unload warning on form submit', async () => { - await triggerFormSubmit(); - - const e = dispatchBeforeUnload(); - expect(e.preventDefault).not.toHaveBeenCalled(); - }); - - it('triggers tracking events on form submit', async () => { - await triggerFormSubmit(); - expect(trackingSpy).toHaveBeenCalledWith(undefined, SAVED_USING_CONTENT_EDITOR_ACTION, { - label: WIKI_CONTENT_EDITOR_TRACKING_LABEL, - }); - - expect(trackingSpy).toHaveBeenCalledWith(undefined, WIKI_FORMAT_UPDATED_ACTION, { - label: WIKI_FORMAT_LABEL, - extra: { - value: findFormat().element.value, - old_format: pageInfoPersisted.format, - project_path: pageInfoPersisted.path, - }, - }); - }); - - it('sets content field to the content editor updated markdown', async () => { - expect(findContent().element.value).toBe(updatedMarkdown); + expect(trackingSpy).toHaveBeenCalledWith(undefined, WIKI_FORMAT_UPDATED_ACTION, { + label: WIKI_FORMAT_LABEL, + extra: { + value: findFormat().element.value, + old_format: pageInfoPersisted.format, + project_path: pageInfoPersisted.path, + }, }); }); }); |