Commit ef64328d authored by Enrique Alcantara's avatar Enrique Alcantara

Refactor wiki_form_spec.js file

Refactor test suite for the wiki_form.vue component
with the following goals:

Prevent timeouts in local and remote environments
Use a single createWrapper function
Follow vue-test-utils best practices
parent 4aa57280
...@@ -596,7 +596,9 @@ export default { ...@@ -596,7 +596,9 @@ export default {
:disabled="disableSubmitButton" :disabled="disableSubmitButton"
>{{ submitButtonText }}</gl-button >{{ submitButtonText }}</gl-button
> >
<gl-button :href="cancelFormPath" class="float-right">{{ $options.i18n.cancel }}</gl-button> <gl-button data-testid="wiki-cancel-button" :href="cancelFormPath" class="float-right">{{
$options.i18n.cancel
}}</gl-button>
</div> </div>
</gl-form> </gl-form>
</template> </template>
import { nextTick } from 'vue'; import { nextTick } from 'vue';
import { GlLoadingIcon, GlModal } from '@gitlab/ui'; import { GlLoadingIcon, GlModal, GlAlert, GlButton } from '@gitlab/ui';
import { mount, shallowMount } from '@vue/test-utils'; import { mount, shallowMount } from '@vue/test-utils';
import axios from 'axios'; import axios from 'axios';
import MockAdapter from 'axios-mock-adapter'; import MockAdapter from 'axios-mock-adapter';
...@@ -31,25 +31,28 @@ describe('WikiForm', () => { ...@@ -31,25 +31,28 @@ describe('WikiForm', () => {
const findContent = () => wrapper.find('#wiki_content'); const findContent = () => wrapper.find('#wiki_content');
const findMessage = () => wrapper.find('#wiki_message'); const findMessage = () => wrapper.find('#wiki_message');
const findSubmitButton = () => wrapper.findByTestId('wiki-submit-button'); const findSubmitButton = () => wrapper.findByTestId('wiki-submit-button');
const findCancelButton = () => wrapper.findByRole('link', { name: 'Cancel' }); const findCancelButton = () => wrapper.findByTestId('wiki-cancel-button');
const findUseNewEditorButton = () => wrapper.findByRole('button', { name: 'Use the new editor' }); const findUseNewEditorButton = () => wrapper.findByText('Use the new editor');
const findToggleEditingModeButton = () => wrapper.findByTestId('toggle-editing-mode-button'); const findToggleEditingModeButton = () => wrapper.findByTestId('toggle-editing-mode-button');
const findDismissContentEditorAlertButton = () => const findDismissContentEditorAlertButton = () => wrapper.findByText('Try this later');
wrapper.findByRole('button', { name: 'Try this later' });
const findSwitchToOldEditorButton = () => const findSwitchToOldEditorButton = () =>
wrapper.findByRole('button', { name: 'Switch me back to the classic editor.' }); wrapper.findByRole('button', { name: 'Switch me back to the classic editor.' });
const findTitleHelpLink = () => wrapper.findByRole('link', { name: 'Learn more.' }); const findTitleHelpLink = () => wrapper.findByText('Learn more.');
const findMarkdownHelpLink = () => wrapper.findByTestId('wiki-markdown-help-link'); const findMarkdownHelpLink = () => wrapper.findByTestId('wiki-markdown-help-link');
const findContentEditor = () => wrapper.findComponent(ContentEditor); const findContentEditor = () => wrapper.findComponent(ContentEditor);
const findClassicEditor = () => wrapper.findComponent(MarkdownField); const findClassicEditor = () => wrapper.findComponent(MarkdownField);
const setFormat = (value) => { const setFormat = (value) => {
const format = findFormat(); const format = findFormat();
format.find(`option[value=${value}]`).setSelected();
format.element.dispatchEvent(new Event('change')); return format.find(`option[value=${value}]`).setSelected();
}; };
const triggerFormSubmit = () => findForm().element.dispatchEvent(new Event('submit')); const triggerFormSubmit = () => {
findForm().element.dispatchEvent(new Event('submit'));
return nextTick();
};
const dispatchBeforeUnload = () => { const dispatchBeforeUnload = () => {
const e = new Event('beforeunload'); const e = new Event('beforeunload');
...@@ -84,34 +87,14 @@ describe('WikiForm', () => { ...@@ -84,34 +87,14 @@ describe('WikiForm', () => {
Org: 'org', Org: 'org',
}; };
function createWrapper( function createWrapper({
persisted = false, mountFn = shallowMount,
{ pageInfo, glFeatures = { wikiSwitchBetweenContentEditorRawMarkdown: false } } = {},
) {
wrapper = extendedWrapper(
mount(
WikiForm,
{
provide: {
formatOptions,
glFeatures,
pageInfo: {
...(persisted ? pageInfoPersisted : pageInfoNew),
...pageInfo,
},
},
},
{ attachToDocument: true },
),
);
}
const createShallowWrapper = (
persisted = false, persisted = false,
{ pageInfo, glFeatures = { wikiSwitchBetweenContentEditorRawMarkdown: false } } = {}, pageInfo,
) => { glFeatures = { wikiSwitchBetweenContentEditorRawMarkdown: false },
} = {}) {
wrapper = extendedWrapper( wrapper = extendedWrapper(
shallowMount(WikiForm, { mountFn(WikiForm, {
provide: { provide: {
formatOptions, formatOptions,
glFeatures, glFeatures,
...@@ -122,10 +105,12 @@ describe('WikiForm', () => { ...@@ -122,10 +105,12 @@ describe('WikiForm', () => {
}, },
stubs: { stubs: {
MarkdownField, MarkdownField,
GlAlert,
GlButton,
}, },
}), }),
); );
}; }
beforeEach(() => { beforeEach(() => {
trackingSpy = mockTracking(undefined, null, jest.spyOn); trackingSpy = mockTracking(undefined, null, jest.spyOn);
...@@ -147,26 +132,24 @@ describe('WikiForm', () => { ...@@ -147,26 +132,24 @@ describe('WikiForm', () => {
`( `(
'updates the commit message to $message when title is $title and persisted=$persisted', 'updates the commit message to $message when title is $title and persisted=$persisted',
async ({ title, message, persisted }) => { async ({ title, message, persisted }) => {
createWrapper(persisted); createWrapper({ persisted });
findTitle().setValue(title);
await wrapper.vm.$nextTick(); await findTitle().setValue(title);
expect(findMessage().element.value).toBe(message); expect(findMessage().element.value).toBe(message);
}, },
); );
it('sets the commit message to "Update My page" when the page first loads when persisted', async () => { it('sets the commit message to "Update My page" when the page first loads when persisted', async () => {
createWrapper(true); createWrapper({ persisted: true });
await wrapper.vm.$nextTick(); await nextTick();
expect(findMessage().element.value).toBe('Update My page'); expect(findMessage().element.value).toBe('Update My page');
}); });
it('does not trim page content by default', () => { it('does not trim page content by default', () => {
createWrapper(true); createWrapper({ persisted: true });
expect(findContent().element.value).toBe(' My page content '); expect(findContent().element.value).toBe(' My page content ');
}); });
...@@ -178,20 +161,16 @@ describe('WikiForm', () => { ...@@ -178,20 +161,16 @@ describe('WikiForm', () => {
${'asciidoc'} | ${'link:page-slug[Link title]'} ${'asciidoc'} | ${'link:page-slug[Link title]'}
${'org'} | ${'[[page-slug]]'} ${'org'} | ${'[[page-slug]]'}
`('updates the link help message when format=$value is selected', async ({ value, text }) => { `('updates the link help message when format=$value is selected', async ({ value, text }) => {
createWrapper(); createWrapper({ mountFn: mount });
setFormat(value); await setFormat(value);
await wrapper.vm.$nextTick();
expect(wrapper.text()).toContain(text); expect(wrapper.text()).toContain(text);
}); });
it('starts with no unload warning', async () => { it('starts with no unload warning', () => {
createWrapper(); createWrapper();
await wrapper.vm.$nextTick();
const e = dispatchBeforeUnload(); const e = dispatchBeforeUnload();
expect(typeof e.returnValue).not.toBe('string'); expect(typeof e.returnValue).not.toBe('string');
expect(e.preventDefault).not.toHaveBeenCalled(); expect(e.preventDefault).not.toHaveBeenCalled();
...@@ -203,20 +182,16 @@ describe('WikiForm', () => { ...@@ -203,20 +182,16 @@ describe('WikiForm', () => {
${false} | ${'You can specify the full path for the new file. We will automatically create any missing directories.'} | ${'/help/user/project/wiki/index#create-a-new-wiki-page'} ${false} | ${'You can specify the full path for the new file. We will automatically create any missing directories.'} | ${'/help/user/project/wiki/index#create-a-new-wiki-page'}
`( `(
'shows appropriate title help text and help link for when persisted=$persisted', 'shows appropriate title help text and help link for when persisted=$persisted',
async ({ persisted, titleHelpLink, titleHelpText }) => { ({ persisted, titleHelpLink, titleHelpText }) => {
createWrapper(persisted); createWrapper({ persisted });
await wrapper.vm.$nextTick();
expect(wrapper.text()).toContain(titleHelpText); expect(wrapper.text()).toContain(titleHelpText);
expect(findTitleHelpLink().attributes().href).toBe(titleHelpLink); expect(findTitleHelpLink().attributes().href).toBe(titleHelpLink);
}, },
); );
it('shows correct link for wiki specific markdown docs', async () => { it('shows correct link for wiki specific markdown docs', () => {
createWrapper(); createWrapper({ mountFn: mount });
await wrapper.vm.$nextTick();
expect(findMarkdownHelpLink().attributes().href).toBe( expect(findMarkdownHelpLink().attributes().href).toBe(
'/help/user/markdown#wiki-specific-markdown', '/help/user/markdown#wiki-specific-markdown',
...@@ -225,12 +200,11 @@ describe('WikiForm', () => { ...@@ -225,12 +200,11 @@ describe('WikiForm', () => {
describe('when wiki content is updated', () => { describe('when wiki content is updated', () => {
beforeEach(async () => { beforeEach(async () => {
createWrapper(true); createWrapper({ mountFn: mount, persisted: true });
const input = findContent(); const input = findContent();
input.setValue(' Lorem ipsum dolar sit! ');
await input.trigger('input'); await input.setValue(' Lorem ipsum dolar sit! ');
}); });
it('sets before unload warning', () => { it('sets before unload warning', () => {
...@@ -241,17 +215,15 @@ describe('WikiForm', () => { ...@@ -241,17 +215,15 @@ describe('WikiForm', () => {
describe('form submit', () => { describe('form submit', () => {
beforeEach(async () => { beforeEach(async () => {
triggerFormSubmit(); await triggerFormSubmit();
await wrapper.vm.$nextTick();
}); });
it('when form submitted, unsets before unload warning', async () => { it('when form submitted, unsets before unload warning', () => {
const e = dispatchBeforeUnload(); const e = dispatchBeforeUnload();
expect(e.preventDefault).not.toHaveBeenCalled(); expect(e.preventDefault).not.toHaveBeenCalled();
}); });
it('triggers wiki format tracking event', async () => { it('triggers wiki format tracking event', () => {
expect(trackingSpy).toHaveBeenCalledTimes(1); expect(trackingSpy).toHaveBeenCalledTimes(1);
}); });
...@@ -264,22 +236,20 @@ describe('WikiForm', () => { ...@@ -264,22 +236,20 @@ describe('WikiForm', () => {
describe('submit button state', () => { describe('submit button state', () => {
it.each` it.each`
title | content | buttonState | disabledAttr title | content | buttonState | disabledAttr
${'something'} | ${'something'} | ${'enabled'} | ${undefined} ${'something'} | ${'something'} | ${'enabled'} | ${false}
${''} | ${'something'} | ${'disabled'} | ${'disabled'} ${''} | ${'something'} | ${'disabled'} | ${true}
${'something'} | ${''} | ${'disabled'} | ${'disabled'} ${'something'} | ${''} | ${'disabled'} | ${true}
${''} | ${''} | ${'disabled'} | ${'disabled'} ${''} | ${''} | ${'disabled'} | ${true}
${' '} | ${' '} | ${'disabled'} | ${'disabled'} ${' '} | ${' '} | ${'disabled'} | ${true}
`( `(
"when title='$title', content='$content', then the button is $buttonState'", "when title='$title', content='$content', then the button is $buttonState'",
async ({ title, content, disabledAttr }) => { async ({ title, content, disabledAttr }) => {
createWrapper(); createWrapper();
findTitle().setValue(title); await findTitle().setValue(title);
findContent().setValue(content); await findContent().setValue(content);
await wrapper.vm.$nextTick(); expect(findSubmitButton().props().disabled).toBe(disabledAttr);
expect(findSubmitButton().attributes().disabled).toBe(disabledAttr);
}, },
); );
...@@ -288,7 +258,7 @@ describe('WikiForm', () => { ...@@ -288,7 +258,7 @@ describe('WikiForm', () => {
${true} | ${'Save changes'} ${true} | ${'Save changes'}
${false} | ${'Create page'} ${false} | ${'Create page'}
`('when persisted=$persisted, label is set to $buttonLabel', ({ persisted, buttonLabel }) => { `('when persisted=$persisted, label is set to $buttonLabel', ({ persisted, buttonLabel }) => {
createWrapper(persisted); createWrapper({ persisted });
expect(findSubmitButton().text()).toBe(buttonLabel); expect(findSubmitButton().text()).toBe(buttonLabel);
}); });
...@@ -302,7 +272,7 @@ describe('WikiForm', () => { ...@@ -302,7 +272,7 @@ describe('WikiForm', () => {
`( `(
'when persisted=$persisted, redirects the user to appropriate path', 'when persisted=$persisted, redirects the user to appropriate path',
({ persisted, redirectLink }) => { ({ persisted, redirectLink }) => {
createWrapper(persisted); createWrapper({ persisted });
expect(findCancelButton().attributes().href).toBe(redirectLink); expect(findCancelButton().attributes().href).toBe(redirectLink);
}, },
...@@ -311,7 +281,7 @@ describe('WikiForm', () => { ...@@ -311,7 +281,7 @@ describe('WikiForm', () => {
describe('when wikiSwitchBetweenContentEditorRawMarkdown feature flag is not enabled', () => { describe('when wikiSwitchBetweenContentEditorRawMarkdown feature flag is not enabled', () => {
beforeEach(() => { beforeEach(() => {
createShallowWrapper(true, { createWrapper({
glFeatures: { wikiSwitchBetweenContentEditorRawMarkdown: false }, glFeatures: { wikiSwitchBetweenContentEditorRawMarkdown: false },
}); });
}); });
...@@ -323,7 +293,7 @@ describe('WikiForm', () => { ...@@ -323,7 +293,7 @@ describe('WikiForm', () => {
describe('when wikiSwitchBetweenContentEditorRawMarkdown feature flag is enabled', () => { describe('when wikiSwitchBetweenContentEditorRawMarkdown feature flag is enabled', () => {
beforeEach(() => { beforeEach(() => {
createShallowWrapper(true, { createWrapper({
glFeatures: { wikiSwitchBetweenContentEditorRawMarkdown: true }, glFeatures: { wikiSwitchBetweenContentEditorRawMarkdown: true },
}); });
}); });
...@@ -404,10 +374,6 @@ describe('WikiForm', () => { ...@@ -404,10 +374,6 @@ describe('WikiForm', () => {
}); });
describe('wiki content editor', () => { describe('wiki content editor', () => {
beforeEach(() => {
createWrapper(true);
});
it.each` it.each`
format | buttonExists format | buttonExists
${'markdown'} | ${true} ${'markdown'} | ${true}
...@@ -415,15 +381,17 @@ describe('WikiForm', () => { ...@@ -415,15 +381,17 @@ describe('WikiForm', () => {
`( `(
'gl-alert containing "use new editor" button exists: $buttonExists if format is $format', 'gl-alert containing "use new editor" button exists: $buttonExists if format is $format',
async ({ format, buttonExists }) => { async ({ format, buttonExists }) => {
setFormat(format); createWrapper();
await wrapper.vm.$nextTick(); await setFormat(format);
expect(findUseNewEditorButton().exists()).toBe(buttonExists); expect(findUseNewEditorButton().exists()).toBe(buttonExists);
}, },
); );
it('gl-alert containing "use new editor" button is dismissed on clicking dismiss button', async () => { it('gl-alert containing "use new editor" button is dismissed on clicking dismiss button', async () => {
createWrapper();
await findDismissContentEditorAlertButton().trigger('click'); await findDismissContentEditorAlertButton().trigger('click');
expect(findUseNewEditorButton().exists()).toBe(false); expect(findUseNewEditorButton().exists()).toBe(false);
...@@ -442,22 +410,24 @@ describe('WikiForm', () => { ...@@ -442,22 +410,24 @@ describe('WikiForm', () => {
); );
}; };
it('shows classic editor by default', assertOldEditorIsVisible); it('shows classic editor by default', () => {
createWrapper({ persisted: true });
assertOldEditorIsVisible();
});
describe('switch format to rdoc', () => { describe('switch format to rdoc', () => {
beforeEach(async () => { beforeEach(async () => {
setFormat('rdoc'); createWrapper({ persisted: true });
await wrapper.vm.$nextTick(); await setFormat('rdoc');
}); });
it('continues to show the classic editor', assertOldEditorIsVisible); it('continues to show the classic editor', assertOldEditorIsVisible);
describe('switch format back to markdown', () => { describe('switch format back to markdown', () => {
beforeEach(async () => { beforeEach(async () => {
setFormat('rdoc'); await setFormat('markdown');
await wrapper.vm.$nextTick();
}); });
it( it(
...@@ -469,6 +439,7 @@ describe('WikiForm', () => { ...@@ -469,6 +439,7 @@ describe('WikiForm', () => {
describe('clicking "use new editor": editor fails to load', () => { describe('clicking "use new editor": editor fails to load', () => {
beforeEach(async () => { beforeEach(async () => {
createWrapper({ mountFn: mount });
mock.onPost(/preview-markdown/).reply(400); mock.onPost(/preview-markdown/).reply(400);
await findUseNewEditorButton().trigger('click'); await findUseNewEditorButton().trigger('click');
...@@ -494,10 +465,12 @@ describe('WikiForm', () => { ...@@ -494,10 +465,12 @@ describe('WikiForm', () => {
}); });
describe('clicking "use new editor": editor loads successfully', () => { describe('clicking "use new editor": editor loads successfully', () => {
beforeEach(() => { beforeEach(async () => {
createWrapper({ persisted: true, mountFn: mount });
mock.onPost(/preview-markdown/).reply(200, { body: '<p>hello <strong>world</strong></p>' }); mock.onPost(/preview-markdown/).reply(200, { body: '<p>hello <strong>world</strong></p>' });
findUseNewEditorButton().trigger('click'); await findUseNewEditorButton().trigger('click');
}); });
it('shows a tip to send feedback', () => { it('shows a tip to send feedback', () => {
...@@ -542,46 +515,40 @@ describe('WikiForm', () => { ...@@ -542,46 +515,40 @@ describe('WikiForm', () => {
}); });
it('unsets before unload warning on form submit', async () => { it('unsets before unload warning on form submit', async () => {
triggerFormSubmit(); await triggerFormSubmit();
await nextTick();
const e = dispatchBeforeUnload(); const e = dispatchBeforeUnload();
expect(e.preventDefault).not.toHaveBeenCalled(); expect(e.preventDefault).not.toHaveBeenCalled();
}); });
});
it('triggers tracking events on form submit', async () => { it('triggers tracking events on form submit', async () => {
triggerFormSubmit(); await triggerFormSubmit();
await wrapper.vm.$nextTick(); expect(trackingSpy).toHaveBeenCalledWith(undefined, SAVED_USING_CONTENT_EDITOR_ACTION, {
label: WIKI_CONTENT_EDITOR_TRACKING_LABEL,
expect(trackingSpy).toHaveBeenCalledWith(undefined, SAVED_USING_CONTENT_EDITOR_ACTION, { });
label: WIKI_CONTENT_EDITOR_TRACKING_LABEL,
});
expect(trackingSpy).toHaveBeenCalledWith(undefined, WIKI_FORMAT_UPDATED_ACTION, { expect(trackingSpy).toHaveBeenCalledWith(undefined, WIKI_FORMAT_UPDATED_ACTION, {
label: WIKI_FORMAT_LABEL, label: WIKI_FORMAT_LABEL,
extra: { extra: {
value: findFormat().element.value, value: findFormat().element.value,
old_format: pageInfoPersisted.format, old_format: pageInfoPersisted.format,
project_path: pageInfoPersisted.path, project_path: pageInfoPersisted.path,
}, },
});
}); });
});
it('updates content from content editor on form submit', async () => {
// old value
expect(findContent().element.value).toBe(' My page content ');
// wait for content editor to load it('updates content from content editor on form submit', async () => {
await waitForPromises(); // old value
expect(findContent().element.value).toBe(' My page content ');
triggerFormSubmit(); // wait for content editor to load
await waitForPromises();
await wrapper.vm.$nextTick(); await triggerFormSubmit();
expect(findContent().element.value).toBe('hello **world**'); expect(findContent().element.value).toBe('hello **world**');
});
}); });
describe('clicking "switch to classic editor"', () => { describe('clicking "switch to classic editor"', () => {
......
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