From 63ed592312378df7a84fb98e2f7e84659806a72a Mon Sep 17 00:00:00 2001 From: Joan Sanchez Date: Wed, 17 Jun 2020 11:51:57 +0200 Subject: [PATCH 1/3] 902 - Added unit tests --- modules/zone/front/descriptor/index.js | 1 + modules/zone/front/descriptor/index.spec.js | 74 +++++++++++++++++++++ modules/zone/front/summary/index.spec.js | 22 ++++++ modules/zone/front/warehouses/index.js | 9 +-- modules/zone/front/warehouses/index.spec.js | 60 +++++++++++++++++ 5 files changed, 162 insertions(+), 4 deletions(-) create mode 100644 modules/zone/front/descriptor/index.spec.js create mode 100644 modules/zone/front/warehouses/index.spec.js diff --git a/modules/zone/front/descriptor/index.js b/modules/zone/front/descriptor/index.js index 288267bfe6..5e365e0ac0 100644 --- a/modules/zone/front/descriptor/index.js +++ b/modules/zone/front/descriptor/index.js @@ -33,6 +33,7 @@ class Controller extends Descriptor { this.vnApp.showSuccess(this.$t('Zone deleted')); }); } + onCloneAccept() { return this.$http.post(`Zones/${this.id}/clone`). then(res => this.$state.go('zone.card.basicData', {id: res.data.id})); diff --git a/modules/zone/front/descriptor/index.spec.js b/modules/zone/front/descriptor/index.spec.js new file mode 100644 index 0000000000..23c6e3a3aa --- /dev/null +++ b/modules/zone/front/descriptor/index.spec.js @@ -0,0 +1,74 @@ +import './index.js'; + +describe('Zone descriptor', () => { + let $httpBackend; + let controller; + let $element; + + beforeEach(ngModule('zone')); + + beforeEach(angular.mock.inject(($componentController, _$httpBackend_) => { + $httpBackend = _$httpBackend_; + $element = angular.element(' {}, + show: () => {} + }; + })); + + describe('onDelete()', () => { + it('should make an HTTP POST query and then call the deleteZone show() method', () => { + jest.spyOn(controller.$.deleteZone, 'show'); + + const expectedData = [{id: 16}]; + $httpBackend.when('GET', 'Tickets').respond(expectedData); + controller.onDelete(); + $httpBackend.flush(); + + expect(controller.$.deleteZone.show).toHaveBeenCalledWith(); + }); + + it('should make an HTTP POST query and then call the deleteZone() method', () => { + jest.spyOn(controller, 'deleteZone').mockReturnThis(); + + const expectedData = []; + $httpBackend.when('GET', 'Tickets').respond(expectedData); + controller.onDelete(); + $httpBackend.flush(); + + expect(controller.deleteZone).toHaveBeenCalledWith(); + }); + }); + + describe('deleteZone()', () => { + it('should make an HTTP POST query and then call the showMessage() method', () => { + jest.spyOn(controller.$state, 'go').mockReturnThis(); + jest.spyOn(controller.vnApp, 'showSuccess'); + + const stateName = 'zone.index'; + $httpBackend.when('POST', 'Zones/1/deleteZone').respond(200); + controller.deleteZone(); + $httpBackend.flush(); + + expect(controller.$state.go).toHaveBeenCalledWith(stateName); + expect(controller.vnApp.showSuccess).toHaveBeenCalledWith('Zone deleted'); + }); + }); + + describe('onCloneAccept()', () => { + it('should make an HTTP POST query and then call the state go() method', () => { + jest.spyOn(controller.$state, 'go').mockReturnThis(); + + const stateName = 'zone.card.basicData'; + const expectedData = {id: 1}; + $httpBackend.when('POST', 'Zones/1/clone').respond(expectedData); + controller.onCloneAccept(); + $httpBackend.flush(); + + expect(controller.$state.go).toHaveBeenCalledWith(stateName, expectedData); + }); + }); +}); diff --git a/modules/zone/front/summary/index.spec.js b/modules/zone/front/summary/index.spec.js index 0956fa8c6b..49d6614ff6 100644 --- a/modules/zone/front/summary/index.spec.js +++ b/modules/zone/front/summary/index.spec.js @@ -51,4 +51,26 @@ describe('component vnZoneSummary', () => { expect(controller.summary).toBeDefined(); }); }); + + describe('getWarehouses()', () => { + it('should make an HTTP get query and then store data on the controller', () => { + controller._zone = {id: 1}; + const params = { + filter: { + include: { + relation: 'warehouse', + fields: ['name'] + } + } + }; + + const serializedParams = $httpParamSerializer(params); + const query = `Zones/1/warehouses?${serializedParams}`; + $httpBackend.expect('GET', query).respond([{id: 1}]); + controller.getWarehouses(); + $httpBackend.flush(); + + expect(controller.zoneWarehouses.length).toEqual(1); + }); + }); }); diff --git a/modules/zone/front/warehouses/index.js b/modules/zone/front/warehouses/index.js index 9191a1f491..f428561fd7 100644 --- a/modules/zone/front/warehouses/index.js +++ b/modules/zone/front/warehouses/index.js @@ -2,13 +2,14 @@ import ngModule from '../module'; import Section from 'salix/components/section'; class Controller extends Section { - constructor($element, $) { - super($element, $); - - this.path = `Zones/${this.$params.id}/warehouses`; + $onInit() { this.refresh(); } + get path() { + return `Zones/${this.$params.id}/warehouses`; + } + refresh() { let filter = {include: 'warehouse'}; this.$http.get(this.path, {params: {filter}}) diff --git a/modules/zone/front/warehouses/index.spec.js b/modules/zone/front/warehouses/index.spec.js new file mode 100644 index 0000000000..aa9cef2e1f --- /dev/null +++ b/modules/zone/front/warehouses/index.spec.js @@ -0,0 +1,60 @@ +import './index.js'; + +describe('Zone warehouses', () => { + let $httpBackend; + let $httpParamSerializer; + let controller; + let $element; + + beforeEach(ngModule('zone')); + + beforeEach(angular.mock.inject(($componentController, _$httpBackend_, _$httpParamSerializer_) => { + $httpBackend = _$httpBackend_; + $httpParamSerializer = _$httpParamSerializer_; + $element = angular.element(' { + it('should make an HTTP GET query and then set the data', () => { + const params = {filter: {include: 'warehouse'}}; + const serializedParams = $httpParamSerializer(params); + const path = `Zones/1/warehouses?${serializedParams}`; + $httpBackend.expect('GET', path).respond([{id: 1, name: 'Warehouse one'}]); + controller.refresh(); + $httpBackend.flush(); + + expect(controller.$.data).toBeDefined(); + }); + }); + + describe('onSave()', () => { + it('should make an HTTP POST query and then call the refresh() method', () => { + jest.spyOn(controller, 'refresh').mockReturnThis(); + + $httpBackend.expect('POST', `Zones/1/warehouses`).respond(200); + controller.onSave('accept'); + $httpBackend.flush(); + + expect(controller.selected).toBeNull(); + expect(controller.isNew).toBeNull(); + expect(controller.$.dialog.hide).toHaveBeenCalledWith(); + expect(controller.refresh).toHaveBeenCalledWith(); + }); + }); + + describe('delete()', () => { + it('should make an HTTP DELETE query and then set deleteRow property to null value', () => { + controller.deleteRow = {id: 1}; + controller.$.data = [{id: 1}]; + $httpBackend.expect('DELETE', `Zones/1/warehouses/1`).respond(200); + controller.delete(); + $httpBackend.flush(); + + expect(controller.deleteRow).toBeNull(); + }); + }); +}); From fa7391145231b926e5c0b9f09f03349487b11053 Mon Sep 17 00:00:00 2001 From: Joan Sanchez Date: Thu, 18 Jun 2020 12:43:33 +0200 Subject: [PATCH 2/3] Added tests --- modules/zone/front/events/index.js | 12 ++- modules/zone/front/events/index.spec.js | 103 ++++++++++++++++++++++++ 2 files changed, 113 insertions(+), 2 deletions(-) create mode 100644 modules/zone/front/events/index.spec.js diff --git a/modules/zone/front/events/index.js b/modules/zone/front/events/index.js index d965d18924..66822bfc1e 100644 --- a/modules/zone/front/events/index.js +++ b/modules/zone/front/events/index.js @@ -6,12 +6,20 @@ class Controller extends Section { super($element, $); this.vnWeekDays = vnWeekDays; this.editMode = 'include'; + } - this.path = `Zones/${this.$params.id}/events`; - this.exclusionsPath = `Zones/${this.$params.id}/exclusions`; + $onInit() { this.refresh(); } + get path() { + return `Zones/${this.$params.id}/events`; + } + + get exclusionsPath() { + return `Zones/${this.$params.id}/exclusions`; + } + refresh() { let data = {}; this.$q.all([ diff --git a/modules/zone/front/events/index.spec.js b/modules/zone/front/events/index.spec.js new file mode 100644 index 0000000000..5f4347f312 --- /dev/null +++ b/modules/zone/front/events/index.spec.js @@ -0,0 +1,103 @@ +import './index'; + +describe('component vnZoneEvents', () => { + let $scope; + let controller; + let $httpBackend; + let $httpParamSerializer; + + beforeEach(ngModule('zone')); + + beforeEach(angular.mock.inject(($componentController, $rootScope, _$httpBackend_, _$httpParamSerializer_) => { + $httpBackend = _$httpBackend_; + $httpParamSerializer = _$httpParamSerializer_; + $scope = $rootScope.$new(); + const $element = angular.element(``); + controller = $componentController('vnZoneEvents', {$element, $scope}); + controller.$params = {id: 1}; + })); + + describe('refresh()', () => { + it('should set the zone and then call both getSummary() and getWarehouses()', () => { + $httpBackend.expectGET(`Zones/1/events`).respond({id: 1}); + $httpBackend.expectGET(`Zones/1/exclusions`).respond({id: 1}); + controller.refresh(); + $httpBackend.flush(); + + const data = controller.$.data; + + expect(data.events).toBeDefined(); + expect(data.exclusions).toBeDefined(); + }); + }); + + describe('onSelection()', () => { + it('should call the edit() method', () => { + jest.spyOn(controller, 'edit').mockReturnThis(); + + const weekday = {}; + const days = []; + const type = 'EventType'; + const events = [{name: 'Event'}]; + const exclusions = []; + controller.editMode = 'include'; + controller.onSelection(days, type, weekday, events, exclusions); + + expect(controller.edit).toHaveBeenCalledWith({name: 'Event'}); + }); + + it('should call the create() method', () => { + jest.spyOn(controller, 'create').mockReturnThis(); + + const weekday = {dated: new Date()}; + const days = [weekday]; + const type = 'EventType'; + const events = []; + const exclusions = []; + controller.editMode = 'include'; + controller.onSelection(days, type, weekday, events, exclusions); + + expect(controller.create).toHaveBeenCalledWith(type, days, weekday); + }); + + it('should call the exclusionDelete() method', () => { + jest.spyOn(controller, 'exclusionDelete').mockReturnThis(); + + const weekday = {}; + const days = []; + const type = 'EventType'; + const events = []; + const exclusions = [{id: 1}]; + controller.editMode = 'delete'; + controller.onSelection(days, type, weekday, events, exclusions); + + expect(controller.exclusionDelete).toHaveBeenCalledWith(exclusions); + }); + + it('should call the exclusionCreate() method', () => { + jest.spyOn(controller, 'exclusionCreate').mockReturnThis(); + + const weekday = {}; + const days = [{dated: new Date()}]; + const type = 'EventType'; + const events = []; + const exclusions = []; + controller.editMode = 'delete'; + controller.onSelection(days, type, weekday, events, exclusions); + + expect(controller.exclusionCreate).toHaveBeenCalledWith(days); + }); + }); + + describe('onDeleteResponse()', () => { + it('', () => { }); + }); + + describe('exclusionCreate()', () => { + it('', () => { }); + }); + + describe('exclusionDelete()', () => { + it('', () => { }); + }); +}); From 3cb783740fbfa35b4bb47024229df346cea34b70 Mon Sep 17 00:00:00 2001 From: Joan Sanchez Date: Mon, 22 Jun 2020 10:01:55 +0200 Subject: [PATCH 3/3] Added unit tests --- modules/zone/front/calendar/index.js | 2 +- modules/zone/front/calendar/index.spec.js | 155 ++++++++++++++++++++++ modules/zone/front/events/index.spec.js | 125 ++++++++++++++++- modules/zone/front/location/index.spec.js | 50 +++++++ 4 files changed, 325 insertions(+), 7 deletions(-) create mode 100644 modules/zone/front/calendar/index.spec.js create mode 100644 modules/zone/front/location/index.spec.js diff --git a/modules/zone/front/calendar/index.js b/modules/zone/front/calendar/index.js index 702a0a0d99..e9265621eb 100644 --- a/modules/zone/front/calendar/index.js +++ b/modules/zone/front/calendar/index.js @@ -76,7 +76,7 @@ class Controller extends Component { let events = value.events; if (events) { - for (event of events) { + for (let event of events) { event.dated = toStamp(event.dated); event.ended = toStamp(event.ended); event.started = toStamp(event.started); diff --git a/modules/zone/front/calendar/index.spec.js b/modules/zone/front/calendar/index.spec.js new file mode 100644 index 0000000000..6ea5240204 --- /dev/null +++ b/modules/zone/front/calendar/index.spec.js @@ -0,0 +1,155 @@ +import './index'; +import crudModel from 'core/mocks/crud-model'; + +describe('component vnZoneCalendar', () => { + let $scope; + let controller; + let $httpBackend; + + beforeEach(ngModule('zone')); + + beforeEach(angular.mock.inject(($componentController, $rootScope, _$httpBackend_) => { + $httpBackend = _$httpBackend_; + $scope = $rootScope.$new(); + const $element = angular.element(``); + controller = $componentController('vnZoneCalendar', {$element, $scope}); + controller.$.model = crudModel; + controller.zone = {id: 1}; + controller.days = []; + controller.exclusions = []; + })); + + describe('date() setter', () => { + it('should set the month property and then call the refreshEvents() method', () => { + jest.spyOn(controller, 'refreshEvents').mockReturnThis(); + + controller.date = new Date(); + + expect(controller.refreshEvents).toHaveBeenCalledWith(); + expect(controller.months.length).toEqual(4); + }); + }); + + describe('step()', () => { + it('should set the date month to 4 months backwards', () => { + const now = new Date(); + now.setMonth(now.getMonth() - 4); + + controller.step(-1); + + const expectedMonth = now.getMonth(); + const currentMonth = controller.date.getMonth(); + + expect(currentMonth).toEqual(expectedMonth); + }); + + it('should set the date month to 4 months forwards', () => { + const now = new Date(); + now.setMonth(now.getMonth() + 4); + + controller.step(1); + + const expectedMonth = now.getMonth(); + const currentMonth = controller.date.getMonth(); + + expect(currentMonth).toEqual(expectedMonth); + }); + }); + + describe('data() setter', () => { + it('should set the events and exclusions and then call the refreshEvents() method', () => { + jest.spyOn(controller, 'refreshEvents').mockReturnThis(); + + controller.data = { + exclusions: [{ + dated: new Date() + }], + events: [{ + dated: new Date() + }] + }; + + expect(controller.refreshEvents).toHaveBeenCalledWith(); + expect(controller.events).toBeDefined(); + expect(controller.events.length).toEqual(1); + expect(controller.exclusions).toBeDefined(); + expect(Object.keys(controller.exclusions).length).toEqual(1); + }); + }); + + describe('refreshEvents()', () => { + it('should fill the days property with the events.', () => { + controller.data = []; + controller.firstDay = new Date(); + + const lastDay = new Date(); + lastDay.setDate(lastDay.getDate() + 10); + controller.lastDay = lastDay; + + const firstEventStamp = controller.firstDay.getTime(); + const lastEventStamp = controller.lastDay.getTime(); + controller.events = [{ + type: 'day', + dated: firstEventStamp + }, + { + type: 'day', + dated: lastEventStamp + }]; + + controller.refreshEvents(); + const expectedDays = Object.keys(controller.days); + + expect(expectedDays.length).toEqual(2); + }); + }); + + describe('onSelection()', () => { + it('should call the emit() method', () => { + jest.spyOn(controller, 'emit'); + + const $event = {}; + const $days = [new Date()]; + const $type = 'day'; + const $weekday = 1; + + controller.onSelection($event, $days, $type, $weekday); + + expect(controller.emit).toHaveBeenCalledWith('selection', + { + $days: $days, + $event: {}, + $events: [], + $exclusions: [], + $type: 'day', + $weekday: 1 + } + ); + }); + }); + + describe('hasEvents()', () => { + it('should return true for an existing event on a date', () => { + const dated = new Date(); + + controller.days[dated.getTime()] = true; + + const result = controller.hasEvents(dated); + + expect(result).toBeTruthy(); + }); + }); + + describe('getClass()', () => { + it('should return the className "excluded" for an excluded date', () => { + const dated = new Date(); + + controller.exclusions = []; + controller.exclusions[dated.getTime()] = true; + + const result = controller.getClass(dated); + + expect(result).toEqual('excluded'); + }); + }); +}); diff --git a/modules/zone/front/events/index.spec.js b/modules/zone/front/events/index.spec.js index 5f4347f312..9d60ab901d 100644 --- a/modules/zone/front/events/index.spec.js +++ b/modules/zone/front/events/index.spec.js @@ -4,13 +4,11 @@ describe('component vnZoneEvents', () => { let $scope; let controller; let $httpBackend; - let $httpParamSerializer; beforeEach(ngModule('zone')); - beforeEach(angular.mock.inject(($componentController, $rootScope, _$httpBackend_, _$httpParamSerializer_) => { + beforeEach(angular.mock.inject(($componentController, $rootScope, _$httpBackend_) => { $httpBackend = _$httpBackend_; - $httpParamSerializer = _$httpParamSerializer_; $scope = $rootScope.$new(); const $element = angular.element(``); controller = $componentController('vnZoneEvents', {$element, $scope}); @@ -89,15 +87,130 @@ describe('component vnZoneEvents', () => { }); }); + describe('create()', () => { + it('shoud set the selected property and then call the dialog show() method', () => { + controller.$.dialog = {show: jest.fn()}; + + const type = 'weekday'; + const days = [new Date()]; + const weekday = 1; + controller.create(type, days, weekday); + + const selection = controller.selected; + const firstWeekday = selection.wdays[weekday]; + + expect(selection.type).toEqual('indefinitely'); + expect(firstWeekday).toBeTruthy(); + expect(controller.isNew).toBeTruthy(); + expect(controller.$.dialog.show).toHaveBeenCalledWith(); + }); + + it('shoud set the selected property with the first day and then call the dialog show() method', () => { + controller.$.dialog = {show: jest.fn()}; + + const type = 'nonListedType'; + const days = [new Date()]; + const weekday = 1; + controller.create(type, days, weekday); + + const selection = controller.selected; + + expect(selection.type).toEqual('day'); + expect(selection.dated).toEqual(days[0]); + expect(controller.isNew).toBeTruthy(); + expect(controller.$.dialog.show).toHaveBeenCalledWith(); + }); + }); + + describe('onIncludeResponse()', () => { + it('shoud call the onDelete() method', () => { + jest.spyOn(controller, 'onDelete').mockReturnValue( + new Promise(accept => accept()) + ); + + controller.selected = {id: 1}; + controller.onIncludeResponse('delete'); + + expect(controller.onDelete).toHaveBeenCalledWith(1); + }); + + it('shoud make an HTTP POST query to create a new one and then call the refresh() method', () => { + jest.spyOn(controller, 'refresh').mockReturnThis(); + + controller.selected = {id: 1}; + controller.isNew = true; + + $httpBackend.when('POST', `Zones/1/events`).respond(200); + controller.onIncludeResponse('accept'); + $httpBackend.flush(); + + expect(controller.refresh).toHaveBeenCalledWith(); + }); + + it('shoud make an HTTP PUT query and then call the refresh() method', () => { + jest.spyOn(controller, 'refresh').mockReturnThis(); + + controller.selected = {id: 1}; + controller.isNew = false; + + const eventId = 1; + $httpBackend.when('PUT', `Zones/1/events/${eventId}`).respond(200); + controller.onIncludeResponse('accept'); + $httpBackend.flush(); + + expect(controller.refresh).toHaveBeenCalledWith(); + }); + }); + describe('onDeleteResponse()', () => { - it('', () => { }); + it('shoud make an HTTP DELETE query and then call the refresh() method', () => { + jest.spyOn(controller, 'refresh').mockReturnThis(); + + const eventId = 1; + $httpBackend.expect('DELETE', `Zones/1/events/1`).respond({id: 1}); + controller.onDeleteResponse('accept', eventId); + $httpBackend.flush(); + + expect(controller.refresh).toHaveBeenCalledWith(); + }); }); describe('exclusionCreate()', () => { - it('', () => { }); + it('shoud make an HTTP POST query and then call the refresh() method', () => { + jest.spyOn(controller, 'refresh').mockReturnThis(); + + const dates = [new Date()]; + $httpBackend.expect('POST', `Zones/1/exclusions`).respond({id: 1}); + controller.exclusionCreate(dates); + $httpBackend.flush(); + + expect(controller.refresh).toHaveBeenCalledWith(); + }); }); describe('exclusionDelete()', () => { - it('', () => { }); + it('shoud make an HTTP DELETE query once and then call the refresh() method', () => { + jest.spyOn(controller, 'refresh').mockReturnThis(); + + const exclusions = [{id: 1}]; + const firstExclusionId = 1; + $httpBackend.when('DELETE', `Zones/1/exclusions/${firstExclusionId}`).respond(200); + controller.exclusionDelete(exclusions); + $httpBackend.flush(); + + expect(controller.refresh).toHaveBeenCalledWith(); + }); + + it('shoud make an HTTP DELETE query for every event and then call the refresh() method', () => { + jest.spyOn(controller, 'refresh').mockReturnThis(); + jest.spyOn(controller.$http, 'delete').mockReturnValue(200); + + const exclusions = [{id: 1}, {id: 2}, {id: 3}, {id: 4}]; + controller.exclusionDelete(exclusions); + $scope.$apply(); + + expect(controller.$http.delete).toHaveBeenCalledTimes(4); + expect(controller.refresh).toHaveBeenCalledWith(); + }); }); }); diff --git a/modules/zone/front/location/index.spec.js b/modules/zone/front/location/index.spec.js new file mode 100644 index 0000000000..6f2b139c02 --- /dev/null +++ b/modules/zone/front/location/index.spec.js @@ -0,0 +1,50 @@ +import './index'; +import crudModel from 'core/mocks/crud-model'; + +describe('component vnZoneLocation', () => { + let $scope; + let controller; + let $httpBackend; + + beforeEach(ngModule('zone')); + + beforeEach(angular.mock.inject(($componentController, $rootScope, _$httpBackend_) => { + $httpBackend = _$httpBackend_; + $scope = $rootScope.$new(); + const $element = angular.element(``); + controller = $componentController('vnZoneLocation', {$element, $scope}); + controller.$.model = crudModel; + controller.zone = {id: 1}; + })); + + describe('onSearch()', () => { + it('should call the applyFilter() method and then set the data', () => { + controller.$.treeview = {}; + controller.onSearch({}); + + const treeviewData = controller.$.treeview.data; + + expect(treeviewData).toBeDefined(); + expect(treeviewData.length).toEqual(3); + }); + }); + + describe('onFetch()', () => { + it('should call the applyFilter() method and then return the model data', () => { + const result = controller.onFetch(); + + expect(result.length).toEqual(3); + }); + }); + + describe('onSelection()', () => { + it('should make an HTTP POST query', () => { + const item = {id: 123}; + + const expectedParams = {geoId: 123, isIncluded: true}; + $httpBackend.expect('POST', `zones/1/toggleIsIncluded`, expectedParams).respond(200); + controller.onSelection(true, item); + $httpBackend.flush(); + }); + }); +});