Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2021-07-20 12:55:51 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2021-07-20 12:55:51 +0300
commite8d2c2579383897a1dd7f9debd359abe8ae8373d (patch)
treec42be41678c2586d49a75cabce89322082698334 /spec/frontend/vue_shared/components/sidebar
parentfc845b37ec3a90aaa719975f607740c22ba6a113 (diff)
Add latest changes from gitlab-org/gitlab@14-1-stable-eev14.1.0-rc42
Diffstat (limited to 'spec/frontend/vue_shared/components/sidebar')
-rw-r--r--spec/frontend/vue_shared/components/sidebar/copyable_field_spec.js5
-rw-r--r--spec/frontend/vue_shared/components/sidebar/labels_select_vue/dropdown_contents_labels_view_spec.js10
-rw-r--r--spec/frontend/vue_shared/components/sidebar/labels_select_vue/store/actions_spec.js19
-rw-r--r--spec/frontend/vue_shared/components/sidebar/labels_select_vue/store/mutations_spec.js29
-rw-r--r--spec/frontend/vue_shared/components/sidebar/labels_select_widget/dropdown_value_spec.js113
-rw-r--r--spec/frontend/vue_shared/components/sidebar/labels_select_widget/labels_select_root_spec.js4
-rw-r--r--spec/frontend/vue_shared/components/sidebar/labels_select_widget/store/actions_spec.js11
-rw-r--r--spec/frontend/vue_shared/components/sidebar/labels_select_widget/store/mutations_spec.js29
-rw-r--r--spec/frontend/vue_shared/components/sidebar/todo_button_spec.js68
9 files changed, 211 insertions, 77 deletions
diff --git a/spec/frontend/vue_shared/components/sidebar/copyable_field_spec.js b/spec/frontend/vue_shared/components/sidebar/copyable_field_spec.js
index b99b1a66b79..3980033862e 100644
--- a/spec/frontend/vue_shared/components/sidebar/copyable_field_spec.js
+++ b/spec/frontend/vue_shared/components/sidebar/copyable_field_spec.js
@@ -1,4 +1,4 @@
-import { GlLoadingIcon } from '@gitlab/ui';
+import { GlLoadingIcon, GlSprintf } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils';
import ClipboardButton from '~/vue_shared/components/clipboard_button.vue';
import CopyableField from '~/vue_shared/components/sidebar/copyable_field.vue';
@@ -14,6 +14,9 @@ describe('SidebarCopyableField', () => {
const createComponent = (propsData = defaultProps) => {
wrapper = shallowMount(CopyableField, {
propsData,
+ stubs: {
+ GlSprintf,
+ },
});
};
diff --git a/spec/frontend/vue_shared/components/sidebar/labels_select_vue/dropdown_contents_labels_view_spec.js b/spec/frontend/vue_shared/components/sidebar/labels_select_vue/dropdown_contents_labels_view_spec.js
index 60903933505..06ea88c09a0 100644
--- a/spec/frontend/vue_shared/components/sidebar/labels_select_vue/dropdown_contents_labels_view_spec.js
+++ b/spec/frontend/vue_shared/components/sidebar/labels_select_vue/dropdown_contents_labels_view_spec.js
@@ -54,7 +54,6 @@ describe('DropdownContentsLabelsView', () => {
afterEach(() => {
wrapper.destroy();
- wrapper = null;
});
const findDropdownContent = () => wrapper.find('[data-testid="dropdown-content"]');
@@ -381,6 +380,15 @@ describe('DropdownContentsLabelsView', () => {
expect(findDropdownFooter().exists()).toBe(false);
});
+ it('does not render footer list items when `allowLabelCreate` is false and `labelsManagePath` is null', () => {
+ createComponent({
+ ...mockConfig,
+ allowLabelCreate: false,
+ labelsManagePath: null,
+ });
+ expect(findDropdownFooter().exists()).toBe(false);
+ });
+
it('renders footer list items when `state.variant` is "embedded"', () => {
expect(findDropdownFooter().exists()).toBe(true);
});
diff --git a/spec/frontend/vue_shared/components/sidebar/labels_select_vue/store/actions_spec.js b/spec/frontend/vue_shared/components/sidebar/labels_select_vue/store/actions_spec.js
index 3f11095cb04..46ade5d5857 100644
--- a/spec/frontend/vue_shared/components/sidebar/labels_select_vue/store/actions_spec.js
+++ b/spec/frontend/vue_shared/components/sidebar/labels_select_vue/store/actions_spec.js
@@ -1,11 +1,14 @@
import MockAdapter from 'axios-mock-adapter';
import testAction from 'helpers/vuex_action_helper';
+import createFlash from '~/flash';
import axios from '~/lib/utils/axios_utils';
import * as actions from '~/vue_shared/components/sidebar/labels_select_vue/store/actions';
import * as types from '~/vue_shared/components/sidebar/labels_select_vue/store/mutation_types';
import defaultState from '~/vue_shared/components/sidebar/labels_select_vue/store/state';
+jest.mock('~/flash');
+
describe('LabelsSelect Actions', () => {
let state;
const mockInitialState = {
@@ -91,10 +94,6 @@ describe('LabelsSelect Actions', () => {
});
describe('receiveLabelsFailure', () => {
- beforeEach(() => {
- setFixtures('<div class="flash-container"></div>');
- });
-
it('sets value `state.labelsFetchInProgress` to `false`', (done) => {
testAction(
actions.receiveLabelsFailure,
@@ -109,9 +108,7 @@ describe('LabelsSelect Actions', () => {
it('shows flash error', () => {
actions.receiveLabelsFailure({ commit: () => {} });
- expect(document.querySelector('.flash-container .flash-text').innerText.trim()).toBe(
- 'Error fetching labels.',
- );
+ expect(createFlash).toHaveBeenCalledWith({ message: 'Error fetching labels.' });
});
});
@@ -186,10 +183,6 @@ describe('LabelsSelect Actions', () => {
});
describe('receiveCreateLabelFailure', () => {
- beforeEach(() => {
- setFixtures('<div class="flash-container"></div>');
- });
-
it('sets value `state.labelCreateInProgress` to `false`', (done) => {
testAction(
actions.receiveCreateLabelFailure,
@@ -204,9 +197,7 @@ describe('LabelsSelect Actions', () => {
it('shows flash error', () => {
actions.receiveCreateLabelFailure({ commit: () => {} });
- expect(document.querySelector('.flash-container .flash-text').innerText.trim()).toBe(
- 'Error creating label.',
- );
+ expect(createFlash).toHaveBeenCalledWith({ message: 'Error creating label.' });
});
});
diff --git a/spec/frontend/vue_shared/components/sidebar/labels_select_vue/store/mutations_spec.js b/spec/frontend/vue_shared/components/sidebar/labels_select_vue/store/mutations_spec.js
index ab266ac8aed..1d2a9c34599 100644
--- a/spec/frontend/vue_shared/components/sidebar/labels_select_vue/store/mutations_spec.js
+++ b/spec/frontend/vue_shared/components/sidebar/labels_select_vue/store/mutations_spec.js
@@ -153,7 +153,16 @@ describe('LabelsSelect Mutations', () => {
});
describe(`${types.UPDATE_SELECTED_LABELS}`, () => {
- const labels = [{ id: 1 }, { id: 2 }, { id: 3 }, { id: 4 }];
+ let labels;
+
+ beforeEach(() => {
+ labels = [
+ { id: 1, title: 'scoped::test', set: true },
+ { id: 2, set: false, title: 'scoped::one' },
+ { id: 3, title: '' },
+ { id: 4, title: '' },
+ ];
+ });
it('updates `state.labels` to include `touched` and `set` props based on provided `labels` param', () => {
const updatedLabelIds = [2];
@@ -169,5 +178,23 @@ describe('LabelsSelect Mutations', () => {
}
});
});
+
+ describe('when label is scoped', () => {
+ it('unsets the currently selected scoped label and sets the current label', () => {
+ const state = {
+ labels,
+ };
+ mutations[types.UPDATE_SELECTED_LABELS](state, {
+ labels: [{ id: 2, title: 'scoped::one' }],
+ });
+
+ expect(state.labels).toEqual([
+ { id: 1, title: 'scoped::test', set: false },
+ { id: 2, set: true, title: 'scoped::one', touched: true },
+ { id: 3, title: '' },
+ { id: 4, title: '' },
+ ]);
+ });
+ });
});
});
diff --git a/spec/frontend/vue_shared/components/sidebar/labels_select_widget/dropdown_value_spec.js b/spec/frontend/vue_shared/components/sidebar/labels_select_widget/dropdown_value_spec.js
index 59f3268c000..b3ffee2d020 100644
--- a/spec/frontend/vue_shared/components/sidebar/labels_select_widget/dropdown_value_spec.js
+++ b/spec/frontend/vue_shared/components/sidebar/labels_select_widget/dropdown_value_spec.js
@@ -1,88 +1,97 @@
import { GlLabel } from '@gitlab/ui';
-import { shallowMount, createLocalVue } from '@vue/test-utils';
-import Vuex from 'vuex';
+import { shallowMount } from '@vue/test-utils';
import DropdownValue from '~/vue_shared/components/sidebar/labels_select_widget/dropdown_value.vue';
-import labelsSelectModule from '~/vue_shared/components/sidebar/labels_select_widget/store';
-
-import { mockConfig, mockRegularLabel, mockScopedLabel } from './mock_data';
-
-const localVue = createLocalVue();
-localVue.use(Vuex);
+import { mockRegularLabel, mockScopedLabel } from './mock_data';
describe('DropdownValue', () => {
let wrapper;
- const createComponent = (initialState = {}, slots = {}) => {
- const store = new Vuex.Store(labelsSelectModule());
-
- store.dispatch('setInitialState', { ...mockConfig, ...initialState });
+ const findAllLabels = () => wrapper.findAllComponents(GlLabel);
+ const findRegularLabel = () => findAllLabels().at(0);
+ const findScopedLabel = () => findAllLabels().at(1);
+ const findWrapper = () => wrapper.find('[data-testid="value-wrapper"]');
+ const findEmptyPlaceholder = () => wrapper.find('[data-testid="empty-placeholder"]');
+ const createComponent = (props = {}, slots = {}) => {
wrapper = shallowMount(DropdownValue, {
- localVue,
- store,
slots,
+ propsData: {
+ selectedLabels: [mockRegularLabel, mockScopedLabel],
+ allowLabelRemove: true,
+ allowScopedLabels: true,
+ labelsFilterBasePath: '/gitlab-org/my-project/issues',
+ labelsFilterParam: 'label_name',
+ ...props,
+ },
});
};
afterEach(() => {
wrapper.destroy();
- wrapper = null;
});
- describe('methods', () => {
- describe('labelFilterUrl', () => {
- it('returns a label filter URL based on provided label param', () => {
- createComponent();
-
- expect(wrapper.vm.labelFilterUrl(mockRegularLabel)).toBe(
- '/gitlab-org/my-project/issues?label_name[]=Foo%20Label',
- );
- });
+ describe('when there are no labels', () => {
+ beforeEach(() => {
+ createComponent(
+ {
+ selectedLabels: [],
+ },
+ {
+ default: 'None',
+ },
+ );
});
- describe('scopedLabel', () => {
- beforeEach(() => {
- createComponent();
- });
+ it('does not apply `has-labels` class to the wrapping container', () => {
+ expect(findWrapper().classes()).not.toContain('has-labels');
+ });
- it('returns `true` when provided label param is a scoped label', () => {
- expect(wrapper.vm.scopedLabel(mockScopedLabel)).toBe(true);
- });
+ it('renders an empty placeholder', () => {
+ expect(findEmptyPlaceholder().exists()).toBe(true);
+ expect(findEmptyPlaceholder().text()).toBe('None');
+ });
- it('returns `false` when provided label param is a regular label', () => {
- expect(wrapper.vm.scopedLabel(mockRegularLabel)).toBe(false);
- });
+ it('does not render any labels', () => {
+ expect(findAllLabels().length).toBe(0);
});
});
- describe('template', () => {
- it('renders class `has-labels` on component container element when `selectedLabels` is not empty', () => {
+ describe('when there are labels', () => {
+ beforeEach(() => {
createComponent();
+ });
- expect(wrapper.attributes('class')).toContain('has-labels');
+ it('applies `has-labels` class to the wrapping container', () => {
+ expect(findWrapper().classes()).toContain('has-labels');
});
- it('renders element containing `None` when `selectedLabels` is empty', () => {
- createComponent(
- {
- selectedLabels: [],
- },
- {
- default: 'None',
- },
- );
- const noneEl = wrapper.find('span.text-secondary');
+ it('does not render an empty placeholder', () => {
+ expect(findEmptyPlaceholder().exists()).toBe(false);
+ });
- expect(noneEl.exists()).toBe(true);
- expect(noneEl.text()).toBe('None');
+ it('renders a list of two labels', () => {
+ expect(findAllLabels().length).toBe(2);
});
- it('renders labels when `selectedLabels` is not empty', () => {
- createComponent();
+ it('passes correct props to the regular label', () => {
+ expect(findRegularLabel().props('target')).toBe(
+ '/gitlab-org/my-project/issues?label_name[]=Foo%20Label',
+ );
+ expect(findRegularLabel().props('scoped')).toBe(false);
+ });
+
+ it('passes correct props to the scoped label', () => {
+ expect(findScopedLabel().props('target')).toBe(
+ '/gitlab-org/my-project/issues?label_name[]=Foo%3A%3ABar',
+ );
+ expect(findScopedLabel().props('scoped')).toBe(true);
+ });
- expect(wrapper.findAll(GlLabel).length).toBe(2);
+ it('emits `onLabelRemove` event with the correct ID', () => {
+ findRegularLabel().vm.$emit('close');
+ expect(wrapper.emitted('onLabelRemove')).toEqual([[mockRegularLabel.id]]);
});
});
});
diff --git a/spec/frontend/vue_shared/components/sidebar/labels_select_widget/labels_select_root_spec.js b/spec/frontend/vue_shared/components/sidebar/labels_select_widget/labels_select_root_spec.js
index ee1346c362f..66971446f47 100644
--- a/spec/frontend/vue_shared/components/sidebar/labels_select_widget/labels_select_root_spec.js
+++ b/spec/frontend/vue_shared/components/sidebar/labels_select_widget/labels_select_root_spec.js
@@ -34,6 +34,10 @@ describe('LabelsSelectRoot', () => {
stubs: {
'dropdown-contents': DropdownContents,
},
+ provide: {
+ iid: '1',
+ projectPath: 'test',
+ },
});
};
diff --git a/spec/frontend/vue_shared/components/sidebar/labels_select_widget/store/actions_spec.js b/spec/frontend/vue_shared/components/sidebar/labels_select_widget/store/actions_spec.js
index 7ef4b769b6b..27de7de2411 100644
--- a/spec/frontend/vue_shared/components/sidebar/labels_select_widget/store/actions_spec.js
+++ b/spec/frontend/vue_shared/components/sidebar/labels_select_widget/store/actions_spec.js
@@ -1,11 +1,14 @@
import MockAdapter from 'axios-mock-adapter';
import testAction from 'helpers/vuex_action_helper';
+import createFlash from '~/flash';
import axios from '~/lib/utils/axios_utils';
import * as actions from '~/vue_shared/components/sidebar/labels_select_widget/store/actions';
import * as types from '~/vue_shared/components/sidebar/labels_select_widget/store/mutation_types';
import defaultState from '~/vue_shared/components/sidebar/labels_select_widget/store/state';
+jest.mock('~/flash');
+
describe('LabelsSelect Actions', () => {
let state;
const mockInitialState = {
@@ -91,10 +94,6 @@ describe('LabelsSelect Actions', () => {
});
describe('receiveLabelsFailure', () => {
- beforeEach(() => {
- setFixtures('<div class="flash-container"></div>');
- });
-
it('sets value `state.labelsFetchInProgress` to `false`', (done) => {
testAction(
actions.receiveLabelsFailure,
@@ -109,9 +108,7 @@ describe('LabelsSelect Actions', () => {
it('shows flash error', () => {
actions.receiveLabelsFailure({ commit: () => {} });
- expect(document.querySelector('.flash-container .flash-text').innerText.trim()).toBe(
- 'Error fetching labels.',
- );
+ expect(createFlash).toHaveBeenCalledWith({ message: 'Error fetching labels.' });
});
});
diff --git a/spec/frontend/vue_shared/components/sidebar/labels_select_widget/store/mutations_spec.js b/spec/frontend/vue_shared/components/sidebar/labels_select_widget/store/mutations_spec.js
index acb275b5d90..9e965cb33e8 100644
--- a/spec/frontend/vue_shared/components/sidebar/labels_select_widget/store/mutations_spec.js
+++ b/spec/frontend/vue_shared/components/sidebar/labels_select_widget/store/mutations_spec.js
@@ -120,7 +120,16 @@ describe('LabelsSelect Mutations', () => {
});
describe(`${types.UPDATE_SELECTED_LABELS}`, () => {
- const labels = [{ id: 1 }, { id: 2 }, { id: 3 }, { id: 4 }];
+ let labels;
+
+ beforeEach(() => {
+ labels = [
+ { id: 1, title: 'scoped::test', set: true },
+ { id: 2, set: false, title: 'scoped::one' },
+ { id: 3, title: '' },
+ { id: 4, title: '' },
+ ];
+ });
it('updates `state.labels` to include `touched` and `set` props based on provided `labels` param', () => {
const updatedLabelIds = [2];
@@ -136,5 +145,23 @@ describe('LabelsSelect Mutations', () => {
}
});
});
+
+ describe('when label is scoped', () => {
+ it('unsets the currently selected scoped label and sets the current label', () => {
+ const state = {
+ labels,
+ };
+ mutations[types.UPDATE_SELECTED_LABELS](state, {
+ labels: [{ id: 2, title: 'scoped::one' }],
+ });
+
+ expect(state.labels).toEqual([
+ { id: 1, title: 'scoped::test', set: false },
+ { id: 2, set: true, title: 'scoped::one', touched: true },
+ { id: 3, title: '' },
+ { id: 4, title: '' },
+ ]);
+ });
+ });
});
});
diff --git a/spec/frontend/vue_shared/components/sidebar/todo_button_spec.js b/spec/frontend/vue_shared/components/sidebar/todo_button_spec.js
new file mode 100644
index 00000000000..de3e1ccfb03
--- /dev/null
+++ b/spec/frontend/vue_shared/components/sidebar/todo_button_spec.js
@@ -0,0 +1,68 @@
+import { GlButton } from '@gitlab/ui';
+import { shallowMount, mount } from '@vue/test-utils';
+import TodoButton from '~/vue_shared/components/sidebar/todo_toggle/todo_button.vue';
+
+describe('Todo Button', () => {
+ let wrapper;
+ let dispatchEventSpy;
+
+ const createComponent = (props = {}, mountFn = shallowMount) => {
+ wrapper = mountFn(TodoButton, {
+ propsData: {
+ ...props,
+ },
+ });
+ };
+
+ beforeEach(() => {
+ dispatchEventSpy = jest.spyOn(document, 'dispatchEvent');
+ jest.spyOn(document, 'querySelector').mockReturnValue({
+ innerText: 2,
+ });
+ });
+
+ afterEach(() => {
+ wrapper.destroy();
+ dispatchEventSpy = null;
+ jest.clearAllMocks();
+ });
+
+ it('renders GlButton', () => {
+ createComponent();
+
+ expect(wrapper.find(GlButton).exists()).toBe(true);
+ });
+
+ it('emits click event when clicked', () => {
+ createComponent({}, mount);
+ wrapper.find(GlButton).trigger('click');
+
+ expect(wrapper.emitted().click).toBeTruthy();
+ });
+
+ it('calls dispatchDocumentEvent to update global To-Do counter correctly', () => {
+ createComponent({}, mount);
+ wrapper.find(GlButton).trigger('click');
+ const dispatchedEvent = dispatchEventSpy.mock.calls[0][0];
+
+ expect(dispatchEventSpy).toHaveBeenCalledTimes(1);
+ expect(dispatchedEvent.detail).toEqual({ count: 1 });
+ expect(dispatchedEvent.type).toBe('todo:toggle');
+ });
+
+ it.each`
+ label | isTodo
+ ${'Mark as done'} | ${true}
+ ${'Add a to do'} | ${false}
+ `('sets correct label when isTodo is $isTodo', ({ label, isTodo }) => {
+ createComponent({ isTodo });
+
+ expect(wrapper.find(GlButton).text()).toBe(label);
+ });
+
+ it('binds additional props to GlButton', () => {
+ createComponent({ loading: true });
+
+ expect(wrapper.find(GlButton).props('loading')).toBe(true);
+ });
+});