From c30ac365c3442248ccc6d5a58210afa12bd3d23a Mon Sep 17 00:00:00 2001 From: Leigh Johnson Date: Thu, 8 Dec 2016 15:21:52 -0500 Subject: [PATCH] Fix broken column-sort toggles, add unit test coverage for column-sort toggles, #4268 (#4281) --- .../column-sort/column-sort.controller.js | 19 ++-- .../column-sort/column-sort.partial.html | 2 +- .../smart-search/smart-search.controller.js | 2 +- .../column-sort/column-sort.directive-test.js | 101 ++++++++++++++++++ 4 files changed, 113 insertions(+), 11 deletions(-) create mode 100644 awx/ui/tests/spec/column-sort/column-sort.directive-test.js diff --git a/awx/ui/client/src/shared/column-sort/column-sort.controller.js b/awx/ui/client/src/shared/column-sort/column-sort.controller.js index e5ce39ff3c..2dee59818c 100644 --- a/awx/ui/client/src/shared/column-sort/column-sort.controller.js +++ b/awx/ui/client/src/shared/column-sort/column-sort.controller.js @@ -1,9 +1,7 @@ export default ['$scope', '$state', 'QuerySet', 'GetBasePath', function($scope, $state, qs, GetBasePath) { - let queryset, path, - order_by = $state.params[`${$scope.columnIterator}_search`].order_by, - activeField = isDescending(order_by) ? order_by.substring(1, order_by.length) : order_by; + let queryset, path, order_by; function isDescending(str) { if (str){ @@ -15,15 +13,16 @@ export default ['$scope', '$state', 'QuerySet', 'GetBasePath', } } function invertOrderBy(str) { - return order_by.charAt(0) === '-' ? `${str.substring(1, str.length)}` : `-${str}`; + return str.charAt(0) === '-' ? `${str.substring(1, str.length)}` : `-${str}`; } $scope.orderByIcon = function() { + order_by = $state.params[`${$scope.columnIterator}_search`].order_by; // column sort is inactive - if (activeField !== $scope.columnField) { + if (order_by !== $scope.columnField && order_by !== invertOrderBy($scope.columnField)) { return 'fa-sort'; } // column sort is active (governed by order_by) and descending - else if (isDescending(order_by)) { + else if (isDescending($state.params[`${$scope.columnIterator}_search`].order_by)) { return 'fa-sort-down'; } // column sort is active governed by order_by) and asscending @@ -33,17 +32,19 @@ export default ['$scope', '$state', 'QuerySet', 'GetBasePath', }; $scope.toggleColumnOrderBy = function() { - // toggle active sort order - if (activeField === $scope.columnField) { + let order_by = $state.params[`${$scope.columnIterator}_search`].order_by; + + if (order_by === $scope.columnField || order_by === invertOrderBy($scope.columnField)) { order_by = invertOrderBy(order_by); } // set new active sort order else { order_by = $scope.columnField; } + queryset = _.merge($state.params[`${$scope.columnIterator}_search`], { order_by: order_by }); path = GetBasePath($scope.basePath) || $scope.basePath; - $state.go('.', { [$scope.iterator + '_search']: queryset }); + $state.go('.', { [$scope.columnIterator + '_search']: queryset }); qs.search(path, queryset).then((res) =>{ $scope.dataset = res.data; $scope.collection = res.data.results; diff --git a/awx/ui/client/src/shared/column-sort/column-sort.partial.html b/awx/ui/client/src/shared/column-sort/column-sort.partial.html index 96ea648b6c..63d45e69c2 100644 --- a/awx/ui/client/src/shared/column-sort/column-sort.partial.html +++ b/awx/ui/client/src/shared/column-sort/column-sort.partial.html @@ -1,4 +1,4 @@ {{columnLabel}} - + diff --git a/awx/ui/client/src/shared/smart-search/smart-search.controller.js b/awx/ui/client/src/shared/smart-search/smart-search.controller.js index 4fa3517547..87dc33198a 100644 --- a/awx/ui/client/src/shared/smart-search/smart-search.controller.js +++ b/awx/ui/client/src/shared/smart-search/smart-search.controller.js @@ -24,7 +24,7 @@ export default ['$stateParams', '$scope', '$state', 'QuerySet', 'GetBasePath', ' function stripDefaultParams(params) { let stripped =_.pick(params, (value, key) => { // setting the default value of a term to null in a state definition is a very explicit way to ensure it will NEVER generate a search tag, even with a non-default value - return defaults[key] !== value && key !== 'page' && key !== 'page_size' && defaults[key] !== null; + return defaults[key] !== value && key !== 'order_by' && key !== 'page' && key !== 'page_size' && defaults[key] !== null; }); return _(stripped).map(qs.decodeParam).flatten().value(); } diff --git a/awx/ui/tests/spec/column-sort/column-sort.directive-test.js b/awx/ui/tests/spec/column-sort/column-sort.directive-test.js new file mode 100644 index 0000000000..4cb1a3ec53 --- /dev/null +++ b/awx/ui/tests/spec/column-sort/column-sort.directive-test.js @@ -0,0 +1,101 @@ +'use strict'; + +describe('Directive: column-sort', () =>{ + + let $scope, template, $compile, QuerySet, GetBasePath; + + beforeEach(angular.mock.module('templateUrl')); + beforeEach(function(){ + + this.mock = { + dataset: [ + {name: 'zero', idx: 0}, + {name: 'one', idx: 1}, + {name: 'two', idx: 2} + ] + }; + + this.name_field = angular.element(` + `); + + this.idx_field = angular.element(` + `); + + this.$state = { + params: {}, + go: jasmine.createSpy('go') + }; + + + angular.mock.module('ColumnSortModule', ($provide) =>{ + + + QuerySet = jasmine.createSpyObj('qs', ['search']); + QuerySet.search.and.callFake(() => { return { then: function(){} } }); + GetBasePath = jasmine.createSpy('GetBasePath'); + $provide.value('QuerySet', QuerySet); + $provide.value('GetBasePath', GetBasePath); + $provide.value('$state', this.$state); + + }); + }); + + beforeEach(angular.mock.inject(($templateCache, _$rootScope_, _$compile_) => { + template = window.__html__['client/src/shared/column-sort/column-sort.partial.html']; + $templateCache.put('/static/partials/shared/column-sort/column-sort.partial.html', template); + + $compile = _$compile_; + $scope = _$rootScope_.$new(); + })); + + it('should be ordered by name', function(){ + + this.$state.params = { + mock_search: {order_by: 'name'} + }; + + $compile(this.name_field)($scope); + $compile(this.idx_field)($scope) + + $scope.$digest(); + expect( $(this.name_field).find('.columnSortIcon').hasClass('fa-sort-up') ).toEqual(true); + expect( $(this.idx_field).find('.columnSortIcon').hasClass('fa-sort') ).toEqual(true); + }); + + it('should toggle to ascending name order, then ascending idx, then descending idx', function(){ + + this.$state.params = { + mock_search: {order_by: 'idx'} + }; + + $compile(this.name_field)($scope); + $compile(this.idx_field)($scope) + + $scope.$digest(); + + $(this.name_field).click(); + expect( $(this.name_field).find('.columnSortIcon').hasClass('fa-sort-up') ).toEqual(true); + expect( $(this.idx_field).find('.columnSortIcon').hasClass('fa-sort') ).toEqual(true); + + $(this.idx_field).click(); + expect( $(this.name_field).find('.columnSortIcon').hasClass('fa-sort') ).toEqual(true); + expect( $(this.idx_field).find('.columnSortIcon').hasClass('fa-sort-up') ).toEqual(true); + + $(this.idx_field).click(); + expect( $(this.name_field).find('.columnSortIcon').hasClass('fa-sort') ).toEqual(true); + expect( $(this.idx_field).find('.columnSortIcon').hasClass('fa-sort-down') ).toEqual(true) + }); + +}); \ No newline at end of file