Commit a78a5ebe authored by Simon Knox's avatar Simon Knox Committed by Kushal Pandya

Move boards_selector_spec to jest

Use vue-test-utils
Use mount for dropdown content, attachToDocument for tooltip
Remove some unneeded Vue.nextTicks in first step of test
Remove Fixtures and window.gl as they are not needed
parent 5c86775a
import Vue from 'vue'; import Vue from 'vue';
import mountComponent from 'spec/helpers/vue_mount_component_helper'; import { mount } from '@vue/test-utils';
import { GlDropdown } from '@gitlab/ui';
import { TEST_HOST } from 'spec/test_constants'; import { TEST_HOST } from 'spec/test_constants';
import BoardsSelector from '~/boards/components/boards_selector.vue'; import BoardsSelector from '~/boards/components/boards_selector.vue';
import boardsStore from '~/boards/stores/boards_store'; import boardsStore from '~/boards/stores/boards_store';
...@@ -18,17 +19,23 @@ function boardGenerator(n) { ...@@ -18,17 +19,23 @@ function boardGenerator(n) {
} }
describe('BoardsSelector', () => { describe('BoardsSelector', () => {
let vm; let wrapper;
let allBoardsResponse; let allBoardsResponse;
let recentBoardsResponse; let recentBoardsResponse;
let fillSearchBox;
const boards = boardGenerator(20); const boards = boardGenerator(20);
const recentBoards = boardGenerator(5); const recentBoards = boardGenerator(5);
beforeEach(done => { const fillSearchBox = filterTerm => {
setFixtures('<div class="js-boards-selector"></div>'); const searchBox = wrapper.find({ ref: 'searchBox' });
window.gl = window.gl || {}; const searchBoxInput = searchBox.find('input');
searchBoxInput.setValue(filterTerm);
searchBoxInput.trigger('input');
};
const getDropdownItems = () => wrapper.findAll('.js-dropdown-item');
const getDropdownHeaders = () => wrapper.findAll('.dropdown-bold-header');
beforeEach(() => {
boardsStore.setEndpoints({ boardsStore.setEndpoints({
boardsEndpoint: '', boardsEndpoint: '',
recentBoardsEndpoint: '', recentBoardsEndpoint: '',
...@@ -44,13 +51,12 @@ describe('BoardsSelector', () => { ...@@ -44,13 +51,12 @@ describe('BoardsSelector', () => {
data: recentBoards, data: recentBoards,
}); });
spyOn(boardsStore, 'allBoards').and.returnValue(allBoardsResponse); boardsStore.allBoards = jest.fn(() => allBoardsResponse);
spyOn(boardsStore, 'recentBoards').and.returnValue(recentBoardsResponse); boardsStore.recentBoards = jest.fn(() => recentBoardsResponse);
const Component = Vue.extend(BoardsSelector); const Component = Vue.extend(BoardsSelector);
vm = mountComponent( wrapper = mount(Component, {
Component, propsData: {
{
throttleDuration, throttleDuration,
currentBoard: { currentBoard: {
id: 1, id: 1,
...@@ -71,133 +77,79 @@ describe('BoardsSelector', () => { ...@@ -71,133 +77,79 @@ describe('BoardsSelector', () => {
scopedIssueBoardFeatureEnabled: true, scopedIssueBoardFeatureEnabled: true,
weights: [], weights: [],
}, },
document.querySelector('.js-boards-selector'), attachToDocument: true,
); });
// Emits gl-dropdown show event to simulate the dropdown is opened at initialization time // Emits gl-dropdown show event to simulate the dropdown is opened at initialization time
vm.$children[0].$emit('show'); wrapper.find(GlDropdown).vm.$emit('show');
Promise.all([allBoardsResponse, recentBoardsResponse]) return Promise.all([allBoardsResponse, recentBoardsResponse]).then(() => Vue.nextTick());
.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(() => { afterEach(() => {
vm.$destroy(); wrapper.destroy();
wrapper = null;
}); });
describe('filtering', () => { describe('filtering', () => {
it('shows all boards without filtering', done => { it('shows all boards without filtering', () => {
vm.$nextTick() expect(getDropdownItems().length).toBe(boards.length + recentBoards.length);
.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 => { it('shows only matching boards when filtering', () => {
const filterTerm = 'board1'; const filterTerm = 'board1';
const expectedCount = boards.filter(board => board.name.includes(filterTerm)).length; const expectedCount = boards.filter(board => board.name.includes(filterTerm)).length;
fillSearchBox(filterTerm); fillSearchBox(filterTerm);
vm.$nextTick() return Vue.nextTick().then(() => {
.then(() => { expect(getDropdownItems().length).toBe(expectedCount);
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 => { it('shows message if there are no matching boards', () => {
fillSearchBox('does not exist'); fillSearchBox('does not exist');
vm.$nextTick() return Vue.nextTick().then(() => {
.then(() => { expect(getDropdownItems().length).toBe(0);
const dropdownItems = vm.$el.querySelectorAll('.js-dropdown-item'); expect(wrapper.text().includes('No matching boards found')).toBe(true);
});
expect(dropdownItems.length).toBe(0);
expect(vm.$el).toContainText('No matching boards found');
})
.then(done)
.catch(done.fail);
}); });
}); });
describe('recent boards section', () => { describe('recent boards section', () => {
it('shows only when boards are greater than 10', done => { it('shows only when boards are greater than 10', () => {
vm.$nextTick()
.then(() => {
const headerEls = vm.$el.querySelectorAll('.dropdown-bold-header');
const expectedCount = 2; // Recent + All const expectedCount = 2; // Recent + All
expect(expectedCount).toBe(headerEls.length); expect(getDropdownHeaders().length).toBe(expectedCount);
})
.then(done)
.catch(done.fail);
}); });
it('does not show when boards are less than 10', done => { it('does not show when boards are less than 10', () => {
spyOn(vm, 'initScrollFade'); wrapper.setData({
spyOn(vm, 'setScrollFade'); boards: boards.slice(0, 5),
});
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); return Vue.nextTick().then(() => {
}) expect(getDropdownHeaders().length).toBe(0);
.then(done) });
.catch(done.fail);
}); });
it('does not show when recentBoards api returns empty array', done => { it('does not show when recentBoards api returns empty array', () => {
vm.$nextTick() wrapper.setData({
.then(() => { recentBoards: [],
vm.recentBoards = []; });
})
.then(vm.$nextTick)
.then(() => {
const headerEls = vm.$el.querySelectorAll('.dropdown-bold-header');
const expectedCount = 0;
expect(expectedCount).toBe(headerEls.length); return Vue.nextTick().then(() => {
}) expect(getDropdownHeaders().length).toBe(0);
.then(done) });
.catch(done.fail);
}); });
it('does not show when search is active', done => { it('does not show when search is active', () => {
fillSearchBox('Random string'); fillSearchBox('Random string');
vm.$nextTick() return Vue.nextTick().then(() => {
.then(() => { expect(getDropdownHeaders().length).toBe(0);
const headerEls = vm.$el.querySelectorAll('.dropdown-bold-header'); });
const expectedCount = 0;
expect(expectedCount).toBe(headerEls.length);
})
.then(done)
.catch(done.fail);
}); });
}); });
}); });
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment