summaryrefslogtreecommitdiff
path: root/spec/frontend/static_site_editor
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2020-06-18 11:18:50 +0000
committerGitLab Bot <gitlab-bot@gitlab.com>2020-06-18 11:18:50 +0000
commit8c7f4e9d5f36cff46365a7f8c4b9c21578c1e781 (patch)
treea77e7fe7a93de11213032ed4ab1f33a3db51b738 /spec/frontend/static_site_editor
parent00b35af3db1abfe813a778f643dad221aad51fca (diff)
downloadgitlab-ce-8c7f4e9d5f36cff46365a7f8c4b9c21578c1e781.tar.gz
Add latest changes from gitlab-org/gitlab@13-1-stable-ee
Diffstat (limited to 'spec/frontend/static_site_editor')
-rw-r--r--spec/frontend/static_site_editor/components/edit_area_spec.js36
-rw-r--r--spec/frontend/static_site_editor/components/unsaved_changes_confirm_dialog_spec.js44
-rw-r--r--spec/frontend/static_site_editor/mock_data.js11
-rw-r--r--spec/frontend/static_site_editor/pages/home_spec.js16
-rw-r--r--spec/frontend/static_site_editor/services/parse_source_file_spec.js64
-rw-r--r--spec/frontend/static_site_editor/services/submit_content_changes_spec.js30
6 files changed, 178 insertions, 23 deletions
diff --git a/spec/frontend/static_site_editor/components/edit_area_spec.js b/spec/frontend/static_site_editor/components/edit_area_spec.js
index bfe41f65d6e..d7c798e6620 100644
--- a/spec/frontend/static_site_editor/components/edit_area_spec.js
+++ b/spec/frontend/static_site_editor/components/edit_area_spec.js
@@ -5,13 +5,19 @@ import RichContentEditor from '~/vue_shared/components/rich_content_editor/rich_
import EditArea from '~/static_site_editor/components/edit_area.vue';
import PublishToolbar from '~/static_site_editor/components/publish_toolbar.vue';
import EditHeader from '~/static_site_editor/components/edit_header.vue';
+import UnsavedChangesConfirmDialog from '~/static_site_editor/components/unsaved_changes_confirm_dialog.vue';
-import { sourceContentTitle as title, sourceContent as content, returnUrl } from '../mock_data';
+import {
+ sourceContentTitle as title,
+ sourceContent as content,
+ sourceContentBody as body,
+ returnUrl,
+} from '../mock_data';
describe('~/static_site_editor/components/edit_area.vue', () => {
let wrapper;
const savingChanges = true;
- const newContent = `new ${content}`;
+ const newBody = `new ${body}`;
const buildWrapper = (propsData = {}) => {
wrapper = shallowMount(EditArea, {
@@ -28,6 +34,7 @@ describe('~/static_site_editor/components/edit_area.vue', () => {
const findEditHeader = () => wrapper.find(EditHeader);
const findRichContentEditor = () => wrapper.find(RichContentEditor);
const findPublishToolbar = () => wrapper.find(PublishToolbar);
+ const findUnsavedChangesConfirmDialog = () => wrapper.find(UnsavedChangesConfirmDialog);
beforeEach(() => {
buildWrapper();
@@ -44,29 +51,40 @@ describe('~/static_site_editor/components/edit_area.vue', () => {
it('renders rich content editor', () => {
expect(findRichContentEditor().exists()).toBe(true);
- expect(findRichContentEditor().props('value')).toBe(content);
+ expect(findRichContentEditor().props('value')).toBe(body);
});
it('renders publish toolbar', () => {
expect(findPublishToolbar().exists()).toBe(true);
- expect(findPublishToolbar().props('returnUrl')).toBe(returnUrl);
- expect(findPublishToolbar().props('savingChanges')).toBe(savingChanges);
- expect(findPublishToolbar().props('saveable')).toBe(false);
+ expect(findPublishToolbar().props()).toMatchObject({
+ returnUrl,
+ savingChanges,
+ saveable: false,
+ });
+ });
+
+ it('renders unsaved changes confirm dialog', () => {
+ expect(findUnsavedChangesConfirmDialog().exists()).toBe(true);
+ expect(findUnsavedChangesConfirmDialog().props('modified')).toBe(false);
});
describe('when content changes', () => {
beforeEach(() => {
- findRichContentEditor().vm.$emit('input', newContent);
+ findRichContentEditor().vm.$emit('input', newBody);
return wrapper.vm.$nextTick();
});
- it('sets publish toolbar as saveable when content changes', () => {
+ it('sets publish toolbar as saveable', () => {
expect(findPublishToolbar().props('saveable')).toBe(true);
});
+ it('sets unsaved changes confirm dialog as modified', () => {
+ expect(findUnsavedChangesConfirmDialog().props('modified')).toBe(true);
+ });
+
it('sets publish toolbar as not saveable when content changes are rollback', () => {
- findRichContentEditor().vm.$emit('input', content);
+ findRichContentEditor().vm.$emit('input', body);
return wrapper.vm.$nextTick().then(() => {
expect(findPublishToolbar().props('saveable')).toBe(false);
diff --git a/spec/frontend/static_site_editor/components/unsaved_changes_confirm_dialog_spec.js b/spec/frontend/static_site_editor/components/unsaved_changes_confirm_dialog_spec.js
new file mode 100644
index 00000000000..9b8b22da693
--- /dev/null
+++ b/spec/frontend/static_site_editor/components/unsaved_changes_confirm_dialog_spec.js
@@ -0,0 +1,44 @@
+import { shallowMount } from '@vue/test-utils';
+
+import UnsavedChangesConfirmDialog from '~/static_site_editor/components/unsaved_changes_confirm_dialog.vue';
+
+describe('static_site_editor/components/unsaved_changes_confirm_dialog', () => {
+ let wrapper;
+ let event;
+ let returnValueSetter;
+
+ const buildWrapper = (propsData = {}) => {
+ wrapper = shallowMount(UnsavedChangesConfirmDialog, {
+ propsData,
+ });
+ };
+
+ beforeEach(() => {
+ event = new Event('beforeunload');
+
+ jest.spyOn(event, 'preventDefault');
+ returnValueSetter = jest.spyOn(event, 'returnValue', 'set');
+ });
+
+ afterEach(() => {
+ event.preventDefault.mockRestore();
+ returnValueSetter.mockRestore();
+ wrapper.destroy();
+ });
+
+ it('displays confirmation dialog when modified = true', () => {
+ buildWrapper({ modified: true });
+ window.dispatchEvent(event);
+
+ expect(event.preventDefault).toHaveBeenCalled();
+ expect(returnValueSetter).toHaveBeenCalledWith('');
+ });
+
+ it('does not display confirmation dialog when modified = false', () => {
+ buildWrapper();
+ window.dispatchEvent(event);
+
+ expect(event.preventDefault).not.toHaveBeenCalled();
+ expect(returnValueSetter).not.toHaveBeenCalled();
+ });
+});
diff --git a/spec/frontend/static_site_editor/mock_data.js b/spec/frontend/static_site_editor/mock_data.js
index 371695e913e..422048a5f69 100644
--- a/spec/frontend/static_site_editor/mock_data.js
+++ b/spec/frontend/static_site_editor/mock_data.js
@@ -1,16 +1,17 @@
-export const sourceContent = `
----
+export const sourceContentHeader = `---
layout: handbook-page-toc
title: Handbook
twitter_image: '/images/tweets/handbook-gitlab.png'
----
-
-## On this page
+---`;
+export const sourceContentSpacing = `
+`;
+export const sourceContentBody = `## On this page
{:.no_toc .hidden-md .hidden-lg}
- TOC
{:toc .hidden-md .hidden-lg}
`;
+export const sourceContent = `${sourceContentHeader}${sourceContentSpacing}${sourceContentBody}`;
export const sourceContentTitle = 'Handbook';
export const username = 'gitlabuser';
diff --git a/spec/frontend/static_site_editor/pages/home_spec.js b/spec/frontend/static_site_editor/pages/home_spec.js
index 8c9c54f593e..d3ee70785d1 100644
--- a/spec/frontend/static_site_editor/pages/home_spec.js
+++ b/spec/frontend/static_site_editor/pages/home_spec.js
@@ -7,6 +7,8 @@ import InvalidContentMessage from '~/static_site_editor/components/invalid_conte
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 { SUCCESS_ROUTE } from '~/static_site_editor/router/constants';
+import { mockTracking, unmockTracking } from 'helpers/tracking_helper';
+import { TRACKING_ACTION_INITIALIZE_EDITOR } from '~/static_site_editor/constants';
import {
projectId as project,
@@ -17,6 +19,7 @@ import {
username,
savedContentMeta,
submitChangesError,
+ trackingCategory,
} from '../mock_data';
const localVue = createLocalVue();
@@ -29,6 +32,7 @@ describe('static_site_editor/pages/home', () => {
let $apollo;
let $router;
let mutateMock;
+ let trackingSpy;
const buildApollo = (queries = {}) => {
mutateMock = jest.fn();
@@ -76,10 +80,14 @@ describe('static_site_editor/pages/home', () => {
beforeEach(() => {
buildApollo();
buildRouter();
+
+ document.body.dataset.page = trackingCategory;
+ trackingSpy = mockTracking(document.body.dataset.page, undefined, jest.spyOn);
});
afterEach(() => {
wrapper.destroy();
+ unmockTracking();
wrapper = null;
$apollo = null;
});
@@ -208,4 +216,12 @@ describe('static_site_editor/pages/home', () => {
expect($router.push).toHaveBeenCalledWith(SUCCESS_ROUTE);
});
});
+
+ it('tracks when editor is initialized on the mounted lifecycle hook', () => {
+ buildWrapper();
+ expect(trackingSpy).toHaveBeenCalledWith(
+ document.body.dataset.page,
+ TRACKING_ACTION_INITIALIZE_EDITOR,
+ );
+ });
});
diff --git a/spec/frontend/static_site_editor/services/parse_source_file_spec.js b/spec/frontend/static_site_editor/services/parse_source_file_spec.js
new file mode 100644
index 00000000000..fe99c4f5334
--- /dev/null
+++ b/spec/frontend/static_site_editor/services/parse_source_file_spec.js
@@ -0,0 +1,64 @@
+import {
+ sourceContent as content,
+ sourceContentHeader as header,
+ sourceContentSpacing as spacing,
+ sourceContentBody as body,
+} from '../mock_data';
+
+import parseSourceFile from '~/static_site_editor/services/parse_source_file';
+
+describe('parseSourceFile', () => {
+ const contentSimple = content;
+ const contentComplex = [content, content, content].join('');
+
+ describe('the editable shape and its expected values', () => {
+ it.each`
+ sourceContent | sourceHeader | sourceSpacing | sourceBody | desc
+ ${contentSimple} | ${header} | ${spacing} | ${body} | ${'extracts header'}
+ ${contentComplex} | ${header} | ${spacing} | ${[body, content, content].join('')} | ${'extracts body'}
+ `('$desc', ({ sourceContent, sourceHeader, sourceSpacing, sourceBody }) => {
+ const { editable } = parseSourceFile(sourceContent);
+
+ expect(editable).toMatchObject({
+ raw: sourceContent,
+ header: sourceHeader,
+ spacing: sourceSpacing,
+ body: sourceBody,
+ });
+ });
+
+ it('returns the same front matter regardless of front matter duplication', () => {
+ const parsedSourceSimple = parseSourceFile(contentSimple);
+ const parsedSourceComplex = parseSourceFile(contentComplex);
+
+ expect(parsedSourceSimple.editable.header).toBe(parsedSourceComplex.editable.header);
+ });
+ });
+
+ describe('editable body to raw content default and changes', () => {
+ it.each`
+ sourceContent | desc
+ ${contentSimple} | ${'returns false by default for both raw and body'}
+ ${contentComplex} | ${'returns false by default for both raw and body'}
+ `('$desc', ({ sourceContent }) => {
+ const parsedSource = parseSourceFile(sourceContent);
+
+ expect(parsedSource.isModifiedRaw()).toBe(false);
+ expect(parsedSource.isModifiedBody()).toBe(false);
+ });
+
+ it.each`
+ sourceContent | editableKey | syncKey | isModifiedKey | desc
+ ${contentSimple} | ${'body'} | ${'syncRaw'} | ${'isModifiedRaw'} | ${'returns true after modification and sync'}
+ ${contentSimple} | ${'raw'} | ${'syncBody'} | ${'isModifiedBody'} | ${'returns true after modification and sync'}
+ ${contentComplex} | ${'body'} | ${'syncRaw'} | ${'isModifiedRaw'} | ${'returns true after modification and sync'}
+ ${contentComplex} | ${'raw'} | ${'syncBody'} | ${'isModifiedBody'} | ${'returns true after modification and sync'}
+ `('$desc', ({ sourceContent, editableKey, syncKey, isModifiedKey }) => {
+ const parsedSource = parseSourceFile(sourceContent);
+ parsedSource.editable[editableKey] += 'Added content';
+ parsedSource[syncKey]();
+
+ expect(parsedSource[isModifiedKey]()).toBe(true);
+ });
+ });
+});
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 a1e9ff4ec4c..3636de3fe70 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
@@ -8,6 +8,7 @@ import {
SUBMIT_CHANGES_COMMIT_ERROR,
SUBMIT_CHANGES_MERGE_REQUEST_ERROR,
TRACKING_ACTION_CREATE_COMMIT,
+ TRACKING_ACTION_CREATE_MERGE_REQUEST,
} from '~/static_site_editor/constants';
import generateBranchName from '~/static_site_editor/services/generate_branch_name';
import submitContentChanges from '~/static_site_editor/services/submit_content_changes';
@@ -83,15 +84,6 @@ describe('submitContentChanges', () => {
});
});
- it('sends the correct tracking event when committing content changes', () => {
- return submitContentChanges({ username, projectId, sourcePath, content }).then(() => {
- expect(trackingSpy).toHaveBeenCalledWith(
- document.body.dataset.page,
- TRACKING_ACTION_CREATE_COMMIT,
- );
- });
- });
-
it('notifies error when content could not be committed', () => {
Api.commitMultiple.mockRejectedValueOnce();
@@ -152,4 +144,24 @@ describe('submitContentChanges', () => {
});
});
});
+
+ describe('sends the correct tracking event', () => {
+ beforeEach(() => {
+ return submitContentChanges({ username, projectId, sourcePath, content });
+ });
+
+ it('for committing changes', () => {
+ expect(trackingSpy).toHaveBeenCalledWith(
+ document.body.dataset.page,
+ TRACKING_ACTION_CREATE_COMMIT,
+ );
+ });
+
+ it('for creating a merge request', () => {
+ expect(trackingSpy).toHaveBeenCalledWith(
+ document.body.dataset.page,
+ TRACKING_ACTION_CREATE_MERGE_REQUEST,
+ );
+ });
+ });
});