diff --git a/awx/ui/client/lib/components/layout/side-nav.directive.js b/awx/ui/client/lib/components/layout/side-nav.directive.js index f089d54eee..672d23d886 100644 --- a/awx/ui/client/lib/components/layout/side-nav.directive.js +++ b/awx/ui/client/lib/components/layout/side-nav.directive.js @@ -5,7 +5,7 @@ let $document; function atSideNavLink (scope, element, attrs, ctrl) { scope.layoutVm = ctrl; - $document.on('click', (e) => { + $(document).on('click', (e) => { if ($(e.target).parents('.at-Layout-side').length === 0) { scope.$emit('clickOutsideSideNav'); } diff --git a/awx/ui/client/test/unit/index.js b/awx/ui/client/test/unit/index.js index 448f41b680..0090365719 100644 --- a/awx/ui/client/test/unit/index.js +++ b/awx/ui/client/test/unit/index.js @@ -1,8 +1,6 @@ // Import angular and angular-mocks to the global scope import 'angular'; import 'angular-mocks'; -import 'angular-gettext'; -import 'angular-ui-router'; // Import custom Angular module dependencies import '../../src/i18n'; @@ -14,3 +12,4 @@ import '../../lib/models'; import './panel-body.spec'; import './layout.spec'; import './side-nav.spec'; +import './side-nav-item.spec'; \ No newline at end of file diff --git a/awx/ui/client/test/unit/karma.conf.js b/awx/ui/client/test/unit/karma.conf.js index e3343b0a00..988db3c462 100644 --- a/awx/ui/client/test/unit/karma.conf.js +++ b/awx/ui/client/test/unit/karma.conf.js @@ -11,8 +11,9 @@ module.exports = config => { browsers: ['PhantomJS'], reporters: ['progress'], files: [ - './index.js', - '../../lib/components/**/*.html' + './index.js', + '../../../client/src/app.js', + '../../lib/components/**/*.html' ], plugins: [ 'karma-webpack', @@ -21,8 +22,9 @@ module.exports = config => { 'karma-ng-html2js-preprocessor' ], preprocessors: { - '../../lib/components/**/*.html': 'ng-html2js', - './index.js': 'webpack' + './index.js': 'webpack', + '../../../client/src/app.js': 'webpack', + '../../lib/components/**/*.html': 'ng-html2js' }, ngHtml2JsPreprocessor: { moduleName: 'at.test.templates', diff --git a/awx/ui/client/test/unit/layout.spec.js b/awx/ui/client/test/unit/layout.spec.js index 5d032caf61..512cfbef50 100644 --- a/awx/ui/client/test/unit/layout.spec.js +++ b/awx/ui/client/test/unit/layout.spec.js @@ -3,13 +3,14 @@ describe('Components | Layout', () => { let $rootScope; let element; let scope; + let i18n; beforeEach(() => { angular.mock.module('gettext'); angular.mock.module('I18N'); angular.mock.module('ui.router'); - angular.mock.module('at.lib.services') - angular.mock.module('at.lib.components') + angular.mock.module('at.lib.services'); + angular.mock.module('at.lib.components'); }); beforeEach(angular.mock.inject((_$compile_, _$rootScope_) => { @@ -125,30 +126,21 @@ describe('Components | Layout', () => { }); describe('getString()', () => { + it('calls ComponentsStrings get() method', angular.mock.inject((_ComponentsStrings_) => { + spyOn(_ComponentsStrings_, 'get'); + controller.getString('VIEW_DOCS') + expect(_ComponentsStrings_.get).toHaveBeenCalled(); + })); + + it('ComponentsStrings get() method should throw an error if string is not a property name of the layout class', () => { + expect(controller.getString.bind(null, 'SUBMISSION_ERROR_TITLE')).toThrow(); + }); + it('should return layout string', () => { let layoutStrings = { CURRENT_USER_LABEL: 'Logged in as', VIEW_DOCS: 'View Documentation', LOGOUT: 'Logout', - DASHBOARD: 'Dashboard', - JOBS: 'Jobs', - SCHEDULES: 'Schedules', - PORTAL_MODE: 'Portal Mode', - PROJECTS: 'Projects', - CREDENTIALS: 'Credentials', - CREDENTIAL_TYPES: 'Credential Types', - INVENTORIES: 'Inventories', - TEMPLATES: 'Templates', - ORGANIZATIONS: 'Organizations', - USERS: 'Users', - TEAMS: 'Teams', - INVENTORY_SCRIPTS: 'Inventory Scripts', - NOTIFICATIONS: 'Notifications', - MANAGEMENT_JOBS: 'Management Jobs', - INSTANCE_GROUPS: 'Instance Groups', - SETTINGS: 'Settings', - FOOTER_ABOUT: 'About', - FOOTER_COPYRIGHT: 'Copyright © 2017 Red Hat, Inc.' }; _.forEach(layoutStrings, (value, key) => { diff --git a/awx/ui/client/test/unit/side-nav-item.spec.js b/awx/ui/client/test/unit/side-nav-item.spec.js new file mode 100644 index 0000000000..f605a40e69 --- /dev/null +++ b/awx/ui/client/test/unit/side-nav-item.spec.js @@ -0,0 +1,61 @@ +describe('Components | Side Nav Item', () => { + let $compile; + let $rootScope; + let element; + let scope; + + beforeEach(() => { + angular.mock.module('gettext'); + angular.mock.module('I18N'); + angular.mock.module('ui.router'); + angular.mock.module('at.lib.services') + angular.mock.module('at.lib.components') + }); + + beforeEach(angular.mock.inject((_$compile_, _$rootScope_) => { + $compile = _$compile_; + $rootScope = _$rootScope_; + scope = $rootScope.$new(); + + element = angular.element(''); + element = $compile(element)(scope); + scope.name = 'dashboard'; + scope.$digest(); + })); + + describe('Side Nav Item Controller', () => { + let LayoutCtrl; + let SideNavItem; + let SideNavItemCtrl; + + beforeEach(() => { + SideNavItem = angular.element(element[0].querySelector('at-side-nav-item')); + SideNavItemCtrl = SideNavItem.controller('atSideNavItem'); + }); + + it('layoutVm.currentState watcher should assign isRoute', () => { + let current = {'name': 'dashboard'}; + $rootScope.$broadcast('$stateChangeSuccess', current); + scope.$digest(); + expect(SideNavItemCtrl.isRoute).toBe(true); + + current = {'name': 'inventories'}; + $rootScope.$broadcast('$stateChangeSuccess', current); + scope.$digest(); + expect(SideNavItemCtrl.isRoute).toBe(false); + }); + + it('go() should call $state.go()', angular.mock.inject((_$state_) => { + spyOn(_$state_, 'go'); + SideNavItemCtrl.go(); + expect(_$state_.go).toHaveBeenCalled(); + expect(_$state_.go).toHaveBeenCalledWith('dashboard', jasmine.any(Object), jasmine.any(Object)); + })); + + it('should load name, icon, and route from scope', () => { + expect(SideNavItem.isolateScope().name).toBeDefined(); + expect(SideNavItem.isolateScope().iconClass).toBeDefined(); + expect(SideNavItem.isolateScope().route).toBeDefined(); + }); + }); +}); diff --git a/awx/ui/client/test/unit/side-nav.spec.js b/awx/ui/client/test/unit/side-nav.spec.js index cfb1d61812..1342e41659 100644 --- a/awx/ui/client/test/unit/side-nav.spec.js +++ b/awx/ui/client/test/unit/side-nav.spec.js @@ -3,13 +3,18 @@ describe('Components | Side Nav', () => { let $rootScope; let element; let scope; + let windowMock = { + innerWidth: 500 + }; beforeEach(() => { angular.mock.module('gettext'); angular.mock.module('I18N'); angular.mock.module('ui.router'); angular.mock.module('at.lib.services') - angular.mock.module('at.lib.components') + angular.mock.module('at.lib.components', ($provide) => { + $provide.value('$window', windowMock); + }); }); beforeEach(angular.mock.inject((_$compile_, _$rootScope_) => { @@ -36,11 +41,38 @@ describe('Components | Side Nav', () => { }); it('toggleExpansion()', () => { + expect(sideNavCtrl.isExpanded).toBe(false); + + sideNavCtrl.toggleExpansion(); + expect(sideNavCtrl.isExpanded).toBe(true); + + sideNavCtrl.toggleExpansion(); + expect(sideNavCtrl.isExpanded).toBe(false); + sideNavCtrl.toggleExpansion(); expect(sideNavCtrl.isExpanded).toBe(true); sideNavCtrl.toggleExpansion(); expect(sideNavCtrl.isExpanded).toBe(false); }); + + it('isExpanded should be false after state change event', () => { + sideNavCtrl.isExpanded = true; + + let current = { + 'name': 'dashboard' + }; + $rootScope.$broadcast('$stateChangeSuccess', current); + scope.$digest(); + expect(sideNavCtrl.isExpanded).toBe(false); + }); + + it('clickOutsideSideNav watcher should assign isExpanded to false', () => { + sideNavCtrl.isExpanded = true; + + $rootScope.$broadcast('clickOutsideSideNav'); + scope.$digest(); + expect(sideNavCtrl.isExpanded).toBe(false); + }); }); }); diff --git a/awx/ui/package.json b/awx/ui/package.json index 14065392d2..f7ab064cee 100644 --- a/awx/ui/package.json +++ b/awx/ui/package.json @@ -25,7 +25,7 @@ "jshint": "grunt jshint:source --no-color", "test:ci": "npm run test -- --single-run --reporter junit,dots --browsers=PhantomJS", "e2e": "./client/test/e2e/runner.js --config ./client/test/e2e/nightwatch.conf.js", - "component-test": "karma start client/test/unit/karma.conf.js --auto-watch --no-single-run", + "component-test": "karma start client/test/unit/karma.conf.js", "lint": "eslint -c .eslintrc.js .", "dev": "webpack --config build/webpack.development.js --progress", "watch": "webpack-dev-server --config build/webpack.watch.js --progress",