2022-08-13 15:12:31 +05:30
|
|
|
import { GlAccordionItem } from '@gitlab/ui';
|
2021-03-11 19:13:27 +05:30
|
|
|
import { shallowMount } from '@vue/test-utils';
|
2022-04-04 11:22:00 +05:30
|
|
|
import { nextTick } from 'vue';
|
2021-03-11 19:13:27 +05:30
|
|
|
import DesignDiscussion from '~/design_management/components/design_notes/design_discussion.vue';
|
2022-03-02 08:16:31 +05:30
|
|
|
import DesignNoteSignedOut from '~/design_management/components/design_notes/design_note_signed_out.vue';
|
2020-06-23 00:09:42 +05:30
|
|
|
import DesignSidebar from '~/design_management/components/design_sidebar.vue';
|
2021-03-11 19:13:27 +05:30
|
|
|
import DesignTodoButton from '~/design_management/components/design_todo_button.vue';
|
|
|
|
import updateActiveDiscussionMutation from '~/design_management/graphql/mutations/update_active_discussion.mutation.graphql';
|
2020-06-23 00:09:42 +05:30
|
|
|
import Participants from '~/sidebar/components/participants/participants.vue';
|
|
|
|
import design from '../mock_data/design';
|
2020-11-24 15:15:51 +05:30
|
|
|
|
|
|
|
const scrollIntoViewMock = jest.fn();
|
|
|
|
HTMLElement.prototype.scrollIntoView = scrollIntoViewMock;
|
2020-06-23 00:09:42 +05:30
|
|
|
|
|
|
|
const updateActiveDiscussionMutationVariables = {
|
|
|
|
mutation: updateActiveDiscussionMutation,
|
|
|
|
variables: {
|
|
|
|
id: design.discussions.nodes[0].notes.nodes[0].id,
|
|
|
|
source: 'discussion',
|
|
|
|
},
|
|
|
|
};
|
|
|
|
|
|
|
|
const $route = {
|
|
|
|
params: {
|
|
|
|
id: '1',
|
|
|
|
},
|
|
|
|
};
|
|
|
|
|
|
|
|
const mutate = jest.fn().mockResolvedValue();
|
|
|
|
|
|
|
|
describe('Design management design sidebar component', () => {
|
|
|
|
let wrapper;
|
|
|
|
|
2022-08-27 11:52:29 +05:30
|
|
|
const findDiscussions = () => wrapper.findAllComponents(DesignDiscussion);
|
2020-06-23 00:09:42 +05:30
|
|
|
const findFirstDiscussion = () => findDiscussions().at(0);
|
|
|
|
const findUnresolvedDiscussions = () => wrapper.findAll('[data-testid="unresolved-discussion"]');
|
|
|
|
const findResolvedDiscussions = () => wrapper.findAll('[data-testid="resolved-discussion"]');
|
2022-08-27 11:52:29 +05:30
|
|
|
const findParticipants = () => wrapper.findComponent(Participants);
|
|
|
|
const findResolvedCommentsToggle = () => wrapper.findComponent(GlAccordionItem);
|
2020-06-23 00:09:42 +05:30
|
|
|
const findNewDiscussionDisclaimer = () =>
|
|
|
|
wrapper.find('[data-testid="new-discussion-disclaimer"]');
|
|
|
|
|
2021-01-03 14:25:43 +05:30
|
|
|
function createComponent(props = {}) {
|
2020-06-23 00:09:42 +05:30
|
|
|
wrapper = shallowMount(DesignSidebar, {
|
|
|
|
propsData: {
|
|
|
|
design,
|
|
|
|
resolvedDiscussionsExpanded: false,
|
|
|
|
markdownPreviewPath: '',
|
2022-07-23 23:45:48 +05:30
|
|
|
isLoading: false,
|
2020-06-23 00:09:42 +05:30
|
|
|
...props,
|
|
|
|
},
|
|
|
|
mocks: {
|
|
|
|
$route,
|
|
|
|
$apollo: {
|
|
|
|
mutate,
|
|
|
|
},
|
|
|
|
},
|
2022-03-02 08:16:31 +05:30
|
|
|
provide: {
|
|
|
|
registerPath: '/users/sign_up?redirect_to_referer=yes',
|
|
|
|
signInPath: '/users/sign_in?redirect_to_referer=yes',
|
|
|
|
},
|
2020-06-23 00:09:42 +05:30
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2022-03-02 08:16:31 +05:30
|
|
|
beforeEach(() => {
|
|
|
|
window.gon = { current_user_id: 1 };
|
|
|
|
});
|
|
|
|
|
2020-06-23 00:09:42 +05:30
|
|
|
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);
|
|
|
|
});
|
|
|
|
|
2021-01-03 14:25:43 +05:30
|
|
|
it('renders To-Do button', () => {
|
|
|
|
createComponent();
|
|
|
|
|
2022-08-27 11:52:29 +05:30
|
|
|
expect(wrapper.findComponent(DesignTodoButton).exists()).toBe(true);
|
2021-01-03 14:25:43 +05:30
|
|
|
});
|
|
|
|
|
2020-06-23 00:09:42 +05:30
|
|
|
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(() => {
|
|
|
|
createComponent();
|
|
|
|
});
|
|
|
|
|
|
|
|
it('renders correct amount of unresolved discussions', () => {
|
|
|
|
expect(findUnresolvedDiscussions()).toHaveLength(1);
|
|
|
|
});
|
|
|
|
|
|
|
|
it('renders correct amount of resolved discussions', () => {
|
|
|
|
expect(findResolvedDiscussions()).toHaveLength(1);
|
|
|
|
});
|
|
|
|
|
2022-08-13 15:12:31 +05:30
|
|
|
it('has resolved comments accordion item collapsed', () => {
|
|
|
|
expect(findResolvedCommentsToggle().props('visible')).toBe(false);
|
2020-06-23 00:09:42 +05:30
|
|
|
});
|
|
|
|
|
2022-08-13 15:12:31 +05:30
|
|
|
it('emits toggleResolveComments event on resolve comments button click', async () => {
|
|
|
|
findResolvedCommentsToggle().vm.$emit('input', true);
|
|
|
|
await nextTick();
|
2020-06-23 00:09:42 +05:30
|
|
|
expect(wrapper.emitted('toggleResolvedComments')).toHaveLength(1);
|
|
|
|
});
|
|
|
|
|
2022-08-13 15:12:31 +05:30
|
|
|
it('opens the accordion item when resolvedDiscussionsExpanded prop changes to true', async () => {
|
|
|
|
expect(findResolvedCommentsToggle().props('visible')).toBe(false);
|
2020-06-23 00:09:42 +05:30
|
|
|
wrapper.setProps({
|
|
|
|
resolvedDiscussionsExpanded: true,
|
|
|
|
});
|
2022-04-04 11:22:00 +05:30
|
|
|
await nextTick();
|
2022-08-13 15:12:31 +05:30
|
|
|
expect(findResolvedCommentsToggle().props('visible')).toBe(true);
|
2020-06-23 00:09:42 +05:30
|
|
|
});
|
|
|
|
|
2023-05-27 22:25:52 +05:30
|
|
|
it('emits correct event to send a mutation to set an active discussion when clicking on a discussion', () => {
|
|
|
|
findFirstDiscussion().vm.$emit('update-active-discussion');
|
2020-06-23 00:09:42 +05:30
|
|
|
|
|
|
|
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', () => {
|
2020-11-24 15:15:51 +05:30
|
|
|
findFirstDiscussion().vm.$emit('create-note-error', 'payload');
|
2020-06-23 00:09:42 +05:30
|
|
|
expect(wrapper.emitted('onDesignDiscussionError')).toEqual([['payload']]);
|
|
|
|
});
|
|
|
|
|
|
|
|
it('emits correct event on discussion update note error', () => {
|
2020-11-24 15:15:51 +05:30
|
|
|
findFirstDiscussion().vm.$emit('update-note-error', 'payload');
|
2020-06-23 00:09:42 +05:30
|
|
|
expect(wrapper.emitted('updateNoteError')).toEqual([['payload']]);
|
|
|
|
});
|
|
|
|
|
|
|
|
it('emits correct event on discussion resolve error', () => {
|
2020-11-24 15:15:51 +05:30
|
|
|
findFirstDiscussion().vm.$emit('resolve-discussion-error', 'payload');
|
2020-06-23 00:09:42 +05:30
|
|
|
expect(wrapper.emitted('resolveDiscussionError')).toEqual([['payload']]);
|
|
|
|
});
|
|
|
|
|
2022-04-04 11:22:00 +05:30
|
|
|
it('changes prop correctly on opening discussion form', async () => {
|
2020-11-24 15:15:51 +05:30
|
|
|
findFirstDiscussion().vm.$emit('open-form', 'some-id');
|
2020-06-23 00:09:42 +05:30
|
|
|
|
2022-04-04 11:22:00 +05:30
|
|
|
await nextTick();
|
|
|
|
expect(findFirstDiscussion().props('discussionWithOpenForm')).toBe('some-id');
|
2020-06-23 00:09:42 +05:30
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
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);
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
2022-03-02 08:16:31 +05:30
|
|
|
describe('when user is not logged in', () => {
|
|
|
|
const findDesignNoteSignedOut = () => wrapper.findComponent(DesignNoteSignedOut);
|
|
|
|
|
|
|
|
beforeEach(() => {
|
|
|
|
window.gon = { current_user_id: null };
|
|
|
|
});
|
|
|
|
|
|
|
|
describe('design has no discussions', () => {
|
|
|
|
beforeEach(() => {
|
|
|
|
createComponent({
|
|
|
|
design: {
|
|
|
|
...design,
|
|
|
|
discussions: {
|
|
|
|
nodes: [],
|
|
|
|
},
|
|
|
|
},
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
it('does not render a message about possibility to create a new discussion', () => {
|
|
|
|
expect(findNewDiscussionDisclaimer().exists()).toBe(false);
|
|
|
|
});
|
|
|
|
|
|
|
|
it('renders design-note-signed-out component', () => {
|
|
|
|
expect(findDesignNoteSignedOut().exists()).toBe(true);
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
describe('design has discussions', () => {
|
|
|
|
beforeEach(() => {
|
|
|
|
createComponent();
|
|
|
|
});
|
|
|
|
|
|
|
|
it('renders design-note-signed-out component', () => {
|
|
|
|
expect(findDesignNoteSignedOut().exists()).toBe(true);
|
|
|
|
});
|
|
|
|
});
|
|
|
|
});
|
2020-06-23 00:09:42 +05:30
|
|
|
});
|