summaryrefslogtreecommitdiff
path: root/spec/frontend/design_management/pages
diff options
context:
space:
mode:
Diffstat (limited to 'spec/frontend/design_management/pages')
-rw-r--r--spec/frontend/design_management/pages/__snapshots__/index_spec.js.snap2
-rw-r--r--spec/frontend/design_management/pages/design/__snapshots__/index_spec.js.snap14
-rw-r--r--spec/frontend/design_management/pages/design/index_spec.js134
-rw-r--r--spec/frontend/design_management/pages/index_apollo_spec.js162
-rw-r--r--spec/frontend/design_management/pages/index_spec.js140
5 files changed, 216 insertions, 236 deletions
diff --git a/spec/frontend/design_management/pages/__snapshots__/index_spec.js.snap b/spec/frontend/design_management/pages/__snapshots__/index_spec.js.snap
index 3881b2d7679..b80b7fdb43e 100644
--- a/spec/frontend/design_management/pages/__snapshots__/index_spec.js.snap
+++ b/spec/frontend/design_management/pages/__snapshots__/index_spec.js.snap
@@ -111,7 +111,7 @@ exports[`Design management index page designs renders designs list and header wi
>
<gl-button-stub
category="primary"
- class="gl-mr-3 js-select-all"
+ class="gl-mr-4 js-select-all"
icon=""
size="small"
variant="link"
diff --git a/spec/frontend/design_management/pages/design/__snapshots__/index_spec.js.snap b/spec/frontend/design_management/pages/design/__snapshots__/index_spec.js.snap
index 823294efc38..c849e4d4ed6 100644
--- a/spec/frontend/design_management/pages/design/__snapshots__/index_spec.js.snap
+++ b/spec/frontend/design_management/pages/design/__snapshots__/index_spec.js.snap
@@ -32,6 +32,8 @@ exports[`Design management design index page renders design index 1`] = `
<div
class="image-notes"
>
+ <!---->
+
<h2
class="gl-font-weight-bold gl-mt-0"
>
@@ -57,11 +59,11 @@ exports[`Design management design index page renders design index 1`] = `
<design-discussion-stub
data-testid="unresolved-discussion"
- designid="test"
+ designid="gid::/gitlab/Design/1"
discussion="[object Object]"
discussionwithopenform=""
markdownpreviewpath="/project-path/preview_markdown?target_type=Issue"
- noteableid="design-id"
+ noteableid="gid::/gitlab/Design/1"
/>
<gl-button-stub
@@ -92,7 +94,7 @@ exports[`Design management design index page renders design index 1`] = `
</p>
<a
- href="#"
+ href="https://docs.gitlab.com/ee/user/project/issues/design_management.html#resolve-design-threads"
rel="noopener noreferrer"
target="_blank"
>
@@ -105,11 +107,11 @@ exports[`Design management design index page renders design index 1`] = `
>
<design-discussion-stub
data-testid="resolved-discussion"
- designid="test"
+ designid="gid::/gitlab/Design/1"
discussion="[object Object]"
discussionwithopenform=""
markdownpreviewpath="/project-path/preview_markdown?target_type=Issue"
- noteableid="design-id"
+ noteableid="gid::/gitlab/Design/1"
/>
</gl-collapse-stub>
@@ -179,6 +181,8 @@ exports[`Design management design index page with error GlAlert is rendered in c
<div
class="image-notes"
>
+ <!---->
+
<h2
class="gl-font-weight-bold gl-mt-0"
>
diff --git a/spec/frontend/design_management/pages/design/index_spec.js b/spec/frontend/design_management/pages/design/index_spec.js
index 369c8667f4d..d9f7146d258 100644
--- a/spec/frontend/design_management/pages/design/index_spec.js
+++ b/spec/frontend/design_management/pages/design/index_spec.js
@@ -7,24 +7,21 @@ import DesignIndex from '~/design_management/pages/design/index.vue';
import DesignSidebar from '~/design_management/components/design_sidebar.vue';
import DesignPresentation from '~/design_management/components/design_presentation.vue';
import createImageDiffNoteMutation from '~/design_management/graphql/mutations/create_image_diff_note.mutation.graphql';
-import design from '../../mock_data/design';
-import mockResponseWithDesigns from '../../mock_data/designs';
-import mockResponseNoDesigns from '../../mock_data/no_designs';
-import mockAllVersions from '../../mock_data/all_versions';
+import updateActiveDiscussion from '~/design_management/graphql/mutations/update_active_discussion.mutation.graphql';
import {
DESIGN_NOT_FOUND_ERROR,
DESIGN_VERSION_NOT_EXIST_ERROR,
} from '~/design_management/utils/error_messages';
-import { DESIGNS_ROUTE_NAME } from '~/design_management/router/constants';
+import { DESIGNS_ROUTE_NAME, DESIGN_ROUTE_NAME } from '~/design_management/router/constants';
import createRouter from '~/design_management/router';
import * as utils from '~/design_management/utils/design_management_utils';
import { DESIGN_DETAIL_LAYOUT_CLASSLIST } from '~/design_management/constants';
+import design from '../../mock_data/design';
+import mockResponseWithDesigns from '../../mock_data/designs';
+import mockResponseNoDesigns from '../../mock_data/no_designs';
+import mockAllVersions from '../../mock_data/all_versions';
jest.mock('~/flash');
-jest.mock('mousetrap', () => ({
- bind: jest.fn(),
- unbind: jest.fn(),
-}));
const focusInput = jest.fn();
@@ -34,6 +31,12 @@ const DesignReplyForm = {
focusInput,
},
};
+const mockDesignNoDiscussions = {
+ ...design,
+ discussions: {
+ nodes: [],
+ },
+};
const localVue = createLocalVue();
localVue.use(VueRouter);
@@ -75,7 +78,7 @@ describe('Design management design index page', () => {
const findSidebar = () => wrapper.find(DesignSidebar);
const findDesignPresentation = () => wrapper.find(DesignPresentation);
- function createComponent(loading = false, data = {}) {
+ function createComponent({ loading = false } = {}, { data = {}, intialRouteOptions = {} } = {}) {
const $apollo = {
queries: {
design: {
@@ -87,6 +90,8 @@ describe('Design management design index page', () => {
router = createRouter();
+ router.push({ name: DESIGN_ROUTE_NAME, params: { id: design.id }, ...intialRouteOptions });
+
wrapper = shallowMount(DesignIndex, {
propsData: { id: '1' },
mocks: { $apollo },
@@ -126,29 +131,28 @@ describe('Design management design index page', () => {
},
};
jest.spyOn(utils, 'getPageLayoutElement').mockReturnValue(mockEl);
- createComponent(true);
+ createComponent({ loading: true });
- wrapper.vm.$router.push('/designs/test');
expect(mockEl.classList.add).toHaveBeenCalledTimes(1);
expect(mockEl.classList.add).toHaveBeenCalledWith(...DESIGN_DETAIL_LAYOUT_CLASSLIST);
});
});
it('sets loading state', () => {
- createComponent(true);
+ createComponent({ loading: true });
expect(wrapper.element).toMatchSnapshot();
});
it('renders design index', () => {
- createComponent(false, { design });
+ createComponent({ loading: false }, { data: { design } });
expect(wrapper.element).toMatchSnapshot();
expect(wrapper.find(GlAlert).exists()).toBe(false);
});
it('passes correct props to sidebar component', () => {
- createComponent(false, { design });
+ createComponent({ loading: false }, { data: { design } });
expect(findSidebar().props()).toEqual({
design,
@@ -158,14 +162,14 @@ describe('Design management design index page', () => {
});
it('opens a new discussion form', () => {
- createComponent(false, {
- design: {
- ...design,
- discussions: {
- nodes: [],
+ createComponent(
+ { loading: false },
+ {
+ data: {
+ design,
},
},
- });
+ );
findDesignPresentation().vm.$emit('openCommentForm', { x: 0, y: 0 });
@@ -175,15 +179,15 @@ describe('Design management design index page', () => {
});
it('keeps new discussion form focused', () => {
- createComponent(false, {
- design: {
- ...design,
- discussions: {
- nodes: [],
+ createComponent(
+ { loading: false },
+ {
+ data: {
+ design,
+ annotationCoordinates,
},
},
- annotationCoordinates,
- });
+ );
findDesignPresentation().vm.$emit('openCommentForm', { x: 10, y: 10 });
@@ -191,18 +195,18 @@ describe('Design management design index page', () => {
});
it('sends a mutation on submitting form and closes form', () => {
- createComponent(false, {
- design: {
- ...design,
- discussions: {
- nodes: [],
+ createComponent(
+ { loading: false },
+ {
+ data: {
+ design,
+ annotationCoordinates,
+ comment: newComment,
},
},
- annotationCoordinates,
- comment: newComment,
- });
+ );
- findDiscussionForm().vm.$emit('submitForm');
+ findDiscussionForm().vm.$emit('submit-form');
expect(mutate).toHaveBeenCalledWith(createDiscussionMutationVariables);
return wrapper.vm
@@ -216,18 +220,18 @@ describe('Design management design index page', () => {
});
it('closes the form and clears the comment on canceling form', () => {
- createComponent(false, {
- design: {
- ...design,
- discussions: {
- nodes: [],
+ createComponent(
+ { loading: false },
+ {
+ data: {
+ design,
+ annotationCoordinates,
+ comment: newComment,
},
},
- annotationCoordinates,
- comment: newComment,
- });
+ );
- findDiscussionForm().vm.$emit('cancelForm');
+ findDiscussionForm().vm.$emit('cancel-form');
expect(wrapper.vm.comment).toBe('');
@@ -238,15 +242,15 @@ describe('Design management design index page', () => {
describe('with error', () => {
beforeEach(() => {
- createComponent(false, {
- design: {
- ...design,
- discussions: {
- nodes: [],
+ createComponent(
+ { loading: false },
+ {
+ data: {
+ design: mockDesignNoDiscussions,
+ errorMessage: 'woops',
},
},
- errorMessage: 'woops',
- });
+ );
});
it('GlAlert is rendered in correct position with correct content', () => {
@@ -257,7 +261,7 @@ describe('Design management design index page', () => {
describe('onDesignQueryResult', () => {
describe('with no designs', () => {
it('redirects to /designs', () => {
- createComponent(true);
+ createComponent({ loading: true });
router.push = jest.fn();
wrapper.vm.onDesignQueryResult({ data: mockResponseNoDesigns, loading: false });
@@ -272,7 +276,7 @@ describe('Design management design index page', () => {
describe('when no design exists for given version', () => {
it('redirects to /designs', () => {
- createComponent(true);
+ createComponent({ loading: true });
wrapper.setData({
allVersions: mockAllVersions,
});
@@ -291,4 +295,24 @@ describe('Design management design index page', () => {
});
});
});
+
+ describe('when hash present in current route', () => {
+ it('calls updateActiveDiscussion mutation', () => {
+ createComponent(
+ { loading: false },
+ {
+ data: {
+ design,
+ },
+ intialRouteOptions: { hash: '#note_123' },
+ },
+ );
+
+ expect(mutate).toHaveBeenCalledTimes(1);
+ expect(mutate).toHaveBeenCalledWith({
+ mutation: updateActiveDiscussion,
+ variables: { id: 'gid://gitlab/DiffNote/123', source: 'url' },
+ });
+ });
+ });
});
diff --git a/spec/frontend/design_management/pages/index_apollo_spec.js b/spec/frontend/design_management/pages/index_apollo_spec.js
deleted file mode 100644
index 3ea711c2cfa..00000000000
--- a/spec/frontend/design_management/pages/index_apollo_spec.js
+++ /dev/null
@@ -1,162 +0,0 @@
-import { shallowMount, createLocalVue } from '@vue/test-utils';
-import { createMockClient } from 'mock-apollo-client';
-import VueApollo from 'vue-apollo';
-import VueRouter from 'vue-router';
-import VueDraggable from 'vuedraggable';
-import { InMemoryCache } from 'apollo-cache-inmemory';
-import Design from '~/design_management/components/list/item.vue';
-import createRouter from '~/design_management/router';
-import getDesignListQuery from '~/design_management/graphql/queries/get_design_list.query.graphql';
-import permissionsQuery from '~/design_management/graphql/queries/design_permissions.query.graphql';
-import moveDesignMutation from '~/design_management/graphql/mutations/move_design.mutation.graphql';
-import { deprecatedCreateFlash as createFlash } from '~/flash';
-import Index from '~/design_management/pages/index.vue';
-import {
- designListQueryResponse,
- permissionsQueryResponse,
- moveDesignMutationResponse,
- reorderedDesigns,
- moveDesignMutationResponseWithErrors,
-} from '../mock_data/apollo_mock';
-
-jest.mock('~/flash');
-
-const localVue = createLocalVue();
-localVue.use(VueApollo);
-
-const router = createRouter();
-localVue.use(VueRouter);
-
-const designToMove = {
- __typename: 'Design',
- id: '2',
- event: 'NONE',
- filename: 'fox_2.jpg',
- notesCount: 2,
- image: 'image-2',
- imageV432x230: 'image-2',
-};
-
-describe('Design management index page with Apollo mock', () => {
- let wrapper;
- let mockClient;
- let apolloProvider;
- let moveDesignHandler;
-
- async function moveDesigns(localWrapper) {
- await jest.runOnlyPendingTimers();
- await localWrapper.vm.$nextTick();
-
- localWrapper.find(VueDraggable).vm.$emit('input', reorderedDesigns);
- localWrapper.find(VueDraggable).vm.$emit('change', {
- moved: {
- newIndex: 0,
- element: designToMove,
- },
- });
- }
-
- const fragmentMatcher = { match: () => true };
-
- const cache = new InMemoryCache({
- fragmentMatcher,
- addTypename: false,
- });
-
- const findDesigns = () => wrapper.findAll(Design);
-
- function createComponent({
- moveHandler = jest.fn().mockResolvedValue(moveDesignMutationResponse),
- }) {
- mockClient = createMockClient({ cache });
-
- mockClient.setRequestHandler(
- getDesignListQuery,
- jest.fn().mockResolvedValue(designListQueryResponse),
- );
-
- mockClient.setRequestHandler(
- permissionsQuery,
- jest.fn().mockResolvedValue(permissionsQueryResponse),
- );
-
- moveDesignHandler = moveHandler;
-
- mockClient.setRequestHandler(moveDesignMutation, moveDesignHandler);
-
- apolloProvider = new VueApollo({
- defaultClient: mockClient,
- });
-
- wrapper = shallowMount(Index, {
- localVue,
- apolloProvider,
- router,
- stubs: { VueDraggable },
- });
- }
-
- afterEach(() => {
- wrapper.destroy();
- wrapper = null;
- mockClient = null;
- apolloProvider = null;
- });
-
- it('has a design with id 1 as a first one', async () => {
- createComponent({});
-
- await jest.runOnlyPendingTimers();
- await wrapper.vm.$nextTick();
-
- expect(findDesigns()).toHaveLength(3);
- expect(
- findDesigns()
- .at(0)
- .props('id'),
- ).toBe('1');
- });
-
- it('calls a mutation with correct parameters and reorders designs', async () => {
- createComponent({});
-
- await moveDesigns(wrapper);
-
- expect(moveDesignHandler).toHaveBeenCalled();
-
- await wrapper.vm.$nextTick();
-
- expect(
- findDesigns()
- .at(0)
- .props('id'),
- ).toBe('2');
- });
-
- it('displays flash if mutation had a recoverable error', async () => {
- createComponent({
- moveHandler: jest.fn().mockResolvedValue(moveDesignMutationResponseWithErrors),
- });
-
- await moveDesigns(wrapper);
-
- await wrapper.vm.$nextTick();
-
- expect(createFlash).toHaveBeenCalledWith('Houston, we have a problem');
- });
-
- it('displays flash if mutation had a non-recoverable error', async () => {
- createComponent({
- moveHandler: jest.fn().mockRejectedValue('Error'),
- });
-
- await moveDesigns(wrapper);
-
- await jest.runOnlyPendingTimers();
- await wrapper.vm.$nextTick();
-
- expect(createFlash).toHaveBeenCalledWith(
- 'Something went wrong when reordering designs. Please try again',
- );
- });
-});
diff --git a/spec/frontend/design_management/pages/index_spec.js b/spec/frontend/design_management/pages/index_spec.js
index 093fa155d2e..661717d29a3 100644
--- a/spec/frontend/design_management/pages/index_spec.js
+++ b/spec/frontend/design_management/pages/index_spec.js
@@ -1,13 +1,15 @@
import { createLocalVue, shallowMount } from '@vue/test-utils';
-import { ApolloMutation } from 'vue-apollo';
+import VueApollo, { ApolloMutation } from 'vue-apollo';
import VueDraggable from 'vuedraggable';
import VueRouter from 'vue-router';
import { GlEmptyState } from '@gitlab/ui';
+import createMockApollo from 'jest/helpers/mock_apollo_helper';
import Index from '~/design_management/pages/index.vue';
import uploadDesignQuery from '~/design_management/graphql/mutations/upload_design.mutation.graphql';
import DesignDestroyer from '~/design_management/components/design_destroyer.vue';
import DesignDropzone from '~/design_management/components/upload/design_dropzone.vue';
import DeleteButton from '~/design_management/components/delete_button.vue';
+import Design from '~/design_management/components/list/item.vue';
import { DESIGNS_ROUTE_NAME } from '~/design_management/router/constants';
import {
EXISTING_DESIGN_DROP_MANY_FILES_MESSAGE,
@@ -17,6 +19,16 @@ import { deprecatedCreateFlash as createFlash } from '~/flash';
import createRouter from '~/design_management/router';
import * as utils from '~/design_management/utils/design_management_utils';
import { DESIGN_DETAIL_LAYOUT_CLASSLIST } from '~/design_management/constants';
+import {
+ designListQueryResponse,
+ permissionsQueryResponse,
+ moveDesignMutationResponse,
+ reorderedDesigns,
+ moveDesignMutationResponseWithErrors,
+} from '../mock_data/apollo_mock';
+import getDesignListQuery from '~/design_management/graphql/queries/get_design_list.query.graphql';
+import permissionsQuery from '~/design_management/graphql/queries/design_permissions.query.graphql';
+import moveDesignMutation from '~/design_management/graphql/mutations/move_design.mutation.graphql';
jest.mock('~/flash.js');
const mockPageEl = {
@@ -61,9 +73,21 @@ const mockVersion = {
id: 'gid://gitlab/DesignManagement::Version/1',
};
+const designToMove = {
+ __typename: 'Design',
+ id: '2',
+ event: 'NONE',
+ filename: 'fox_2.jpg',
+ notesCount: 2,
+ image: 'image-2',
+ imageV432x230: 'image-2',
+};
+
describe('Design management index page', () => {
let mutate;
let wrapper;
+ let fakeApollo;
+ let moveDesignHandler;
const findDesignCheckboxes = () => wrapper.findAll('.design-checkbox');
const findSelectAllButton = () => wrapper.find('.js-select-all');
@@ -74,6 +98,20 @@ describe('Design management index page', () => {
const findDropzoneWrapper = () => wrapper.find('[data-testid="design-dropzone-wrapper"]');
const findFirstDropzoneWithDesign = () => wrapper.findAll(DesignDropzone).at(1);
const findDesignsWrapper = () => wrapper.find('[data-testid="designs-root"]');
+ const findDesigns = () => wrapper.findAll(Design);
+
+ async function moveDesigns(localWrapper) {
+ await jest.runOnlyPendingTimers();
+ await localWrapper.vm.$nextTick();
+
+ localWrapper.find(VueDraggable).vm.$emit('input', reorderedDesigns);
+ localWrapper.find(VueDraggable).vm.$emit('change', {
+ moved: {
+ newIndex: 0,
+ element: designToMove,
+ },
+ });
+ }
function createComponent({
loading = false,
@@ -118,8 +156,30 @@ describe('Design management index page', () => {
});
}
+ function createComponentWithApollo({
+ moveHandler = jest.fn().mockResolvedValue(moveDesignMutationResponse),
+ }) {
+ localVue.use(VueApollo);
+ moveDesignHandler = moveHandler;
+
+ const requestHandlers = [
+ [getDesignListQuery, jest.fn().mockResolvedValue(designListQueryResponse)],
+ [permissionsQuery, jest.fn().mockResolvedValue(permissionsQueryResponse)],
+ [moveDesignMutation, moveDesignHandler],
+ ];
+
+ fakeApollo = createMockApollo(requestHandlers);
+ wrapper = shallowMount(Index, {
+ localVue,
+ apolloProvider: fakeApollo,
+ router,
+ stubs: { VueDraggable },
+ });
+ }
+
afterEach(() => {
wrapper.destroy();
+ wrapper = null;
});
describe('designs', () => {
@@ -478,16 +538,15 @@ describe('Design management index page', () => {
describe('on non-latest version', () => {
beforeEach(() => {
createComponent({ designs: mockDesigns, allVersions: [mockVersion] });
+ });
- router.replace({
+ it('does not render design checkboxes', async () => {
+ await router.replace({
name: DESIGNS_ROUTE_NAME,
query: {
version: '2',
},
});
- });
-
- it('does not render design checkboxes', () => {
expect(findDesignCheckboxes()).toHaveLength(0);
});
@@ -514,13 +573,6 @@ describe('Design management index page', () => {
files: [{ name: 'image.png', type: 'image/png' }],
getData: () => 'test.png',
};
-
- router.replace({
- name: DESIGNS_ROUTE_NAME,
- query: {
- version: '2',
- },
- });
});
it('does not call paste event if designs wrapper is not hovered', () => {
@@ -587,7 +639,69 @@ describe('Design management index page', () => {
});
createComponent(true);
- expect(scrollIntoViewMock).toHaveBeenCalled();
+ return wrapper.vm.$nextTick().then(() => {
+ expect(scrollIntoViewMock).toHaveBeenCalled();
+ });
+ });
+ });
+
+ describe('with mocked Apollo client', () => {
+ it('has a design with id 1 as a first one', async () => {
+ createComponentWithApollo({});
+
+ await jest.runOnlyPendingTimers();
+ await wrapper.vm.$nextTick();
+
+ expect(findDesigns()).toHaveLength(3);
+ expect(
+ findDesigns()
+ .at(0)
+ .props('id'),
+ ).toBe('1');
+ });
+
+ it('calls a mutation with correct parameters and reorders designs', async () => {
+ createComponentWithApollo({});
+
+ await moveDesigns(wrapper);
+
+ expect(moveDesignHandler).toHaveBeenCalled();
+
+ await wrapper.vm.$nextTick();
+
+ expect(
+ findDesigns()
+ .at(0)
+ .props('id'),
+ ).toBe('2');
+ });
+
+ it('displays flash if mutation had a recoverable error', async () => {
+ createComponentWithApollo({
+ moveHandler: jest.fn().mockResolvedValue(moveDesignMutationResponseWithErrors),
+ });
+
+ await moveDesigns(wrapper);
+
+ await wrapper.vm.$nextTick();
+
+ expect(createFlash).toHaveBeenCalledWith('Houston, we have a problem');
+ });
+
+ it('displays flash if mutation had a non-recoverable error', async () => {
+ createComponentWithApollo({
+ moveHandler: jest.fn().mockRejectedValue('Error'),
+ });
+
+ await moveDesigns(wrapper);
+
+ await wrapper.vm.$nextTick(); // kick off the DOM update
+ await jest.runOnlyPendingTimers(); // kick off the mocked GQL stuff (promises)
+ await wrapper.vm.$nextTick(); // kick off the DOM update for flash
+
+ expect(createFlash).toHaveBeenCalledWith(
+ 'Something went wrong when reordering designs. Please try again',
+ );
});
});
});