Commit 8ccae7fa authored by Paul Slaughter's avatar Paul Slaughter

Merge branch '27258-migrate-boards-to-jest' into 'master'

First round of karma to jest migration for boards

See merge request gitlab-org/gitlab!27607
parents e16b3f39 2e606cc5
......@@ -11,9 +11,9 @@ describe('Boards blank state', () => {
boardsStore.create();
spyOn(boardsStore, 'addList').and.stub();
spyOn(boardsStore, 'removeList').and.stub();
spyOn(boardsStore, 'generateDefaultLists').and.callFake(
jest.spyOn(boardsStore, 'addList').mockImplementation();
jest.spyOn(boardsStore, 'removeList').mockImplementation();
jest.spyOn(boardsStore, 'generateDefaultLists').mockImplementation(
() =>
new Promise((resolve, reject) => {
if (fail) {
......@@ -39,7 +39,7 @@ describe('Boards blank state', () => {
vm = new Comp();
setTimeout(() => {
setImmediate(() => {
vm.$mount();
done();
});
......@@ -60,7 +60,7 @@ describe('Boards blank state', () => {
it('clears blank state', done => {
vm.$el.querySelector('.btn-default').click();
setTimeout(() => {
setImmediate(() => {
expect(boardsStore.welcomeIsHidden()).toBeTruthy();
done();
......@@ -70,15 +70,11 @@ describe('Boards blank state', () => {
it('creates pre-defined labels', done => {
vm.$el.querySelector('.btn-success').click();
setTimeout(() => {
setImmediate(() => {
expect(boardsStore.addList).toHaveBeenCalledTimes(2);
expect(boardsStore.addList).toHaveBeenCalledWith(
jasmine.objectContaining({ title: 'To Do' }),
);
expect(boardsStore.addList).toHaveBeenCalledWith(expect.objectContaining({ title: 'To Do' }));
expect(boardsStore.addList).toHaveBeenCalledWith(
jasmine.objectContaining({ title: 'Doing' }),
);
expect(boardsStore.addList).toHaveBeenCalledWith(expect.objectContaining({ title: 'Doing' }));
done();
});
......@@ -89,7 +85,7 @@ describe('Boards blank state', () => {
vm.$el.querySelector('.btn-success').click();
setTimeout(() => {
setImmediate(() => {
expect(boardsStore.welcomeIsHidden()).toBeFalsy();
expect(boardsStore.removeList).toHaveBeenCalledWith(undefined, 'label');
......
/* global List */
import $ from 'jquery';
import Vue from 'vue';
import MockAdapter from 'axios-mock-adapter';
import axios from '~/lib/utils/axios_utils';
......@@ -14,6 +15,9 @@ describe('Issue boards new issue form', () => {
let list;
let mock;
let newIssueMock;
const jQueryMock = {
enable: jest.fn(),
};
const promiseReturn = {
data: {
iid: 100,
......@@ -28,7 +32,7 @@ describe('Issue boards new issue form', () => {
return vm.submit(dummySubmitEvent);
};
beforeEach(done => {
beforeEach(() => {
setFixtures('<div class="test-container"></div>');
const BoardNewIssueComp = Vue.extend(boardNewIssue);
......@@ -41,7 +45,7 @@ describe('Issue boards new issue form', () => {
list = new List(listObj);
newIssueMock = Promise.resolve(promiseReturn);
spyOn(list, 'newIssue').and.callFake(() => newIssueMock);
jest.spyOn(list, 'newIssue').mockImplementation(() => newIssueMock);
vm = new BoardNewIssueComp({
propsData: {
......@@ -49,9 +53,9 @@ describe('Issue boards new issue form', () => {
},
}).$mount(document.querySelector('.test-container'));
Vue.nextTick()
.then(done)
.catch(done.fail);
$.fn.extend(jQueryMock);
return Vue.nextTick();
});
afterEach(() => {
......@@ -59,142 +63,116 @@ describe('Issue boards new issue form', () => {
mock.restore();
});
it('calls submit if submit button is clicked', done => {
spyOn(vm, 'submit').and.callFake(e => e.preventDefault());
it('calls submit if submit button is clicked', () => {
jest.spyOn(vm, 'submit').mockImplementation(e => e.preventDefault());
vm.title = 'Testing Title';
Vue.nextTick()
.then(() => {
vm.$el.querySelector('.btn-success').click();
return Vue.nextTick().then(() => {
vm.$el.querySelector('.btn-success').click();
expect(vm.submit.calls.count()).toBe(1);
})
.then(done)
.catch(done.fail);
expect(vm.submit.mock.calls.length).toBe(1);
});
});
it('disables submit button if title is empty', () => {
expect(vm.$el.querySelector('.btn-success').disabled).toBe(true);
});
it('enables submit button if title is not empty', done => {
it('enables submit button if title is not empty', () => {
vm.title = 'Testing Title';
Vue.nextTick()
.then(() => {
expect(vm.$el.querySelector('.form-control').value).toBe('Testing Title');
expect(vm.$el.querySelector('.btn-success').disabled).not.toBe(true);
})
.then(done)
.catch(done.fail);
return Vue.nextTick().then(() => {
expect(vm.$el.querySelector('.form-control').value).toBe('Testing Title');
expect(vm.$el.querySelector('.btn-success').disabled).not.toBe(true);
});
});
it('clears title after clicking cancel', done => {
it('clears title after clicking cancel', () => {
vm.$el.querySelector('.btn-default').click();
Vue.nextTick()
.then(() => {
expect(vm.title).toBe('');
})
.then(done)
.catch(done.fail);
return Vue.nextTick().then(() => {
expect(vm.title).toBe('');
});
});
it('does not create new issue if title is empty', done => {
submitIssue()
.then(() => {
expect(list.newIssue).not.toHaveBeenCalled();
})
.then(done)
.catch(done.fail);
it('does not create new issue if title is empty', () => {
return submitIssue().then(() => {
expect(list.newIssue).not.toHaveBeenCalled();
});
});
describe('submit success', () => {
it('creates new issue', done => {
it('creates new issue', () => {
vm.title = 'submit title';
Vue.nextTick()
return Vue.nextTick()
.then(submitIssue)
.then(() => {
expect(list.newIssue).toHaveBeenCalled();
})
.then(done)
.catch(done.fail);
});
});
it('enables button after submit', done => {
it('enables button after submit', () => {
vm.title = 'submit issue';
Vue.nextTick()
return Vue.nextTick()
.then(submitIssue)
.then(() => {
expect(vm.$el.querySelector('.btn-success').disabled).toBe(false);
})
.then(done)
.catch(done.fail);
expect(jQueryMock.enable).toHaveBeenCalled();
});
});
it('clears title after submit', done => {
it('clears title after submit', () => {
vm.title = 'submit issue';
Vue.nextTick()
return Vue.nextTick()
.then(submitIssue)
.then(() => {
expect(vm.title).toBe('');
})
.then(done)
.catch(done.fail);
});
});
it('sets detail issue after submit', done => {
it('sets detail issue after submit', () => {
expect(boardsStore.detail.issue.title).toBe(undefined);
vm.title = 'submit issue';
Vue.nextTick()
return Vue.nextTick()
.then(submitIssue)
.then(() => {
expect(boardsStore.detail.issue.title).toBe('submit issue');
})
.then(done)
.catch(done.fail);
});
});
it('sets detail list after submit', done => {
it('sets detail list after submit', () => {
vm.title = 'submit issue';
Vue.nextTick()
return Vue.nextTick()
.then(submitIssue)
.then(() => {
expect(boardsStore.detail.list.id).toBe(list.id);
})
.then(done)
.catch(done.fail);
});
});
it('sets detail weight after submit', done => {
it('sets detail weight after submit', () => {
boardsStore.weightFeatureAvailable = true;
vm.title = 'submit issue';
Vue.nextTick()
return Vue.nextTick()
.then(submitIssue)
.then(() => {
expect(boardsStore.detail.list.weight).toBe(list.weight);
})
.then(done)
.catch(done.fail);
});
});
it('does not set detail weight after submit', done => {
it('does not set detail weight after submit', () => {
boardsStore.weightFeatureAvailable = false;
vm.title = 'submit issue';
Vue.nextTick()
return Vue.nextTick()
.then(submitIssue)
.then(() => {
expect(boardsStore.detail.list.weight).toBe(list.weight);
})
.then(done)
.catch(done.fail);
});
});
});
......@@ -204,24 +182,21 @@ describe('Issue boards new issue form', () => {
vm.title = 'error';
});
it('removes issue', done => {
Vue.nextTick()
it('removes issue', () => {
const lengthBefore = list.issues.length;
return Vue.nextTick()
.then(submitIssue)
.then(() => {
expect(list.issues.length).toBe(1);
})
.then(done)
.catch(done.fail);
expect(list.issues.length).toBe(lengthBefore);
});
});
it('shows error', done => {
Vue.nextTick()
it('shows error', () => {
return Vue.nextTick()
.then(submitIssue)
.then(() => {
expect(vm.error).toBe(true);
})
.then(done)
.catch(done.fail);
});
});
});
});
import $ from 'jquery';
import Vue from 'vue';
import mountComponent from 'spec/helpers/vue_mount_component_helper';
import { mount } from '@vue/test-utils';
import boardsStore from '~/boards/stores/boards_store';
import boardForm from '~/boards/components/board_form.vue';
import DeprecatedModal from '~/vue_shared/components/deprecated_modal.vue';
describe('board_form.vue', () => {
const props = {
let wrapper;
const propsData = {
canAdminBoard: false,
labelsPath: `${gl.TEST_HOST}/labels/path`,
milestonePath: `${gl.TEST_HOST}/milestone/path`,
};
let vm;
const findModal = () => wrapper.find(DeprecatedModal);
beforeEach(() => {
spyOn($, 'ajax');
boardsStore.state.currentPage = 'edit';
const Component = Vue.extend(boardForm);
vm = mountComponent(Component, props);
wrapper = mount(boardForm, { propsData });
});
afterEach(() => {
vm.$destroy();
wrapper.destroy();
wrapper = null;
});
describe('methods', () => {
describe('cancel', () => {
it('resets currentPage', done => {
vm.cancel();
Vue.nextTick()
.then(() => {
expect(boardsStore.state.currentPage).toBe('');
})
.then(done)
.catch(done.fail);
it('resets currentPage', () => {
wrapper.vm.cancel();
expect(boardsStore.state.currentPage).toBe('');
});
});
});
describe('buttons', () => {
it('cancel button triggers cancel()', done => {
spyOn(vm, 'cancel');
Vue.nextTick()
.then(() => {
const cancelButton = vm.$el.querySelector('button[data-dismiss="modal"]');
cancelButton.click();
expect(vm.cancel).toHaveBeenCalled();
})
.then(done)
.catch(done.fail);
it('cancel button triggers cancel()', () => {
wrapper.setMethods({ cancel: jest.fn() });
findModal().vm.$emit('cancel');
return wrapper.vm.$nextTick().then(() => {
expect(wrapper.vm.cancel).toHaveBeenCalled();
});
});
});
});
......@@ -174,7 +174,7 @@ describe('Issue model', () => {
describe('update', () => {
it('passes assignee ids when there are assignees', done => {
spyOn(axios, 'patch').and.callFake((url, data) => {
jest.spyOn(axios, 'patch').mockImplementation((url, data) => {
expect(data.issue.assignee_ids).toEqual([1]);
done();
return Promise.resolve();
......@@ -184,7 +184,7 @@ describe('Issue model', () => {
});
it('passes assignee ids of [0] when there are no assignees', done => {
spyOn(axios, 'patch').and.callFake((url, data) => {
jest.spyOn(axios, 'patch').mockImplementation((url, data) => {
expect(data.issue.assignee_ids).toEqual([0]);
done();
return Promise.resolve();
......
import boardsStore from '~/boards/stores/boards_store';
export const boardObj = {
id: 1,
name: 'test',
......@@ -89,3 +91,54 @@ export const mockMilestone = {
start_date: '2018-01-01',
due_date: '2019-12-31',
};
export const BoardsMockData = {
GET: {
'/test/-/boards/1/lists/300/issues?id=300&page=1': {
issues: [
{
title: 'Testing',
id: 1,
iid: 1,
confidential: false,
labels: [],
assignees: [],
},
],
},
'/test/issue-boards/-/milestones.json': [
{
id: 1,
title: 'test',
},
],
},
POST: {
'/test/-/boards/1/lists': listObj,
},
PUT: {
'/test/issue-boards/-/board/1/lists{/id}': {},
},
DELETE: {
'/test/issue-boards/-/board/1/lists{/id}': {},
},
};
export const boardsMockInterceptor = config => {
const body = BoardsMockData[config.method.toUpperCase()][config.url];
return [200, body];
};
export const setMockEndpoints = (opts = {}) => {
const boardsEndpoint = opts.boardsEndpoint || '/test/issue-boards/-/boards.json';
const listsEndpoint = opts.listsEndpoint || '/test/-/boards/1/lists';
const bulkUpdatePath = opts.bulkUpdatePath || '';
const boardId = opts.boardId || '1';
boardsStore.setEndpoints({
boardsEndpoint,
listsEndpoint,
bulkUpdatePath,
boardId,
});
};
import boardsStore from '~/boards/stores/boards_store';
import { listObj } from '../../frontend/boards/mock_data';
export * from '../../frontend/boards/mock_data';
export const BoardsMockData = {
GET: {
'/test/-/boards/1/lists/300/issues?id=300&page=1': {
issues: [
{
title: 'Testing',
id: 1,
iid: 1,
confidential: false,
labels: [],
assignees: [],
},
],
},
'/test/issue-boards/-/milestones.json': [
{
id: 1,
title: 'test',
},
],
},
POST: {
'/test/-/boards/1/lists': listObj,
},
PUT: {
'/test/issue-boards/-/board/1/lists{/id}': {},
},
DELETE: {
'/test/issue-boards/-/board/1/lists{/id}': {},
},
};
export const boardsMockInterceptor = config => {
const body = BoardsMockData[config.method.toUpperCase()][config.url];
return [200, body];
};
export const setMockEndpoints = (opts = {}) => {
const boardsEndpoint = opts.boardsEndpoint || '/test/issue-boards/-/boards.json';
const listsEndpoint = opts.listsEndpoint || '/test/-/boards/1/lists';
const bulkUpdatePath = opts.bulkUpdatePath || '';
const boardId = opts.boardId || '1';
boardsStore.setEndpoints({
boardsEndpoint,
listsEndpoint,
bulkUpdatePath,
boardId,
});
};
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