206 lines
5.5 KiB
JavaScript
206 lines
5.5 KiB
JavaScript
|
import Vue from 'vue';
|
||
|
import BoardService from '~/boards/services/board_service';
|
||
|
import BoardsSelector from '~/boards/components/boards_selector.vue';
|
||
|
import mountComponent from 'spec/helpers/vue_mount_component_helper';
|
||
|
import { TEST_HOST } from 'spec/test_constants';
|
||
|
import boardsStore from '~/boards/stores/boards_store';
|
||
|
|
||
|
const throttleDuration = 1;
|
||
|
|
||
|
function boardGenerator(n) {
|
||
|
return new Array(n).fill().map((board, id) => {
|
||
|
const name = `board${id}`;
|
||
|
|
||
|
return {
|
||
|
id,
|
||
|
name,
|
||
|
};
|
||
|
});
|
||
|
}
|
||
|
|
||
|
describe('BoardsSelector', () => {
|
||
|
let vm;
|
||
|
let allBoardsResponse;
|
||
|
let recentBoardsResponse;
|
||
|
let fillSearchBox;
|
||
|
const boards = boardGenerator(20);
|
||
|
const recentBoards = boardGenerator(5);
|
||
|
|
||
|
beforeEach(done => {
|
||
|
setFixtures('<div class="js-boards-selector"></div>');
|
||
|
window.gl = window.gl || {};
|
||
|
|
||
|
boardsStore.setEndpoints({
|
||
|
boardsEndpoint: '',
|
||
|
recentBoardsEndpoint: '',
|
||
|
listsEndpoint: '',
|
||
|
bulkUpdatePath: '',
|
||
|
boardId: '',
|
||
|
});
|
||
|
window.gl.boardService = new BoardService();
|
||
|
|
||
|
allBoardsResponse = Promise.resolve({
|
||
|
data: boards,
|
||
|
});
|
||
|
recentBoardsResponse = Promise.resolve({
|
||
|
data: recentBoards,
|
||
|
});
|
||
|
|
||
|
spyOn(BoardService.prototype, 'allBoards').and.returnValue(allBoardsResponse);
|
||
|
spyOn(BoardService.prototype, 'recentBoards').and.returnValue(recentBoardsResponse);
|
||
|
|
||
|
const Component = Vue.extend(BoardsSelector);
|
||
|
vm = mountComponent(
|
||
|
Component,
|
||
|
{
|
||
|
throttleDuration,
|
||
|
currentBoard: {
|
||
|
id: 1,
|
||
|
name: 'Development',
|
||
|
milestone_id: null,
|
||
|
weight: null,
|
||
|
assignee_id: null,
|
||
|
labels: [],
|
||
|
},
|
||
|
milestonePath: `${TEST_HOST}/milestone/path`,
|
||
|
boardBaseUrl: `${TEST_HOST}/board/base/url`,
|
||
|
hasMissingBoards: false,
|
||
|
canAdminBoard: true,
|
||
|
multipleIssueBoardsAvailable: true,
|
||
|
labelsPath: `${TEST_HOST}/labels/path`,
|
||
|
projectId: 42,
|
||
|
groupId: 19,
|
||
|
scopedIssueBoardFeatureEnabled: true,
|
||
|
weights: [],
|
||
|
},
|
||
|
document.querySelector('.js-boards-selector'),
|
||
|
);
|
||
|
|
||
|
vm.$el.querySelector('.js-dropdown-toggle').click();
|
||
|
|
||
|
Promise.all([allBoardsResponse, recentBoardsResponse])
|
||
|
.then(() => vm.$nextTick())
|
||
|
.then(done)
|
||
|
.catch(done.fail);
|
||
|
|
||
|
fillSearchBox = filterTerm => {
|
||
|
const { searchBox } = vm.$refs;
|
||
|
const searchBoxInput = searchBox.$el.querySelector('input');
|
||
|
searchBoxInput.value = filterTerm;
|
||
|
searchBoxInput.dispatchEvent(new Event('input'));
|
||
|
};
|
||
|
});
|
||
|
|
||
|
afterEach(() => {
|
||
|
vm.$destroy();
|
||
|
window.gl.boardService = undefined;
|
||
|
});
|
||
|
|
||
|
describe('filtering', () => {
|
||
|
it('shows all boards without filtering', done => {
|
||
|
vm.$nextTick()
|
||
|
.then(() => {
|
||
|
const dropdownItem = vm.$el.querySelectorAll('.js-dropdown-item');
|
||
|
|
||
|
expect(dropdownItem.length).toBe(boards.length + recentBoards.length);
|
||
|
})
|
||
|
.then(done)
|
||
|
.catch(done.fail);
|
||
|
});
|
||
|
|
||
|
it('shows only matching boards when filtering', done => {
|
||
|
const filterTerm = 'board1';
|
||
|
const expectedCount = boards.filter(board => board.name.includes(filterTerm)).length;
|
||
|
|
||
|
fillSearchBox(filterTerm);
|
||
|
|
||
|
vm.$nextTick()
|
||
|
.then(() => {
|
||
|
const dropdownItems = vm.$el.querySelectorAll('.js-dropdown-item');
|
||
|
|
||
|
expect(dropdownItems.length).toBe(expectedCount);
|
||
|
})
|
||
|
.then(done)
|
||
|
.catch(done.fail);
|
||
|
});
|
||
|
|
||
|
it('shows message if there are no matching boards', done => {
|
||
|
fillSearchBox('does not exist');
|
||
|
|
||
|
vm.$nextTick()
|
||
|
.then(() => {
|
||
|
const dropdownItems = vm.$el.querySelectorAll('.js-dropdown-item');
|
||
|
|
||
|
expect(dropdownItems.length).toBe(0);
|
||
|
expect(vm.$el).toContainText('No matching boards found');
|
||
|
})
|
||
|
.then(done)
|
||
|
.catch(done.fail);
|
||
|
});
|
||
|
});
|
||
|
|
||
|
describe('recent boards section', () => {
|
||
|
it('shows only when boards are greater than 10', done => {
|
||
|
vm.$nextTick()
|
||
|
.then(() => {
|
||
|
const headerEls = vm.$el.querySelectorAll('.dropdown-bold-header');
|
||
|
|
||
|
const expectedCount = 2; // Recent + All
|
||
|
|
||
|
expect(expectedCount).toBe(headerEls.length);
|
||
|
})
|
||
|
.then(done)
|
||
|
.catch(done.fail);
|
||
|
});
|
||
|
|
||
|
it('does not show when boards are less than 10', done => {
|
||
|
spyOn(vm, 'initScrollFade');
|
||
|
spyOn(vm, 'setScrollFade');
|
||
|
|
||
|
vm.$nextTick()
|
||
|
.then(() => {
|
||
|
vm.boards = vm.boards.slice(0, 5);
|
||
|
})
|
||
|
.then(vm.$nextTick)
|
||
|
.then(() => {
|
||
|
const headerEls = vm.$el.querySelectorAll('.dropdown-bold-header');
|
||
|
const expectedCount = 0;
|
||
|
|
||
|
expect(expectedCount).toBe(headerEls.length);
|
||
|
})
|
||
|
.then(done)
|
||
|
.catch(done.fail);
|
||
|
});
|
||
|
|
||
|
it('does not show when recentBoards api returns empty array', done => {
|
||
|
vm.$nextTick()
|
||
|
.then(() => {
|
||
|
vm.recentBoards = [];
|
||
|
})
|
||
|
.then(vm.$nextTick)
|
||
|
.then(() => {
|
||
|
const headerEls = vm.$el.querySelectorAll('.dropdown-bold-header');
|
||
|
const expectedCount = 0;
|
||
|
|
||
|
expect(expectedCount).toBe(headerEls.length);
|
||
|
})
|
||
|
.then(done)
|
||
|
.catch(done.fail);
|
||
|
});
|
||
|
|
||
|
it('does not show when search is active', done => {
|
||
|
fillSearchBox('Random string');
|
||
|
|
||
|
vm.$nextTick()
|
||
|
.then(() => {
|
||
|
const headerEls = vm.$el.querySelectorAll('.dropdown-bold-header');
|
||
|
const expectedCount = 0;
|
||
|
|
||
|
expect(expectedCount).toBe(headerEls.length);
|
||
|
})
|
||
|
.then(done)
|
||
|
.catch(done.fail);
|
||
|
});
|
||
|
});
|
||
|
});
|