Added front & back tests
gitea/salix/pipeline/head This commit looks good Details

This commit is contained in:
Joan Sanchez 2020-07-16 10:04:16 +02:00
parent 4397060f36
commit bbf3b72001
8 changed files with 310 additions and 5 deletions

View File

@ -31,9 +31,11 @@ module.exports = Self => {
Self.createAbsence = async(ctx, id, absenceTypeId, dated) => { Self.createAbsence = async(ctx, id, absenceTypeId, dated) => {
const models = Self.app.models; const models = Self.app.models;
const userId = ctx.req.accessToken.userId;
const isSubordinate = await models.Worker.isSubordinate(ctx, id); const isSubordinate = await models.Worker.isSubordinate(ctx, id);
const isTeamBoss = await models.Account.hasRole(userId, 'teamBoss');
if (!isSubordinate) if (!isSubordinate || (isSubordinate && userId == id && !isTeamBoss))
throw new UserError(`You don't have enough privileges`); throw new UserError(`You don't have enough privileges`);
const labour = await models.WorkerLabour.findOne({ const labour = await models.WorkerLabour.findOne({

View File

@ -23,9 +23,11 @@ module.exports = Self => {
Self.deleteAbsence = async(ctx, id, absenceId) => { Self.deleteAbsence = async(ctx, id, absenceId) => {
const models = Self.app.models; const models = Self.app.models;
const userId = ctx.req.accessToken.userId;
const isSubordinate = await models.Worker.isSubordinate(ctx, id); const isSubordinate = await models.Worker.isSubordinate(ctx, id);
const isTeamBoss = await models.Account.hasRole(userId, 'teamBoss');
if (!isSubordinate) if (!isSubordinate || (isSubordinate && userId == id && !isTeamBoss))
throw new UserError(`You don't have enough privileges`); throw new UserError(`You don't have enough privileges`);
const absence = await models.WorkerCalendar.findById(absenceId); const absence = await models.WorkerCalendar.findById(absenceId);

View File

@ -0,0 +1,39 @@
const app = require('vn-loopback/server/server');
describe('Worker createAbsence()', () => {
const workerId = 106;
let createdAbsence;
afterAll(async() => {
const absence = await app.models.WorkerCalendar.findById(createdAbsence.id);
await absence.destroy();
});
it('should return an error for a user without enough privileges', async() => {
const ctx = {req: {accessToken: {userId: 106}}};
const absenceTypeId = 1;
const dated = new Date();
let error;
await app.models.Worker.createAbsence(ctx, workerId, absenceTypeId, dated).catch(e => {
error = e;
}).finally(() => {
expect(error.message).toEqual(`You don't have enough privileges`);
});
expect(error).toBeDefined();
});
it('should create a new absence', async() => {
const ctx = {req: {accessToken: {userId: 37}}};
const absenceTypeId = 1;
const dated = new Date();
createdAbsence = await app.models.Worker.createAbsence(ctx, workerId, absenceTypeId, dated);
const expectedBusinessId = 106;
const expectedAbsenceTypeId = 1;
expect(createdAbsence.businessFk).toEqual(expectedBusinessId);
expect(createdAbsence.absenceTypeFk).toEqual(expectedAbsenceTypeId);
});
});

View File

@ -0,0 +1,38 @@
const app = require('vn-loopback/server/server');
describe('Worker deleteAbsence()', () => {
const workerId = 106;
let createdAbsence;
it('should return an error for a user without enough privileges', async() => {
const ctx = {req: {accessToken: {userId: 106}}};
const businessId = 106;
createdAbsence = await app.models.WorkerCalendar.create({
businessFk: businessId,
absenceTypeFk: 1,
dated: new Date()
});
let error;
await app.models.Worker.deleteAbsence(ctx, workerId, createdAbsence.id).catch(e => {
error = e;
}).finally(() => {
expect(error.message).toEqual(`You don't have enough privileges`);
});
expect(error).toBeDefined();
});
it('should create a new absence', async() => {
const ctx = {req: {accessToken: {userId: 37}}};
const businessId = 106;
expect(createdAbsence.businessFk).toEqual(businessId);
await app.models.Worker.deleteAbsence(ctx, workerId, createdAbsence.id);
const deletedAbsence = await app.models.WorkerCalendar.findById(createdAbsence.id);
expect(deletedAbsence).toBeNull();
});
});

View File

@ -0,0 +1,38 @@
const app = require('vn-loopback/server/server');
describe('Worker updateAbsence()', () => {
const workerId = 106;
let createdAbsence;
afterAll(async() => {
const absence = await app.models.WorkerCalendar.findById(createdAbsence.id);
await absence.destroy();
});
it('should return an error for a user without enough privileges', async() => {
const ctx = {req: {accessToken: {userId: 106}}};
const expectedAbsenceTypeId = 2;
createdAbsence = await app.models.WorkerCalendar.create({
businessFk: 106,
absenceTypeFk: 1,
dated: new Date()
});
let error;
await app.models.Worker.updateAbsence(ctx, workerId, createdAbsence.id, expectedAbsenceTypeId).catch(e => {
error = e;
}).finally(() => {
expect(error.message).toEqual(`You don't have enough privileges`);
});
expect(error).toBeDefined();
});
it('should create a new absence', async() => {
const ctx = {req: {accessToken: {userId: 37}}};
const expectedAbsenceTypeId = 2;
const updatedAbsence = await app.models.Worker.updateAbsence(ctx, workerId, createdAbsence.id, expectedAbsenceTypeId);
expect(updatedAbsence.absenceTypeFk).toEqual(expectedAbsenceTypeId);
});
});

View File

@ -28,9 +28,11 @@ module.exports = Self => {
Self.updateAbsence = async(ctx, id, absenceId, absenceTypeId) => { Self.updateAbsence = async(ctx, id, absenceId, absenceTypeId) => {
const models = Self.app.models; const models = Self.app.models;
const userId = ctx.req.accessToken.userId;
const isSubordinate = await models.Worker.isSubordinate(ctx, id); const isSubordinate = await models.Worker.isSubordinate(ctx, id);
const isTeamBoss = await models.Account.hasRole(userId, 'teamBoss');
if (!isSubordinate) if (!isSubordinate || (isSubordinate && userId == id && !isTeamBoss))
throw new UserError(`You don't have enough privileges`); throw new UserError(`You don't have enough privileges`);
const absence = await models.WorkerCalendar.findById(absenceId); const absence = await models.WorkerCalendar.findById(absenceId);

View File

@ -164,7 +164,7 @@ class Controller extends Section {
this.$http.patch(path, params).then(() => { this.$http.patch(path, params).then(() => {
event.color = absenceType.rgb; event.color = absenceType.rgb;
event.name = absenceType.name; event.name = absenceType.name;
event.code = absenceType.code; event.type = absenceType.code;
this.repaintCanceller(() => this.repaintCanceller(() =>
this.refresh().then(calendar.repaint()) this.refresh().then(calendar.repaint())

View File

@ -3,20 +3,39 @@ import './index';
describe('Worker', () => { describe('Worker', () => {
describe('Component vnWorkerCalendar', () => { describe('Component vnWorkerCalendar', () => {
let $httpBackend; let $httpBackend;
let $httpParamSerializer;
let $scope; let $scope;
let controller; let controller;
let year = new Date().getFullYear(); let year = new Date().getFullYear();
beforeEach(ngModule('worker')); beforeEach(ngModule('worker'));
beforeEach(angular.mock.inject(($componentController, $rootScope, _$httpBackend_) => { beforeEach(angular.mock.inject(($componentController, $rootScope, _$httpParamSerializer_, _$httpBackend_) => {
$scope = $rootScope.$new(); $scope = $rootScope.$new();
$httpBackend = _$httpBackend_; $httpBackend = _$httpBackend_;
$httpParamSerializer = _$httpParamSerializer_;
const $element = angular.element('<vn-worker-calendar></vn-worker-calendar>'); const $element = angular.element('<vn-worker-calendar></vn-worker-calendar>');
controller = $componentController('vnWorkerCalendar', {$element, $scope}); controller = $componentController('vnWorkerCalendar', {$element, $scope});
controller.isSubordinate = true; controller.isSubordinate = true;
controller.absenceType = {id: 1, name: 'Holiday', code: 'holiday', rgb: 'red'};
controller.$params.id = 106;
controller._worker = {id: 106};
})); }));
describe('worker() setter', () => {
it(`should set the data an then call the refresh() and getIsSubordinate() methods`, () => {
jest.spyOn(controller, 'refresh').mockReturnValue(new Promise(resolve => {
return resolve();
}));
jest.spyOn(controller, 'getIsSubordinate').mockReturnValue(true);
controller.worker = {id: 107};
expect(controller.refresh).toHaveBeenCalledWith();
expect(controller.getIsSubordinate).toHaveBeenCalledWith();
});
});
describe('started property', () => { describe('started property', () => {
it(`should return first day and month of current year`, () => { it(`should return first day and month of current year`, () => {
let started = new Date(year, 0, 1); let started = new Date(year, 0, 1);
@ -131,6 +150,7 @@ describe('Worker', () => {
const $event = {}; const $event = {};
const $days = []; const $days = [];
controller.absenceType = null;
controller.onSelection($event, $days); controller.onSelection($event, $days);
expect(controller.vnApp.showMessage).toHaveBeenCalledWith('Choose an absence type from the right menu'); expect(controller.vnApp.showMessage).toHaveBeenCalledWith('Choose an absence type from the right menu');
@ -153,6 +173,170 @@ describe('Worker', () => {
expect(controller.create).toHaveBeenCalledWith(jasmine.any(Object), selectedDay); expect(controller.create).toHaveBeenCalledWith(jasmine.any(Object), selectedDay);
}); });
it(`should call to the delete() method`, () => {
jest.spyOn(controller, 'delete').mockReturnThis();
const selectedDay = new Date();
const expectedEvent = {
dated: selectedDay,
type: 'holiday'
};
const $event = {
target: {
closest: () => {
return {$ctrl: {}};
}
}
};
const $days = [selectedDay];
controller.events[selectedDay.getTime()] = expectedEvent;
controller.absenceType = {id: 1, code: 'holiday'};
controller.onSelection($event, $days);
expect(controller.delete).toHaveBeenCalledWith(jasmine.any(Object), selectedDay, expectedEvent);
});
it(`should call to the edit() method`, () => {
jest.spyOn(controller, 'edit').mockReturnThis();
const selectedDay = new Date();
const expectedEvent = {
dated: selectedDay,
type: 'leaveOfAbsence'
};
const $event = {
target: {
closest: () => {
return {$ctrl: {}};
}
}
};
const $days = [selectedDay];
controller.events[selectedDay.getTime()] = expectedEvent;
controller.absenceType = {id: 1, code: 'holiday'};
controller.onSelection($event, $days);
expect(controller.edit).toHaveBeenCalledWith(jasmine.any(Object), expectedEvent);
});
});
describe('create()', () => {
it(`should make a HTTP POST query and then call to the repaintCanceller() method`, () => {
jest.spyOn(controller, 'repaintCanceller').mockReturnThis();
const dated = new Date();
const calendarElement = {};
const expectedResponse = {id: 10};
$httpBackend.expect('POST', `Workers/106/createAbsence`).respond(200, expectedResponse);
controller.create(calendarElement, dated);
$httpBackend.flush();
const createdEvent = controller.events[dated.getTime()];
const absenceType = controller.absenceType;
expect(createdEvent.absenceId).toEqual(expectedResponse.id);
expect(createdEvent.color).toEqual(absenceType.rgb);
expect(controller.repaintCanceller).toHaveBeenCalled();
});
});
describe('edit()', () => {
it(`should make a HTTP PATCH query and then call to the repaintCanceller() method`, () => {
jest.spyOn(controller, 'repaintCanceller').mockReturnThis();
const event = {absenceId: 10};
const calendarElement = {};
const newAbsenceType = {
id: 2,
name: 'Leave of absence',
code: 'leaveOfAbsence',
rgb: 'purple'
};
controller.absenceType = newAbsenceType;
const expectedParams = {absenceId: 10, absenceTypeId: 2};
$httpBackend.expect('PATCH', `Workers/106/updateAbsence`, expectedParams).respond(200);
controller.edit(calendarElement, event);
$httpBackend.flush();
expect(event.name).toEqual(newAbsenceType.name);
expect(event.color).toEqual(newAbsenceType.rgb);
expect(event.type).toEqual(newAbsenceType.code);
expect(controller.repaintCanceller).toHaveBeenCalled();
});
});
describe('delete()', () => {
it(`should make a HTTP DELETE query and then call to the repaintCanceller() method`, () => {
jest.spyOn(controller, 'repaintCanceller').mockReturnThis();
const expectedParams = {absenceId: 10};
const calendarElement = {};
const selectedDay = new Date();
const expectedEvent = {
dated: selectedDay,
type: 'leaveOfAbsence',
absenceId: 10
};
controller.events[selectedDay.getTime()] = expectedEvent;
const serializedParams = $httpParamSerializer(expectedParams);
$httpBackend.expect('DELETE', `Workers/106/deleteAbsence?${serializedParams}`).respond(200);
controller.delete(calendarElement, selectedDay, expectedEvent);
$httpBackend.flush();
const event = controller.events[selectedDay.getTime()];
expect(event).toBeUndefined();
expect(controller.repaintCanceller).toHaveBeenCalled();
});
});
describe('repaintCanceller()', () => {
it(`should cancell the callback execution timer`, () => {
jest.spyOn(window, 'clearTimeout');
jest.spyOn(window, 'setTimeout');
const timeoutId = 90;
controller.canceller = timeoutId;
controller.repaintCanceller(() => {
return 'My callback';
});
expect(window.clearTimeout).toHaveBeenCalledWith(timeoutId);
expect(window.setTimeout).toHaveBeenCalledWith(jasmine.any(Function), 500);
});
});
describe('refresh()', () => {
it(`should make a HTTP GET query and then call to the onData() method`, () => {
jest.spyOn(controller, 'onData').mockReturnThis();
const dated = controller.date;
const started = new Date(dated.getTime());
started.setMonth(0);
started.setDate(1);
const ended = new Date(dated.getTime());
ended.setMonth(12);
ended.setDate(0);
controller.started = started;
controller.ended = ended;
const expecteResponse = [{id: 1}];
const expectedParams = {workerFk: 106, started: started, ended: ended};
const serializedParams = $httpParamSerializer(expectedParams);
$httpBackend.expect('GET', `WorkerCalendars/absences?${serializedParams}`).respond(200, expecteResponse);
controller.refresh();
$httpBackend.flush();
expect(controller.onData).toHaveBeenCalledWith(expecteResponse);
});
}); });
}); });
}); });