Commit d90635ef authored by Kushal Pandya's avatar Kushal Pandya Committed by Jarka Kadlecová

Add tests for todos

parent e0d783c6
...@@ -220,6 +220,96 @@ describe('epicSidebar', () => { ...@@ -220,6 +220,96 @@ describe('epicSidebar', () => {
}); });
}); });
describe('handleToggleTodo', () => {
let mock;
beforeEach(() => {
mock = new MockAdapter(axios);
document.body.innerHTML += '<div class="flash-container"></div>';
});
afterEach(() => {
document.querySelector('.flash-container').remove();
mock.restore();
});
it('calls `addTodo` on service object when `todoExists` prop is `false`', () => {
spyOn(vm.service, 'addTodo').and.callThrough();
vm.store.setTodoExists(false);
expect(vm.savingTodoAction).toBe(false);
vm.handleToggleTodo();
expect(vm.savingTodoAction).toBe(true);
expect(vm.service.addTodo).toHaveBeenCalledWith(epicId);
});
it('calls `addTodo` on service and sets response on store when request is successful', done => {
mock.onPost(gl.TEST_HOST).reply(200, {
delete_path: '/foo/bar',
count: 1,
});
spyOn(vm.service, 'addTodo').and.callThrough();
vm.store.setTodoExists(false);
vm.handleToggleTodo();
setTimeout(() => {
expect(vm.savingTodoAction).toBe(false);
expect(vm.store.todoDeletePath).toBe('/foo/bar');
expect(vm.store.todoExists).toBe(true);
done();
}, 0);
});
it('calls `addTodo` on service and shows Flash error when request is unsuccessful', done => {
mock.onPost(gl.TEST_HOST).reply(500, {});
spyOn(vm.service, 'addTodo').and.callThrough();
vm.store.setTodoExists(false);
vm.handleToggleTodo();
setTimeout(() => {
expect(vm.savingTodoAction).toBe(false);
expect(document.querySelector('.flash-text').innerText.trim()).toBe('There was an error adding a todo.');
done();
}, 0);
});
it('calls `deleteTodo` on service object when `todoExists` prop is `true`', () => {
spyOn(vm.service, 'deleteTodo').and.callThrough();
vm.store.setTodoExists(true);
expect(vm.savingTodoAction).toBe(false);
vm.handleToggleTodo();
expect(vm.savingTodoAction).toBe(true);
expect(vm.service.deleteTodo).toHaveBeenCalledWith(gl.TEST_HOST);
});
it('calls `deleteTodo` on service and sets response on store when request is successful', done => {
mock.onDelete(gl.TEST_HOST).reply(200, {
count: 1,
});
spyOn(vm.service, 'deleteTodo').and.callThrough();
vm.store.setTodoExists(true);
vm.handleToggleTodo();
setTimeout(() => {
expect(vm.savingTodoAction).toBe(false);
expect(vm.store.todoExists).toBe(false);
done();
}, 0);
});
it('calls `deleteTodo` on service and shows Flash error when request is unsuccessful', done => {
mock.onDelete(gl.TEST_HOST).reply(500, {});
spyOn(vm.service, 'deleteTodo').and.callThrough();
vm.store.setTodoExists(true);
vm.handleToggleTodo();
setTimeout(() => {
expect(vm.savingTodoAction).toBe(false);
expect(document.querySelector('.flash-text').innerText.trim()).toBe('There was an error deleting the todo.');
done();
}, 0);
});
});
describe('saveDate error', () => { describe('saveDate error', () => {
let interceptor; let interceptor;
let component; let component;
......
import axios from '~/lib/utils/axios_utils';
import SidebarService from 'ee/epics/sidebar/services/sidebar_service';
describe('Sidebar Service', () => {
let service;
beforeEach(() => {
service = new SidebarService({
endpoint: gl.TEST_HOST,
subscriptionEndpoint: gl.TEST_HOST,
todoPath: gl.TEST_HOST,
});
});
describe('updateStartDate', () => {
it('returns axios instance with PUT for `endpoint` and `start_date` as request body', () => {
spyOn(axios, 'put').and.stub();
const startDate = '2018-06-21';
service.updateStartDate(startDate);
expect(axios.put).toHaveBeenCalledWith(service.endpoint, {
start_date: startDate,
});
});
});
describe('updateEndDate', () => {
it('returns axios instance with PUT for `endpoint` and `end_date` as request body', () => {
spyOn(axios, 'put').and.stub();
const endDate = '2018-06-21';
service.updateEndDate(endDate);
expect(axios.put).toHaveBeenCalledWith(service.endpoint, {
end_date: endDate,
});
});
});
describe('toggleSubscribed', () => {
it('returns axios instance with POST for `subscriptionEndpoint`', () => {
spyOn(axios, 'post').and.stub();
service.toggleSubscribed();
expect(axios.post).toHaveBeenCalled();
});
});
describe('addTodo', () => {
it('returns axios instance with POST for `todoPath` with `issuable_id` and `issuable_type` as request body', () => {
spyOn(axios, 'post').and.stub();
const epicId = 1;
service.addTodo(epicId);
expect(axios.post).toHaveBeenCalledWith(service.todoPath, {
issuable_id: epicId,
issuable_type: 'epic',
});
});
});
describe('deleteTodo', () => {
it('returns axios instance with DELETE for provided `todoDeletePath` param', () => {
spyOn(axios, 'delete').and.stub();
service.deleteTodo('/foo/bar');
expect(axios.delete).toHaveBeenCalledWith('/foo/bar');
});
});
});
...@@ -63,4 +63,22 @@ describe('Sidebar Store', () => { ...@@ -63,4 +63,22 @@ describe('Sidebar Store', () => {
expect(store.subscribed).toEqual(false); expect(store.subscribed).toEqual(false);
}); });
}); });
describe('setTodoExists', () => {
it('should set store.subscribed value', () => {
const store = new SidebarStore({ todoExists: true });
store.setTodoExists(false);
expect(store.todoExists).toEqual(false);
});
});
describe('setTodoDeletePath', () => {
it('should set store.subscribed value', () => {
const store = new SidebarStore({ todoDeletePath: gl.TEST_HOST });
store.setTodoDeletePath('/foo/bar');
expect(store.todoDeletePath).toEqual('/foo/bar');
});
});
}); });
import Vue from 'vue';
import SidebarTodos from '~/sidebar/components/todo_toggle/todo.vue';
import mountComponent from 'spec/helpers/vue_mount_component_helper';
const createComponent = ({
issuableId = 1,
issuableType = 'epic',
isTodo,
isActionActive,
collapsed,
}) => {
const Component = Vue.extend(SidebarTodos);
return mountComponent(Component, {
issuableId,
issuableType,
isTodo,
isActionActive,
collapsed,
});
};
describe('SidebarTodo', () => {
let vm;
beforeEach(() => {
vm = createComponent({});
});
afterEach(() => {
vm.$destroy();
});
describe('computed', () => {
describe('buttonClasses', () => {
it('returns todo button classes for when `collapsed` prop is `false`', () => {
expect(vm.buttonClasses).toBe('btn btn-default btn-todo issuable-header-btn float-right');
});
it('returns todo button classes for when `collapsed` prop is `true`', done => {
vm.collapsed = true;
Vue.nextTick()
.then(() => {
expect(vm.buttonClasses).toBe('btn-blank btn-todo sidebar-collapsed-icon dont-change-state');
})
.then(done)
.catch(done.fail);
});
});
describe('buttonLabel', () => {
it('returns todo button text for marking todo as done when `isTodo` prop is `true`', () => {
expect(vm.buttonLabel).toBe('Mark todo as done');
});
it('returns todo button text for add todo when `isTodo` prop is `false`', done => {
vm.isTodo = false;
Vue.nextTick()
.then(() => {
expect(vm.buttonLabel).toBe('Add todo');
})
.then(done)
.catch(done.fail);
});
});
describe('collapsedButtonIconClasses', () => {
it('returns collapsed button icon class when `isTodo` prop is `true`', () => {
expect(vm.collapsedButtonIconClasses).toBe('todo-undone');
});
it('returns empty string when `isTodo` prop is `false`', done => {
vm.isTodo = false;
Vue.nextTick()
.then(() => {
expect(vm.collapsedButtonIconClasses).toBe('');
})
.then(done)
.catch(done.fail);
});
});
describe('collapsedButtonIcon', () => {
it('returns button icon name when `isTodo` prop is `true`', () => {
expect(vm.collapsedButtonIcon).toBe('todo-done');
});
it('returns button icon name when `isTodo` prop is `false`', done => {
vm.isTodo = false;
Vue.nextTick()
.then(() => {
expect(vm.collapsedButtonIcon).toBe('todo-add');
})
.then(done)
.catch(done.fail);
});
});
});
describe('methods', () => {
describe('handleButtonClick', () => {
it('emits `toggleTodo` event on component', () => {
spyOn(vm, '$emit');
vm.handleButtonClick();
expect(vm.$emit).toHaveBeenCalledWith('toggleTodo');
});
});
});
describe('template', () => {
it('renders component container element', () => {
const dataAttributes = {
issuableId: '1',
issuableType: 'epic',
originalTitle: 'Mark todo as done',
placement: 'left',
container: 'body',
boundary: 'viewport',
};
expect(vm.$el.nodeName).toBe('BUTTON');
const elDataAttrs = vm.$el.dataset;
Object.keys(elDataAttrs).forEach((attr) => {
expect(elDataAttrs[attr]).toBe(dataAttributes[attr]);
});
});
it('renders button label element when `collapsed` prop is `false`', () => {
const buttonLabelEl = vm.$el.querySelector('span.issuable-todo-inner');
expect(buttonLabelEl).not.toBeNull();
expect(buttonLabelEl.innerText.trim()).toBe('Mark todo as done');
});
it('renders button icon when `collapsed` prop is `true`', done => {
vm.collapsed = true;
Vue.nextTick()
.then(() => {
const buttonIconEl = vm.$el.querySelector('svg');
expect(buttonIconEl).not.toBeNull();
expect(buttonIconEl.querySelector('use').getAttribute('xlink:href')).toContain('todo-done');
})
.then(done)
.catch(done.fail);
});
it('renders loading icon when `isActionActive` prop is true', done => {
vm.isActionActive = true;
Vue.nextTick()
.then(() => {
const loadingEl = vm.$el.querySelector('span.loading-container');
expect(loadingEl).not.toBeNull();
})
.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