debian-mirror-gitlab/spec/frontend/boards/components/boards_selector_spec.js

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

281 lines
9 KiB
JavaScript
Raw Normal View History

2021-02-22 17:27:13 +05:30
import { GlDropdown, GlLoadingIcon, GlDropdownSectionHeader } from '@gitlab/ui';
2021-12-11 22:18:48 +05:30
import Vue, { nextTick } from 'vue';
import VueApollo from 'vue-apollo';
import Vuex from 'vuex';
2022-07-23 23:45:48 +05:30
import waitForPromises from 'helpers/wait_for_promises';
2020-04-08 14:13:33 +05:30
import { TEST_HOST } from 'spec/test_constants';
import BoardsSelector from '~/boards/components/boards_selector.vue';
2022-04-04 11:22:00 +05:30
import groupBoardsQuery from '~/boards/graphql/group_boards.query.graphql';
import projectBoardsQuery from '~/boards/graphql/project_boards.query.graphql';
import groupRecentBoardsQuery from '~/boards/graphql/group_recent_boards.query.graphql';
import projectRecentBoardsQuery from '~/boards/graphql/project_recent_boards.query.graphql';
2023-05-27 22:25:52 +05:30
import { WORKSPACE_GROUP, WORKSPACE_PROJECT } from '~/issues/constants';
2021-12-11 22:18:48 +05:30
import createMockApollo from 'helpers/mock_apollo_helper';
2022-06-21 17:19:12 +05:30
import { mountExtended } from 'helpers/vue_test_utils_helper';
2022-04-04 11:22:00 +05:30
import {
2022-07-23 23:45:48 +05:30
mockBoard,
2022-04-04 11:22:00 +05:30
mockGroupAllBoardsResponse,
mockProjectAllBoardsResponse,
mockGroupRecentBoardsResponse,
mockProjectRecentBoardsResponse,
mockSmallProjectAllBoardsResponse,
mockEmptyProjectRecentBoardsResponse,
boards,
recentIssueBoards,
} from '../mock_data';
2020-04-08 14:13:33 +05:30
const throttleDuration = 1;
2021-12-11 22:18:48 +05:30
Vue.use(VueApollo);
2023-03-17 16:20:25 +05:30
Vue.use(Vuex);
2021-12-11 22:18:48 +05:30
2020-04-08 14:13:33 +05:30
describe('BoardsSelector', () => {
let wrapper;
2021-12-11 22:18:48 +05:30
let fakeApollo;
let store;
2020-04-08 14:13:33 +05:30
2023-03-17 16:20:25 +05:30
const createStore = () => {
2021-12-11 22:18:48 +05:30
store = new Vuex.Store({
actions: {
setError: jest.fn(),
2022-05-07 20:08:51 +05:30
setBoardConfig: jest.fn(),
2021-12-11 22:18:48 +05:30
},
state: {
2022-07-23 23:45:48 +05:30
board: mockBoard,
2021-12-11 22:18:48 +05:30
},
});
};
2021-03-08 18:12:59 +05:30
const fillSearchBox = (filterTerm) => {
2022-08-27 11:52:29 +05:30
const searchBox = wrapper.findComponent({ ref: 'searchBox' });
2020-04-08 14:13:33 +05:30
const searchBoxInput = searchBox.find('input');
searchBoxInput.setValue(filterTerm);
searchBoxInput.trigger('input');
};
2022-06-21 17:19:12 +05:30
const getDropdownItems = () => wrapper.findAllByTestId('dropdown-item');
2022-04-04 11:22:00 +05:30
const getDropdownHeaders = () => wrapper.findAllComponents(GlDropdownSectionHeader);
const getLoadingIcon = () => wrapper.findComponent(GlLoadingIcon);
const findDropdown = () => wrapper.findComponent(GlDropdown);
2020-04-08 14:13:33 +05:30
2022-04-04 11:22:00 +05:30
const projectBoardsQueryHandlerSuccess = jest
.fn()
.mockResolvedValue(mockProjectAllBoardsResponse);
const groupBoardsQueryHandlerSuccess = jest.fn().mockResolvedValue(mockGroupAllBoardsResponse);
const projectRecentBoardsQueryHandlerSuccess = jest
.fn()
.mockResolvedValue(mockProjectRecentBoardsResponse);
const groupRecentBoardsQueryHandlerSuccess = jest
.fn()
.mockResolvedValue(mockGroupRecentBoardsResponse);
const smallBoardsQueryHandlerSuccess = jest
.fn()
.mockResolvedValue(mockSmallProjectAllBoardsResponse);
const emptyRecentBoardsQueryHandlerSuccess = jest
.fn()
.mockResolvedValue(mockEmptyProjectRecentBoardsResponse);
const createComponent = ({
projectBoardsQueryHandler = projectBoardsQueryHandlerSuccess,
projectRecentBoardsQueryHandler = projectRecentBoardsQueryHandlerSuccess,
2023-03-17 16:20:25 +05:30
isGroupBoard = false,
isProjectBoard = false,
2023-04-23 21:23:45 +05:30
provide = {},
2022-04-04 11:22:00 +05:30
} = {}) => {
2021-12-11 22:18:48 +05:30
fakeApollo = createMockApollo([
2022-04-04 11:22:00 +05:30
[projectBoardsQuery, projectBoardsQueryHandler],
[groupBoardsQuery, groupBoardsQueryHandlerSuccess],
[projectRecentBoardsQuery, projectRecentBoardsQueryHandler],
[groupRecentBoardsQuery, groupRecentBoardsQueryHandlerSuccess],
2021-12-11 22:18:48 +05:30
]);
2020-04-08 14:13:33 +05:30
2022-06-21 17:19:12 +05:30
wrapper = mountExtended(BoardsSelector, {
2021-12-11 22:18:48 +05:30
store,
apolloProvider: fakeApollo,
2020-04-08 14:13:33 +05:30
propsData: {
throttleDuration,
2022-06-21 17:19:12 +05:30
},
attachTo: document.body,
provide: {
fullPath: '',
2020-04-08 14:13:33 +05:30
boardBaseUrl: `${TEST_HOST}/board/base/url`,
hasMissingBoards: false,
canAdminBoard: true,
multipleIssueBoardsAvailable: true,
scopedIssueBoardFeatureEnabled: true,
weights: [],
2023-03-17 16:20:25 +05:30
boardType: isGroupBoard ? 'group' : 'project',
isGroupBoard,
isProjectBoard,
2023-04-23 21:23:45 +05:30
isApolloBoard: false,
...provide,
2020-04-08 14:13:33 +05:30
},
});
2021-12-11 22:18:48 +05:30
};
2020-04-08 14:13:33 +05:30
afterEach(() => {
2022-04-04 11:22:00 +05:30
fakeApollo = null;
2020-04-08 14:13:33 +05:30
});
2022-04-04 11:22:00 +05:30
describe('template', () => {
2021-12-11 22:18:48 +05:30
beforeEach(() => {
2023-03-17 16:20:25 +05:30
createStore();
createComponent({ isProjectBoard: true });
2020-04-08 14:13:33 +05:30
});
2021-12-11 22:18:48 +05:30
describe('loading', () => {
// we are testing loading state, so don't resolve responses until after the tests
afterEach(async () => {
2022-07-23 23:45:48 +05:30
await waitForPromises();
2021-02-22 17:27:13 +05:30
});
2020-04-08 14:13:33 +05:30
2022-07-23 23:45:48 +05:30
it('shows loading spinner', async () => {
2022-04-04 11:22:00 +05:30
// Emits gl-dropdown show event to simulate the dropdown is opened at initialization time
findDropdown().vm.$emit('show');
2022-07-23 23:45:48 +05:30
await nextTick();
2022-04-04 11:22:00 +05:30
expect(getLoadingIcon().exists()).toBe(true);
2021-12-11 22:18:48 +05:30
expect(getDropdownHeaders()).toHaveLength(0);
expect(getDropdownItems()).toHaveLength(0);
});
2020-04-08 14:13:33 +05:30
});
2021-12-11 22:18:48 +05:30
describe('loaded', () => {
beforeEach(async () => {
// Wait for current board to be loaded
await nextTick();
// Emits gl-dropdown show event to simulate the dropdown is opened at initialization time
findDropdown().vm.$emit('show');
2020-04-08 14:13:33 +05:30
2021-12-11 22:18:48 +05:30
await nextTick();
2020-04-08 14:13:33 +05:30
});
2022-04-04 11:22:00 +05:30
it('fetches all issue boards', () => {
expect(projectBoardsQueryHandlerSuccess).toHaveBeenCalled();
});
2021-12-11 22:18:48 +05:30
it('hides loading spinner', async () => {
await nextTick();
expect(getLoadingIcon().exists()).toBe(false);
2020-04-08 14:13:33 +05:30
});
2021-12-11 22:18:48 +05:30
describe('filtering', () => {
beforeEach(async () => {
await nextTick();
});
2020-04-08 14:13:33 +05:30
2021-12-11 22:18:48 +05:30
it('shows all boards without filtering', () => {
2022-04-04 11:22:00 +05:30
expect(getDropdownItems()).toHaveLength(boards.length + recentIssueBoards.length);
2021-12-11 22:18:48 +05:30
});
2020-04-08 14:13:33 +05:30
2021-12-11 22:18:48 +05:30
it('shows only matching boards when filtering', async () => {
const filterTerm = 'board1';
2022-04-04 11:22:00 +05:30
const expectedCount = boards.filter((board) => board.node.name.includes(filterTerm))
.length;
2021-12-11 22:18:48 +05:30
fillSearchBox(filterTerm);
await nextTick();
2020-04-08 14:13:33 +05:30
expect(getDropdownItems()).toHaveLength(expectedCount);
});
2021-12-11 22:18:48 +05:30
it('shows message if there are no matching boards', async () => {
fillSearchBox('does not exist');
2020-04-08 14:13:33 +05:30
2021-12-11 22:18:48 +05:30
await nextTick();
2020-04-08 14:13:33 +05:30
expect(getDropdownItems()).toHaveLength(0);
expect(wrapper.text().includes('No matching boards found')).toBe(true);
});
});
2021-12-11 22:18:48 +05:30
describe('recent boards section', () => {
it('shows only when boards are greater than 10', async () => {
await nextTick();
2022-04-04 11:22:00 +05:30
expect(projectRecentBoardsQueryHandlerSuccess).toHaveBeenCalled();
2020-04-08 14:13:33 +05:30
expect(getDropdownHeaders()).toHaveLength(2);
});
2021-12-11 22:18:48 +05:30
it('does not show when boards are less than 10', async () => {
2022-04-04 11:22:00 +05:30
createComponent({ projectBoardsQueryHandler: smallBoardsQueryHandlerSuccess });
2020-04-08 14:13:33 +05:30
2021-12-11 22:18:48 +05:30
await nextTick();
2020-04-08 14:13:33 +05:30
expect(getDropdownHeaders()).toHaveLength(0);
});
2022-04-04 11:22:00 +05:30
it('does not show when recentIssueBoards api returns empty array', async () => {
createComponent({
projectRecentBoardsQueryHandler: emptyRecentBoardsQueryHandlerSuccess,
2021-12-11 22:18:48 +05:30
});
2020-04-08 14:13:33 +05:30
2021-12-11 22:18:48 +05:30
await nextTick();
2020-04-08 14:13:33 +05:30
expect(getDropdownHeaders()).toHaveLength(0);
});
2021-12-11 22:18:48 +05:30
it('does not show when search is active', async () => {
fillSearchBox('Random string');
2020-04-08 14:13:33 +05:30
2021-12-11 22:18:48 +05:30
await nextTick();
2020-04-08 14:13:33 +05:30
expect(getDropdownHeaders()).toHaveLength(0);
});
});
});
});
2021-12-11 22:18:48 +05:30
2022-04-04 11:22:00 +05:30
describe('fetching all boards', () => {
it.each`
boardType | queryHandler | notCalledHandler
2023-05-27 22:25:52 +05:30
${WORKSPACE_GROUP} | ${groupBoardsQueryHandlerSuccess} | ${projectBoardsQueryHandlerSuccess}
${WORKSPACE_PROJECT} | ${projectBoardsQueryHandlerSuccess} | ${groupBoardsQueryHandlerSuccess}
2022-04-04 11:22:00 +05:30
`('fetches $boardType boards', async ({ boardType, queryHandler, notCalledHandler }) => {
2023-03-17 16:20:25 +05:30
createStore();
createComponent({
2023-05-27 22:25:52 +05:30
isGroupBoard: boardType === WORKSPACE_GROUP,
isProjectBoard: boardType === WORKSPACE_PROJECT,
2022-04-04 11:22:00 +05:30
});
await nextTick();
// Emits gl-dropdown show event to simulate the dropdown is opened at initialization time
findDropdown().vm.$emit('show');
await nextTick();
expect(queryHandler).toHaveBeenCalled();
expect(notCalledHandler).not.toHaveBeenCalled();
});
});
2023-04-23 21:23:45 +05:30
describe('dropdown visibility', () => {
describe('when multipleIssueBoardsAvailable is enabled', () => {
2023-06-20 00:43:36 +05:30
it('show dropdown', () => {
2023-04-23 21:23:45 +05:30
createStore();
createComponent({ provide: { multipleIssueBoardsAvailable: true } });
expect(findDropdown().exists()).toBe(true);
});
});
describe('when multipleIssueBoardsAvailable is disabled but it hasMissingBoards', () => {
2023-06-20 00:43:36 +05:30
it('show dropdown', () => {
2023-04-23 21:23:45 +05:30
createStore();
createComponent({
provide: { multipleIssueBoardsAvailable: false, hasMissingBoards: true },
});
expect(findDropdown().exists()).toBe(true);
});
});
describe("when multipleIssueBoardsAvailable is disabled and it dosn't hasMissingBoards", () => {
2023-06-20 00:43:36 +05:30
it('hide dropdown', () => {
2023-04-23 21:23:45 +05:30
createStore();
createComponent({
provide: { multipleIssueBoardsAvailable: false, hasMissingBoards: false },
});
expect(findDropdown().exists()).toBe(false);
});
});
});
2020-04-08 14:13:33 +05:30
});