diff options
Diffstat (limited to 'spec/frontend/sidebar')
6 files changed, 125 insertions, 40 deletions
diff --git a/spec/frontend/sidebar/components/assignees/assignee_avatar_link_spec.js b/spec/frontend/sidebar/components/assignees/assignee_avatar_link_spec.js index 5a3a152d201..69f6a6e6e04 100644 --- a/spec/frontend/sidebar/components/assignees/assignee_avatar_link_spec.js +++ b/spec/frontend/sidebar/components/assignees/assignee_avatar_link_spec.js @@ -81,30 +81,33 @@ describe('AssigneeAvatarLink component', () => { ); describe.each` - tooltipHasName | availability | canMerge | expected - ${true} | ${'Busy'} | ${false} | ${'Root (Busy) (cannot merge)'} - ${true} | ${'Busy'} | ${true} | ${'Root (Busy)'} - ${true} | ${''} | ${false} | ${'Root (cannot merge)'} - ${true} | ${''} | ${true} | ${'Root'} - ${false} | ${'Busy'} | ${false} | ${'Cannot merge'} - ${false} | ${'Busy'} | ${true} | ${''} - ${false} | ${''} | ${false} | ${'Cannot merge'} - ${false} | ${''} | ${true} | ${''} + tooltipHasName | name | availability | canMerge | expected + ${true} | ${"Rabbit O'Hare"} | ${''} | ${true} | ${"Rabbit O'Hare"} + ${true} | ${"Rabbit O'Hare"} | ${'Busy'} | ${false} | ${"Rabbit O'Hare (Busy) (cannot merge)"} + ${true} | ${'Root'} | ${'Busy'} | ${false} | ${'Root (Busy) (cannot merge)'} + ${true} | ${'Root'} | ${'Busy'} | ${true} | ${'Root (Busy)'} + ${true} | ${'Root'} | ${''} | ${false} | ${'Root (cannot merge)'} + ${true} | ${'Root'} | ${''} | ${true} | ${'Root'} + ${false} | ${'Root'} | ${'Busy'} | ${false} | ${'Cannot merge'} + ${false} | ${'Root'} | ${'Busy'} | ${true} | ${''} + ${false} | ${'Root'} | ${''} | ${false} | ${'Cannot merge'} + ${false} | ${'Root'} | ${''} | ${true} | ${''} `( - "with tooltipHasName=$tooltipHasName and availability='$availability' and canMerge=$canMerge", - ({ tooltipHasName, availability, canMerge, expected }) => { + "with name=$name tooltipHasName=$tooltipHasName and availability='$availability' and canMerge=$canMerge", + ({ name, tooltipHasName, availability, canMerge, expected }) => { beforeEach(() => { createComponent({ tooltipHasName, user: { ...userDataMock(), + name, can_merge: canMerge, availability, }, }); }); - it('sets tooltip to $expected', () => { + it(`sets tooltip to "${expected}"`, () => { expect(findTooltipText()).toBe(expected); }); }, diff --git a/spec/frontend/sidebar/components/severity/sidebar_severity_spec.js b/spec/frontend/sidebar/components/severity/sidebar_severity_spec.js index 747d370e1cf..6116bc68927 100644 --- a/spec/frontend/sidebar/components/severity/sidebar_severity_spec.js +++ b/spec/frontend/sidebar/components/severity/sidebar_severity_spec.js @@ -1,5 +1,6 @@ import { GlDropdown, GlDropdownItem, GlLoadingIcon, GlTooltip, GlSprintf } from '@gitlab/ui'; -import { shallowMount } from '@vue/test-utils'; +import { nextTick } from 'vue'; +import { shallowMountExtended } from 'helpers/vue_test_utils_helper'; import waitForPromises from 'helpers/wait_for_promises'; import createFlash from '~/flash'; import { INCIDENT_SEVERITY, ISSUABLE_TYPES } from '~/sidebar/components/severity/constants'; @@ -15,6 +16,7 @@ describe('SidebarSeverity', () => { const projectPath = 'gitlab-org/gitlab-test'; const iid = '1'; const severity = 'CRITICAL'; + let canUpdate = true; function createComponent(props = {}) { const propsData = { @@ -25,8 +27,11 @@ describe('SidebarSeverity', () => { ...props, }; mutate = jest.fn(); - wrapper = shallowMount(SidebarSeverity, { + wrapper = shallowMountExtended(SidebarSeverity, { propsData, + provide: { + canUpdate, + }, mocks: { $apollo: { mutate, @@ -45,22 +50,34 @@ describe('SidebarSeverity', () => { afterEach(() => { if (wrapper) { wrapper.destroy(); - wrapper = null; } }); - const findSeverityToken = () => wrapper.findAll(SeverityToken); - const findEditBtn = () => wrapper.find('[data-testid="editButton"]'); - const findDropdown = () => wrapper.find(GlDropdown); - const findCriticalSeverityDropdownItem = () => wrapper.find(GlDropdownItem); - const findLoadingIcon = () => wrapper.find(GlLoadingIcon); - const findTooltip = () => wrapper.find(GlTooltip); + const findSeverityToken = () => wrapper.findAllComponents(SeverityToken); + const findEditBtn = () => wrapper.findByTestId('editButton'); + const findDropdown = () => wrapper.findComponent(GlDropdown); + const findCriticalSeverityDropdownItem = () => wrapper.findComponent(GlDropdownItem); + const findLoadingIcon = () => wrapper.findComponent(GlLoadingIcon); + const findTooltip = () => wrapper.findComponent(GlTooltip); const findCollapsedSeverity = () => wrapper.find({ ref: 'severity' }); - it('renders severity widget', () => { - expect(findEditBtn().exists()).toBe(true); - expect(findSeverityToken().exists()).toBe(true); - expect(findDropdown().exists()).toBe(true); + describe('Severity widget', () => { + it('renders severity dropdown and token', () => { + expect(findSeverityToken().exists()).toBe(true); + expect(findDropdown().exists()).toBe(true); + }); + + describe('edit button', () => { + it('is rendered when `canUpdate` provided as `true`', () => { + expect(findEditBtn().exists()).toBe(true); + }); + + it('is NOT rendered when `canUpdate` provided as `false`', () => { + canUpdate = false; + createComponent(); + expect(findEditBtn().exists()).toBe(false); + }); + }); }); describe('Update severity', () => { @@ -100,7 +117,7 @@ describe('SidebarSeverity', () => { ); findCriticalSeverityDropdownItem().vm.$emit('click'); - await wrapper.vm.$nextTick(); + await nextTick(); expect(findLoadingIcon().exists()).toBe(true); resolvePromise(); @@ -128,27 +145,29 @@ describe('SidebarSeverity', () => { it('should expand the dropdown on collapsed icon click', async () => { wrapper.vm.isDropdownShowing = false; - await wrapper.vm.$nextTick(); + await nextTick(); expect(findDropdown().classes(HIDDDEN_CLASS)).toBe(true); findCollapsedSeverity().trigger('click'); - await wrapper.vm.$nextTick(); + await nextTick(); expect(findDropdown().classes(SHOWN_CLASS)).toBe(true); }); }); describe('expanded', () => { it('toggles dropdown with edit button', async () => { + canUpdate = true; + createComponent(); wrapper.vm.isDropdownShowing = false; - await wrapper.vm.$nextTick(); + await nextTick(); expect(findDropdown().classes(HIDDDEN_CLASS)).toBe(true); findEditBtn().vm.$emit('click'); - await wrapper.vm.$nextTick(); + await nextTick(); expect(findDropdown().classes(SHOWN_CLASS)).toBe(true); findEditBtn().vm.$emit('click'); - await wrapper.vm.$nextTick(); + await nextTick(); expect(findDropdown().classes(HIDDDEN_CLASS)).toBe(true); }); }); diff --git a/spec/frontend/sidebar/components/sidebar_dropdown_widget_spec.js b/spec/frontend/sidebar/components/sidebar_dropdown_widget_spec.js index f5e5ab4a984..ca6e5ac5e7f 100644 --- a/spec/frontend/sidebar/components/sidebar_dropdown_widget_spec.js +++ b/spec/frontend/sidebar/components/sidebar_dropdown_widget_spec.js @@ -12,11 +12,13 @@ import { createLocalVue, shallowMount, mount } from '@vue/test-utils'; import VueApollo from 'vue-apollo'; import createMockApollo from 'helpers/mock_apollo_helper'; +import { createMockDirective, getBinding } from 'helpers/vue_mock_directive'; import { extendedWrapper } from 'helpers/vue_test_utils_helper'; import waitForPromises from 'helpers/wait_for_promises'; import createFlash from '~/flash'; import { getIdFromGraphQLId } from '~/graphql_shared/utils'; import { IssuableType } from '~/issue_show/constants'; +import { timeFor } from '~/lib/utils/datetime_utility'; import SidebarDropdownWidget from '~/sidebar/components/sidebar_dropdown_widget.vue'; import SidebarEditableItem from '~/sidebar/components/sidebar_editable_item.vue'; import { IssuableAttributeType } from '~/sidebar/constants'; @@ -54,6 +56,7 @@ describe('SidebarDropdownWidget', () => { const mutationSuccessWithErrors = () => jest.fn().mockResolvedValue({ data: promiseWithErrors }); const findGlLink = () => wrapper.findComponent(GlLink); + const findDateTooltip = () => getBinding(findGlLink().element, 'gl-tooltip'); const findDropdown = () => wrapper.findComponent(GlDropdown); const findDropdownText = () => wrapper.findComponent(GlDropdownText); const findSearchBox = () => wrapper.findComponent(GlSearchBoxByType); @@ -155,6 +158,9 @@ describe('SidebarDropdownWidget', () => { }, }, }, + directives: { + GlTooltip: createMockDirective(), + }, stubs: { SidebarEditableItem, GlSearchBoxByType, @@ -177,7 +183,7 @@ describe('SidebarDropdownWidget', () => { beforeEach(() => { createComponent({ data: { - currentAttribute: { id: 'id', title: 'title', webUrl: 'webUrl' }, + currentAttribute: { id: 'id', title: 'title', webUrl: 'webUrl', dueDate: '2021-09-09' }, }, stubs: { GlDropdown, @@ -223,6 +229,10 @@ describe('SidebarDropdownWidget', () => { expect(findSelectedAttribute().text()).toBe('Some milestone title'); }); + it('displays time for milestone due date in tooltip', () => { + expect(findDateTooltip().value).toBe(timeFor('2021-09-09')); + }); + describe('when current attribute does not exist', () => { it('renders "None" as the selected attribute title', () => { createComponent(); @@ -451,7 +461,6 @@ describe('SidebarDropdownWidget', () => { expect(projectMilestonesSpy).toHaveBeenNthCalledWith(1, { fullPath: mockIssue.projectPath, - sort: null, state: 'active', title: '', }); @@ -478,7 +487,6 @@ describe('SidebarDropdownWidget', () => { expect(projectMilestonesSpy).toHaveBeenNthCalledWith(2, { fullPath: mockIssue.projectPath, - sort: null, state: 'active', title: mockSearchTerm, }); diff --git a/spec/frontend/sidebar/components/time_tracking/mock_data.js b/spec/frontend/sidebar/components/time_tracking/mock_data.js index 862bcbe861e..938750bd58b 100644 --- a/spec/frontend/sidebar/components/time_tracking/mock_data.js +++ b/spec/frontend/sidebar/components/time_tracking/mock_data.js @@ -16,9 +16,10 @@ export const getIssueTimelogsQueryResponse = { }, spentAt: '2020-05-01T00:00:00Z', note: { - body: 'I paired with @root on this last week.', + body: 'A note', __typename: 'Note', }, + summary: 'A summary', }, { __typename: 'Timelog', @@ -29,6 +30,7 @@ export const getIssueTimelogsQueryResponse = { }, spentAt: '2021-05-07T13:19:01Z', note: null, + summary: 'A summary', }, { __typename: 'Timelog', @@ -39,9 +41,10 @@ export const getIssueTimelogsQueryResponse = { }, spentAt: '2021-05-01T00:00:00Z', note: { - body: 'I did some work on this last week.', + body: 'A note', __typename: 'Note', }, + summary: null, }, ], __typename: 'TimelogConnection', @@ -70,6 +73,7 @@ export const getMrTimelogsQueryResponse = { body: 'Thirty minutes!', __typename: 'Note', }, + summary: null, }, { __typename: 'Timelog', @@ -80,6 +84,7 @@ export const getMrTimelogsQueryResponse = { }, spentAt: '2021-05-07T14:44:39Z', note: null, + summary: null, }, { __typename: 'Timelog', @@ -93,6 +98,7 @@ export const getMrTimelogsQueryResponse = { body: 'A note with some time', __typename: 'Note', }, + summary: null, }, ], __typename: 'TimelogConnection', diff --git a/spec/frontend/sidebar/components/time_tracking/report_spec.js b/spec/frontend/sidebar/components/time_tracking/report_spec.js index 710fae8ddf7..66218626e6b 100644 --- a/spec/frontend/sidebar/components/time_tracking/report_spec.js +++ b/spec/frontend/sidebar/components/time_tracking/report_spec.js @@ -74,6 +74,8 @@ describe('Issuable Time Tracking Report', () => { expect(getAllByRole(wrapper.element, 'row', { name: /John Doe18/i })).toHaveLength(1); expect(getAllByRole(wrapper.element, 'row', { name: /Administrator/i })).toHaveLength(2); + expect(getAllByRole(wrapper.element, 'row', { name: /A note/i })).toHaveLength(1); + expect(getAllByRole(wrapper.element, 'row', { name: /A summary/i })).toHaveLength(2); }); }); diff --git a/spec/frontend/sidebar/mock_data.js b/spec/frontend/sidebar/mock_data.js index 9fab24d7518..1ebd3c622ca 100644 --- a/spec/frontend/sidebar/mock_data.js +++ b/spec/frontend/sidebar/mock_data.js @@ -415,7 +415,7 @@ const mockUser1 = { status: null, }; -const mockUser2 = { +export const mockUser2 = { id: 'gid://gitlab/User/4', avatarUrl: '/avatar2', name: 'rookie', @@ -452,9 +452,40 @@ export const projectMembersResponse = { null, null, // Remove duplicated entry https://gitlab.com/gitlab-org/gitlab/-/issues/327822 - mockUser1, - mockUser1, - mockUser2, + { user: mockUser1 }, + { user: mockUser1 }, + { user: mockUser2 }, + { + user: { + id: 'gid://gitlab/User/2', + avatarUrl: + 'https://www.gravatar.com/avatar/a95e5b71488f4b9d69ce5ff58bfd28d6?s=80\u0026d=identicon', + name: 'Jacki Kub', + username: 'francina.skiles', + webUrl: '/franc', + status: { + availability: 'BUSY', + }, + }, + }, + ], + }, + }, + }, +}; + +export const groupMembersResponse = { + data: { + workspace: { + __typename: 'roup', + users: { + nodes: [ + // Remove nulls https://gitlab.com/gitlab-org/gitlab/-/issues/329750 + null, + null, + // Remove duplicated entry https://gitlab.com/gitlab-org/gitlab/-/issues/327822 + { user: mockUser1 }, + { user: mockUser1 }, { user: { id: 'gid://gitlab/User/2', @@ -531,6 +562,7 @@ export const mockMilestone1 = { webUrl: 'http://gdk.test:3000/groups/gitlab-org/-/milestones/1', state: 'active', expired: false, + dueDate: '2030-09-09', }; export const mockMilestone2 = { @@ -540,6 +572,7 @@ export const mockMilestone2 = { webUrl: 'http://gdk.test:3000/groups/gitlab-org/-/milestones/2', state: 'active', expired: false, + dueDate: '2030-09-09', }; export const mockProjectMilestonesResponse = { @@ -554,6 +587,19 @@ export const mockProjectMilestonesResponse = { }, }; +export const mockGroupMilestonesResponse = { + data: { + workspace: { + id: 'gid://gitlab/Group/1', + attributes: { + nodes: [mockMilestone1, mockMilestone2], + }, + __typename: 'MilestoneConnection', + }, + __typename: 'Group', + }, +}; + export const noCurrentMilestoneResponse = { data: { workspace: { @@ -574,6 +620,7 @@ export const mockMilestoneMutationResponse = { title: 'Awesome Milestone', state: 'active', expired: false, + dueDate: '2030-09-09', __typename: 'Milestone', }, __typename: 'Issue', |