summaryrefslogtreecommitdiff
path: root/spec/frontend/design_management/components/design_overlay_spec.js
diff options
context:
space:
mode:
Diffstat (limited to 'spec/frontend/design_management/components/design_overlay_spec.js')
-rw-r--r--spec/frontend/design_management/components/design_overlay_spec.js305
1 files changed, 116 insertions, 189 deletions
diff --git a/spec/frontend/design_management/components/design_overlay_spec.js b/spec/frontend/design_management/components/design_overlay_spec.js
index 169f2dbdccb..2807fe7727f 100644
--- a/spec/frontend/design_management/components/design_overlay_spec.js
+++ b/spec/frontend/design_management/components/design_overlay_spec.js
@@ -1,32 +1,54 @@
-import { mount } from '@vue/test-utils';
-import { nextTick } from 'vue';
+import { shallowMount } from '@vue/test-utils';
+import Vue, { nextTick } from 'vue';
+import VueApollo from 'vue-apollo';
+import createMockApollo from 'helpers/mock_apollo_helper';
+import waitForPromises from 'helpers/wait_for_promises';
import DesignOverlay from '~/design_management/components/design_overlay.vue';
-import { ACTIVE_DISCUSSION_SOURCE_TYPES } from '~/design_management/constants';
-import updateActiveDiscussion from '~/design_management/graphql/mutations/update_active_discussion.mutation.graphql';
+import { resolvers } from '~/design_management/graphql';
+import activeDiscussionQuery from '~/design_management/graphql/queries/active_discussion.query.graphql';
import notes from '../mock_data/notes';
-const mutate = jest.fn(() => Promise.resolve());
+Vue.use(VueApollo);
describe('Design overlay component', () => {
let wrapper;
+ let apolloProvider;
const mockDimensions = { width: 100, height: 100 };
- const findAllNotes = () => wrapper.findAll('.js-image-badge');
- const findCommentBadge = () => wrapper.find('.comment-indicator');
+ const findOverlay = () => wrapper.find('[data-testid="design-overlay"]');
+ const findAllNotes = () => wrapper.findAll('[data-testid="note-pin"]');
+ const findCommentBadge = () => wrapper.find('[data-testid="comment-badge"]');
const findBadgeAtIndex = (noteIndex) => findAllNotes().at(noteIndex);
const findFirstBadge = () => findBadgeAtIndex(0);
const findSecondBadge = () => findBadgeAtIndex(1);
const clickAndDragBadge = async (elem, fromPoint, toPoint) => {
- elem.trigger('mousedown', { clientX: fromPoint.x, clientY: fromPoint.y });
+ elem.vm.$emit(
+ 'mousedown',
+ new MouseEvent('click', { clientX: fromPoint.x, clientY: fromPoint.y }),
+ );
+ findOverlay().trigger('mousemove', { clientX: toPoint.x, clientY: toPoint.y });
await nextTick();
- elem.trigger('mousemove', { clientX: toPoint.x, clientY: toPoint.y });
+ elem.vm.$emit('mouseup', new MouseEvent('click', { clientX: toPoint.x, clientY: toPoint.y }));
await nextTick();
};
function createComponent(props = {}, data = {}) {
- wrapper = mount(DesignOverlay, {
+ apolloProvider = createMockApollo([], resolvers);
+ apolloProvider.clients.defaultClient.writeQuery({
+ query: activeDiscussionQuery,
+ data: {
+ activeDiscussion: {
+ __typename: 'ActiveDiscussion',
+ id: null,
+ source: null,
+ },
+ },
+ });
+
+ wrapper = shallowMount(DesignOverlay, {
+ apolloProvider,
propsData: {
dimensions: mockDimensions,
position: {
@@ -45,14 +67,13 @@ describe('Design overlay component', () => {
...data,
};
},
- mocks: {
- $apollo: {
- mutate,
- },
- },
});
}
+ afterEach(() => {
+ apolloProvider = null;
+ });
+
it('should have correct inline style', () => {
createComponent();
@@ -96,12 +117,15 @@ describe('Design overlay component', () => {
});
it('should have set the correct position for each note badge', () => {
- expect(findFirstBadge().attributes().style).toBe('left: 10px; top: 15px;');
- expect(findSecondBadge().attributes().style).toBe('left: 50px; top: 50px;');
+ expect(findFirstBadge().props('position')).toEqual({
+ left: '10px',
+ top: '15px',
+ });
+ expect(findSecondBadge().props('position')).toEqual({ left: '50px', top: '50px' });
});
it('should apply resolved class to the resolved note pin', () => {
- expect(findSecondBadge().classes()).toContain('resolved');
+ expect(findSecondBadge().props('isResolved')).toBe(true);
});
describe('when no discussion is active', () => {
@@ -116,33 +140,37 @@ describe('Design overlay component', () => {
it.each([notes[0].discussion.notes.nodes[1], notes[0].discussion.notes.nodes[0]])(
'should not apply inactive class to the pin for the active discussion',
async (note) => {
- // setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
- // eslint-disable-next-line no-restricted-syntax
- wrapper.setData({
- activeDiscussion: {
- id: note.id,
- source: 'discussion',
+ apolloProvider.clients.defaultClient.writeQuery({
+ query: activeDiscussionQuery,
+ data: {
+ activeDiscussion: {
+ __typename: 'ActiveDiscussion',
+ id: note.id,
+ source: 'discussion',
+ },
},
});
await nextTick();
- expect(findBadgeAtIndex(0).classes()).not.toContain('inactive');
+ expect(findBadgeAtIndex(0).props('isInactive')).toBe(false);
},
);
it('should apply inactive class to all pins besides the active one', async () => {
- // setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
- // eslint-disable-next-line no-restricted-syntax
- wrapper.setData({
- activeDiscussion: {
- id: notes[0].id,
- source: 'discussion',
+ apolloProvider.clients.defaultClient.writeQuery({
+ query: activeDiscussionQuery,
+ data: {
+ activeDiscussion: {
+ __typename: 'ActiveDiscussion',
+ id: notes[0].id,
+ source: 'discussion',
+ },
},
});
await nextTick();
- expect(findSecondBadge().classes()).toContain('inactive');
- expect(findFirstBadge().classes()).not.toContain('inactive');
+ expect(findSecondBadge().props('isInactive')).toBe(true);
+ expect(findFirstBadge().props('isInactive')).toBe(false);
});
});
});
@@ -156,7 +184,7 @@ describe('Design overlay component', () => {
},
});
- expect(findFirstBadge().attributes().style).toBe('left: 40px; top: 60px;');
+ expect(findFirstBadge().props('position')).toEqual({ left: '40px', top: '60px' });
wrapper.setProps({
dimensions: {
@@ -166,10 +194,10 @@ describe('Design overlay component', () => {
});
await nextTick();
- expect(findFirstBadge().attributes().style).toBe('left: 20px; top: 30px;');
+ expect(findFirstBadge().props('position')).toEqual({ left: '20px', top: '30px' });
});
- it('should call an update active discussion mutation when clicking a note without moving it', async () => {
+ it('should update active discussion when clicking a note without moving it', async () => {
createComponent({
notes,
dimensions: {
@@ -178,61 +206,36 @@ describe('Design overlay component', () => {
},
});
+ expect(findFirstBadge().props('isInactive')).toBe(null);
+
const note = notes[0];
const { position } = note;
- const mutationVariables = {
- mutation: updateActiveDiscussion,
- variables: {
- id: note.id,
- source: ACTIVE_DISCUSSION_SOURCE_TYPES.pin,
- },
- };
- findFirstBadge().trigger('mousedown', { clientX: position.x, clientY: position.y });
+ findFirstBadge().vm.$emit(
+ 'mousedown',
+ new MouseEvent('click', { clientX: position.x, clientY: position.y }),
+ );
await nextTick();
- findFirstBadge().trigger('mouseup', { clientX: position.x, clientY: position.y });
- expect(mutate).toHaveBeenCalledWith(mutationVariables);
+ findFirstBadge().vm.$emit(
+ 'mouseup',
+ new MouseEvent('click', { clientX: position.x, clientY: position.y }),
+ );
+ await waitForPromises();
+ expect(findFirstBadge().props('isInactive')).toBe(false);
});
});
describe('when moving notes', () => {
- it('should update badge style when note is being moved', async () => {
- createComponent({
- notes,
- });
-
- const { position } = notes[0];
-
- await clickAndDragBadge(findFirstBadge(), { x: position.x, y: position.y }, { x: 20, y: 20 });
- expect(findFirstBadge().attributes().style).toBe('left: 20px; top: 20px;');
- });
-
it('should emit `moveNote` event when note-moving action ends', async () => {
createComponent({ notes });
const note = notes[0];
const { position } = note;
const newCoordinates = { x: 20, y: 20 };
- // setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
- // eslint-disable-next-line no-restricted-syntax
- wrapper.setData({
- movingNoteNewPosition: {
- ...position,
- ...newCoordinates,
- },
- movingNoteStartPosition: {
- noteId: notes[0].id,
- discussionId: notes[0].discussion.id,
- ...position,
- },
- });
-
const badge = findFirstBadge();
await clickAndDragBadge(badge, { x: position.x, y: position.y }, newCoordinates);
- badge.trigger('mouseup');
- await nextTick();
expect(wrapper.emitted('moveNote')).toEqual([
[
{
@@ -266,9 +269,10 @@ describe('Design overlay component', () => {
const badge = findAllNotes().at(0);
await clickAndDragBadge(badge, { ...mockNoteCoordinates }, { x: 20, y: 20 });
// note position should not change after a click-and-drag attempt
- expect(findFirstBadge().attributes().style).toContain(
- `left: ${mockNoteCoordinates.x}px; top: ${mockNoteCoordinates.y}px;`,
- );
+ expect(findFirstBadge().props('position')).toEqual({
+ left: `${mockNoteCoordinates.x}px`,
+ top: `${mockNoteCoordinates.y}px`,
+ });
});
});
});
@@ -282,27 +286,10 @@ describe('Design overlay component', () => {
});
expect(findCommentBadge().exists()).toBe(true);
- expect(findCommentBadge().attributes().style).toBe('left: 10px; top: 15px;');
+ expect(findCommentBadge().props('position')).toEqual({ left: '10px', top: '15px' });
});
describe('when moving the comment badge', () => {
- it('should update badge style to reflect new position', async () => {
- const { position } = notes[0];
-
- createComponent({
- currentCommentForm: {
- ...position,
- },
- });
-
- await clickAndDragBadge(
- findCommentBadge(),
- { x: position.x, y: position.y },
- { x: 20, y: 20 },
- );
- expect(findCommentBadge().attributes().style).toBe('left: 20px; top: 20px;');
- });
-
it('should update badge style when note-moving action ends', async () => {
const { position } = notes[0];
createComponent({
@@ -315,7 +302,7 @@ describe('Design overlay component', () => {
const toPoint = { x: 20, y: 20 };
await clickAndDragBadge(commentBadge, { x: position.x, y: position.y }, toPoint);
- commentBadge.trigger('mouseup');
+ commentBadge.vm.$emit('mouseup', new MouseEvent('click'));
// simulates the currentCommentForm being updated in index.vue component, and
// propagated back down to this prop
wrapper.setProps({
@@ -323,110 +310,50 @@ describe('Design overlay component', () => {
});
await nextTick();
- expect(commentBadge.attributes().style).toBe('left: 20px; top: 20px;');
+ expect(commentBadge.props('position')).toEqual({ left: '20px', top: '20px' });
});
- it.each`
- element | getElementFunc | event
- ${'overlay'} | ${() => wrapper} | ${'mouseleave'}
- ${'comment badge'} | ${findCommentBadge} | ${'mouseup'}
- `(
- 'should emit `openCommentForm` event when $event fired on $element element',
- async ({ getElementFunc, event }) => {
- createComponent({
- notes,
- currentCommentForm: {
- ...notes[0].position,
- },
- });
-
- const newCoordinates = { x: 20, y: 20 };
- // setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
- // eslint-disable-next-line no-restricted-syntax
- wrapper.setData({
- movingNoteStartPosition: {
- ...notes[0].position,
- },
- movingNoteNewPosition: {
- ...notes[0].position,
- ...newCoordinates,
- },
- });
-
- getElementFunc().trigger(event);
- await nextTick();
- expect(wrapper.emitted('openCommentForm')).toEqual([[newCoordinates]]);
- },
- );
- });
- });
-
- describe('getMovingNotePositionDelta', () => {
- it('should calculate delta correctly from state', () => {
- createComponent();
+ it('should emit `openCommentForm` event when mouseleave fired on overlay element', async () => {
+ const { position } = notes[0];
+ createComponent({
+ notes,
+ currentCommentForm: {
+ ...position,
+ },
+ });
- // setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
- // eslint-disable-next-line no-restricted-syntax
- wrapper.setData({
- movingNoteStartPosition: {
- clientX: 10,
- clientY: 20,
- },
- });
+ const newCoordinates = { x: 20, y: 20 };
- const mockMouseEvent = {
- clientX: 30,
- clientY: 10,
- };
+ await clickAndDragBadge(
+ findCommentBadge(),
+ { x: position.x, y: position.y },
+ newCoordinates,
+ );
- expect(wrapper.vm.getMovingNotePositionDelta(mockMouseEvent)).toEqual({
- deltaX: 20,
- deltaY: -10,
+ wrapper.trigger('mouseleave');
+ await nextTick();
+ expect(wrapper.emitted('openCommentForm')).toEqual([[newCoordinates]]);
});
- });
- });
- describe('isPositionInOverlay', () => {
- createComponent({ dimensions: mockDimensions });
-
- it.each`
- test | coordinates | expectedResult
- ${'within overlay bounds'} | ${{ x: 50, y: 50 }} | ${true}
- ${'outside overlay bounds'} | ${{ x: 101, y: 101 }} | ${false}
- `('returns [$expectedResult] when position is $test', ({ coordinates, expectedResult }) => {
- const position = { ...mockDimensions, ...coordinates };
+ it('should emit `openCommentForm` event when mouseup fired on comment badge element', async () => {
+ const { position } = notes[0];
+ createComponent({
+ notes,
+ currentCommentForm: {
+ ...position,
+ },
+ });
- expect(wrapper.vm.isPositionInOverlay(position)).toBe(expectedResult);
- });
- });
+ const newCoordinates = { x: 20, y: 20 };
- describe('getNoteRelativePosition', () => {
- it('calculates position correctly', () => {
- createComponent({ dimensions: mockDimensions });
- const position = { x: 50, y: 50, width: 200, height: 200 };
+ await clickAndDragBadge(
+ findCommentBadge(),
+ { x: position.x, y: position.y },
+ newCoordinates,
+ );
- expect(wrapper.vm.getNoteRelativePosition(position)).toEqual({ left: 25, top: 25 });
+ expect(wrapper.emitted('openCommentForm')).toEqual([[newCoordinates]]);
+ });
});
});
-
- describe('canMoveNote', () => {
- it.each`
- repositionNotePermission | canMoveNoteResult
- ${true} | ${true}
- ${false} | ${false}
- ${undefined} | ${false}
- `(
- 'returns [$canMoveNoteResult] when [repositionNote permission] is [$repositionNotePermission]',
- ({ repositionNotePermission, canMoveNoteResult }) => {
- createComponent();
-
- const note = {
- userPermissions: {
- repositionNote: repositionNotePermission,
- },
- };
- expect(wrapper.vm.canMoveNote(note)).toBe(canMoveNoteResult);
- },
- );
- });
});