diff options
Diffstat (limited to 'spec/frontend/design_management_legacy/components/design_sidebar_spec.js')
-rw-r--r-- | spec/frontend/design_management_legacy/components/design_sidebar_spec.js | 236 |
1 files changed, 236 insertions, 0 deletions
diff --git a/spec/frontend/design_management_legacy/components/design_sidebar_spec.js b/spec/frontend/design_management_legacy/components/design_sidebar_spec.js new file mode 100644 index 00000000000..fc0f618c359 --- /dev/null +++ b/spec/frontend/design_management_legacy/components/design_sidebar_spec.js @@ -0,0 +1,236 @@ +import { shallowMount } from '@vue/test-utils'; +import { GlCollapse, GlPopover } from '@gitlab/ui'; +import Cookies from 'js-cookie'; +import DesignSidebar from '~/design_management_legacy/components/design_sidebar.vue'; +import Participants from '~/sidebar/components/participants/participants.vue'; +import DesignDiscussion from '~/design_management_legacy/components/design_notes/design_discussion.vue'; +import design from '../mock_data/design'; +import updateActiveDiscussionMutation from '~/design_management_legacy/graphql/mutations/update_active_discussion.mutation.graphql'; + +const updateActiveDiscussionMutationVariables = { + mutation: updateActiveDiscussionMutation, + variables: { + id: design.discussions.nodes[0].notes.nodes[0].id, + source: 'discussion', + }, +}; + +const $route = { + params: { + id: '1', + }, +}; + +const cookieKey = 'hide_design_resolved_comments_popover'; + +const mutate = jest.fn().mockResolvedValue(); + +describe('Design management design sidebar component', () => { + let wrapper; + + const findDiscussions = () => wrapper.findAll(DesignDiscussion); + const findFirstDiscussion = () => findDiscussions().at(0); + const findUnresolvedDiscussions = () => wrapper.findAll('[data-testid="unresolved-discussion"]'); + const findResolvedDiscussions = () => wrapper.findAll('[data-testid="resolved-discussion"]'); + const findParticipants = () => wrapper.find(Participants); + const findCollapsible = () => wrapper.find(GlCollapse); + const findToggleResolvedCommentsButton = () => wrapper.find('[data-testid="resolved-comments"]'); + const findPopover = () => wrapper.find(GlPopover); + const findNewDiscussionDisclaimer = () => + wrapper.find('[data-testid="new-discussion-disclaimer"]'); + + function createComponent(props = {}) { + wrapper = shallowMount(DesignSidebar, { + propsData: { + design, + resolvedDiscussionsExpanded: false, + markdownPreviewPath: '', + ...props, + }, + mocks: { + $route, + $apollo: { + mutate, + }, + }, + }); + } + + afterEach(() => { + wrapper.destroy(); + }); + + it('renders participants', () => { + createComponent(); + + expect(findParticipants().exists()).toBe(true); + }); + + it('passes the correct amount of participants to the Participants component', () => { + createComponent(); + + expect(findParticipants().props('participants')).toHaveLength(1); + }); + + describe('when has no discussions', () => { + beforeEach(() => { + createComponent({ + design: { + ...design, + discussions: { + nodes: [], + }, + }, + }); + }); + + it('does not render discussions', () => { + expect(findDiscussions().exists()).toBe(false); + }); + + it('renders a message about possibility to create a new discussion', () => { + expect(findNewDiscussionDisclaimer().exists()).toBe(true); + }); + }); + + describe('when has discussions', () => { + beforeEach(() => { + Cookies.set(cookieKey, true); + createComponent(); + }); + + it('renders correct amount of unresolved discussions', () => { + expect(findUnresolvedDiscussions()).toHaveLength(1); + }); + + it('renders correct amount of resolved discussions', () => { + expect(findResolvedDiscussions()).toHaveLength(1); + }); + + it('has resolved comments collapsible collapsed', () => { + expect(findCollapsible().attributes('visible')).toBeUndefined(); + }); + + it('emits toggleResolveComments event on resolve comments button click', () => { + findToggleResolvedCommentsButton().vm.$emit('click'); + expect(wrapper.emitted('toggleResolvedComments')).toHaveLength(1); + }); + + it('opens a collapsible when resolvedDiscussionsExpanded prop changes to true', () => { + expect(findCollapsible().attributes('visible')).toBeUndefined(); + wrapper.setProps({ + resolvedDiscussionsExpanded: true, + }); + return wrapper.vm.$nextTick().then(() => { + expect(findCollapsible().attributes('visible')).toBe('true'); + }); + }); + + it('does not popover about resolved comments', () => { + expect(findPopover().exists()).toBe(false); + }); + + it('sends a mutation to set an active discussion when clicking on a discussion', () => { + findFirstDiscussion().trigger('click'); + + expect(mutate).toHaveBeenCalledWith(updateActiveDiscussionMutationVariables); + }); + + it('sends a mutation to reset an active discussion when clicking outside of discussion', () => { + wrapper.trigger('click'); + + expect(mutate).toHaveBeenCalledWith({ + ...updateActiveDiscussionMutationVariables, + variables: { id: undefined, source: 'discussion' }, + }); + }); + + it('emits correct event on discussion create note error', () => { + findFirstDiscussion().vm.$emit('createNoteError', 'payload'); + expect(wrapper.emitted('onDesignDiscussionError')).toEqual([['payload']]); + }); + + it('emits correct event on discussion update note error', () => { + findFirstDiscussion().vm.$emit('updateNoteError', 'payload'); + expect(wrapper.emitted('updateNoteError')).toEqual([['payload']]); + }); + + it('emits correct event on discussion resolve error', () => { + findFirstDiscussion().vm.$emit('resolveDiscussionError', 'payload'); + expect(wrapper.emitted('resolveDiscussionError')).toEqual([['payload']]); + }); + + it('changes prop correctly on opening discussion form', () => { + findFirstDiscussion().vm.$emit('openForm', 'some-id'); + + return wrapper.vm.$nextTick().then(() => { + expect(findFirstDiscussion().props('discussionWithOpenForm')).toBe('some-id'); + }); + }); + }); + + describe('when all discussions are resolved', () => { + beforeEach(() => { + createComponent({ + design: { + ...design, + discussions: { + nodes: [ + { + id: 'discussion-id', + replyId: 'discussion-reply-id', + resolved: true, + notes: { + nodes: [ + { + id: 'note-id', + body: '123', + author: { + name: 'Administrator', + username: 'root', + webUrl: 'link-to-author', + avatarUrl: 'link-to-avatar', + }, + }, + ], + }, + }, + ], + }, + }, + }); + }); + + it('renders a message about possibility to create a new discussion', () => { + expect(findNewDiscussionDisclaimer().exists()).toBe(true); + }); + + it('does not render unresolved discussions', () => { + expect(findUnresolvedDiscussions()).toHaveLength(0); + }); + }); + + describe('when showing resolved discussions for the first time', () => { + beforeEach(() => { + Cookies.set(cookieKey, false); + createComponent(); + }); + + it('renders a popover if we show resolved comments collapsible for the first time', () => { + expect(findPopover().exists()).toBe(true); + }); + + it('dismisses a popover on the outside click', () => { + wrapper.trigger('click'); + return wrapper.vm.$nextTick(() => { + expect(findPopover().exists()).toBe(false); + }); + }); + + it(`sets a ${cookieKey} cookie on clicking outside the popover`, () => { + jest.spyOn(Cookies, 'set'); + wrapper.trigger('click'); + expect(Cookies.set).toHaveBeenCalledWith(cookieKey, 'true', { expires: 365 * 10 }); + }); + }); +}); |