From e53af13b3ce94d1a2362c4f2807e4fc48355a068 Mon Sep 17 00:00:00 2001 From: carlosjr Date: Thu, 18 Nov 2021 11:04:51 +0100 Subject: [PATCH 1/2] unit tests for smart table and ticket index --- front/core/components/smart-table/index.js | 16 +-- .../core/components/smart-table/index.spec.js | 97 +++++++++++++++++++ .../monitor/front/index/tickets/index.spec.js | 18 ++++ 3 files changed, 116 insertions(+), 15 deletions(-) create mode 100644 front/core/components/smart-table/index.spec.js diff --git a/front/core/components/smart-table/index.js b/front/core/components/smart-table/index.js index f32d8aa4f..cc359e41f 100644 --- a/front/core/components/smart-table/index.js +++ b/front/core/components/smart-table/index.js @@ -54,20 +54,6 @@ export default class SmartTable extends Component { set viewConfigId(value) { this._viewConfigId = value; - - /* if (value) { - this.defaultViewConfig = {}; - - const url = 'DefaultViewConfigs'; - const filter = {where: {tableCode: value}}; - this.$http.get(url, {filter}) - .then(res => { - if (res && res.data.length) { - const columns = res.data[0].columns; - this.defaultViewConfig = columns; - } - }); - } */ } getDefaultViewConfig() { @@ -163,7 +149,7 @@ export default class SmartTable extends Component { } } - let styleElement = document.querySelector('style[id="smart-table"]'); + const styleElement = document.querySelector('style[id="smart-table"]'); if (styleElement) styleElement.parentNode.removeChild(styleElement); diff --git a/front/core/components/smart-table/index.spec.js b/front/core/components/smart-table/index.spec.js new file mode 100644 index 000000000..d0ff2f53f --- /dev/null +++ b/front/core/components/smart-table/index.spec.js @@ -0,0 +1,97 @@ +describe('Component smartTable', () => { + let $element; + let controller; + let $httpBackend; + + beforeEach(ngModule('vnCore')); + + beforeEach(inject(($compile, $rootScope, _$httpBackend_) => { + $httpBackend = _$httpBackend_; + $element = $compile(``)($rootScope); + controller = $element.controller('smartTable'); + })); + + afterEach(() => { + $element.remove(); + }); + + describe('options setter()', () => { + it(`should throw an error if the table doesn't have an identifier`, () => { + const options = {activeButtons: {shownColumns: []}}; + + expect(() => controller.options = options).toThrowError(/View identifier not defined/); + }); + + it('should not throw an error if the table does have an identifier', () => { + const options = {activeButtons: {shownColumns: []}}; + controller.viewConfigId = 'test'; + + expect(() => controller.options = options).not.toThrow(); + }); + }); + + describe('getDefaultViewConfig()', () => { + it('should perform a query and return the default view columns', done => { + const expectedResponse = [{ + columns: {} + }]; + + $httpBackend.expectGET('DefaultViewConfigs').respond(expectedResponse); + controller.getDefaultViewConfig().then(columns => { + expect(columns).toEqual(expectedResponse[0].columns); + done(); + }).catch(done.fail); + $httpBackend.flush(); + }); + }); + + describe('viewConfig setter', () => { + it('should just call applyViewConfig() if a viewConfig was provided', () => { + spyOn(controller, 'applyViewConfig'); + controller.viewConfig = [{}]; + + expect(controller.applyViewConfig).toHaveBeenCalled(); + }); + + it('should not get a defaultConfig then insert a new one', () => { + spyOn(controller, 'applyViewConfig'); + + controller.$.userViewModel = { + insert: jest.fn() + }; + + const emptyResponse = [{ + columns: {} + }]; + + controller.columns = [ + {field: 'test1'}, + {field: 'test2'} + ]; + + $httpBackend.expectGET('DefaultViewConfigs').respond(emptyResponse); + controller.viewConfig = []; + $httpBackend.flush(); + + const expectedObject = {configuration: {'test1': true, 'test2': true}}; + + expect(controller.$.userViewModel.insert).toHaveBeenCalledWith(expect.objectContaining(expectedObject)); + expect(controller.applyViewConfig).toHaveBeenCalled(); + }); + }); + + describe('applyViewConfig()', () => { + it('should ', () => { + controller.$.userViewModel = { + viewConfig: {'test1': true, 'test2': false} + }; + + controller._columns = [ + {field: 'test1'}, + {field: 'test2'} + ]; + + controller.applyViewConfig(); + }); + }); +}); diff --git a/modules/monitor/front/index/tickets/index.spec.js b/modules/monitor/front/index/tickets/index.spec.js index 8d06b8d7d..fb507dbbc 100644 --- a/modules/monitor/front/index/tickets/index.spec.js +++ b/modules/monitor/front/index/tickets/index.spec.js @@ -123,6 +123,24 @@ describe('Component vnMonitorSalesTickets', () => { }); }); + describe('dateRange()', () => { + it('should return two dates with the hours at the start and end of the given date', () => { + const now = new Date(); + + const today = now.getDate(); + + const dateRange = controller.dateRange(now); + const start = dateRange[0].toString(); + const end = dateRange[1].toString(); + + expect(start).toContain(today); + expect(start).toContain('00:00:00'); + + expect(end).toContain(today); + expect(end).toContain('23:59:59'); + }); + }); + describe('preview()', () => { it('should show the dialog summary', () => { controller.$.summary = {show: () => {}}; From 372d5ade17b1cf73798c46b14c78949439592e28 Mon Sep 17 00:00:00 2001 From: carlosjr Date: Tue, 23 Nov 2021 13:58:12 +0100 Subject: [PATCH 2/2] refactor(smartTable): removeProp updated and tests --- front/core/components/contextmenu/index.js | 23 +-- front/core/components/smart-table/index.js | 28 ++-- .../core/components/smart-table/index.spec.js | 150 ++++++++++++++++-- 3 files changed, 173 insertions(+), 28 deletions(-) diff --git a/front/core/components/contextmenu/index.js b/front/core/components/contextmenu/index.js index fa1db6887..a7980b435 100755 --- a/front/core/components/contextmenu/index.js +++ b/front/core/components/contextmenu/index.js @@ -223,26 +223,29 @@ export default class Contextmenu { delete userFilter.where; } - function removeProp(instance, findProp, prop) { - if (prop == findProp) - delete instance[prop]; + function removeProp(obj, targetProp, prop) { + if (prop == targetProp) + delete obj[prop]; if (prop === 'and' || prop === 'or') { - const instanceCopy = instance[prop].slice(); - for (let param of instanceCopy) { + const arrayCopy = obj[prop].slice(); + for (let param of arrayCopy) { const [key] = Object.keys(param); - const index = instance[prop].findIndex(param => { + const index = obj[prop].findIndex(param => { return Object.keys(param)[0] == key; }); - if (key == findProp) - instance[prop].splice(index, 1); + if (key == targetProp) + obj[prop].splice(index, 1); if (param[key] instanceof Array) removeProp(param, filterKey, key); + + if (Object.keys(param).length == 0) + obj[prop].splice(index, 1); } - if (instance[prop].length == 0) - delete instance[prop]; + if (obj[prop].length == 0) + delete obj[prop]; } } diff --git a/front/core/components/smart-table/index.js b/front/core/components/smart-table/index.js index cc359e41f..93d5f9394 100644 --- a/front/core/components/smart-table/index.js +++ b/front/core/components/smart-table/index.js @@ -365,23 +365,33 @@ export default class SmartTable extends Component { for (let key of whereKeys) { removeProp(where, field, key); - if (!Object.keys(where)) + if (Object.keys(where).length == 0) delete userFilter.where; } - function removeProp(instance, findProp, prop) { - if (prop == findProp) - delete instance[prop]; + function removeProp(obj, targetProp, prop) { + if (prop == targetProp) + delete obj[prop]; - if (prop === 'and') { - for (let [index, param] of instance[prop].entries()) { + if (prop === 'and' || prop === 'or') { + const arrayCopy = obj[prop].slice(); + for (let param of arrayCopy) { const [key] = Object.keys(param); - if (key == findProp) - instance[prop].splice(index, 1); + const index = obj[prop].findIndex(param => { + return Object.keys(param)[0] == key; + }); + if (key == targetProp) + obj[prop].splice(index, 1); if (param[key] instanceof Array) removeProp(param, field, key); + + if (Object.keys(param).length == 0) + obj[prop].splice(index, 1); } + + if (obj[prop].length == 0) + delete obj[prop]; } } @@ -415,7 +425,7 @@ export default class SmartTable extends Component { if (!model.isChanged) return this.vnApp.showError(this.$t('No changes to save')); - this.model.save() + return this.model.save() .then(() => this.vnApp.showSuccess(this.$t('Data saved!'))); } } diff --git a/front/core/components/smart-table/index.spec.js b/front/core/components/smart-table/index.spec.js index d0ff2f53f..9b8cc1d09 100644 --- a/front/core/components/smart-table/index.spec.js +++ b/front/core/components/smart-table/index.spec.js @@ -80,18 +80,150 @@ describe('Component smartTable', () => { }); }); - describe('applyViewConfig()', () => { - it('should ', () => { - controller.$.userViewModel = { - viewConfig: {'test1': true, 'test2': false} + describe('addFilter()', () => { + it('should call the model addFilter() with a basic where filter if exprBuilder() was not received', () => { + controller.model = {addFilter: jest.fn()}; + + controller.addFilter('myField', 'myValue'); + + const expectedFilter = { + where: { + myField: 'myValue' + } }; - controller._columns = [ - {field: 'test1'}, - {field: 'test2'} - ]; + expect(controller.model.addFilter).toHaveBeenCalledWith(expectedFilter); + }); - controller.applyViewConfig(); + it('should call the model addFilter() with a built where filter resultant of exprBuilder()', () => { + controller.exprBuilder = jest.fn().mockReturnValue({builtField: 'builtValue'}); + controller.model = {addFilter: jest.fn()}; + + controller.addFilter('myField', 'myValue'); + + const expectedFilter = { + where: { + builtField: 'builtValue' + } + }; + + expect(controller.model.addFilter).toHaveBeenCalledWith(expectedFilter); + }); + }); + + describe('applySort()', () => { + it('should call the model refresh() without making changes on the model order', () => { + controller.model = {refresh: jest.fn()}; + + controller.applySort(); + + expect(controller.model.order).toBeUndefined(); + expect(controller.model.refresh).toHaveBeenCalled(); + }); + + it('should call the model.refresh() after setting model order according to the controller sortCriteria', () => { + controller.model = {refresh: jest.fn()}; + const orderBy = {field: 'myField', sortType: 'ASC'}; + controller.sortCriteria = [orderBy]; + + controller.applySort(); + + expect(controller.model.order).toEqual(`${orderBy.field} ${orderBy.sortType}`); + expect(controller.model.refresh).toHaveBeenCalled(); + }); + }); + + describe('filterSanitizer()', () => { + it('should remove the where filter after leaving no fields in it', () => { + controller.model = { + userFilter: { + where: {fieldToRemove: 'valueToRemove'} + }, + userParams: {} + }; + + const result = controller.filterSanitizer('fieldToRemove'); + + const exectedObject = {userFilter: {}, userParams: {}}; + + expect(result).toEqual(exectedObject); + }); + + it('should remove the where filter after leaving no fields and "empty ands/ors" in it', () => { + controller.model = { + userFilter: { + where: { + and: [ + {aFieldToRemove: 'aValueToRemove'}, + {aFieldToRemove: 'aValueToRemove'}, + { + or: [ + {aFieldToRemove: 'aValueToRemove'}, + {aFieldToRemove: 'aValueToRemove'}, + ] + } + ] + } + }, + userParams: {} + }; + + const result = controller.filterSanitizer('aFieldToRemove'); + + const exectedObject = {userFilter: {}, userParams: {}}; + + expect(result).toEqual(exectedObject); + }); + + it('should not remove the where filter after leaving no empty "ands/ors" in it', () => { + controller.model = { + userFilter: { + where: { + and: [ + {aFieldToRemove: 'aValueToRemove'}, + {aFieldToRemove: 'aValueToRemove'}, + { + or: [ + {aFieldToRemove: 'aValueToRemove'}, + {aFieldToRemove: 'aValueToRemove'}, + ] + } + ], + or: [{dontKillMe: 'thanks'}] + } + }, + userParams: {} + }; + + const result = controller.filterSanitizer('aFieldToRemove'); + + const exectedObject = {userFilter: {where: {or: [{dontKillMe: 'thanks'}]}}, userParams: {}}; + + expect(result).toEqual(exectedObject); + }); + }); + + describe('saveAll()', () => { + it('should throw an error if there are no changes to save in the model', () => { + jest.spyOn(controller.vnApp, 'showError'); + controller.model = {isChanged: false}; + controller.saveAll(); + + expect(controller.vnApp.showError).toHaveBeenCalledWith('No changes to save'); + }); + + it('should call the showSuccess() if there are changes to save in the model', done => { + jest.spyOn(controller.vnApp, 'showSuccess'); + + controller.model = { + save: jest.fn().mockReturnValue(Promise.resolve()), + isChanged: true + }; + + controller.saveAll().then(() => { + expect(controller.vnApp.showSuccess).toHaveBeenCalledWith('Data saved!'); + done(); + }).catch(done.fail); }); }); });