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:
Diffstat (limited to 'spec/frontend/static_site_editor')
-rw-r--r--spec/frontend/static_site_editor/components/edit_meta_controls_spec.js99
-rw-r--r--spec/frontend/static_site_editor/components/edit_meta_modal_spec.js80
-rw-r--r--spec/frontend/static_site_editor/components/front_matter_controls_spec.js11
-rw-r--r--spec/frontend/static_site_editor/graphql/resolvers/has_submitted_changes_spec.js27
-rw-r--r--spec/frontend/static_site_editor/mock_data.js11
-rw-r--r--spec/frontend/static_site_editor/pages/home_spec.js99
-rw-r--r--spec/frontend/static_site_editor/pages/success_spec.js110
-rw-r--r--spec/frontend/static_site_editor/services/front_matterify_spec.js47
-rw-r--r--spec/frontend/static_site_editor/services/submit_content_changes_spec.js53
-rw-r--r--spec/frontend/static_site_editor/services/templater_spec.js8
10 files changed, 452 insertions, 93 deletions
diff --git a/spec/frontend/static_site_editor/components/edit_meta_controls_spec.js b/spec/frontend/static_site_editor/components/edit_meta_controls_spec.js
new file mode 100644
index 00000000000..191f91be076
--- /dev/null
+++ b/spec/frontend/static_site_editor/components/edit_meta_controls_spec.js
@@ -0,0 +1,99 @@
+import { shallowMount } from '@vue/test-utils';
+
+import { useLocalStorageSpy } from 'helpers/local_storage_helper';
+import { GlFormInput, GlFormTextarea } from '@gitlab/ui';
+
+import EditMetaControls from '~/static_site_editor/components/edit_meta_controls.vue';
+
+import { mergeRequestMeta } from '../mock_data';
+
+describe('~/static_site_editor/components/edit_meta_controls.vue', () => {
+ useLocalStorageSpy();
+
+ let wrapper;
+ let mockSelect;
+ let mockGlFormInputTitleInstance;
+ const { title, description } = mergeRequestMeta;
+ const newTitle = 'New title';
+ const newDescription = 'New description';
+
+ const buildWrapper = (propsData = {}) => {
+ wrapper = shallowMount(EditMetaControls, {
+ propsData: {
+ title,
+ description,
+ ...propsData,
+ },
+ });
+ };
+
+ const buildMocks = () => {
+ mockSelect = jest.fn();
+ mockGlFormInputTitleInstance = { $el: { select: mockSelect } };
+ wrapper.vm.$refs.title = mockGlFormInputTitleInstance;
+ };
+
+ const findGlFormInputTitle = () => wrapper.find(GlFormInput);
+ const findGlFormTextAreaDescription = () => wrapper.find(GlFormTextarea);
+
+ beforeEach(() => {
+ buildWrapper();
+ buildMocks();
+
+ return wrapper.vm.$nextTick();
+ });
+
+ afterEach(() => {
+ wrapper.destroy();
+ wrapper = null;
+ });
+
+ it('renders the title input', () => {
+ expect(findGlFormInputTitle().exists()).toBe(true);
+ });
+
+ it('renders the description input', () => {
+ expect(findGlFormTextAreaDescription().exists()).toBe(true);
+ });
+
+ it('forwards the title prop to the title input', () => {
+ expect(findGlFormInputTitle().attributes().value).toBe(title);
+ });
+
+ it('forwards the description prop to the description input', () => {
+ expect(findGlFormTextAreaDescription().attributes().value).toBe(description);
+ });
+
+ it('calls select on the title input when mounted', () => {
+ expect(mockGlFormInputTitleInstance.$el.select).toHaveBeenCalled();
+ });
+
+ describe('when inputs change', () => {
+ const storageKey = 'sse-merge-request-meta-local-storage-editable';
+
+ afterEach(() => {
+ localStorage.removeItem(storageKey);
+ });
+
+ it.each`
+ findFn | key | value
+ ${findGlFormInputTitle} | ${'title'} | ${newTitle}
+ ${findGlFormTextAreaDescription} | ${'description'} | ${newDescription}
+ `('emits updated settings when $findFn input updates', ({ key, value, findFn }) => {
+ findFn().vm.$emit('input', value);
+
+ const newSettings = { ...mergeRequestMeta, [key]: value };
+
+ expect(wrapper.emitted('updateSettings')[0][0]).toMatchObject(newSettings);
+ });
+
+ it('should remember the input changes', () => {
+ findGlFormInputTitle().vm.$emit('input', newTitle);
+ findGlFormTextAreaDescription().vm.$emit('input', newDescription);
+
+ const newSettings = { title: newTitle, description: newDescription };
+
+ expect(localStorage.setItem).toHaveBeenCalledWith(storageKey, JSON.stringify(newSettings));
+ });
+ });
+});
diff --git a/spec/frontend/static_site_editor/components/edit_meta_modal_spec.js b/spec/frontend/static_site_editor/components/edit_meta_modal_spec.js
new file mode 100644
index 00000000000..7a5685033f3
--- /dev/null
+++ b/spec/frontend/static_site_editor/components/edit_meta_modal_spec.js
@@ -0,0 +1,80 @@
+import { shallowMount } from '@vue/test-utils';
+
+import { GlModal } from '@gitlab/ui';
+
+import EditMetaModal from '~/static_site_editor/components/edit_meta_modal.vue';
+import EditMetaControls from '~/static_site_editor/components/edit_meta_controls.vue';
+
+import { sourcePath, mergeRequestMeta } from '../mock_data';
+
+describe('~/static_site_editor/components/edit_meta_modal.vue', () => {
+ let wrapper;
+ let resetCachedEditable;
+ let mockEditMetaControlsInstance;
+ const { title, description } = mergeRequestMeta;
+
+ const buildWrapper = (propsData = {}) => {
+ wrapper = shallowMount(EditMetaModal, {
+ propsData: {
+ sourcePath,
+ ...propsData,
+ },
+ });
+ };
+
+ const buildMocks = () => {
+ resetCachedEditable = jest.fn();
+ mockEditMetaControlsInstance = { resetCachedEditable };
+ wrapper.vm.$refs.editMetaControls = mockEditMetaControlsInstance;
+ };
+
+ const findGlModal = () => wrapper.find(GlModal);
+ const findEditMetaControls = () => wrapper.find(EditMetaControls);
+
+ beforeEach(() => {
+ buildWrapper();
+ buildMocks();
+
+ return wrapper.vm.$nextTick();
+ });
+
+ afterEach(() => {
+ wrapper.destroy();
+ wrapper = null;
+ });
+
+ it('renders the modal', () => {
+ expect(findGlModal().exists()).toBe(true);
+ });
+
+ it('renders the edit meta controls', () => {
+ expect(findEditMetaControls().exists()).toBe(true);
+ });
+
+ it('contains the sourcePath in the title', () => {
+ expect(findEditMetaControls().props('title')).toContain(sourcePath);
+ });
+
+ it('forwards the title prop', () => {
+ expect(findEditMetaControls().props('title')).toBe(title);
+ });
+
+ it('forwards the description prop', () => {
+ expect(findEditMetaControls().props('description')).toBe(description);
+ });
+
+ it('emits the primary event with mergeRequestMeta', () => {
+ findGlModal().vm.$emit('primary', mergeRequestMeta);
+ expect(wrapper.emitted('primary')).toEqual([[mergeRequestMeta]]);
+ });
+
+ it('calls resetCachedEditable on EditMetaControls when primary emits', () => {
+ findGlModal().vm.$emit('primary', mergeRequestMeta);
+ expect(mockEditMetaControlsInstance.resetCachedEditable).toHaveBeenCalled();
+ });
+
+ it('emits the hide event', () => {
+ findGlModal().vm.$emit('hide');
+ expect(wrapper.emitted('hide')).toEqual([[]]);
+ });
+});
diff --git a/spec/frontend/static_site_editor/components/front_matter_controls_spec.js b/spec/frontend/static_site_editor/components/front_matter_controls_spec.js
index 82e8fad643e..8001f2fbd29 100644
--- a/spec/frontend/static_site_editor/components/front_matter_controls_spec.js
+++ b/spec/frontend/static_site_editor/components/front_matter_controls_spec.js
@@ -5,18 +5,11 @@ import { humanize } from '~/lib/utils/text_utility';
import FrontMatterControls from '~/static_site_editor/components/front_matter_controls.vue';
+import { sourceContentHeaderObjYAML as settings } from '../mock_data';
+
describe('~/static_site_editor/components/front_matter_controls.vue', () => {
let wrapper;
- // TODO Refactor and update `sourceContentHeaderObjYAML` in mock_data when !41230 lands
- const settings = {
- layout: 'handbook-page-toc',
- title: 'Handbook',
- twitter_image: '/images/tweets/handbook-gitlab.png',
- suppress_header: true,
- extra_css: ['sales-and-free-trial-common.css', 'form-to-resource.css'],
- };
-
const buildWrapper = (propsData = {}) => {
wrapper = shallowMount(FrontMatterControls, {
propsData: {
diff --git a/spec/frontend/static_site_editor/graphql/resolvers/has_submitted_changes_spec.js b/spec/frontend/static_site_editor/graphql/resolvers/has_submitted_changes_spec.js
new file mode 100644
index 00000000000..0670b240a3f
--- /dev/null
+++ b/spec/frontend/static_site_editor/graphql/resolvers/has_submitted_changes_spec.js
@@ -0,0 +1,27 @@
+import appDataQuery from '~/static_site_editor/graphql/queries/app_data.query.graphql';
+import hasSubmittedChanges from '~/static_site_editor/graphql/resolvers/has_submitted_changes';
+
+describe('static_site_editor/graphql/resolvers/has_submitted_changes', () => {
+ it('updates the cache with the data passed in input', () => {
+ const cachedData = { appData: { original: 'foo' } };
+ const newValue = { input: { hasSubmittedChanges: true } };
+
+ const cache = {
+ readQuery: jest.fn().mockReturnValue(cachedData),
+ writeQuery: jest.fn(),
+ };
+ hasSubmittedChanges(null, newValue, { cache });
+
+ expect(cache.readQuery).toHaveBeenCalledWith({ query: appDataQuery });
+ expect(cache.writeQuery).toHaveBeenCalledWith({
+ query: appDataQuery,
+ data: {
+ appData: {
+ __typename: 'AppData',
+ original: 'foo',
+ hasSubmittedChanges: true,
+ },
+ },
+ });
+ });
+});
diff --git a/spec/frontend/static_site_editor/mock_data.js b/spec/frontend/static_site_editor/mock_data.js
index d861f6c9cd7..0b08e290227 100644
--- a/spec/frontend/static_site_editor/mock_data.js
+++ b/spec/frontend/static_site_editor/mock_data.js
@@ -2,11 +2,17 @@ export const sourceContentHeaderYAML = `---
layout: handbook-page-toc
title: Handbook
twitter_image: /images/tweets/handbook-gitlab.png
+suppress_header: true
+extra_css:
+ - sales-and-free-trial-common.css
+ - form-to-resource.css
---`;
export const sourceContentHeaderObjYAML = {
layout: 'handbook-page-toc',
title: 'Handbook',
twitter_image: '/images/tweets/handbook-gitlab.png',
+ suppress_header: true,
+ extra_css: ['sales-and-free-trial-common.css', 'form-to-resource.css'],
};
export const sourceContentSpacing = `\n`;
export const sourceContentBody = `## On this page
@@ -23,7 +29,10 @@ export const username = 'gitlabuser';
export const projectId = '123456';
export const returnUrl = 'https://www.gitlab.com';
export const sourcePath = 'foobar.md.html';
-
+export const mergeRequestMeta = {
+ title: `Update ${sourcePath} file`,
+ description: 'Copy update',
+};
export const savedContentMeta = {
branch: {
label: 'foobar',
diff --git a/spec/frontend/static_site_editor/pages/home_spec.js b/spec/frontend/static_site_editor/pages/home_spec.js
index 41f8a1075c0..2c69e884005 100644
--- a/spec/frontend/static_site_editor/pages/home_spec.js
+++ b/spec/frontend/static_site_editor/pages/home_spec.js
@@ -1,12 +1,13 @@
-import Vuex from 'vuex';
import { shallowMount, createLocalVue } from '@vue/test-utils';
import { mockTracking, unmockTracking } from 'helpers/tracking_helper';
import Home from '~/static_site_editor/pages/home.vue';
import SkeletonLoader from '~/static_site_editor/components/skeleton_loader.vue';
import EditArea from '~/static_site_editor/components/edit_area.vue';
+import EditMetaModal from '~/static_site_editor/components/edit_meta_modal.vue';
import InvalidContentMessage from '~/static_site_editor/components/invalid_content_message.vue';
import SubmitChangesError from '~/static_site_editor/components/submit_changes_error.vue';
import submitContentChangesMutation from '~/static_site_editor/graphql/mutations/submit_content_changes.mutation.graphql';
+import hasSubmittedChangesMutation from '~/static_site_editor/graphql/mutations/has_submitted_changes.mutation.graphql';
import { SUCCESS_ROUTE } from '~/static_site_editor/router/constants';
import { TRACKING_ACTION_INITIALIZE_EDITOR } from '~/static_site_editor/constants';
@@ -17,15 +18,15 @@ import {
sourceContentTitle as title,
sourcePath,
username,
+ mergeRequestMeta,
savedContentMeta,
submitChangesError,
trackingCategory,
+ images,
} from '../mock_data';
const localVue = createLocalVue();
-localVue.use(Vuex);
-
describe('static_site_editor/pages/home', () => {
let wrapper;
let store;
@@ -33,6 +34,19 @@ describe('static_site_editor/pages/home', () => {
let $router;
let mutateMock;
let trackingSpy;
+ const defaultAppData = {
+ isSupportedContent: true,
+ hasSubmittedChanges: false,
+ returnUrl,
+ project,
+ username,
+ sourcePath,
+ };
+ const hasSubmittedChangesMutationPayload = {
+ data: {
+ appData: { ...defaultAppData, hasSubmittedChanges: true },
+ },
+ };
const buildApollo = (queries = {}) => {
mutateMock = jest.fn();
@@ -64,7 +78,7 @@ describe('static_site_editor/pages/home', () => {
},
data() {
return {
- appData: { isSupportedContent: true, returnUrl, project, username, sourcePath },
+ appData: { ...defaultAppData },
sourceContent: { title, content },
...data,
};
@@ -73,6 +87,7 @@ describe('static_site_editor/pages/home', () => {
};
const findEditArea = () => wrapper.find(EditArea);
+ const findEditMetaModal = () => wrapper.find(EditMetaModal);
const findInvalidContentMessage = () => wrapper.find(InvalidContentMessage);
const findSkeletonLoader = () => wrapper.find(SkeletonLoader);
const findSubmitChangesError = () => wrapper.find(SubmitChangesError);
@@ -140,24 +155,51 @@ describe('static_site_editor/pages/home', () => {
});
it('displays invalid content message when content is not supported', () => {
- buildWrapper({ appData: { isSupportedContent: false } });
+ buildWrapper({ appData: { ...defaultAppData, isSupportedContent: false } });
expect(findInvalidContentMessage().exists()).toBe(true);
});
it('does not display invalid content message when content is supported', () => {
- buildWrapper({ appData: { isSupportedContent: true } });
+ buildWrapper();
expect(findInvalidContentMessage().exists()).toBe(false);
});
- describe('when submitting changes fails', () => {
- beforeEach(() => {
- mutateMock.mockRejectedValue(new Error(submitChangesError));
+ it('renders an EditMetaModal component', () => {
+ buildWrapper();
+
+ expect(findEditMetaModal().exists()).toBe(true);
+ });
+ describe('when preparing submission', () => {
+ it('calls the show method when the edit-area submit event is emitted', () => {
buildWrapper();
+
+ const mockInstance = { show: jest.fn() };
+ wrapper.vm.$refs.editMetaModal = mockInstance;
+
findEditArea().vm.$emit('submit', { content });
+ return wrapper.vm.$nextTick().then(() => {
+ expect(mockInstance.show).toHaveBeenCalled();
+ });
+ });
+ });
+
+ describe('when submitting changes fails', () => {
+ const setupMutateMock = () => {
+ mutateMock
+ .mockResolvedValueOnce(hasSubmittedChangesMutationPayload)
+ .mockRejectedValueOnce(new Error(submitChangesError));
+ };
+
+ beforeEach(() => {
+ setupMutateMock();
+
+ buildWrapper({ content });
+ findEditMetaModal().vm.$emit('primary', mergeRequestMeta);
+
return wrapper.vm.$nextTick();
});
@@ -166,6 +208,8 @@ describe('static_site_editor/pages/home', () => {
});
it('retries submitting changes when retry button is clicked', () => {
+ setupMutateMock();
+
findSubmitChangesError().vm.$emit('retry');
expect(mutateMock).toHaveBeenCalled();
@@ -180,26 +224,35 @@ describe('static_site_editor/pages/home', () => {
});
});
- it('does not display submit changes error when an error does not exist', () => {
- buildWrapper();
-
- expect(findSubmitChangesError().exists()).toBe(false);
- });
-
describe('when submitting changes succeeds', () => {
const newContent = `new ${content}`;
beforeEach(() => {
- mutateMock.mockResolvedValueOnce({ data: { submitContentChanges: savedContentMeta } });
+ mutateMock.mockResolvedValueOnce(hasSubmittedChangesMutationPayload).mockResolvedValueOnce({
+ data: {
+ submitContentChanges: savedContentMeta,
+ },
+ });
- buildWrapper();
- findEditArea().vm.$emit('submit', { content: newContent });
+ buildWrapper({ content: newContent, images });
+ findEditMetaModal().vm.$emit('primary', mergeRequestMeta);
return wrapper.vm.$nextTick();
});
+ it('dispatches hasSubmittedChanges mutation', () => {
+ expect(mutateMock).toHaveBeenNthCalledWith(1, {
+ mutation: hasSubmittedChangesMutation,
+ variables: {
+ input: {
+ hasSubmittedChanges: true,
+ },
+ },
+ });
+ });
+
it('dispatches submitContentChanges mutation', () => {
- expect(mutateMock).toHaveBeenCalledWith({
+ expect(mutateMock).toHaveBeenNthCalledWith(2, {
mutation: submitContentChangesMutation,
variables: {
input: {
@@ -207,6 +260,8 @@ describe('static_site_editor/pages/home', () => {
project,
sourcePath,
username,
+ images,
+ mergeRequestMeta,
},
},
});
@@ -217,6 +272,12 @@ describe('static_site_editor/pages/home', () => {
});
});
+ it('does not display submit changes error when an error does not exist', () => {
+ buildWrapper();
+
+ expect(findSubmitChangesError().exists()).toBe(false);
+ });
+
it('tracks when editor is initialized on the mounted lifecycle hook', () => {
buildWrapper();
expect(trackingSpy).toHaveBeenCalledWith(
diff --git a/spec/frontend/static_site_editor/pages/success_spec.js b/spec/frontend/static_site_editor/pages/success_spec.js
index 3e19e2413e7..3fc69dc4586 100644
--- a/spec/frontend/static_site_editor/pages/success_spec.js
+++ b/spec/frontend/static_site_editor/pages/success_spec.js
@@ -1,10 +1,10 @@
import { shallowMount } from '@vue/test-utils';
-import { GlEmptyState, GlButton } from '@gitlab/ui';
+import { GlButton, GlEmptyState, GlLoadingIcon } from '@gitlab/ui';
import Success from '~/static_site_editor/pages/success.vue';
import { savedContentMeta, returnUrl, sourcePath } from '../mock_data';
import { HOME_ROUTE } from '~/static_site_editor/router/constants';
-describe('static_site_editor/pages/success', () => {
+describe('~/static_site_editor/pages/success.vue', () => {
const mergeRequestsIllustrationPath = 'illustrations/merge_requests.svg';
let wrapper;
let router;
@@ -15,14 +15,15 @@ describe('static_site_editor/pages/success', () => {
};
};
- const buildWrapper = (data = {}) => {
+ const buildWrapper = (data = {}, appData = {}) => {
wrapper = shallowMount(Success, {
mocks: {
$router: router,
},
stubs: {
- GlEmptyState,
GlButton,
+ GlEmptyState,
+ GlLoadingIcon,
},
propsData: {
mergeRequestsIllustrationPath,
@@ -33,6 +34,8 @@ describe('static_site_editor/pages/success', () => {
appData: {
returnUrl,
sourcePath,
+ hasSubmittedChanges: true,
+ ...appData,
},
...data,
};
@@ -40,8 +43,9 @@ describe('static_site_editor/pages/success', () => {
});
};
- const findEmptyState = () => wrapper.find(GlEmptyState);
const findReturnUrlButton = () => wrapper.find(GlButton);
+ const findEmptyState = () => wrapper.find(GlEmptyState);
+ const findLoadingIcon = () => wrapper.find(GlLoadingIcon);
beforeEach(() => {
buildRouter();
@@ -52,50 +56,76 @@ describe('static_site_editor/pages/success', () => {
wrapper = null;
});
- it('renders empty state with a link to the created merge request', () => {
- buildWrapper();
+ describe('when savedContentMeta is valid', () => {
+ it('renders empty state with a link to the created merge request', () => {
+ buildWrapper();
+
+ expect(findEmptyState().exists()).toBe(true);
+ expect(findEmptyState().props()).toMatchObject({
+ primaryButtonText: 'View merge request',
+ primaryButtonLink: savedContentMeta.mergeRequest.url,
+ title: 'Your merge request has been created',
+ svgPath: mergeRequestsIllustrationPath,
+ svgHeight: 146,
+ });
+ });
- expect(findEmptyState().exists()).toBe(true);
- expect(findEmptyState().props()).toMatchObject({
- primaryButtonText: 'View merge request',
- primaryButtonLink: savedContentMeta.mergeRequest.url,
- title: 'Your merge request has been created',
- svgPath: mergeRequestsIllustrationPath,
+ it('displays merge request instructions in the empty state', () => {
+ buildWrapper();
+
+ expect(findEmptyState().text()).toContain(
+ 'To see your changes live you will need to do the following things:',
+ );
+ expect(findEmptyState().text()).toContain('1. Add a clear title to describe the change.');
+ expect(findEmptyState().text()).toContain(
+ '2. Add a description to explain why the change is being made.',
+ );
+ expect(findEmptyState().text()).toContain(
+ '3. Assign a person to review and accept the merge request.',
+ );
});
- });
- it('displays merge request instructions in the empty state', () => {
- buildWrapper();
-
- expect(findEmptyState().text()).toContain(
- 'To see your changes live you will need to do the following things:',
- );
- expect(findEmptyState().text()).toContain('1. Add a clear title to describe the change.');
- expect(findEmptyState().text()).toContain(
- '2. Add a description to explain why the change is being made.',
- );
- expect(findEmptyState().text()).toContain(
- '3. Assign a person to review and accept the merge request.',
- );
- });
+ it('displays return to site button', () => {
+ buildWrapper();
+
+ expect(findReturnUrlButton().text()).toBe('Return to site');
+ expect(findReturnUrlButton().attributes().href).toBe(returnUrl);
+ });
- it('displays return to site button', () => {
- buildWrapper();
+ it('displays source path', () => {
+ buildWrapper();
- expect(findReturnUrlButton().text()).toBe('Return to site');
- expect(findReturnUrlButton().attributes().href).toBe(returnUrl);
+ expect(wrapper.text()).toContain(`Update ${sourcePath} file`);
+ });
});
- it('displays source path', () => {
- buildWrapper();
+ describe('when savedContentMeta is invalid', () => {
+ it('renders empty state with a loader', () => {
+ buildWrapper({ savedContentMeta: null });
- expect(wrapper.text()).toContain(`Update ${sourcePath} file`);
- });
+ expect(findEmptyState().exists()).toBe(true);
+ expect(findEmptyState().props()).toMatchObject({
+ title: 'Creating your merge request',
+ svgPath: mergeRequestsIllustrationPath,
+ });
+ expect(findLoadingIcon().exists()).toBe(true);
+ });
- it('redirects to the HOME route when content has not been submitted', () => {
- buildWrapper({ savedContentMeta: null });
+ it('displays helper info in the empty state', () => {
+ buildWrapper({ savedContentMeta: null });
- expect(router.push).toHaveBeenCalledWith(HOME_ROUTE);
- expect(wrapper.html()).toBe('');
+ expect(findEmptyState().text()).toContain(
+ 'You can set an assignee to get your changes reviewed and deployed once your merge request is created',
+ );
+ expect(findEmptyState().text()).toContain(
+ 'A link to view the merge request will appear once ready',
+ );
+ });
+
+ it('redirects to the HOME route when content has not been submitted', () => {
+ buildWrapper({ savedContentMeta: null }, { hasSubmittedChanges: false });
+
+ expect(router.push).toHaveBeenCalledWith(HOME_ROUTE);
+ });
});
});
diff --git a/spec/frontend/static_site_editor/services/front_matterify_spec.js b/spec/frontend/static_site_editor/services/front_matterify_spec.js
new file mode 100644
index 00000000000..dbaedc30849
--- /dev/null
+++ b/spec/frontend/static_site_editor/services/front_matterify_spec.js
@@ -0,0 +1,47 @@
+import {
+ sourceContentYAML as content,
+ sourceContentHeaderObjYAML as yamlFrontMatterObj,
+ sourceContentSpacing as spacing,
+ sourceContentBody as body,
+} from '../mock_data';
+
+import { frontMatterify, stringify } from '~/static_site_editor/services/front_matterify';
+
+describe('static_site_editor/services/front_matterify', () => {
+ const frontMatterifiedContent = {
+ source: content,
+ matter: yamlFrontMatterObj,
+ spacing,
+ content: body,
+ delimiter: '---',
+ type: 'yaml',
+ };
+ const frontMatterifiedBody = {
+ source: body,
+ matter: null,
+ spacing: null,
+ content: body,
+ delimiter: null,
+ type: null,
+ };
+
+ describe('frontMatterify', () => {
+ it.each`
+ frontMatterified | target
+ ${frontMatterify(content)} | ${frontMatterifiedContent}
+ ${frontMatterify(body)} | ${frontMatterifiedBody}
+ `('returns $target from $frontMatterified', ({ frontMatterified, target }) => {
+ expect(frontMatterified).toEqual(target);
+ });
+ });
+
+ describe('stringify', () => {
+ it.each`
+ stringified | target
+ ${stringify(frontMatterifiedContent)} | ${content}
+ ${stringify(frontMatterifiedBody)} | ${body}
+ `('returns $target from $stringified', ({ stringified, target }) => {
+ expect(stringified).toBe(target);
+ });
+ });
+});
diff --git a/spec/frontend/static_site_editor/services/submit_content_changes_spec.js b/spec/frontend/static_site_editor/services/submit_content_changes_spec.js
index d464e6b1895..5018da7300b 100644
--- a/spec/frontend/static_site_editor/services/submit_content_changes_spec.js
+++ b/spec/frontend/static_site_editor/services/submit_content_changes_spec.js
@@ -19,6 +19,7 @@ import {
commitBranchResponse,
commitMultipleResponse,
createMergeRequestResponse,
+ mergeRequestMeta,
sourcePath,
sourceContentYAML as content,
trackingCategory,
@@ -28,11 +29,20 @@ import {
jest.mock('~/static_site_editor/services/generate_branch_name');
describe('submitContentChanges', () => {
- const mergeRequestTitle = `Update ${sourcePath} file`;
const branch = 'branch-name';
let trackingSpy;
let origPage;
+ const buildPayload = (overrides = {}) => ({
+ username,
+ projectId,
+ sourcePath,
+ content,
+ images,
+ mergeRequestMeta,
+ ...overrides,
+ });
+
beforeEach(() => {
jest.spyOn(Api, 'createBranch').mockResolvedValue({ data: commitBranchResponse });
jest.spyOn(Api, 'commitMultiple').mockResolvedValue({ data: commitMultipleResponse });
@@ -53,7 +63,7 @@ describe('submitContentChanges', () => {
});
it('creates a branch named after the username and target branch', () => {
- return submitContentChanges({ username, projectId }).then(() => {
+ return submitContentChanges(buildPayload()).then(() => {
expect(Api.createBranch).toHaveBeenCalledWith(projectId, {
ref: DEFAULT_TARGET_BRANCH,
branch,
@@ -64,16 +74,16 @@ describe('submitContentChanges', () => {
it('notifies error when branch could not be created', () => {
Api.createBranch.mockRejectedValueOnce();
- return expect(submitContentChanges({ username, projectId })).rejects.toThrow(
+ return expect(submitContentChanges(buildPayload())).rejects.toThrow(
SUBMIT_CHANGES_BRANCH_ERROR,
);
});
it('commits the content changes to the branch when creating branch succeeds', () => {
- return submitContentChanges({ username, projectId, sourcePath, content, images }).then(() => {
+ return submitContentChanges(buildPayload()).then(() => {
expect(Api.commitMultiple).toHaveBeenCalledWith(projectId, {
branch,
- commit_message: mergeRequestTitle,
+ commit_message: mergeRequestMeta.title,
actions: [
{
action: 'update',
@@ -93,16 +103,11 @@ describe('submitContentChanges', () => {
it('does not commit an image if it has been removed from the content', () => {
const contentWithoutImages = '## Content without images';
- return submitContentChanges({
- username,
- projectId,
- sourcePath,
- content: contentWithoutImages,
- images,
- }).then(() => {
+ const payload = buildPayload({ content: contentWithoutImages });
+ return submitContentChanges(payload).then(() => {
expect(Api.commitMultiple).toHaveBeenCalledWith(projectId, {
branch,
- commit_message: mergeRequestTitle,
+ commit_message: mergeRequestMeta.title,
actions: [
{
action: 'update',
@@ -117,17 +122,19 @@ describe('submitContentChanges', () => {
it('notifies error when content could not be committed', () => {
Api.commitMultiple.mockRejectedValueOnce();
- return expect(submitContentChanges({ username, projectId, images })).rejects.toThrow(
+ return expect(submitContentChanges(buildPayload())).rejects.toThrow(
SUBMIT_CHANGES_COMMIT_ERROR,
);
});
- it('creates a merge request when commiting changes succeeds', () => {
- return submitContentChanges({ username, projectId, sourcePath, content, images }).then(() => {
+ it('creates a merge request when committing changes succeeds', () => {
+ return submitContentChanges(buildPayload()).then(() => {
+ const { title, description } = mergeRequestMeta;
expect(Api.createProjectMergeRequest).toHaveBeenCalledWith(
projectId,
convertObjectPropsToSnakeCase({
- title: mergeRequestTitle,
+ title,
+ description,
targetBranch: DEFAULT_TARGET_BRANCH,
sourceBranch: branch,
}),
@@ -138,7 +145,7 @@ describe('submitContentChanges', () => {
it('notifies error when merge request could not be created', () => {
Api.createProjectMergeRequest.mockRejectedValueOnce();
- return expect(submitContentChanges({ username, projectId, images })).rejects.toThrow(
+ return expect(submitContentChanges(buildPayload())).rejects.toThrow(
SUBMIT_CHANGES_MERGE_REQUEST_ERROR,
);
});
@@ -147,11 +154,9 @@ describe('submitContentChanges', () => {
let result;
beforeEach(() => {
- return submitContentChanges({ username, projectId, sourcePath, content, images }).then(
- _result => {
- result = _result;
- },
- );
+ return submitContentChanges(buildPayload()).then(_result => {
+ result = _result;
+ });
});
it('returns the branch name', () => {
@@ -179,7 +184,7 @@ describe('submitContentChanges', () => {
describe('sends the correct tracking event', () => {
beforeEach(() => {
- return submitContentChanges({ username, projectId, sourcePath, content, images });
+ return submitContentChanges(buildPayload());
});
it('for committing changes', () => {
diff --git a/spec/frontend/static_site_editor/services/templater_spec.js b/spec/frontend/static_site_editor/services/templater_spec.js
index 1e7ae872b7e..cb3a0a0c106 100644
--- a/spec/frontend/static_site_editor/services/templater_spec.js
+++ b/spec/frontend/static_site_editor/services/templater_spec.js
@@ -39,6 +39,10 @@ Below this line is a codeblock of the same HTML that should be ignored and prese
<p>Some paragraph...</p>
</div>
\`\`\`
+
+Below this line is a iframe that should be ignored and preserved
+
+<iframe></iframe>
`;
const sourceTemplated = `Below this line is a simple ERB (single-line erb block) example.
@@ -87,6 +91,10 @@ Below this line is a codeblock of the same HTML that should be ignored and prese
<p>Some paragraph...</p>
</div>
\`\`\`
+
+Below this line is a iframe that should be ignored and preserved
+
+<iframe></iframe>
`;
it.each`