From e5dee219267bc8fad1010a95f6851470fbeebe98 Mon Sep 17 00:00:00 2001 From: Juan Ferrer Toribio Date: Wed, 18 Mar 2020 13:54:05 +0100 Subject: [PATCH] Pull request fixes --- e2e/helpers/extensions.js | 5 - e2e/paths/04-item/08_create_and_clone.spec.js | 3 + front/core/components/searchbar/searchbar.js | 15 ++- .../components/searchbar/searchbar.spec.js | 91 ++++++++++++++++++- front/core/lib/focus.js | 4 +- jest-front.js | 4 +- 6 files changed, 99 insertions(+), 23 deletions(-) diff --git a/e2e/helpers/extensions.js b/e2e/helpers/extensions.js index 0361ce35a6..440085d852 100644 --- a/e2e/helpers/extensions.js +++ b/e2e/helpers/extensions.js @@ -348,11 +348,6 @@ let actions = { await this.clearInput('vn-searchbar'); await this.write('vn-searchbar', searchValue); await this.waitToClick('vn-searchbar vn-icon[icon="search"]'); - // await this.waitForNumberOfElements('.search-result', 1); - // await this.waitForContentLoaded(); - // await this.evaluate(() => { - // return document.querySelector('.search-result').click(); - // }); await this.waitForContentLoaded(); }, diff --git a/e2e/paths/04-item/08_create_and_clone.spec.js b/e2e/paths/04-item/08_create_and_clone.spec.js index 7665388d7a..d06ef46823 100644 --- a/e2e/paths/04-item/08_create_and_clone.spec.js +++ b/e2e/paths/04-item/08_create_and_clone.spec.js @@ -80,6 +80,9 @@ describe('Item Create/Clone path', () => { }); }); + // Issue #2201 + // When there is just one result you're redirected automatically to it, so + // it's not possible to use the clone option. xdescribe('clone', () => { it('should return to the items index by clicking the return to items button', async() => { await page.waitToClick(selectors.itemBasicData.goToItemIndexButton); diff --git a/front/core/components/searchbar/searchbar.js b/front/core/components/searchbar/searchbar.js index b8da899db5..640ed48d6a 100644 --- a/front/core/components/searchbar/searchbar.js +++ b/front/core/components/searchbar/searchbar.js @@ -69,10 +69,11 @@ export default class Searchbar extends Component { } onStateChange(transition) { - if (!this.element.parentNode - || transition == this.transition) - return; + let ignoreHandler = + !this.element.parentNode + || transition == this.transition; + if (ignoreHandler) return; this.fetchStateFilter(); } @@ -197,13 +198,13 @@ export default class Searchbar extends Component { let opts; if (filter) { - let oneResult = this.autoState + let isOneResult = this.autoState && source != 'state' && !angular.equals(filter, {}) && data && data.length == 1; - if (oneResult) { + if (isOneResult) { let baseDepth = this.baseState.split('.').length; let stateParts = this.$state.current.name .split('.') @@ -275,10 +276,6 @@ export default class Searchbar extends Component { return this.model.applyFilter(where ? {where} : null, params) .then(() => this.model.data); } - - onClear() { - if (this.model) this.model.clear(); - } } ngModule.vnComponent('vnSearchbar', { diff --git a/front/core/components/searchbar/searchbar.spec.js b/front/core/components/searchbar/searchbar.spec.js index 9d51dfd650..95035f504c 100644 --- a/front/core/components/searchbar/searchbar.spec.js +++ b/front/core/components/searchbar/searchbar.spec.js @@ -8,9 +8,35 @@ describe('Component vnSearchbar', () => { let $scope; let filter = {id: 1, search: 'needle'}; - beforeEach(ngModule('vnCore')); + beforeEach(ngModule('vnCore', $stateProvider => { + $stateProvider + .state('foo', { + abstract: true + }) + .state('foo.index', { + url: '/foo/index' + }) + .state('foo.card', { + abstract: true + }) + .state('foo.card.summary', { + url: '/foo/:id/summary' + }) + .state('foo.card.bar', { + url: '/foo/:id/bar' + }) + .state('foo.card.baz', { + abstract: true + }) + .state('foo.card.baz.index', { + url: '/foo/:id/bar' + }) + .state('foo.card.baz.edit', { + url: '/foo/:id/bar' + }); + })); - beforeEach(angular.mock.inject(($componentController, $rootScope, _$state_) => { + beforeEach(inject(($componentController, $rootScope, _$state_) => { $scope = $rootScope.$new(); $state = _$state_; $params = $state.params; @@ -19,7 +45,6 @@ describe('Component vnSearchbar', () => { $element = angular.element(`
`); controller = $componentController('vnSearchbar', {$element, $scope}); - controller.panel = 'vn-client-search-panel'; })); describe('$postLink()', () => { @@ -158,12 +183,68 @@ describe('Component vnSearchbar', () => { }); describe('doSearch()', () => { - it(`should go to the search state and pass the filter as query param`, () => { + it(`should do the filter`, () => { + jest.spyOn(controller, 'onSearch'); + jest.spyOn(controller, 'onFilter'); + + controller.doSearch(filter, 'any'); + $scope.$apply(); + + expect(controller.onSearch).toHaveBeenCalledWith({$params: filter}); + expect(controller.onFilter).toHaveBeenCalledWith(filter, 'any', undefined); + }); + }); + + describe('onFilter()', () => { + it(`should go to the summary state when one result`, () => { + jest.spyOn($state, 'go'); + + let data = [{id: 1}]; + + controller.baseState = 'foo'; + controller.onFilter(filter, 'any', data); + $scope.$apply(); + + expect($state.go).toHaveBeenCalledWith('foo.card.summary', {id: 1}, undefined); + expect(controller.filter).toEqual(null); + }); + + it(`should keep the same card state when one result and it's already inside any card state`, () => { + $state.go('foo.card.bar', {id: 1}); + $scope.$apply(); + + jest.spyOn($state, 'go'); + let data = [{id: 1}]; + + controller.baseState = 'foo'; + controller.onFilter(filter, 'any', data); + $scope.$apply(); + + expect($state.go).toHaveBeenCalledWith('foo.card.bar', {id: 1}, undefined); + expect(controller.filter).toEqual(null); + }); + + it(`should keep the same card state but index when one result and it's already in card state but inside more than three-nested states`, () => { + $state.go('foo.card.baz.edit', {id: 1}); + $scope.$apply(); + + jest.spyOn($state, 'go'); + let data = [{id: 1}]; + + controller.baseState = 'foo'; + controller.onFilter(filter, 'any', data); + $scope.$apply(); + + expect($state.go).toHaveBeenCalledWith('foo.card.baz.index', {id: 1}, undefined); + expect(controller.filter).toEqual(null); + }); + + it(`should go to the search state when multiple results and pass the filter as query param`, () => { jest.spyOn($state, 'go'); controller.autoState = false; controller.searchState = 'search.state'; - controller.doSearch(filter); + controller.onFilter(filter, 'any'); $scope.$apply(); let queryParams = {q: JSON.stringify(filter)}; diff --git a/front/core/lib/focus.js b/front/core/lib/focus.js index 8b997d9208..6e19e11843 100644 --- a/front/core/lib/focus.js +++ b/front/core/lib/focus.js @@ -2,12 +2,12 @@ import isMobile from './is-mobile'; export default function focus(element) { - if (isMobile) return; + if (isMobile || !element) return; setTimeout(() => element.focus(), 10); } export function select(element) { - if (isMobile) return; + if (isMobile || !element) return; setTimeout(() => { element.focus(); if (element.select) diff --git a/jest-front.js b/jest-front.js index 5d6c342c0b..ab88dd4737 100644 --- a/jest-front.js +++ b/jest-front.js @@ -17,7 +17,7 @@ core.run(vnInterceptor => { vnInterceptor.setApiPath(null); }); -window.ngModule = function(moduleName) { +window.ngModule = function(moduleName, fn) { return angular.mock.module(moduleName, function($provide, $translateProvider) { // Avoid unexpected request warnings caused by angular translate // https://angular-translate.github.io/docs/#/guide/22_unit-testing-with-angular-translate @@ -30,5 +30,5 @@ window.ngModule = function(moduleName) { }); $translateProvider.useLoader('customLocaleLoader'); - }); + }, fn); };