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:
Diffstat (limited to 'spec/frontend/milestones/milestone_combobox_spec.js')
-rw-r--r--spec/frontend/milestones/milestone_combobox_spec.js512
1 files changed, 0 insertions, 512 deletions
diff --git a/spec/frontend/milestones/milestone_combobox_spec.js b/spec/frontend/milestones/milestone_combobox_spec.js
deleted file mode 100644
index 4d1a0a0a440..00000000000
--- a/spec/frontend/milestones/milestone_combobox_spec.js
+++ /dev/null
@@ -1,512 +0,0 @@
-import { GlLoadingIcon, GlSearchBoxByType, GlDropdownItem } from '@gitlab/ui';
-import { mount } from '@vue/test-utils';
-import axios from 'axios';
-import MockAdapter from 'axios-mock-adapter';
-import Vue, { nextTick } from 'vue';
-import Vuex from 'vuex';
-import { ENTER_KEY } from '~/lib/utils/keys';
-import MilestoneCombobox from '~/milestones/components/milestone_combobox.vue';
-import createStore from '~/milestones/stores/';
-import { projectMilestones, groupMilestones } from './mock_data';
-
-const extraLinks = [
- { text: 'Create new', url: 'http://127.0.0.1:3000/h5bp/html5-boilerplate/-/milestones/new' },
- { text: 'Manage milestones', url: '/h5bp/html5-boilerplate/-/milestones' },
-];
-
-Vue.use(Vuex);
-
-describe('Milestone combobox component', () => {
- const projectId = '8';
- const groupId = '24';
- const groupMilestonesAvailable = true;
- const X_TOTAL_HEADER = 'x-total';
-
- let wrapper;
- let projectMilestonesApiCallSpy;
- let groupMilestonesApiCallSpy;
- let searchApiCallSpy;
-
- const createComponent = (props = {}, attrs = {}) => {
- const propsData = {
- projectId,
- groupId,
- groupMilestonesAvailable,
- extraLinks,
- value: [],
- ...props,
- };
-
- wrapper = mount(MilestoneCombobox, {
- propsData,
- attrs,
- listeners: {
- // simulate a parent component v-model binding
- input: (selectedMilestone) => {
- // ugly hack because setProps plays bad with immediate watchers
- // see https://github.com/vuejs/vue-test-utils/issues/1140 and
- // https://github.com/vuejs/vue-test-utils/pull/1752
- propsData.value = selectedMilestone;
- wrapper.setProps({ value: selectedMilestone });
- },
- },
- stubs: {
- GlSearchBoxByType: true,
- },
- store: createStore(),
- });
- };
-
- beforeEach(() => {
- const mock = new MockAdapter(axios);
- gon.api_version = 'v4';
-
- projectMilestonesApiCallSpy = jest
- .fn()
- .mockReturnValue([200, projectMilestones, { [X_TOTAL_HEADER]: '6' }]);
-
- groupMilestonesApiCallSpy = jest
- .fn()
- .mockReturnValue([200, groupMilestones, { [X_TOTAL_HEADER]: '6' }]);
-
- searchApiCallSpy = jest
- .fn()
- .mockReturnValue([200, projectMilestones, { [X_TOTAL_HEADER]: '6' }]);
-
- mock
- .onGet(`/api/v4/projects/${projectId}/milestones`)
- .reply((config) => projectMilestonesApiCallSpy(config));
-
- mock
- .onGet(`/api/v4/groups/${groupId}/milestones`)
- .reply((config) => groupMilestonesApiCallSpy(config));
-
- mock.onGet(`/api/v4/projects/${projectId}/search`).reply((config) => searchApiCallSpy(config));
- });
-
- afterEach(() => {
- wrapper.destroy();
- wrapper = null;
- });
-
- //
- // Finders
- //
- const findButtonContent = () => wrapper.find('[data-testid="milestone-combobox-button-content"]');
-
- const findNoResults = () => wrapper.find('[data-testid="milestone-combobox-no-results"]');
-
- const findLoadingIcon = () => wrapper.find(GlLoadingIcon);
-
- const findSearchBox = () => wrapper.find(GlSearchBoxByType);
-
- const findProjectMilestonesSection = () =>
- wrapper.find('[data-testid="project-milestones-section"]');
- const findProjectMilestonesDropdownItems = () =>
- findProjectMilestonesSection().findAll(GlDropdownItem);
- const findFirstProjectMilestonesDropdownItem = () => findProjectMilestonesDropdownItems().at(0);
-
- const findGroupMilestonesSection = () => wrapper.find('[data-testid="group-milestones-section"]');
- const findGroupMilestonesDropdownItems = () =>
- findGroupMilestonesSection().findAll(GlDropdownItem);
- const findFirstGroupMilestonesDropdownItem = () => findGroupMilestonesDropdownItems().at(0);
-
- //
- // Expecters
- //
- const projectMilestoneSectionContainsErrorMessage = () => {
- const projectMilestoneSection = findProjectMilestonesSection();
-
- return projectMilestoneSection
- .text()
- .includes('An error occurred while searching for milestones');
- };
-
- const groupMilestoneSectionContainsErrorMessage = () => {
- const groupMilestoneSection = findGroupMilestonesSection();
-
- return groupMilestoneSection
- .text()
- .includes('An error occurred while searching for milestones');
- };
-
- //
- // Convenience methods
- //
- const updateQuery = (newQuery) => {
- findSearchBox().vm.$emit('input', newQuery);
- };
-
- const selectFirstProjectMilestone = () => {
- findFirstProjectMilestonesDropdownItem().vm.$emit('click');
- };
-
- const selectFirstGroupMilestone = () => {
- findFirstGroupMilestonesDropdownItem().vm.$emit('click');
- };
-
- const waitForRequests = async ({ andClearMocks } = { andClearMocks: false }) => {
- await axios.waitForAll();
- if (andClearMocks) {
- projectMilestonesApiCallSpy.mockClear();
- groupMilestonesApiCallSpy.mockClear();
- }
- };
-
- describe('initialization behavior', () => {
- beforeEach(createComponent);
-
- it('initializes the dropdown with milestones when mounted', () => {
- return waitForRequests().then(() => {
- expect(projectMilestonesApiCallSpy).toHaveBeenCalledTimes(1);
- expect(groupMilestonesApiCallSpy).toHaveBeenCalledTimes(1);
- });
- });
-
- it('shows a spinner while network requests are in progress', () => {
- expect(findLoadingIcon().exists()).toBe(true);
-
- return waitForRequests().then(() => {
- expect(findLoadingIcon().exists()).toBe(false);
- });
- });
-
- it('shows additional links', () => {
- const links = wrapper.findAll('[data-testid="milestone-combobox-extra-links"]');
- links.wrappers.forEach((item, idx) => {
- expect(item.text()).toBe(extraLinks[idx].text);
- expect(item.attributes('href')).toBe(extraLinks[idx].url);
- });
- });
- });
-
- describe('post-initialization behavior', () => {
- describe('when the parent component provides an `id` binding', () => {
- const id = '8';
-
- beforeEach(() => {
- createComponent({}, { id });
-
- return waitForRequests();
- });
-
- it('adds the provided ID to the GlDropdown instance', () => {
- expect(wrapper.attributes().id).toBe(id);
- });
- });
-
- describe('when milestones are pre-selected', () => {
- beforeEach(() => {
- createComponent({ value: projectMilestones });
-
- return waitForRequests();
- });
-
- it('renders the pre-selected milestones', () => {
- expect(findButtonContent().text()).toBe('v0.1 + 5 more');
- });
- });
-
- describe('when the search query is updated', () => {
- beforeEach(() => {
- createComponent();
-
- return waitForRequests({ andClearMocks: true });
- });
-
- it('requeries the search when the search query is updated', () => {
- updateQuery('v1.2.3');
-
- return waitForRequests().then(() => {
- expect(searchApiCallSpy).toHaveBeenCalledTimes(1);
- });
- });
- });
-
- describe('when the Enter is pressed', () => {
- beforeEach(() => {
- createComponent();
-
- return waitForRequests({ andClearMocks: true });
- });
-
- it('requeries the search when Enter is pressed', () => {
- findSearchBox().vm.$emit('keydown', new KeyboardEvent({ key: ENTER_KEY }));
-
- return waitForRequests().then(() => {
- expect(searchApiCallSpy).toHaveBeenCalledTimes(1);
- });
- });
- });
-
- describe('when no results are found', () => {
- beforeEach(() => {
- projectMilestonesApiCallSpy = jest
- .fn()
- .mockReturnValue([200, [], { [X_TOTAL_HEADER]: '0' }]);
-
- groupMilestonesApiCallSpy = jest.fn().mockReturnValue([200, [], { [X_TOTAL_HEADER]: '0' }]);
-
- createComponent();
-
- return waitForRequests();
- });
-
- describe('when the search query is empty', () => {
- it('renders a "no results" message', () => {
- expect(findNoResults().text()).toBe('No matching results');
- });
- });
- });
-
- describe('project milestones', () => {
- describe('when the project milestones search returns results', () => {
- beforeEach(() => {
- createComponent();
-
- return waitForRequests();
- });
-
- it('renders the project milestones section in the dropdown', () => {
- expect(findProjectMilestonesSection().exists()).toBe(true);
- });
-
- it('renders the "Project milestones" heading with a total number indicator', () => {
- expect(
- findProjectMilestonesSection()
- .find('[data-testid="milestone-results-section-header"]')
- .text(),
- ).toBe('Project milestones 6');
- });
-
- it("does not render an error message in the project milestone section's body", () => {
- expect(projectMilestoneSectionContainsErrorMessage()).toBe(false);
- });
-
- it('renders each project milestones as a selectable item', () => {
- const dropdownItems = findProjectMilestonesDropdownItems();
-
- projectMilestones.forEach((milestone, i) => {
- expect(dropdownItems.at(i).text()).toBe(milestone.title);
- });
- });
- });
-
- describe('when the project milestones search returns no results', () => {
- beforeEach(() => {
- projectMilestonesApiCallSpy = jest
- .fn()
- .mockReturnValue([200, [], { [X_TOTAL_HEADER]: '0' }]);
-
- createComponent();
-
- return waitForRequests();
- });
-
- it('does not render the project milestones section in the dropdown', () => {
- expect(findProjectMilestonesSection().exists()).toBe(false);
- });
- });
-
- describe('when the project milestones search returns an error', () => {
- beforeEach(() => {
- projectMilestonesApiCallSpy = jest.fn().mockReturnValue([500]);
- searchApiCallSpy = jest.fn().mockReturnValue([500]);
-
- createComponent({ value: [] });
-
- return waitForRequests();
- });
-
- it('renders the project milestones section in the dropdown', () => {
- expect(findProjectMilestonesSection().exists()).toBe(true);
- });
-
- it("renders an error message in the project milestones section's body", () => {
- expect(projectMilestoneSectionContainsErrorMessage()).toBe(true);
- });
- });
-
- describe('selection', () => {
- beforeEach(() => {
- createComponent();
-
- return waitForRequests();
- });
-
- it('renders a checkmark by the selected item', async () => {
- selectFirstProjectMilestone();
-
- await nextTick();
-
- expect(
- findFirstProjectMilestonesDropdownItem().find('span').classes('selected-item'),
- ).toBe(true);
-
- selectFirstProjectMilestone();
-
- await nextTick();
-
- expect(
- findFirstProjectMilestonesDropdownItem().find('span').classes('selected-item'),
- ).toBe(false);
- });
-
- describe('when a project milestones is selected', () => {
- beforeEach(() => {
- createComponent();
- projectMilestonesApiCallSpy = jest
- .fn()
- .mockReturnValue([200, [{ title: 'v1.0' }], { [X_TOTAL_HEADER]: '1' }]);
-
- return waitForRequests();
- });
-
- it("displays the project milestones name in the dropdown's button", async () => {
- selectFirstProjectMilestone();
- await nextTick();
-
- expect(findButtonContent().text()).toBe('v1.0');
-
- selectFirstProjectMilestone();
- await nextTick();
-
- expect(findButtonContent().text()).toBe('No milestone');
- });
-
- it('updates the v-model binding with the project milestone title', async () => {
- selectFirstProjectMilestone();
- await nextTick();
-
- expect(wrapper.emitted().input[0][0]).toStrictEqual(['v1.0']);
- });
- });
- });
- });
-
- describe('group milestones', () => {
- describe('when the group milestones search returns results', () => {
- beforeEach(() => {
- createComponent();
-
- return waitForRequests();
- });
-
- it('renders the group milestones section in the dropdown', () => {
- expect(findGroupMilestonesSection().exists()).toBe(true);
- });
-
- it('renders the "Group milestones" heading with a total number indicator', () => {
- expect(
- findGroupMilestonesSection()
- .find('[data-testid="milestone-results-section-header"]')
- .text(),
- ).toBe('Group milestones 6');
- });
-
- it("does not render an error message in the group milestone section's body", () => {
- expect(groupMilestoneSectionContainsErrorMessage()).toBe(false);
- });
-
- it('renders each group milestones as a selectable item', () => {
- const dropdownItems = findGroupMilestonesDropdownItems();
-
- groupMilestones.forEach((milestone, i) => {
- expect(dropdownItems.at(i).text()).toBe(milestone.title);
- });
- });
- });
-
- describe('when the group milestones search returns no results', () => {
- beforeEach(() => {
- groupMilestonesApiCallSpy = jest
- .fn()
- .mockReturnValue([200, [], { [X_TOTAL_HEADER]: '0' }]);
-
- createComponent();
-
- return waitForRequests();
- });
-
- it('does not render the group milestones section in the dropdown', () => {
- expect(findGroupMilestonesSection().exists()).toBe(false);
- });
- });
-
- describe('when the group milestones search returns an error', () => {
- beforeEach(() => {
- groupMilestonesApiCallSpy = jest.fn().mockReturnValue([500]);
- searchApiCallSpy = jest.fn().mockReturnValue([500]);
-
- createComponent({ value: [] });
-
- return waitForRequests();
- });
-
- it('renders the group milestones section in the dropdown', () => {
- expect(findGroupMilestonesSection().exists()).toBe(true);
- });
-
- it("renders an error message in the group milestones section's body", () => {
- expect(groupMilestoneSectionContainsErrorMessage()).toBe(true);
- });
- });
-
- describe('selection', () => {
- beforeEach(() => {
- createComponent();
-
- return waitForRequests();
- });
-
- it('renders a checkmark by the selected item', async () => {
- selectFirstGroupMilestone();
-
- await nextTick();
-
- expect(findFirstGroupMilestonesDropdownItem().find('span').classes('selected-item')).toBe(
- true,
- );
-
- selectFirstGroupMilestone();
-
- await nextTick();
-
- expect(findFirstGroupMilestonesDropdownItem().find('span').classes('selected-item')).toBe(
- false,
- );
- });
-
- describe('when a group milestones is selected', () => {
- beforeEach(() => {
- createComponent();
- groupMilestonesApiCallSpy = jest
- .fn()
- .mockReturnValue([200, [{ title: 'group-v1.0' }], { [X_TOTAL_HEADER]: '1' }]);
-
- return waitForRequests();
- });
-
- it("displays the group milestones name in the dropdown's button", async () => {
- selectFirstGroupMilestone();
- await nextTick();
-
- expect(findButtonContent().text()).toBe('group-v1.0');
-
- selectFirstGroupMilestone();
- await nextTick();
-
- expect(findButtonContent().text()).toBe('No milestone');
- });
-
- it('updates the v-model binding with the group milestone title', async () => {
- selectFirstGroupMilestone();
- await nextTick();
-
- expect(wrapper.emitted().input[0][0]).toStrictEqual(['group-v1.0']);
- });
- });
- });
- });
- });
-});