gitlab-org--gitlab-foss/spec/frontend/boards/components/board_card_spec.js

184 lines
4.8 KiB
JavaScript

import { GlLabel } from '@gitlab/ui';
import { shallowMount, mount } from '@vue/test-utils';
import Vue, { nextTick } from 'vue';
import Vuex from 'vuex';
import BoardCard from '~/boards/components/board_card.vue';
import BoardCardInner from '~/boards/components/board_card_inner.vue';
import { inactiveId } from '~/boards/constants';
import { mockLabelList, mockIssue } from '../mock_data';
describe('Board card', () => {
let wrapper;
let store;
let mockActions;
Vue.use(Vuex);
const createStore = ({ initialState = {} } = {}) => {
mockActions = {
toggleBoardItem: jest.fn(),
toggleBoardItemMultiSelection: jest.fn(),
performSearch: jest.fn(),
};
store = new Vuex.Store({
state: {
activeId: inactiveId,
selectedBoardItems: [],
...initialState,
},
actions: mockActions,
getters: {
isEpicBoard: () => false,
isProjectBoard: () => false,
},
});
};
// this particular mount component needs to be used after the root beforeEach because it depends on list being initialized
const mountComponent = ({
propsData = {},
provide = {},
mountFn = shallowMount,
stubs = { BoardCardInner },
item = mockIssue,
} = {}) => {
wrapper = mountFn(BoardCard, {
stubs,
store,
propsData: {
list: mockLabelList,
item,
disabled: false,
index: 0,
...propsData,
},
provide: {
groupId: null,
rootPath: '/',
scopedLabelsAvailable: false,
...provide,
},
});
};
const selectCard = async () => {
wrapper.trigger('click');
await nextTick();
};
const multiSelectCard = async () => {
wrapper.trigger('click', { ctrlKey: true });
await nextTick();
};
beforeEach(() => {
window.gon = { features: {} };
});
afterEach(() => {
wrapper.destroy();
wrapper = null;
store = null;
});
describe('when GlLabel is clicked in BoardCardInner', () => {
it('doesnt call toggleBoardItem', () => {
createStore({ initialState: { isShowingLabels: true } });
mountComponent({ mountFn: mount, stubs: {} });
wrapper.find(GlLabel).trigger('mouseup');
expect(mockActions.toggleBoardItem).toHaveBeenCalledTimes(0);
});
});
it('should not highlight the card by default', async () => {
createStore();
mountComponent();
expect(wrapper.classes()).not.toContain('is-active');
expect(wrapper.classes()).not.toContain('multi-select');
});
it('should highlight the card with a correct style when selected', async () => {
createStore({
initialState: {
activeId: mockIssue.id,
},
});
mountComponent();
expect(wrapper.classes()).toContain('is-active');
expect(wrapper.classes()).not.toContain('multi-select');
});
it('should highlight the card with a correct style when multi-selected', async () => {
createStore({
initialState: {
activeId: inactiveId,
selectedBoardItems: [mockIssue],
},
});
mountComponent();
expect(wrapper.classes()).toContain('multi-select');
expect(wrapper.classes()).not.toContain('is-active');
});
describe('when mouseup event is called on the card', () => {
beforeEach(() => {
createStore();
mountComponent();
});
describe('when not using multi-select', () => {
it('should call vuex action "toggleBoardItem" with correct parameters', async () => {
await selectCard();
expect(mockActions.toggleBoardItem).toHaveBeenCalledTimes(1);
expect(mockActions.toggleBoardItem).toHaveBeenCalledWith(expect.any(Object), {
boardItem: mockIssue,
});
});
});
describe('when using multi-select', () => {
beforeEach(() => {
window.gon = { features: { boardMultiSelect: true } };
});
it('should call vuex action "multiSelectBoardItem" with correct parameters', async () => {
await multiSelectCard();
expect(mockActions.toggleBoardItemMultiSelection).toHaveBeenCalledTimes(1);
expect(mockActions.toggleBoardItemMultiSelection).toHaveBeenCalledWith(
expect.any(Object),
mockIssue,
);
});
});
});
describe('when card is loading', () => {
it('card is disabled and user cannot drag', () => {
createStore();
mountComponent({ item: { ...mockIssue, isLoading: true } });
expect(wrapper.classes()).toContain('is-disabled');
expect(wrapper.classes()).not.toContain('gl-cursor-grab');
});
});
describe('when card is not loading', () => {
it('user can drag', () => {
createStore();
mountComponent();
expect(wrapper.classes()).not.toContain('is-disabled');
expect(wrapper.classes()).toContain('gl-cursor-grab');
});
});
});