Commit 7e2bd5ec authored by Nicolò Maria Mezzopera's avatar Nicolò Maria Mezzopera Committed by Phil Hughes

Refactor board list to jest

- add sortablejs mock
- remove common file
- refactor to jest
- remove old test
parent c5e82147
import Sortablejs from 'sortablejs';
export default Sortablejs;
export const Sortable = Sortablejs;
export class MultiDrag {}
......@@ -2,9 +2,11 @@
/* global ListAssignee */
/* global ListLabel */
import Vue from 'vue';
import { shallowMount } from '@vue/test-utils';
import MockAdapter from 'axios-mock-adapter';
import axios from '~/lib/utils/axios_utils';
import waitForPromises from 'helpers/wait_for_promises';
import eventHub from '~/boards/eventhub';
import '~/boards/models/label';
......@@ -13,22 +15,41 @@ import '~/boards/models/list';
import store from '~/boards/stores';
import boardsStore from '~/boards/stores/boards_store';
import boardCard from '~/boards/components/board_card.vue';
import issueCardInner from '~/boards/components/issue_card_inner.vue';
import userAvatarLink from '~/vue_shared/components/user_avatar/user_avatar_link.vue';
import { listObj, boardsMockInterceptor, setMockEndpoints } from './mock_data';
describe('Board card', () => {
let vm;
let wrapper;
let mock;
let list;
const findIssueCardInner = () => wrapper.find(issueCardInner);
const findUserAvatarLink = () => wrapper.find(userAvatarLink);
// this particular mount component needs to be used after the root beforeEach because it depends on list being initialized
const mountComponent = propsData => {
wrapper = shallowMount(boardCard, {
stubs: {
issueCardInner,
},
store,
propsData: {
list,
issue: list.issues[0],
issueLinkBase: '/',
disabled: false,
index: 0,
rootPath: '/',
...propsData,
},
});
};
beforeEach(done => {
mock = new MockAdapter(axios);
mock.onAny().reply(boardsMockInterceptor);
setMockEndpoints();
const setupData = () => {
list = new List(listObj);
boardsStore.create();
boardsStore.detail.issue = {};
const BoardCardComp = Vue.extend(boardCard);
const list = new List(listObj);
const label1 = new ListLabel({
id: 3,
title: 'testing 123',
......@@ -36,178 +57,155 @@ describe('Board card', () => {
text_color: 'white',
description: 'test',
});
setTimeout(() => {
return waitForPromises().then(() => {
list.issues[0].labels.push(label1);
});
};
vm = new BoardCardComp({
store,
propsData: {
list,
issue: list.issues[0],
issueLinkBase: '/',
disabled: false,
index: 0,
rootPath: '/',
},
}).$mount();
done();
}, 0);
beforeEach(() => {
mock = new MockAdapter(axios);
mock.onAny().reply(boardsMockInterceptor);
setMockEndpoints();
return setupData();
});
afterEach(() => {
wrapper.destroy();
wrapper = null;
list = null;
mock.restore();
});
it('returns false when detailIssue is empty', () => {
expect(vm.issueDetailVisible).toBe(false);
it('when details issue is empty does not show the element', () => {
mountComponent();
expect(wrapper.classes()).not.toContain('is-active');
});
it('returns true when detailIssue is equal to card issue', () => {
boardsStore.detail.issue = vm.issue;
it('when detailIssue is equal to card issue shows the element', () => {
[boardsStore.detail.issue] = list.issues;
mountComponent();
expect(vm.issueDetailVisible).toBe(true);
expect(wrapper.classes()).toContain('is-active');
});
it("returns false when multiSelect doesn't contain issue", () => {
expect(vm.multiSelectVisible).toBe(false);
it('when multiSelect does not contain issue removes multi select class', () => {
mountComponent();
expect(wrapper.classes()).not.toContain('multi-select');
});
it('returns true when multiSelect contains issue', () => {
boardsStore.multiSelect.list = [vm.issue];
it('when multiSelect contain issue add multi select class', () => {
boardsStore.multiSelect.list = [list.issues[0]];
mountComponent();
expect(vm.multiSelectVisible).toBe(true);
expect(wrapper.classes()).toContain('multi-select');
});
it('adds user-can-drag class if not disabled', () => {
expect(vm.$el.classList.contains('user-can-drag')).toBe(true);
mountComponent();
expect(wrapper.classes()).toContain('user-can-drag');
});
it('does not add user-can-drag class disabled', done => {
vm.disabled = true;
it('does not add user-can-drag class disabled', () => {
mountComponent({ disabled: true });
setTimeout(() => {
expect(vm.$el.classList.contains('user-can-drag')).toBe(false);
done();
}, 0);
expect(wrapper.classes()).not.toContain('user-can-drag');
});
it('does not add disabled class', () => {
expect(vm.$el.classList.contains('is-disabled')).toBe(false);
mountComponent();
expect(wrapper.classes()).not.toContain('is-disabled');
});
it('adds disabled class is disabled is true', done => {
vm.disabled = true;
it('adds disabled class is disabled is true', () => {
mountComponent({ disabled: true });
setTimeout(() => {
expect(vm.$el.classList.contains('is-disabled')).toBe(true);
done();
}, 0);
expect(wrapper.classes()).toContain('is-disabled');
});
describe('mouse events', () => {
const triggerEvent = (eventName, el = vm.$el) => {
const event = document.createEvent('MouseEvents');
event.initMouseEvent(
eventName,
true,
true,
window,
1,
0,
0,
0,
0,
false,
false,
false,
false,
0,
null,
);
el.dispatchEvent(event);
};
it('sets showDetail to true on mousedown', () => {
triggerEvent('mousedown');
expect(vm.showDetail).toBe(true);
mountComponent();
wrapper.trigger('mousedown');
return wrapper.vm.$nextTick().then(() => {
expect(wrapper.vm.showDetail).toBe(true);
});
});
it('sets showDetail to false on mousemove', () => {
triggerEvent('mousedown');
expect(vm.showDetail).toBe(true);
triggerEvent('mousemove');
expect(vm.showDetail).toBe(false);
mountComponent();
wrapper.trigger('mousedown');
return wrapper.vm
.$nextTick()
.then(() => {
expect(wrapper.vm.showDetail).toBe(true);
wrapper.trigger('mousemove');
return wrapper.vm.$nextTick();
})
.then(() => {
expect(wrapper.vm.showDetail).toBe(false);
});
});
it('does not set detail issue if showDetail is false', () => {
mountComponent();
expect(boardsStore.detail.issue).toEqual({});
});
it('does not set detail issue if link is clicked', () => {
triggerEvent('mouseup', vm.$el.querySelector('a'));
mountComponent();
findIssueCardInner()
.find('a')
.trigger('mouseup');
expect(boardsStore.detail.issue).toEqual({});
});
it('does not set detail issue if img is clicked', done => {
vm.issue.assignees = [
new ListAssignee({
id: 1,
name: 'testing 123',
username: 'test',
avatar: 'test_image',
}),
];
Vue.nextTick(() => {
triggerEvent('mouseup', vm.$el.querySelector('img'));
it('does not set detail issue if img is clicked', () => {
mountComponent({
issue: {
...list.issues[0],
assignees: [
new ListAssignee({
id: 1,
name: 'testing 123',
username: 'test',
avatar: 'test_image',
}),
],
},
});
expect(boardsStore.detail.issue).toEqual({});
findUserAvatarLink().trigger('mouseup');
done();
});
expect(boardsStore.detail.issue).toEqual({});
});
it('does not set detail issue if showDetail is false after mouseup', () => {
triggerEvent('mouseup');
mountComponent();
wrapper.trigger('mouseup');
expect(boardsStore.detail.issue).toEqual({});
});
it('sets detail issue to card issue on mouse up', () => {
spyOn(eventHub, '$emit');
triggerEvent('mousedown');
triggerEvent('mouseup');
jest.spyOn(eventHub, '$emit').mockImplementation(() => {});
expect(eventHub.$emit).toHaveBeenCalledWith('newDetailIssue', vm.issue, undefined);
expect(boardsStore.detail.list).toEqual(vm.list);
});
mountComponent();
it('adds active class if detail issue is set', done => {
vm.detailIssue.issue = vm.issue;
wrapper.trigger('mousedown');
wrapper.trigger('mouseup');
Vue.nextTick()
.then(() => {
expect(vm.$el.classList.contains('is-active')).toBe(true);
})
.then(done)
.catch(done.fail);
expect(eventHub.$emit).toHaveBeenCalledWith('newDetailIssue', wrapper.vm.issue, undefined);
expect(boardsStore.detail.list).toEqual(wrapper.vm.list);
});
it('resets detail issue to empty if already set', () => {
spyOn(eventHub, '$emit');
boardsStore.detail.issue = vm.issue;
jest.spyOn(eventHub, '$emit').mockImplementation(() => {});
[boardsStore.detail.issue] = list.issues;
mountComponent();
triggerEvent('mousedown');
triggerEvent('mouseup');
wrapper.trigger('mousedown');
wrapper.trigger('mouseup');
expect(eventHub.$emit).toHaveBeenCalledWith('clearDetailIssue', undefined);
});
......
......@@ -9,7 +9,9 @@ import '~/boards/models/label';
import '~/boards/models/assignee';
import '~/boards/models/issue';
import '~/boards/models/list';
import { ListType } from '~/boards/constants';
import boardsStore from '~/boards/stores/boards_store';
import waitForPromises from 'helpers/wait_for_promises';
import { listObj, listObjDuplicate, boardsMockInterceptor } from './mock_data';
describe('List model', () => {
......@@ -20,22 +22,35 @@ describe('List model', () => {
mock = new MockAdapter(axios);
mock.onAny().reply(boardsMockInterceptor);
boardsStore.create();
boardsStore.setEndpoints({
listsEndpoint: '/test/-/boards/1/lists',
});
list = new List(listObj);
return waitForPromises();
});
afterEach(() => {
mock.restore();
});
it('gets issues when created', done => {
setTimeout(() => {
expect(list.issues.length).toBe(1);
done();
}, 0);
describe('list type', () => {
const notExpandableList = ['blank'];
const table = Object.keys(ListType).map(k => {
const value = ListType[k];
return [value, !notExpandableList.includes(value)];
});
it.each(table)(`when list_type is %s boards isExpandable is %p`, (type, result) => {
expect(new List({ id: 1, list_type: type }).isExpandable).toBe(result);
});
});
it('saves list and returns ID', done => {
it('gets issues when created', () => {
expect(list.issues.length).toBe(1);
});
it('saves list and returns ID', () => {
list = new List({
title: 'test',
label: {
......@@ -45,50 +60,40 @@ describe('List model', () => {
text_color: 'white',
},
});
list.save();
setTimeout(() => {
return list.save().then(() => {
expect(list.id).toBe(listObj.id);
expect(list.type).toBe('label');
expect(list.position).toBe(0);
expect(list.label.color).toBe('red');
expect(list.label.textColor).toBe('white');
done();
}, 0);
});
});
it('destroys the list', done => {
it('destroys the list', () => {
boardsStore.addList(listObj);
list = boardsStore.findList('id', listObj.id);
expect(boardsStore.state.lists.length).toBe(1);
list.destroy();
setTimeout(() => {
return waitForPromises().then(() => {
expect(boardsStore.state.lists.length).toBe(0);
done();
}, 0);
});
});
it('gets issue from list', done => {
setTimeout(() => {
const issue = list.findIssue(1);
it('gets issue from list', () => {
const issue = list.findIssue(1);
expect(issue).toBeDefined();
done();
}, 0);
expect(issue).toBeDefined();
});
it('removes issue', done => {
setTimeout(() => {
const issue = list.findIssue(1);
it('removes issue', () => {
const issue = list.findIssue(1);
expect(list.issues.length).toBe(1);
list.removeIssue(issue);
expect(list.issues.length).toBe(1);
list.removeIssue(issue);
expect(list.issues.length).toBe(0);
done();
}, 0);
expect(list.issues.length).toBe(0);
});
it('sends service request to update issue label', () => {
......@@ -105,7 +110,7 @@ describe('List model', () => {
list.issues.push(issue);
listDup.issues.push(issue);
spyOn(boardsStore, 'moveIssue').and.callThrough();
jest.spyOn(boardsStore, 'moveIssue');
listDup.updateIssueLabel(issue, list);
......@@ -120,7 +125,8 @@ describe('List model', () => {
describe('page number', () => {
beforeEach(() => {
spyOn(list, 'getIssues');
jest.spyOn(list, 'getIssues').mockImplementation(() => {});
list.issues = [];
});
it('increase page number if current issue count is more than the page size', () => {
......@@ -167,7 +173,7 @@ describe('List model', () => {
describe('newIssue', () => {
beforeEach(() => {
spyOn(boardsStore, 'newIssue').and.returnValue(
jest.spyOn(boardsStore, 'newIssue').mockReturnValue(
Promise.resolve({
data: {
id: 42,
......@@ -178,6 +184,7 @@ describe('List model', () => {
},
}),
);
list.issues = [];
});
it('adds new issue to top of list', done => {
......
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