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>2023-04-24 15:08:36 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2023-04-24 15:08:36 +0300
commit4720346c2e10e1ff62a20b39dfc9866eb88858e6 (patch)
tree1b277cb86d928b3372a714d21b5e068c5b9d66f1 /spec/frontend/sidebar
parent028c7bdc315c3770f2ccc86f1100d90a5f702cad (diff)
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'spec/frontend/sidebar')
-rw-r--r--spec/frontend/sidebar/components/labels/labels_select_vue/dropdown_contents_labels_view_spec.js292
1 files changed, 129 insertions, 163 deletions
diff --git a/spec/frontend/sidebar/components/labels/labels_select_vue/dropdown_contents_labels_view_spec.js b/spec/frontend/sidebar/components/labels/labels_select_vue/dropdown_contents_labels_view_spec.js
index 7940518f1e8..1fa613d15d4 100644
--- a/spec/frontend/sidebar/components/labels/labels_select_vue/dropdown_contents_labels_view_spec.js
+++ b/spec/frontend/sidebar/components/labels/labels_select_vue/dropdown_contents_labels_view_spec.js
@@ -5,27 +5,31 @@ import {
GlSearchBoxByType,
GlLink,
} from '@gitlab/ui';
-import { shallowMount } from '@vue/test-utils';
import Vue, { nextTick } from 'vue';
import Vuex from 'vuex';
-import { UP_KEY_CODE, DOWN_KEY_CODE, ENTER_KEY_CODE, ESC_KEY_CODE } from '~/lib/utils/keycodes';
+import { shallowMountExtended, mountExtended } from 'helpers/vue_test_utils_helper';
import DropdownContentsLabelsView from '~/sidebar/components/labels/labels_select_vue/dropdown_contents_labels_view.vue';
import LabelItem from '~/sidebar/components/labels/labels_select_vue/label_item.vue';
-
+import { stubComponent } from 'helpers/stub_component';
import * as actions from '~/sidebar/components/labels/labels_select_vue/store/actions';
import * as getters from '~/sidebar/components/labels/labels_select_vue/store/getters';
import mutations from '~/sidebar/components/labels/labels_select_vue/store/mutations';
import defaultState from '~/sidebar/components/labels/labels_select_vue/store/state';
-import { mockConfig, mockLabels, mockRegularLabel } from './mock_data';
+import { mockConfig, mockLabels } from './mock_data';
Vue.use(Vuex);
describe('DropdownContentsLabelsView', () => {
let wrapper;
+ let store;
+
+ const focusInputMock = jest.fn();
+ const updateSelectedLabelsMock = jest.fn();
+ const toggleDropdownContentsMock = jest.fn();
- const createComponent = (initialState = mockConfig) => {
- const store = new Vuex.Store({
+ const createComponent = (initialState = mockConfig, mountFn = shallowMountExtended) => {
+ store = new Vuex.Store({
getters,
mutations,
state: {
@@ -36,14 +40,20 @@ describe('DropdownContentsLabelsView', () => {
actions: {
...actions,
fetchLabels: jest.fn(),
+ updateSelectedLabels: updateSelectedLabelsMock,
+ toggleDropdownContents: toggleDropdownContentsMock,
},
});
store.dispatch('setInitialState', initialState);
- store.dispatch('receiveLabelsSuccess', mockLabels);
- wrapper = shallowMount(DropdownContentsLabelsView, {
+ wrapper = mountFn(DropdownContentsLabelsView, {
store,
+ stubs: {
+ GlSearchBoxByType: stubComponent(GlSearchBoxByType, {
+ methods: { focusInput: focusInputMock },
+ }),
+ },
});
};
@@ -51,44 +61,54 @@ describe('DropdownContentsLabelsView', () => {
createComponent();
});
- const findDropdownContent = () => wrapper.find('[data-testid="dropdown-content"]');
- const findDropdownTitle = () => wrapper.find('[data-testid="dropdown-title"]');
- const findDropdownFooter = () => wrapper.find('[data-testid="dropdown-footer"]');
+ const findDropdownContent = () => wrapper.findByTestId('dropdown-content');
+ const findDropdownTitle = () => wrapper.findByTestId('dropdown-title');
+ const findDropdownFooter = () => wrapper.findByTestId('dropdown-footer');
+ const findNoMatchingResults = () => wrapper.findByTestId('no-matching-results');
+ const findCreateLabelLink = () => wrapper.findByTestId('create-label-link');
+ const findLabelsList = () => wrapper.findByTestId('labels-list');
const findLoadingIcon = () => wrapper.findComponent(GlLoadingIcon);
+ const findSearchBoxByType = () => wrapper.findComponent(GlSearchBoxByType);
+ const findIntersectionObserver = () => wrapper.findComponent(GlIntersectionObserver);
+ const findLabelItems = () => wrapper.findAllComponents(LabelItem);
+
+ const setCurrentHighlightItem = (value) => {
+ let initialValue = -1;
+
+ while (initialValue < value) {
+ findLabelsList().trigger('keydown.down');
+ initialValue += 1;
+ }
+ };
describe('computed', () => {
describe('visibleLabels', () => {
- it('returns matching labels filtered with `searchKey`', () => {
- // setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
- // eslint-disable-next-line no-restricted-syntax
- wrapper.setData({
- searchKey: 'bug',
- });
-
- expect(wrapper.vm.visibleLabels.length).toBe(1);
- expect(wrapper.vm.visibleLabels[0].title).toBe('Bug');
+ beforeEach(() => {
+ createComponent(undefined, mountExtended);
+ store.dispatch('receiveLabelsSuccess', mockLabels);
});
- it('returns matching labels with fuzzy filtering', () => {
- // setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
- // eslint-disable-next-line no-restricted-syntax
- wrapper.setData({
- searchKey: 'bg',
- });
+ it('returns matching labels filtered with `searchKey`', async () => {
+ await findSearchBoxByType().vm.$emit('input', 'bug');
- expect(wrapper.vm.visibleLabels.length).toBe(2);
- expect(wrapper.vm.visibleLabels[0].title).toBe('Bug');
- expect(wrapper.vm.visibleLabels[1].title).toBe('Boog');
+ const labelItems = findLabelItems();
+ expect(labelItems).toHaveLength(1);
+ expect(labelItems.at(0).text()).toBe('Bug');
});
- it('returns all labels when `searchKey` is empty', () => {
- // setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
- // eslint-disable-next-line no-restricted-syntax
- wrapper.setData({
- searchKey: '',
- });
+ it('returns matching labels with fuzzy filtering', async () => {
+ await findSearchBoxByType().vm.$emit('input', 'bg');
- expect(wrapper.vm.visibleLabels.length).toBe(mockLabels.length);
+ const labelItems = findLabelItems();
+ expect(labelItems).toHaveLength(2);
+ expect(labelItems.at(0).text()).toBe('Bug');
+ expect(labelItems.at(1).text()).toBe('Boog');
+ });
+
+ it('returns all labels when `searchKey` is empty', async () => {
+ await findSearchBoxByType().vm.$emit('input', '');
+
+ expect(findLabelItems()).toHaveLength(mockLabels.length);
});
});
@@ -102,17 +122,11 @@ describe('DropdownContentsLabelsView', () => {
`(
'returns $returnValue when searchKey is "$searchKey" and visibleLabels is $labelsDescription',
async ({ searchKey, labels, returnValue }) => {
- // setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
- // eslint-disable-next-line no-restricted-syntax
- wrapper.setData({
- searchKey,
- });
-
- wrapper.vm.$store.dispatch('receiveLabelsSuccess', labels);
+ store.dispatch('receiveLabelsSuccess', labels);
- await nextTick();
+ await findSearchBoxByType().vm.$emit('input', searchKey);
- expect(wrapper.vm.showNoMatchingResultsMessage).toBe(returnValue);
+ expect(findNoMatchingResults().isVisible()).toBe(returnValue);
},
);
});
@@ -121,171 +135,134 @@ describe('DropdownContentsLabelsView', () => {
describe('methods', () => {
const fakePreventDefault = jest.fn();
- describe('isLabelSelected', () => {
- it('returns true when provided `label` param is one of the selected labels', () => {
- expect(wrapper.vm.isLabelSelected(mockRegularLabel)).toBe(true);
- });
-
- it('returns false when provided `label` param is not one of the selected labels', () => {
- expect(wrapper.vm.isLabelSelected(mockLabels[1])).toBe(false);
- });
- });
-
describe('handleComponentAppear', () => {
it('calls `focusInput` on searchInput field', async () => {
- wrapper.vm.$refs.searchInput.focusInput = jest.fn();
+ findIntersectionObserver().vm.$emit('appear');
- await wrapper.vm.handleComponentAppear();
+ await nextTick();
- expect(wrapper.vm.$refs.searchInput.focusInput).toHaveBeenCalled();
+ expect(focusInputMock).toHaveBeenCalled();
});
});
describe('handleComponentDisappear', () => {
- it('calls action `receiveLabelsSuccess` with empty array', () => {
- jest.spyOn(wrapper.vm, 'receiveLabelsSuccess');
+ it('calls action `receiveLabelsSuccess` with empty array', async () => {
+ jest.spyOn(store, 'dispatch');
- wrapper.vm.handleComponentDisappear();
+ await findIntersectionObserver().vm.$emit('disappear');
- expect(wrapper.vm.receiveLabelsSuccess).toHaveBeenCalledWith([]);
+ expect(store.dispatch).toHaveBeenCalledWith(expect.anything(), []);
});
});
describe('handleCreateLabelClick', () => {
- it('calls actions `receiveLabelsSuccess` with empty array and `toggleDropdownContentsCreateView`', () => {
- jest.spyOn(wrapper.vm, 'receiveLabelsSuccess');
- jest.spyOn(wrapper.vm, 'toggleDropdownContentsCreateView');
+ it('calls actions `receiveLabelsSuccess` with empty array and `toggleDropdownContentsCreateView`', async () => {
+ jest.spyOn(store, 'dispatch');
- wrapper.vm.handleCreateLabelClick();
+ await findCreateLabelLink().vm.$emit('click');
- expect(wrapper.vm.receiveLabelsSuccess).toHaveBeenCalledWith([]);
- expect(wrapper.vm.toggleDropdownContentsCreateView).toHaveBeenCalled();
+ expect(store.dispatch).toHaveBeenCalledWith('receiveLabelsSuccess', []);
+ expect(store.dispatch).toHaveBeenCalledWith('toggleDropdownContentsCreateView');
});
});
describe('handleKeyDown', () => {
- it('decreases `currentHighlightItem` value by 1 when Up arrow key is pressed', () => {
- // setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
- // eslint-disable-next-line no-restricted-syntax
- wrapper.setData({
- currentHighlightItem: 1,
- });
-
- wrapper.vm.handleKeyDown({
- keyCode: UP_KEY_CODE,
- });
-
- expect(wrapper.vm.currentHighlightItem).toBe(0);
+ beforeEach(() => {
+ createComponent(undefined, mountExtended);
+ store.dispatch('receiveLabelsSuccess', mockLabels);
});
- it('increases `currentHighlightItem` value by 1 when Down arrow key is pressed', () => {
- // setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
- // eslint-disable-next-line no-restricted-syntax
- wrapper.setData({
- currentHighlightItem: 1,
- });
+ it('decreases `currentHighlightItem` value by 1 when Up arrow key is pressed', async () => {
+ await setCurrentHighlightItem(1);
+
+ expect(findLabelItems().at(1).classes()).toContain('is-focused');
- wrapper.vm.handleKeyDown({
- keyCode: DOWN_KEY_CODE,
- });
+ await findLabelsList().trigger('keydown.up');
- expect(wrapper.vm.currentHighlightItem).toBe(2);
+ expect(findLabelItems().at(1).classes()).not.toContain('is-focused');
});
- it('resets the search text when the Enter key is pressed', () => {
- // setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
- // eslint-disable-next-line no-restricted-syntax
- wrapper.setData({
- currentHighlightItem: 1,
- searchKey: 'bug',
- });
+ it('increases `currentHighlightItem` value by 1 when Down arrow key is pressed', async () => {
+ expect(findLabelItems().at(0).classes()).not.toContain('is-focused');
- wrapper.vm.handleKeyDown({
- keyCode: ENTER_KEY_CODE,
- preventDefault: fakePreventDefault,
- });
+ await findLabelsList().trigger('keydown.down');
- expect(wrapper.vm.searchKey).toBe('');
- expect(fakePreventDefault).toHaveBeenCalled();
+ expect(findLabelItems().at(0).classes()).toContain('is-focused');
});
- it('calls action `updateSelectedLabels` with currently highlighted label when Enter key is pressed', () => {
- jest.spyOn(wrapper.vm, 'updateSelectedLabels').mockImplementation();
- // setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
- // eslint-disable-next-line no-restricted-syntax
- wrapper.setData({
- currentHighlightItem: 2,
- });
-
- wrapper.vm.handleKeyDown({
- keyCode: ENTER_KEY_CODE,
- preventDefault: fakePreventDefault,
- });
+ it('resets the search text when the Enter key is pressed', async () => {
+ await setCurrentHighlightItem(1);
+ await findSearchBoxByType().vm.$emit('input', 'bug');
+ await findLabelsList().trigger('keydown.enter', { preventDefault: fakePreventDefault });
- expect(wrapper.vm.updateSelectedLabels).toHaveBeenCalledWith([mockLabels[2]]);
+ expect(findSearchBoxByType().props('value')).toBe('');
+ expect(fakePreventDefault).toHaveBeenCalled();
});
- it('calls action `toggleDropdownContents` when Esc key is pressed', () => {
- jest.spyOn(wrapper.vm, 'toggleDropdownContents').mockImplementation();
- // setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
- // eslint-disable-next-line no-restricted-syntax
- wrapper.setData({
- currentHighlightItem: 1,
- });
+ it('calls action `updateSelectedLabels` with currently highlighted label when Enter key is pressed', async () => {
+ await setCurrentHighlightItem(2);
+ await findLabelsList().trigger('keydown.enter', { preventDefault: fakePreventDefault });
+
+ expect(updateSelectedLabelsMock).toHaveBeenCalledWith(expect.anything(), [mockLabels[2]]);
+ });
- wrapper.vm.handleKeyDown({
- keyCode: ESC_KEY_CODE,
- });
+ it('calls action `toggleDropdownContents` when Esc key is pressed', async () => {
+ await setCurrentHighlightItem(1);
+ await findLabelsList().trigger('keydown.esc');
- expect(wrapper.vm.toggleDropdownContents).toHaveBeenCalled();
+ expect(toggleDropdownContentsMock).toHaveBeenCalled();
});
- it('calls action `scrollIntoViewIfNeeded` in next tick when any key is pressed', async () => {
- jest.spyOn(wrapper.vm, 'scrollIntoViewIfNeeded').mockImplementation();
- // setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
- // eslint-disable-next-line no-restricted-syntax
- wrapper.setData({
- currentHighlightItem: 1,
- });
+ it('calls action `scrollIntoViewIfNeeded` in next tick when esc key is pressed', async () => {
+ const containerTop = 500;
+ const labelTop = 0;
- wrapper.vm.handleKeyDown({
- keyCode: DOWN_KEY_CODE,
- });
+ jest
+ .spyOn(findDropdownContent().element, 'getBoundingClientRect')
+ .mockReturnValueOnce({ top: containerTop });
- await nextTick();
- expect(wrapper.vm.scrollIntoViewIfNeeded).toHaveBeenCalled();
+ await setCurrentHighlightItem(1);
+ await findLabelsList().trigger('keydown.esc');
+
+ expect(findDropdownContent().element.scrollTop).toBe(labelTop - containerTop);
});
});
describe('handleLabelClick', () => {
beforeEach(() => {
- jest.spyOn(wrapper.vm, 'updateSelectedLabels').mockImplementation();
+ createComponent(undefined, mountExtended);
+ store.dispatch('receiveLabelsSuccess', mockLabels);
});
it('calls action `updateSelectedLabels` with provided `label` param', () => {
- wrapper.vm.handleLabelClick(mockRegularLabel);
+ findLabelItems().at(0).findComponent(GlLink).vm.$emit('click');
- expect(wrapper.vm.updateSelectedLabels).toHaveBeenCalledWith([mockRegularLabel]);
+ expect(updateSelectedLabelsMock).toHaveBeenCalledWith(expect.anything(), [
+ { ...mockLabels[0], indeterminate: expect.anything(), set: expect.anything() },
+ ]);
});
it('calls action `toggleDropdownContents` when `state.allowMultiselect` is false', () => {
- jest.spyOn(wrapper.vm, 'toggleDropdownContents');
- wrapper.vm.$store.state.allowMultiselect = false;
+ store.state.allowMultiselect = false;
- wrapper.vm.handleLabelClick(mockRegularLabel);
+ findLabelItems().at(0).findComponent(GlLink).vm.$emit('click');
- expect(wrapper.vm.toggleDropdownContents).toHaveBeenCalled();
+ expect(toggleDropdownContentsMock).toHaveBeenCalled();
});
});
});
describe('template', () => {
+ beforeEach(() => {
+ store.dispatch('receiveLabelsSuccess', mockLabels);
+ });
+
it('renders gl-intersection-observer as component root', () => {
expect(wrapper.findComponent(GlIntersectionObserver).exists()).toBe(true);
});
it('renders gl-loading-icon component when `labelsFetchInProgress` prop is true', async () => {
- wrapper.vm.$store.dispatch('requestLabels');
+ store.dispatch('requestLabels');
await nextTick();
const loadingIconEl = findLoadingIcon();
@@ -325,30 +302,19 @@ describe('DropdownContentsLabelsView', () => {
});
it('renders label elements for all labels', () => {
- expect(wrapper.findAllComponents(LabelItem)).toHaveLength(mockLabels.length);
+ expect(findLabelItems()).toHaveLength(mockLabels.length);
});
it('renders label element with `highlight` set to true when value of `currentHighlightItem` is more than -1', async () => {
- // setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
- // eslint-disable-next-line no-restricted-syntax
- wrapper.setData({
- currentHighlightItem: 0,
- });
+ await setCurrentHighlightItem(0);
- await nextTick();
const labelItemEl = findDropdownContent().findComponent(LabelItem);
expect(labelItemEl.attributes('highlight')).toBe('true');
});
it('renders element containing "No matching results" when `searchKey` does not match with any label', async () => {
- // setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
- // eslint-disable-next-line no-restricted-syntax
- wrapper.setData({
- searchKey: 'abc',
- });
-
- await nextTick();
+ await findSearchBoxByType().vm.$emit('input', 'abc');
const noMatchEl = findDropdownContent().find('li');
expect(noMatchEl.isVisible()).toBe(true);
@@ -356,7 +322,7 @@ describe('DropdownContentsLabelsView', () => {
});
it('renders empty content while loading', async () => {
- wrapper.vm.$store.state.labelsFetchInProgress = true;
+ store.state.labelsFetchInProgress = true;
await nextTick();
const dropdownContent = findDropdownContent();
@@ -380,7 +346,7 @@ describe('DropdownContentsLabelsView', () => {
});
it('does not render "Create label" footer link when `state.allowLabelCreate` is `false`', async () => {
- wrapper.vm.$store.state.allowLabelCreate = false;
+ store.state.allowLabelCreate = false;
await nextTick();
const createLabelLink = findDropdownFooter().findAllComponents(GlLink).at(0);