diff --git a/front/core/components/searchbar/searchbar.js b/front/core/components/searchbar/searchbar.js index b9c761874..3ccc2a316 100644 --- a/front/core/components/searchbar/searchbar.js +++ b/front/core/components/searchbar/searchbar.js @@ -77,9 +77,9 @@ export default class Searchbar extends Component { } fetchStateFilter(autoLoad) { - if (this.$state.is(this.searchState)) { - let filter = null; + let filter = null; + if (this.$state.is(this.searchState)) { if (this.$params.q) { try { filter = JSON.parse(this.$params.q); @@ -90,10 +90,9 @@ export default class Searchbar extends Component { if (!filter && autoLoad) filter = {}; + } - this.doSearch(filter, 'state'); - } else - this.clearSearch(); + this.doSearch(filter, 'state'); } openPanel(event) { @@ -185,28 +184,78 @@ export default class Searchbar extends Component { }); } - clearSearch() { - if (!this.filter) return; - if (this.model) this.model.clear(); - this.filter = null; - } - doSearch(filter, source) { - let promise; - - if (this.model) - promise = this.modelSearch(filter); - else if (this.onSearch) - promise = this.onSearch({$params: filter}); - + if (filter === this.filter) return; + let promise = this.onSearch({$params: filter}); promise = promise || this.$q.resolve(); promise.then(data => this.onFilter(filter, source, data)); } - modelSearch(filter) { + onFilter(filter, source, data) { + let state; + let params; + let opts; + + if (filter) { + let oneResult = this.autoState + && source != 'state' + && data + && data.length == 1; + + if (oneResult) { + let baseDepth = this.baseState.split('.').length; + let stateParts = this.$state.current.name + .split('.') + .slice(baseDepth); + + let subState = stateParts[0]; + + switch (subState) { + case 'card': + subState += `.${stateParts[1]}`; + if (stateParts.length >= 3) + subState += '.index'; + break; + default: + subState = 'card.summary'; + } + + if (this.stateParams) + params = this.stateParams({$row: data[0]}); + + state = `${this.baseState}.${subState}`; + filter = null; + } else { + state = this.searchState; + + if (filter) + params = {q: JSON.stringify(filter)}; + if (this.$state.is(state)) + opts = {location: 'replace'}; + } + } + + this.filter = filter; + + if (source != 'state') + this.transition = this.$state.go(state, params, opts).transition; + if (source != 'bar') + focus(this.element.querySelector('vn-textfield input')); + } + + // Default search handlers + + stateParams(params) { + return {id: params.$row.id}; + } + + onSearch(args) { + if (!this.model) return; + let filter = args.$params; + if (filter === null) { this.model.clear(); - return this.$q.resolve(); + return; } let where = null; @@ -226,53 +275,8 @@ export default class Searchbar extends Component { .then(() => this.model.data); } - onFilter(filter, source, data) { - let state; - let params; - let opts; - - if (data && data.length == 1 && this.autoState && source != 'state') { - let baseDepth = this.baseState.split('.').length; - let stateParts = this.$state.current.name - .split('.') - .slice(baseDepth); - - let subState = stateParts[0]; - - switch (subState) { - case 'card': - subState += `.${stateParts[1]}`; - if (stateParts.length >= 3) - subState += '.index'; - break; - default: - subState = 'card.summary'; - } - - if (this.singleParams) - params = this.singleParams({$row: data[0]}); - - state = `${this.baseState}.${subState}`; - filter = null; - } else { - state = this.searchState; - - if (filter) - params = {q: JSON.stringify(filter)}; - if (this.$state.is(state)) - opts = {location: 'replace'}; - } - - this.filter = filter; - - if (source != 'state') - this.transition = this.$state.go(state, params, opts).transition; - if (source != 'bar') - focus(this.element.querySelector('vn-textfield input')); - } - - singleParams(params) { - return {id: params.$row.id}; + onClear() { + if (this.model) this.model.clear(); } } @@ -285,11 +289,11 @@ ngModule.vnComponent('vnSearchbar', { panel: '@', info: '@?', onSearch: '&?', - model: ' { describe('$postLink()', () => { it(`should fetch the filter from the state if it's in the filter state`, () => { + jest.spyOn(controller, 'doSearch'); + + controller.autoState = false; controller.$postLink(); - expect(controller.filter).toEqual(filter); - expect(controller.searchString).toBe('needle'); - expect(controller.params.length).toBe(1); + expect(controller.doSearch).toHaveBeenCalledWith(filter, 'state'); }); it(`should not fetch the filter from the state if not in the filter state`, () => { + jest.spyOn(controller, 'doSearch'); + + controller.autoState = false; controller.searchState = 'other.state'; controller.$postLink(); - expect(controller.filter).toBeNull(); - expect(controller.searchString).toBeNull(); - expect(controller.params.length).toBe(0); + expect(controller.doSearch).toHaveBeenCalledWith(null, 'state'); }); }); @@ -67,6 +69,14 @@ describe('Component vnSearchbar', () => { expect(chips.negated).toBe('not negated'); expect(chips.myObjectProp).toBe('myObjectProp'); }); + + it(`should clear the filter when null`, () => { + controller.filter = null; + + expect(controller.filter).toBeNull(); + expect(controller.searchString).toBeNull(); + expect(controller.params.length).toBe(0); + }); }); describe('shownFilter() getter', () => { @@ -98,6 +108,7 @@ describe('Component vnSearchbar', () => { describe('onPanelSubmit()', () => { it(`should compact and define the filter`, () => { controller.$.popover = {hide: jasmine.createSpy('hide')}; + jest.spyOn(controller, 'doSearch'); const filter = { id: 1, @@ -110,42 +121,54 @@ describe('Component vnSearchbar', () => { }; controller.onPanelSubmit(filter); - expect(controller.filter).toEqual({ + expect(controller.doSearch).toHaveBeenCalledWith({ id: 1, myObject: {keepThis: true}, myArray: [true] - }); + }, 'panel'); }); }); describe('onSubmit()', () => { it(`should define the filter`, () => { + jest.spyOn(controller, 'doSearch'); + controller.filter = filter; controller.searchString = 'mySearch'; controller.onSubmit(); - expect(controller.filter).toEqual({id: 1, search: 'mySearch'}); + expect(controller.doSearch).toHaveBeenCalledWith({ + id: 1, + search: 'mySearch' + }, 'bar'); }); }); describe('removeParam()', () => { it(`should remove the parameter from the filter`, () => { + jest.spyOn(controller, 'doSearch'); + controller.filter = filter; controller.removeParam(0); - expect(controller.filter).toEqual({search: 'needle'}); + expect(controller.doSearch).toHaveBeenCalledWith({ + search: 'needle' + }, 'bar'); }); }); describe('doSearch()', () => { it(`should go to the search state and pass the filter as query param`, () => { jest.spyOn($state, 'go'); + + controller.autoState = false; controller.searchState = 'search.state'; controller.doSearch(filter); + $scope.$apply(); let queryParams = {q: JSON.stringify(filter)}; - expect($state.go).toHaveBeenCalledWith('search.state', queryParams, null); + expect($state.go).toHaveBeenCalledWith('search.state', queryParams, undefined); expect(controller.filter).toEqual(filter); }); }); diff --git a/modules/travel/front/index/index.js b/modules/travel/front/index/index.js index ca45f8452..fe2f7e8a9 100644 --- a/modules/travel/front/index/index.js +++ b/modules/travel/front/index/index.js @@ -1,9 +1,8 @@ import ngModule from '../module'; export default class Controller { - constructor($scope) { - this.$ = $scope; - this.ticketSelected = null; + constructor($) { + this.$ = $; } preview(event, travel) { @@ -13,7 +12,6 @@ export default class Controller { event.stopImmediatePropagation(); } } - Controller.$inject = ['$scope']; ngModule.component('vnTravelIndex', { diff --git a/modules/travel/front/index/index.spec.js b/modules/travel/front/index/index.spec.js index 5affc7c1a..15247a1e1 100644 --- a/modules/travel/front/index/index.spec.js +++ b/modules/travel/front/index/index.spec.js @@ -1,64 +1,31 @@ import './index.js'; describe('Travel Component vnTravelIndex', () => { - let $componentController; let controller; - let $window; - let travels = [{ + let travel = { id: 1, warehouseInFk: 1, totalEntries: 3, isDelivered: false - }, { - id: 2, - warehouseInFk: 1, - total: 4, - isDelivered: true - }, { - id: 3, - warehouseInFk: 1, - total: 2, - isDelivered: true - }]; + }; - beforeEach(angular.mock.module('travel', $translateProvider => { - $translateProvider.translations('en', {}); - })); + beforeEach(ngModule('travel')); - beforeEach(angular.mock.inject((_$componentController_, $rootScope) => { - $componentController = _$componentController_; + beforeEach(angular.mock.inject(($componentController, $rootScope) => { let $scope = $rootScope.$new(); - controller = $componentController('vnTravelIndex', $scope); + controller = $componentController('vnTravelIndex', {$scope}); controller.$.summary = {show: jasmine.createSpy('show')}; })); describe('preview()', () => { it('should show the dialog summary', () => { let event = new MouseEvent('click', { - view: $window, bubbles: true, cancelable: true }); - controller.preview(event, travels[0]); + controller.preview(event, travel); expect(controller.$.summary.show).toHaveBeenCalledWith(); }); }); - - describe('getScopeDates()', () => { - it('should return a range of dates', () => { - let days = 2; // never put 1 or anything higher than 2 - let result = controller.getScopeDates(days); - - let from = new Date(result.shippedFrom).getTime(); - let to = new Date(result.shippedTo).getTime(); - let range = to - from; - - const dayInMilliseconds = 24 * 60 * 60 * 1000; - - let millisecondsPerAddedDay = dayInMilliseconds - 1; - - expect(range - dayInMilliseconds).toEqual(dayInMilliseconds + millisecondsPerAddedDay); - }); - }); }); diff --git a/modules/travel/front/main/index.spec.js b/modules/travel/front/main/index.spec.js new file mode 100644 index 000000000..2abcb0a33 --- /dev/null +++ b/modules/travel/front/main/index.spec.js @@ -0,0 +1,24 @@ +import './index.js'; + +describe('Travel Component vnTravel', () => { + let controller; + + beforeEach(ngModule('travel')); + + beforeEach(angular.mock.inject($componentController => { + let $element = angular.element(`
`); + controller = $componentController('vnTravel', {$element}); + })); + + describe('fetchParams()', () => { + it('should return a range of dates with passed scope days', () => { + let params = controller.fetchParams({scopeDays: 2}); + + let from = params.shippedFrom.getTime(); + let to = params.shippedTo.getTime() + 1; + let msInDay = 86400 * 1000; + + expect(to - from).toEqual(3 * msInDay); + }); + }); +}); diff --git a/modules/zone/front/index/index.spec.js b/modules/zone/front/main/index.spec.js similarity index 74% rename from modules/zone/front/index/index.spec.js rename to modules/zone/front/main/index.spec.js index 69ce934cd..d8d283ad1 100644 --- a/modules/zone/front/index/index.spec.js +++ b/modules/zone/front/main/index.spec.js @@ -1,14 +1,13 @@ import './index.js'; -describe('Zone Component vnZoneIndex', () => { - let $componentController; +describe('Zone Component vnZone', () => { let controller; beforeEach(ngModule('zone')); - beforeEach(angular.mock.inject(_$componentController_ => { - $componentController = _$componentController_; - controller = $componentController('vnZoneIndex'); + beforeEach(angular.mock.inject($componentController => { + let $element = angular.element(`
`); + controller = $componentController('vnZone', {$element}); })); describe('exprBuilder()', () => {