diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2020-10-21 07:08:36 +0000 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2020-10-21 07:08:36 +0000 |
commit | 48aff82709769b098321c738f3444b9bdaa694c6 (patch) | |
tree | e00c7c43e2d9b603a5a6af576b1685e400410dee /spec/frontend/sidebar | |
parent | 879f5329ee916a948223f8f43d77fba4da6cd028 (diff) | |
download | gitlab-ce-48aff82709769b098321c738f3444b9bdaa694c6.tar.gz |
Add latest changes from gitlab-org/gitlab@13-5-stable-eev13.5.0-rc42
Diffstat (limited to 'spec/frontend/sidebar')
-rw-r--r-- | spec/frontend/sidebar/assignee_title_spec.js | 17 | ||||
-rw-r--r-- | spec/frontend/sidebar/components/time_tracking/time_tracker_spec.js | 3 | ||||
-rw-r--r-- | spec/frontend/sidebar/confidential/edit_form_buttons_spec.js | 15 | ||||
-rw-r--r-- | spec/frontend/sidebar/lock/edit_form_buttons_spec.js | 14 | ||||
-rw-r--r-- | spec/frontend/sidebar/lock/issuable_lock_form_spec.js | 13 | ||||
-rw-r--r-- | spec/frontend/sidebar/reviewer_title_spec.js | 116 | ||||
-rw-r--r-- | spec/frontend/sidebar/reviewers_spec.js | 169 | ||||
-rw-r--r-- | spec/frontend/sidebar/sidebar_assignees_spec.js | 1 | ||||
-rw-r--r-- | spec/frontend/sidebar/sidebar_labels_spec.js | 35 | ||||
-rw-r--r-- | spec/frontend/sidebar/sidebar_store_spec.js | 37 |
10 files changed, 384 insertions, 36 deletions
diff --git a/spec/frontend/sidebar/assignee_title_spec.js b/spec/frontend/sidebar/assignee_title_spec.js index 92fabaa664e..b5d1e5216f8 100644 --- a/spec/frontend/sidebar/assignee_title_spec.js +++ b/spec/frontend/sidebar/assignee_title_spec.js @@ -11,6 +11,7 @@ describe('AssigneeTitle component', () => { propsData: { numberOfAssignees: 0, editable: false, + changing: false, ...props, }, }); @@ -62,6 +63,22 @@ describe('AssigneeTitle component', () => { }); }); + describe('when changing is false', () => { + it('renders "Edit"', () => { + wrapper = createComponent({ editable: true }); + + expect(wrapper.find('[data-test-id="edit-link"]').text()).toEqual('Edit'); + }); + }); + + describe('when changing is true', () => { + it('renders "Edit"', () => { + wrapper = createComponent({ editable: true, changing: true }); + + expect(wrapper.find('[data-test-id="edit-link"]').text()).toEqual('Apply'); + }); + }); + it('does not render spinner by default', () => { wrapper = createComponent({ numberOfAssignees: 0, diff --git a/spec/frontend/sidebar/components/time_tracking/time_tracker_spec.js b/spec/frontend/sidebar/components/time_tracking/time_tracker_spec.js index 1f028f74423..5307be0bf58 100644 --- a/spec/frontend/sidebar/components/time_tracking/time_tracker_spec.js +++ b/spec/frontend/sidebar/components/time_tracking/time_tracker_spec.js @@ -155,8 +155,7 @@ describe('Issuable Time Tracker', () => { it('should show the correct tooltip text', done => { Vue.nextTick(() => { expect(vm.showComparisonState).toBe(true); - const $title = vm.$el.querySelector('.time-tracking-content .compare-meter').dataset - .originalTitle; + const $title = vm.$el.querySelector('.time-tracking-content .compare-meter').title; expect($title).toBe('Time remaining: 26h 23m'); done(); diff --git a/spec/frontend/sidebar/confidential/edit_form_buttons_spec.js b/spec/frontend/sidebar/confidential/edit_form_buttons_spec.js index 2f11c6a07c2..8c868205295 100644 --- a/spec/frontend/sidebar/confidential/edit_form_buttons_spec.js +++ b/spec/frontend/sidebar/confidential/edit_form_buttons_spec.js @@ -1,5 +1,4 @@ import { shallowMount } from '@vue/test-utils'; -import { GlLoadingIcon } from '@gitlab/ui'; import waitForPromises from 'helpers/wait_for_promises'; import EditFormButtons from '~/sidebar/components/confidential/edit_form_buttons.vue'; import eventHub from '~/sidebar/event_hub'; @@ -56,11 +55,11 @@ describe('Edit Form Buttons', () => { }); it('disables the toggle button', () => { - expect(findConfidentialToggle().attributes('disabled')).toBe('disabled'); + expect(findConfidentialToggle().props('disabled')).toBe(true); }); - it('finds the GlLoadingIcon', () => { - expect(wrapper.find(GlLoadingIcon).exists()).toBe(true); + it('sets loading on the toggle button', () => { + expect(findConfidentialToggle().props('loading')).toBe(true); }); }); @@ -99,7 +98,7 @@ describe('Edit Form Buttons', () => { describe('when succeeds', () => { beforeEach(() => { createComponent({ data: { isLoading: false }, props: { confidential: true } }); - findConfidentialToggle().trigger('click'); + findConfidentialToggle().vm.$emit('click', new Event('click')); }); it('dispatches the correct action', () => { @@ -109,9 +108,9 @@ describe('Edit Form Buttons', () => { }); }); - it('resets loading', () => { + it('resets loading on the toggle button', () => { return waitForPromises().then(() => { - expect(wrapper.find(GlLoadingIcon).exists()).toBe(false); + expect(findConfidentialToggle().props('loading')).toBe(false); }); }); @@ -135,7 +134,7 @@ describe('Edit Form Buttons', () => { props: { confidential: true }, resolved: false, }); - findConfidentialToggle().trigger('click'); + findConfidentialToggle().vm.$emit('click', new Event('click')); }); it('calls flash with the correct message', () => { diff --git a/spec/frontend/sidebar/lock/edit_form_buttons_spec.js b/spec/frontend/sidebar/lock/edit_form_buttons_spec.js index de1da3456f8..913646c8f8d 100644 --- a/spec/frontend/sidebar/lock/edit_form_buttons_spec.js +++ b/spec/frontend/sidebar/lock/edit_form_buttons_spec.js @@ -1,5 +1,4 @@ -import { shallowMount } from '@vue/test-utils'; -import { GlLoadingIcon } from '@gitlab/ui'; +import { mount } from '@vue/test-utils'; import EditFormButtons from '~/sidebar/components/lock/edit_form_buttons.vue'; import eventHub from '~/sidebar/event_hub'; import { deprecatedCreateFlash as flash } from '~/flash'; @@ -22,7 +21,6 @@ describe('EditFormButtons', () => { }; const findLockToggle = () => wrapper.find('[data-testid="lock-toggle"]'); - const findGlLoadingIcon = () => wrapper.find(GlLoadingIcon); const createComponent = ({ props = {}, data = {}, resolved = true }) => { store = issuableType === ISSUABLE_TYPE_ISSUE ? createStore() : createMrStore(); @@ -33,7 +31,7 @@ describe('EditFormButtons', () => { jest.spyOn(store, 'dispatch').mockRejectedValue(); } - wrapper = shallowMount(EditFormButtons, { + wrapper = mount(EditFormButtons, { store, provide: { fullPath: '', @@ -78,8 +76,8 @@ describe('EditFormButtons', () => { expect(findLockToggle().attributes('disabled')).toBe('disabled'); }); - it('displays the GlLoadingIcon', () => { - expect(findGlLoadingIcon().exists()).toBe(true); + it('sets loading on the toggle button', () => { + expect(findLockToggle().props('loading')).toBe(true); }); }); @@ -121,7 +119,7 @@ describe('EditFormButtons', () => { it('resets loading', async () => { await wrapper.vm.$nextTick().then(() => { - expect(findGlLoadingIcon().exists()).toBe(false); + expect(findLockToggle().props('loading')).toBe(false); }); }); @@ -156,7 +154,7 @@ describe('EditFormButtons', () => { it('resets loading', async () => { await wrapper.vm.$nextTick().then(() => { - expect(findGlLoadingIcon().exists()).toBe(false); + expect(findLockToggle().props('loading')).toBe(false); }); }); diff --git a/spec/frontend/sidebar/lock/issuable_lock_form_spec.js b/spec/frontend/sidebar/lock/issuable_lock_form_spec.js index ab1423a9bbb..e8091dcb51d 100644 --- a/spec/frontend/sidebar/lock/issuable_lock_form_spec.js +++ b/spec/frontend/sidebar/lock/issuable_lock_form_spec.js @@ -1,5 +1,6 @@ import { shallowMount } from '@vue/test-utils'; import { mockTracking, triggerEvent } from 'helpers/tracking_helper'; +import { createMockDirective, getBinding } from 'helpers/vue_mock_directive'; import IssuableLockForm from '~/sidebar/components/lock/issuable_lock_form.vue'; import EditForm from '~/sidebar/components/lock/edit_form.vue'; import createStore from '~/notes/stores'; @@ -19,6 +20,8 @@ describe('IssuableLockForm', () => { const findLockStatus = () => wrapper.find('[data-testid="lock-status"]'); const findEditLink = () => wrapper.find('[data-testid="edit-link"]'); const findEditForm = () => wrapper.find(EditForm); + const findSidebarLockStatusTooltip = () => + getBinding(findSidebarCollapseIcon().element, 'gl-tooltip'); const initStore = isLocked => { if (issuableType === ISSUABLE_TYPE_ISSUE) { @@ -37,6 +40,9 @@ describe('IssuableLockForm', () => { isEditable: true, ...props, }, + directives: { + GlTooltip: createMockDirective(), + }, }); }; @@ -125,6 +131,13 @@ describe('IssuableLockForm', () => { expect(findEditForm().exists()).toBe(true); }); }); + + it('renders a tooltip with the lock status text', () => { + const tooltip = findSidebarLockStatusTooltip(); + + expect(tooltip).toBeDefined(); + expect(tooltip.value.title).toBe(isLocked ? 'Locked' : 'Unlocked'); + }); }); }); }); diff --git a/spec/frontend/sidebar/reviewer_title_spec.js b/spec/frontend/sidebar/reviewer_title_spec.js new file mode 100644 index 00000000000..eae266688d5 --- /dev/null +++ b/spec/frontend/sidebar/reviewer_title_spec.js @@ -0,0 +1,116 @@ +import { shallowMount } from '@vue/test-utils'; +import { GlLoadingIcon } from '@gitlab/ui'; +import { mockTracking, triggerEvent } from 'helpers/tracking_helper'; +import Component from '~/sidebar/components/reviewers/reviewer_title.vue'; + +describe('ReviewerTitle component', () => { + let wrapper; + + const createComponent = props => { + return shallowMount(Component, { + propsData: { + numberOfReviewers: 0, + editable: false, + ...props, + }, + }); + }; + + afterEach(() => { + wrapper.destroy(); + wrapper = null; + }); + + describe('reviewer title', () => { + it('renders reviewer', () => { + wrapper = createComponent({ + numberOfReviewers: 1, + editable: false, + }); + + expect(wrapper.vm.$el.innerText.trim()).toEqual('Reviewer'); + }); + + it('renders 2 reviewers', () => { + wrapper = createComponent({ + numberOfReviewers: 2, + editable: false, + }); + + expect(wrapper.vm.$el.innerText.trim()).toEqual('2 Reviewers'); + }); + }); + + describe('gutter toggle', () => { + it('does not show toggle by default', () => { + wrapper = createComponent({ + numberOfReviewers: 2, + editable: false, + }); + + expect(wrapper.vm.$el.querySelector('.gutter-toggle')).toBeNull(); + }); + + it('shows toggle when showToggle is true', () => { + wrapper = createComponent({ + numberOfReviewers: 2, + editable: false, + showToggle: true, + }); + + expect(wrapper.vm.$el.querySelector('.gutter-toggle')).toEqual(expect.any(Object)); + }); + }); + + it('does not render spinner by default', () => { + wrapper = createComponent({ + numberOfReviewers: 0, + editable: false, + }); + + expect(wrapper.find(GlLoadingIcon).exists()).toBeFalsy(); + }); + + it('renders spinner when loading', () => { + wrapper = createComponent({ + loading: true, + numberOfReviewers: 0, + editable: false, + }); + + expect(wrapper.find(GlLoadingIcon).exists()).toBeTruthy(); + }); + + it('does not render edit link when not editable', () => { + wrapper = createComponent({ + numberOfReviewers: 0, + editable: false, + }); + + expect(wrapper.vm.$el.querySelector('.edit-link')).toBeNull(); + }); + + it('renders edit link when editable', () => { + wrapper = createComponent({ + numberOfReviewers: 0, + editable: true, + }); + + expect(wrapper.vm.$el.querySelector('.edit-link')).not.toBeNull(); + }); + + it('tracks the event when edit is clicked', () => { + wrapper = createComponent({ + numberOfReviewers: 0, + editable: true, + }); + + const spy = mockTracking('_category_', wrapper.element, jest.spyOn); + triggerEvent('.js-sidebar-dropdown-toggle'); + + expect(spy).toHaveBeenCalledWith('_category_', 'click_edit_button', { + label: 'right_sidebar', + property: 'reviewer', + }); + }); +}); diff --git a/spec/frontend/sidebar/reviewers_spec.js b/spec/frontend/sidebar/reviewers_spec.js new file mode 100644 index 00000000000..effcac266f0 --- /dev/null +++ b/spec/frontend/sidebar/reviewers_spec.js @@ -0,0 +1,169 @@ +import { mount } from '@vue/test-utils'; +import { trimText } from 'helpers/text_helper'; +import { GlIcon } from '@gitlab/ui'; +import Reviewer from '~/sidebar/components/reviewers/reviewers.vue'; +import UsersMock from './mock_data'; +import UsersMockHelper from '../helpers/user_mock_data_helper'; + +describe('Reviewer component', () => { + const getDefaultProps = () => ({ + rootPath: 'http://localhost:3000', + users: [], + editable: false, + }); + let wrapper; + + const createWrapper = (propsData = getDefaultProps()) => { + wrapper = mount(Reviewer, { + propsData, + }); + }; + + const findCollapsedChildren = () => wrapper.findAll('.sidebar-collapsed-icon > *'); + + afterEach(() => { + wrapper.destroy(); + }); + + describe('No reviewers/users', () => { + it('displays no reviewer icon when collapsed', () => { + createWrapper(); + const collapsedChildren = findCollapsedChildren(); + const userIcon = collapsedChildren.at(0).find(GlIcon); + + expect(collapsedChildren.length).toBe(1); + expect(collapsedChildren.at(0).attributes('aria-label')).toBe('None'); + expect(userIcon.exists()).toBe(true); + expect(userIcon.props('name')).toBe('user'); + }); + }); + + describe('One reviewer/user', () => { + it('displays one reviewer icon when collapsed', () => { + createWrapper({ + ...getDefaultProps(), + users: [UsersMock.user], + }); + + const collapsedChildren = findCollapsedChildren(); + const reviewer = collapsedChildren.at(0); + + expect(collapsedChildren.length).toBe(1); + expect(reviewer.find('.avatar').attributes('src')).toBe(UsersMock.user.avatar); + expect(reviewer.find('.avatar').attributes('alt')).toBe(`${UsersMock.user.name}'s avatar`); + + expect(trimText(reviewer.find('.author').text())).toBe(UsersMock.user.name); + }); + }); + + describe('Two or more reviewers/users', () => { + it('displays two reviewer icons when collapsed', () => { + const users = UsersMockHelper.createNumberRandomUsers(2); + createWrapper({ + ...getDefaultProps(), + users, + }); + + const collapsedChildren = findCollapsedChildren(); + + expect(collapsedChildren.length).toBe(2); + + const first = collapsedChildren.at(0); + + expect(first.find('.avatar').attributes('src')).toBe(users[0].avatar_url); + expect(first.find('.avatar').attributes('alt')).toBe(`${users[0].name}'s avatar`); + + expect(trimText(first.find('.author').text())).toBe(users[0].name); + + const second = collapsedChildren.at(1); + + expect(second.find('.avatar').attributes('src')).toBe(users[1].avatar_url); + expect(second.find('.avatar').attributes('alt')).toBe(`${users[1].name}'s avatar`); + + expect(trimText(second.find('.author').text())).toBe(users[1].name); + }); + + it('displays one reviewer icon and counter when collapsed', () => { + const users = UsersMockHelper.createNumberRandomUsers(3); + createWrapper({ + ...getDefaultProps(), + users, + }); + + const collapsedChildren = findCollapsedChildren(); + + expect(collapsedChildren.length).toBe(2); + + const first = collapsedChildren.at(0); + + expect(first.find('.avatar').attributes('src')).toBe(users[0].avatar_url); + expect(first.find('.avatar').attributes('alt')).toBe(`${users[0].name}'s avatar`); + + expect(trimText(first.find('.author').text())).toBe(users[0].name); + + const second = collapsedChildren.at(1); + + expect(trimText(second.find('.avatar-counter').text())).toBe('+2'); + }); + + it('Shows two reviewers', () => { + const users = UsersMockHelper.createNumberRandomUsers(2); + createWrapper({ + ...getDefaultProps(), + users, + editable: true, + }); + + expect(wrapper.findAll('.user-item').length).toBe(users.length); + expect(wrapper.find('.user-list-more').exists()).toBe(false); + }); + + it('shows sorted reviewer where "can merge" users are sorted first', () => { + const users = UsersMockHelper.createNumberRandomUsers(3); + users[0].can_merge = false; + users[1].can_merge = false; + users[2].can_merge = true; + + createWrapper({ + ...getDefaultProps(), + users, + editable: true, + }); + + expect(wrapper.vm.sortedReviewers[0].can_merge).toBe(true); + }); + + it('passes the sorted reviewers to the uncollapsed-reviewer-list', () => { + const users = UsersMockHelper.createNumberRandomUsers(3); + users[0].can_merge = false; + users[1].can_merge = false; + users[2].can_merge = true; + + createWrapper({ + ...getDefaultProps(), + users, + }); + + const userItems = wrapper.findAll('.user-list .user-item a'); + + expect(userItems.length).toBe(3); + expect(userItems.at(0).attributes('title')).toBe(users[2].name); + }); + + it('passes the sorted reviewers to the collapsed-reviewer-list', () => { + const users = UsersMockHelper.createNumberRandomUsers(3); + users[0].can_merge = false; + users[1].can_merge = false; + users[2].can_merge = true; + + createWrapper({ + ...getDefaultProps(), + users, + }); + + const collapsedButton = wrapper.find('.sidebar-collapsed-user button'); + + expect(trimText(collapsedButton.text())).toBe(users[2].name); + }); + }); +}); diff --git a/spec/frontend/sidebar/sidebar_assignees_spec.js b/spec/frontend/sidebar/sidebar_assignees_spec.js index 88e2d2c9514..dc4560d2ae8 100644 --- a/spec/frontend/sidebar/sidebar_assignees_spec.js +++ b/spec/frontend/sidebar/sidebar_assignees_spec.js @@ -20,6 +20,7 @@ describe('sidebar assignees', () => { mediator, field: '', projectPath: 'projectPath', + changing: false, ...props, }, provide: { diff --git a/spec/frontend/sidebar/sidebar_labels_spec.js b/spec/frontend/sidebar/sidebar_labels_spec.js index 29333a344e1..7a687ffa761 100644 --- a/spec/frontend/sidebar/sidebar_labels_spec.js +++ b/spec/frontend/sidebar/sidebar_labels_spec.js @@ -1,6 +1,5 @@ -import { createLocalVue, shallowMount } from '@vue/test-utils'; +import { shallowMount } from '@vue/test-utils'; import AxiosMockAdapter from 'axios-mock-adapter'; -import Vuex from 'vuex'; import { mockLabels, mockRegularLabel, @@ -9,17 +8,11 @@ import axios from '~/lib/utils/axios_utils'; import SidebarLabels from '~/sidebar/components/labels/sidebar_labels.vue'; import { DropdownVariant } from '~/vue_shared/components/sidebar/labels_select_vue/constants'; import LabelsSelect from '~/vue_shared/components/sidebar/labels_select_vue/labels_select_root.vue'; -import labelsSelectModule from '~/vue_shared/components/sidebar/labels_select_vue/store'; - -const localVue = createLocalVue(); -localVue.use(Vuex); describe('sidebar labels', () => { let axiosMock; let wrapper; - const store = new Vuex.Store(labelsSelectModule()); - const defaultProps = { allowLabelCreate: true, allowLabelEdit: true, @@ -39,11 +32,9 @@ describe('sidebar labels', () => { const mountComponent = () => { wrapper = shallowMount(SidebarLabels, { - localVue, provide: { ...defaultProps, }, - store, }); }; @@ -81,7 +72,7 @@ describe('sidebar labels', () => { }); }); - describe('when labels are changed', () => { + describe('when labels are updated', () => { beforeEach(() => { mountComponent(); }); @@ -114,7 +105,27 @@ describe('sidebar labels', () => { const expected = { [defaultProps.issuableType]: { - label_ids: [27, 28, 40], + label_ids: [27, 28, 29, 40], + }, + }; + + expect(axiosMock.history.put[0].data).toEqual(JSON.stringify(expected)); + }); + }); + + describe('when label `x` is clicked', () => { + beforeEach(() => { + mountComponent(); + }); + + it('makes an API call to update labels', async () => { + findLabelsSelect().vm.$emit('onLabelRemove', 27); + + await axios.waitForAll(); + + const expected = { + [defaultProps.issuableType]: { + label_ids: [26, 28, 29], }, }; diff --git a/spec/frontend/sidebar/sidebar_store_spec.js b/spec/frontend/sidebar/sidebar_store_spec.js index 6d063a7cfcf..7c18222f300 100644 --- a/spec/frontend/sidebar/sidebar_store_spec.js +++ b/spec/frontend/sidebar/sidebar_store_spec.js @@ -57,16 +57,40 @@ describe('Sidebar store', () => { expect(testContext.store.isFetching.assignees).toBe(true); }); - it('adds a new assignee', () => { - testContext.store.addAssignee(ASSIGNEE); + it('resets changing when resetChanging is called', () => { + testContext.store.changing = true; + + testContext.store.resetChanging(); - expect(testContext.store.assignees.length).toEqual(1); + expect(testContext.store.changing).toBe(false); }); - it('removes an assignee', () => { - testContext.store.removeAssignee(ASSIGNEE); + describe('when it adds a new assignee', () => { + beforeEach(() => { + testContext.store.addAssignee(ASSIGNEE); + }); - expect(testContext.store.assignees.length).toEqual(0); + it('adds a new assignee', () => { + expect(testContext.store.assignees).toHaveLength(1); + }); + + it('sets changing to true', () => { + expect(testContext.store.changing).toBe(true); + }); + }); + + describe('when it removes an assignee', () => { + beforeEach(() => { + testContext.store.removeAssignee(ASSIGNEE); + }); + + it('removes an assignee', () => { + expect(testContext.store.assignees).toHaveLength(0); + }); + + it('sets changing to true', () => { + expect(testContext.store.changing).toBe(true); + }); }); it('finds an existent assignee', () => { @@ -86,6 +110,7 @@ describe('Sidebar store', () => { testContext.store.removeAllAssignees(); expect(testContext.store.assignees.length).toEqual(0); + expect(testContext.store.changing).toBe(true); }); it('sets participants data', () => { |