From d2440f6cd77f7568fe8046fb45ad049bcd65a054 Mon Sep 17 00:00:00 2001 From: Joe Fiorini Date: Wed, 8 Jul 2015 10:13:50 -0400 Subject: [PATCH] Extract factory for generating template URLs --- awx/ui/static/js/app.js | 2 + .../counts/dashboard-counts.directive.js | 6 +- .../js/dashboard/dashboard.directive.js | 6 +- .../graphs/dashboard-graphs.directive.js | 6 +- .../host-status-graph.directive.js | 5 +- .../job-status/job-status-graph.directive.js | 5 +- .../js/dashboard/graphs/job-status/main.js | 4 +- .../job-templates-list.directive.js | 5 +- .../lists/jobs/jobs-list.directive.js | 79 ++++++++++--------- .../js/main-menu/default-menu.directive.js | 29 ++++--- .../js/main-menu/main-menu.directive.js | 79 ++++++++++--------- .../js/main-menu/menu-toggle.directive.js | 49 ++++++------ .../js/main-menu/portal-menu.directive.js | 29 ++++--- .../main-menu/web-socket-status.directive.js | 34 ++++---- .../breadcrumbs/breadcrumbs.directive.js | 49 ++++++------ .../static/js/shared/icon/icon.directive.js | 49 ++++++------ .../js/shared/multi-select-list/main.js | 3 +- .../multi-select-list/select-all.directive.js | 8 +- awx/ui/static/js/shared/template-url/main.js | 6 ++ .../template-url/template-url.factory.js | 20 +++++ .../date-picker/date-picker.directive.js | 5 +- .../fact-data-table.directive.js | 5 +- awx/ui/tests/unit/setup-browser.js | 39 +++++++++ 23 files changed, 308 insertions(+), 214 deletions(-) create mode 100644 awx/ui/static/js/shared/template-url/main.js create mode 100644 awx/ui/static/js/shared/template-url/template-url.factory.js create mode 100644 awx/ui/tests/unit/setup-browser.js diff --git a/awx/ui/static/js/app.js b/awx/ui/static/js/app.js index 41f795e625..e8f65b5a6d 100644 --- a/awx/ui/static/js/app.js +++ b/awx/ui/static/js/app.js @@ -38,6 +38,7 @@ import mainMenu from 'tower/main-menu/main'; import browserData from 'tower/browser-data/main'; import dashboard from 'tower/dashboard/main'; import moment from 'tower/shared/moment/main'; +import templateUrl from 'tower/shared/template-url/main'; import {JobDetailController} from 'tower/controllers/JobDetail'; import {JobStdoutController} from 'tower/controllers/JobStdout'; @@ -84,6 +85,7 @@ var tower = angular.module('Tower', [ mainMenu.name, dashboard.name, moment.name, + templateUrl.name, 'AuthService', 'Utilities', 'LicenseHelper', diff --git a/awx/ui/static/js/dashboard/counts/dashboard-counts.directive.js b/awx/ui/static/js/dashboard/counts/dashboard-counts.directive.js index ac0f201237..3dafe1f13e 100644 --- a/awx/ui/static/js/dashboard/counts/dashboard-counts.directive.js +++ b/awx/ui/static/js/dashboard/counts/dashboard-counts.directive.js @@ -1,14 +1,14 @@ /* jshint unused: vars */ export default - [ '$rootScope', - function() { + [ 'templateUrl', + function(templateUrl) { return { restrict: 'E', scope: { data: '=' }, replace: false, - templateUrl: '/static/js/dashboard/counts/dashboard-counts.partial.html', + templateUrl: templateUrl('dashboard/counts/dashboard-counts'), link: function(scope, element, attrs) { scope.$watch("data", function(data) { if (data && data.hosts) { diff --git a/awx/ui/static/js/dashboard/dashboard.directive.js b/awx/ui/static/js/dashboard/dashboard.directive.js index c330aeb137..243a423a67 100644 --- a/awx/ui/static/js/dashboard/dashboard.directive.js +++ b/awx/ui/static/js/dashboard/dashboard.directive.js @@ -1,11 +1,11 @@ /* jshint unused: vars */ export default - [ '$rootScope', - function() { + [ 'templateUrl', + function(templateUrl) { return { restrict: 'E', scope: true, - templateUrl: '/static/js/dashboard/dashboard.partial.html', + templateUrl: templateUrl('dashboard/dashboard'), link: function(scope, element, attrs) { } }; diff --git a/awx/ui/static/js/dashboard/graphs/dashboard-graphs.directive.js b/awx/ui/static/js/dashboard/graphs/dashboard-graphs.directive.js index b27418a94c..ce0052e132 100644 --- a/awx/ui/static/js/dashboard/graphs/dashboard-graphs.directive.js +++ b/awx/ui/static/js/dashboard/graphs/dashboard-graphs.directive.js @@ -1,11 +1,11 @@ /* jshint unused: vars */ export default - [ '$rootScope', - function() { + [ 'templateUrl', + function(templateUrl) { return { restrict: 'E', scope: true, - templateUrl: '/static/js/dashboard/graphs/dashboard-graphs.partial.html', + templateUrl: templateUrl('dashboard/graphs/dashboard-graphs'), link: function(scope, element, attrs) { function clearGraphs() { scope.jobStatusSelected = false; diff --git a/awx/ui/static/js/dashboard/graphs/host-status/host-status-graph.directive.js b/awx/ui/static/js/dashboard/graphs/host-status/host-status-graph.directive.js index 8fb44090b8..9ec11d5d46 100644 --- a/awx/ui/static/js/dashboard/graphs/host-status/host-status-graph.directive.js +++ b/awx/ui/static/js/dashboard/graphs/host-status/host-status-graph.directive.js @@ -8,14 +8,15 @@ [ '$compile', '$window', 'adjustGraphSize', + 'templateUrl', HostStatusGraph, ]; -function HostStatusGraph($compile, $window, adjustGraphSize) { +function HostStatusGraph($compile, $window, adjustGraphSize, templateUrl) { return { restrict: 'E', link: link, - templateUrl: '/static/js/dashboard/graphs/host-status/host_status_graph.partial.html' + templateUrl: templateUrl('dashboard/graphs/host-status/host_status_graph') }; function link(scope, element, attr) { diff --git a/awx/ui/static/js/dashboard/graphs/job-status/job-status-graph.directive.js b/awx/ui/static/js/dashboard/graphs/job-status/job-status-graph.directive.js index 1d233ab42f..e6c3af0095 100644 --- a/awx/ui/static/js/dashboard/graphs/job-status/job-status-graph.directive.js +++ b/awx/ui/static/js/dashboard/graphs/job-status/job-status-graph.directive.js @@ -12,16 +12,17 @@ 'Wait', 'adjustGraphSize', 'jobStatusGraphData', + 'templateUrl', JobStatusGraph ]; -function JobStatusGraph($rootScope, $compile , $location, $window, Wait, adjustGraphSize, graphDataService) { +function JobStatusGraph($rootScope, $compile , $location, $window, Wait, adjustGraphSize, graphDataService, templateUrl) { return { restrict: 'E', scope: { data: '=' }, - templateUrl: '/static/js/dashboard/graphs/job-status/job_status_graph.partial.html', + templateUrl: templateUrl('dashboard/graphs/job-status/job_status_graph'), link: link }; diff --git a/awx/ui/static/js/dashboard/graphs/job-status/main.js b/awx/ui/static/js/dashboard/graphs/job-status/main.js index 5758354a28..9c122acf3b 100644 --- a/awx/ui/static/js/dashboard/graphs/job-status/main.js +++ b/awx/ui/static/js/dashboard/graphs/job-status/main.js @@ -1,8 +1,8 @@ import JobStatusGraphDirective from 'tower/dashboard/graphs/job-status/job-status-graph.directive'; import JobStatusGraphService from 'tower/dashboard/graphs/job-status/job-status-graph.service'; import DashboardGraphHelpers from 'tower/dashboard/graphs/graph-helpers/main'; -import ApiLoader from 'tower/shared/api-loader'; +import templateUrl from 'tower/shared/template-url/main'; -export default angular.module('JobStatusGraph', [DashboardGraphHelpers.name, ApiLoader.name]) +export default angular.module('JobStatusGraph', [DashboardGraphHelpers.name, templateUrl.name]) .directive('jobStatusGraph', JobStatusGraphDirective) .service('jobStatusGraphData', JobStatusGraphService); diff --git a/awx/ui/static/js/dashboard/lists/job-templates/job-templates-list.directive.js b/awx/ui/static/js/dashboard/lists/job-templates/job-templates-list.directive.js index 6dc6f20afb..19ba322888 100644 --- a/awx/ui/static/js/dashboard/lists/job-templates/job-templates-list.directive.js +++ b/awx/ui/static/js/dashboard/lists/job-templates/job-templates-list.directive.js @@ -1,14 +1,15 @@ /* jshint unused: vars */ export default [ "PlaybookRun", - function JobTemplatesList(PlaybookRun) { + 'templateUrl', + function JobTemplatesList(PlaybookRun, templateUrl) { return { restrict: 'E', link: link, scope: { data: '=' }, - templateUrl: '/static/js/dashboard/lists/job-templates/job-templates-list.partial.html' + templateUrl: templateUrl('dashboard/lists/job-templates/job-templates-list') }; function link(scope, element, attr) { diff --git a/awx/ui/static/js/dashboard/lists/jobs/jobs-list.directive.js b/awx/ui/static/js/dashboard/lists/jobs/jobs-list.directive.js index 31a433db1a..f0c9d742e2 100644 --- a/awx/ui/static/js/dashboard/lists/jobs/jobs-list.directive.js +++ b/awx/ui/static/js/dashboard/lists/jobs/jobs-list.directive.js @@ -1,43 +1,44 @@ /* jshint unused: vars */ export default - ['moment', - function JobsList(moment) { - return { - restrict: 'E', - link: link, - scope: { - data: '=' - }, - templateUrl: '/static/js/dashboard/lists/jobs/jobs-list.partial.html' - }; - - function link(scope, element, attr) { - scope.$watch("data", function(data) { - if (data) { - if (data.length > 0) { - createList(data); - scope.noJobs = false; - } else { - scope.noJobs = true; - } - } - }); - - function createList(list) { - // detailsUrl, status, name, time - scope.jobs = _.map(list, function(job){ - return { - detailsUrl: job.url.replace("api/v1", "#"), - status: job.status, - name: job.name, - time: moment(job.finished).fromNow() - }; }); - - scope.snapRows = (list.length < 4); - } - - scope.isSuccessful = function (status) { - return (status === "successful"); + [ 'moment', + 'templateUrl', + function JobsList(moment, templateUrl) { + return { + restrict: 'E', + link: link, + scope: { + data: '=' + }, + templateUrl: templateUrl('dashboard/lists/jobs/jobs-list') }; - } + + function link(scope, element, attr) { + scope.$watch("data", function(data) { + if (data) { + if (data.length > 0) { + createList(data); + scope.noJobs = false; + } else { + scope.noJobs = true; + } + } + }); + + function createList(list) { + // detailsUrl, status, name, time + scope.jobs = _.map(list, function(job){ + return { + detailsUrl: job.url.replace("api/v1", "#"), + status: job.status, + name: job.name, + time: moment(job.finished).fromNow() + }; }); + + scope.snapRows = (list.length < 4); + } + + scope.isSuccessful = function (status) { + return (status === "successful"); + }; + } }]; diff --git a/awx/ui/static/js/main-menu/default-menu.directive.js b/awx/ui/static/js/main-menu/default-menu.directive.js index 792009307e..59e7039be5 100644 --- a/awx/ui/static/js/main-menu/default-menu.directive.js +++ b/awx/ui/static/js/main-menu/default-menu.directive.js @@ -1,15 +1,18 @@ -export default function() { - return { - restrict: 'E', - templateUrl: '/static/js/main-menu/menu-default.partial.html', - link: function(scope, element) { - var contents = element.contents(); - contents.unwrap(); +export default + [ 'templateUrl', + function(templateUrl) { + return { + restrict: 'E', + templateUrl: templateUrl('main-menu/menu-default'), + link: function(scope, element) { + var contents = element.contents(); + contents.unwrap(); - scope.$on('$destroy', function() { - contents.remove(); - $(".MenuItem--socketStatus").remove(); - }); + scope.$on('$destroy', function() { + contents.remove(); + $(".MenuItem--socketStatus").remove(); + }); + } + }; } - }; -} + ]; diff --git a/awx/ui/static/js/main-menu/main-menu.directive.js b/awx/ui/static/js/main-menu/main-menu.directive.js index 4e2eafee22..ad139cd24e 100644 --- a/awx/ui/static/js/main-menu/main-menu.directive.js +++ b/awx/ui/static/js/main-menu/main-menu.directive.js @@ -1,45 +1,48 @@ /* jshint unused: vars */ -export default function() { - return { - restrict: 'E', - controllerAs: 'mainMenu', - templateUrl: '/static/js/main-menu/main-menu.partial.html', - controller: ['$scope', function($scope) { - this.open = function() { - $scope.isOpen = true; - }; +export default + [ 'templateUrl', + function(templateUrl) { + return { + restrict: 'E', + controllerAs: 'mainMenu', + templateUrl: templateUrl('main-menu/main-menu'), + controller: ['$scope', function($scope) { + this.open = function() { + $scope.isOpen = true; + }; - this.close = function() { - $scope.isOpen = false; - }; + this.close = function() { + $scope.isOpen = false; + }; - this.toggle = function() { - $scope.isOpen = !$scope.isOpen; - }; + this.toggle = function() { + $scope.isOpen = !$scope.isOpen; + }; - $scope.isOpen = false; - }], - scope: { - menuStyle: '&menuStyle', - currentUser: '=' - }, - link: function(scope, element, attrs) { - scope.menuStyleClassName = 'blah'; - scope.$watch(function() { - return scope.$eval(scope.menuStyle); - }, function(newValue) { - scope.menuStyleClassName = 'MainMenu--' + newValue; - }); - scope.$watch('isOpen', function(isOpen) { - if (isOpen) { - element.find('.MainMenu').addClass("Menu--open"); - element.find('menu-toggle-button').addClass("MenuToggle--open"); - } else { - element.find('.MainMenu').removeClass("Menu--open"); - element.find('menu-toggle-button').removeClass("MenuToggle--open"); + $scope.isOpen = false; + }], + scope: { + menuStyle: '&menuStyle', + currentUser: '=' + }, + link: function(scope, element, attrs) { + scope.menuStyleClassName = 'blah'; + scope.$watch(function() { + return scope.$eval(scope.menuStyle); + }, function(newValue) { + scope.menuStyleClassName = 'MainMenu--' + newValue; + }); + scope.$watch('isOpen', function(isOpen) { + if (isOpen) { + element.find('.MainMenu').addClass("Menu--open"); + element.find('menu-toggle-button').addClass("MenuToggle--open"); + } else { + element.find('.MainMenu').removeClass("Menu--open"); + element.find('menu-toggle-button').removeClass("MenuToggle--open"); + } + }); } - }); + }; } - }; -} + ]; diff --git a/awx/ui/static/js/main-menu/menu-toggle.directive.js b/awx/ui/static/js/main-menu/menu-toggle.directive.js index df399bbce9..6459f3e09b 100644 --- a/awx/ui/static/js/main-menu/menu-toggle.directive.js +++ b/awx/ui/static/js/main-menu/menu-toggle.directive.js @@ -1,27 +1,30 @@ /* jshint unused: vars */ -export default function() { - return { - templateUrl: '/static/js/main-menu/menu-toggle.partial.html', - restrict: 'E', - require: '^^mainMenu', - scope: { - width: '@', - height: '@', - barHeight: '@' - }, - link: function(scope, element, attrs, mainMenuController) { - scope.$on('$destroy', function() { - element.off('click'); - }); +export default + [ 'templateUrl', + function(templateUrl) { + return { + templateUrl: templateUrl('main-menu/menu-toggle'), + restrict: 'E', + require: '^^mainMenu', + scope: { + width: '@', + height: '@', + barHeight: '@' + }, + link: function(scope, element, attrs, mainMenuController) { + scope.$on('$destroy', function() { + element.off('click'); + }); - element.on("click", function(e) { - e.preventDefault(); - e.stopPropagation(); - scope.$apply(function() { - mainMenuController.toggle(); - }); - }); + element.on("click", function(e) { + e.preventDefault(); + e.stopPropagation(); + scope.$apply(function() { + mainMenuController.toggle(); + }); + }); + } + }; } - }; -} + ]; diff --git a/awx/ui/static/js/main-menu/portal-menu.directive.js b/awx/ui/static/js/main-menu/portal-menu.directive.js index e7aeceb0e6..cd4c7b588d 100644 --- a/awx/ui/static/js/main-menu/portal-menu.directive.js +++ b/awx/ui/static/js/main-menu/portal-menu.directive.js @@ -1,15 +1,18 @@ -export default function() { - return { - restrict: 'E', - templateUrl: '/static/js/main-menu/menu-portal.partial.html', - link: function(scope, element) { - var contents = element.contents(); - contents.unwrap(); +export default + [ 'templateUrl', + function(templateUrl) { + return { + restrict: 'E', + templateUrl: templateUrl('main-menu/menu-portal'), + link: function(scope, element) { + var contents = element.contents(); + contents.unwrap(); - scope.$on('$destroy', function() { - contents.remove(); - $(".MenuItem--socketStatus").remove(); - }); + scope.$on('$destroy', function() { + contents.remove(); + $(".MenuItem--socketStatus").remove(); + }); + } + }; } - }; -} + ]; diff --git a/awx/ui/static/js/main-menu/web-socket-status.directive.js b/awx/ui/static/js/main-menu/web-socket-status.directive.js index 4f847e72f7..e7cdb5a0df 100644 --- a/awx/ui/static/js/main-menu/web-socket-status.directive.js +++ b/awx/ui/static/js/main-menu/web-socket-status.directive.js @@ -1,18 +1,22 @@ /* jshint unused: vars */ -export default ['$rootScope', function($rootScope) { - return { - restrict: 'E', - templateUrl: '/static/js/main-menu/web-socket-status.partial.html', - link: function(scope, element, attrs) { - scope.socketHelp = $rootScope.socketHelp; - scope.socketTip = $rootScope.socketTip; - $rootScope.$watch('socketStatus', function(newStatus) { - scope.socketStatus = newStatus; - }); - $rootScope.$watch('socketTip', function(newTip) { - scope.socketTip = newTip; - }); +export default + [ '$rootScope', + 'templateUrl', + function($rootScope, templateUrl) { + return { + restrict: 'E', + templateUrl: templateUrl('main-menu/web-socket-status'), + link: function(scope, element, attrs) { + scope.socketHelp = $rootScope.socketHelp; + scope.socketTip = $rootScope.socketTip; + $rootScope.$watch('socketStatus', function(newStatus) { + scope.socketStatus = newStatus; + }); + $rootScope.$watch('socketTip', function(newTip) { + scope.socketTip = newTip; + }); + } + }; } - }; -}]; + ]; diff --git a/awx/ui/static/js/shared/breadcrumbs/breadcrumbs.directive.js b/awx/ui/static/js/shared/breadcrumbs/breadcrumbs.directive.js index ae1f3fd85c..0d613d0a91 100644 --- a/awx/ui/static/js/shared/breadcrumbs/breadcrumbs.directive.js +++ b/awx/ui/static/js/shared/breadcrumbs/breadcrumbs.directive.js @@ -9,30 +9,33 @@ import controller from './breadcrumbs.controller'; import 'tower/shared/generator-helpers'; -export default function() { +export default + [ 'templateUrl', + function(templateUrl) { - return { - restrict: 'E', - controller: controller, - transclude: true, - templateUrl: '/static/js/shared/breadcrumbs/breadcrumbs.partial.html', - scope: { - }, - link: function(scope, element, attrs, controller) { - // make breadcrumbs hidden until the current - // breadcrumb has a title; this avoids - // ugly rendering when an object's title - // is fetched via ajax - // - controller.setHidden(); + return { + restrict: 'E', + controller: controller, + transclude: true, + templateUrl: templateUrl('shared/breadcrumbs/breadcrumbs'), + scope: { + }, + link: function(scope, element, attrs, controller) { + // make breadcrumbs hidden until the current + // breadcrumb has a title; this avoids + // ugly rendering when an object's title + // is fetched via ajax + // + controller.setHidden(); - scope.$watch('isHidden', function(value) { - if (value) { - element.hide(); - } else { - element.show(); + scope.$watch('isHidden', function(value) { + if (value) { + element.hide(); + } else { + element.show(); + } + }); } - }); + }; } - }; -} + ]; diff --git a/awx/ui/static/js/shared/icon/icon.directive.js b/awx/ui/static/js/shared/icon/icon.directive.js index b0735704fb..d4da46b5a6 100644 --- a/awx/ui/static/js/shared/icon/icon.directive.js +++ b/awx/ui/static/js/shared/icon/icon.directive.js @@ -1,29 +1,32 @@ -export default function() { - return { - restrict: 'E', - templateUrl: '/static/js/shared/icon/icon.partial.html', - scope: { - }, - link: function(scope, element, attrs) { - var svg = $('svg', element); - var iconPath = '#' + attrs.name; +export default + [ 'templateUrl', + function(templateUrl) { + return { + restrict: 'E', + templateUrl: templateUrl('shared/icon/icon'), + scope: { + }, + link: function(scope, element, attrs) { + var svg = $('svg', element); + var iconPath = '#' + attrs.name; - // Make a copy of the tag to insert its contents into this - // element's svg tag - var content = $(iconPath).clone(); + // Make a copy of the tag to insert its contents into this + // element's svg tag + var content = $(iconPath).clone(); - // Copy classes & viewBox off the so that we preserve any styling - // when we copy the item inline - var classes = $(iconPath).attr('class'); + // Copy classes & viewBox off the so that we preserve any styling + // when we copy the item inline + var classes = $(iconPath).attr('class'); - // viewBox needs to be access via native - // javascript's setAttribute function - var viewBox = $(iconPath)[0].getAttribute('viewBox'); + // viewBox needs to be access via native + // javascript's setAttribute function + var viewBox = $(iconPath)[0].getAttribute('viewBox'); - svg[0].setAttribute('viewBox', viewBox); - svg.attr('class', classes) - .html(content.contents()); + svg[0].setAttribute('viewBox', viewBox); + svg.attr('class', classes) + .html(content.contents()); + } + }; } - }; -} + ]; diff --git a/awx/ui/static/js/shared/multi-select-list/main.js b/awx/ui/static/js/shared/multi-select-list/main.js index 089fc7cd7b..7679b5e9d4 100644 --- a/awx/ui/static/js/shared/multi-select-list/main.js +++ b/awx/ui/static/js/shared/multi-select-list/main.js @@ -7,9 +7,10 @@ import multiSelect from './multi-select-list.directive'; import selectAll from './select-all.directive'; import selectListItem from './select-list-item.directive'; +import templateUrl from 'tower/shared/template-url/main'; export default - angular.module('multiSelectList', []) + angular.module('multiSelectList', [templateUrl.name]) .directive('multiSelectList', multiSelect) .directive('selectAll', selectAll) .directive('selectListItem', selectListItem); diff --git a/awx/ui/static/js/shared/multi-select-list/select-all.directive.js b/awx/ui/static/js/shared/multi-select-list/select-all.directive.js index 251fd6a008..4470f05e79 100644 --- a/awx/ui/static/js/shared/multi-select-list/select-all.directive.js +++ b/awx/ui/static/js/shared/multi-select-list/select-all.directive.js @@ -129,12 +129,10 @@ // // => // '/static/js/shared/multi-select-list/select-all.html // -function template(base) { - return '/static/js/' + base + '.partial.html'; -} export default - [ function() { + [ 'templateUrl', + function(templateUrl) { return { require: '^multiSelectList', restrict: 'E', @@ -145,7 +143,7 @@ export default extendedLabel: '&', isSelectionEmpty: '=selectionsEmpty' }, - templateUrl: template('shared/multi-select-list/select-all'), + templateUrl: templateUrl('shared/multi-select-list/select-all'), link: function(scope, element, attrs, controller) { scope.label = scope.label || 'All'; diff --git a/awx/ui/static/js/shared/template-url/main.js b/awx/ui/static/js/shared/template-url/main.js new file mode 100644 index 0000000000..8c1c64185e --- /dev/null +++ b/awx/ui/static/js/shared/template-url/main.js @@ -0,0 +1,6 @@ +import templateUrl from './template-url.factory'; + +export default + angular.module('templateUrl', []) + .factory('templateUrl', templateUrl); + diff --git a/awx/ui/static/js/shared/template-url/template-url.factory.js b/awx/ui/static/js/shared/template-url/template-url.factory.js new file mode 100644 index 0000000000..c3fb17fd68 --- /dev/null +++ b/awx/ui/static/js/shared/template-url/template-url.factory.js @@ -0,0 +1,20 @@ +function templateUrl($sce, path, isTrusted) { + isTrusted = isTrusted !== false; // defaults to true, can be passed in as false + var parts = ['', 'static', 'js']; + parts.push(path); + + var url = parts.join('/') + '.partial.html'; + + if (isTrusted) { + url = $sce.trustAsResourceUrl(url); + } + + return url; +} + +export default + [ '$sce', + function($sce) { + return _.partial(templateUrl, $sce); + } + ]; diff --git a/awx/ui/static/js/system-tracking/date-picker/date-picker.directive.js b/awx/ui/static/js/system-tracking/date-picker/date-picker.directive.js index 167ef8688b..211705768f 100644 --- a/awx/ui/static/js/system-tracking/date-picker/date-picker.directive.js +++ b/awx/ui/static/js/system-tracking/date-picker/date-picker.directive.js @@ -8,7 +8,8 @@ export default [ 'moment', - function(moment) { + 'templateUrl', + function(moment, templateUrl) { return { restrict: 'E', scope: { @@ -17,7 +18,7 @@ export default autoUpdate: '=?', inputClass: '&' }, - templateUrl: '/static/js/system-tracking/date-picker/date-picker.partial.html', + templateUrl: templateUrl('system-tracking/date-picker/date-picker'), link: function(scope, element, attrs) { // We need to make sure this _never_ recurses, which sometimes happens diff --git a/awx/ui/static/js/system-tracking/fact-data-table/fact-data-table.directive.js b/awx/ui/static/js/system-tracking/fact-data-table/fact-data-table.directive.js index 21f157d3ff..1c99f546a0 100644 --- a/awx/ui/static/js/system-tracking/fact-data-table/fact-data-table.directive.js +++ b/awx/ui/static/js/system-tracking/fact-data-table/fact-data-table.directive.js @@ -1,9 +1,10 @@ /* jshint unused: vars */ export default - [ function() { + [ 'templateUrl', + function(templateUrl) { return { restrict: 'E', - templateUrl: '/static/js/system-tracking/fact-data-table/fact-data-table.partial.html', + templateUrl: templateUrl('system-tracking/fact-data-table/fact-data-table'), scope: { leftHostname: '=', rightHostname: '=', diff --git a/awx/ui/tests/unit/setup-browser.js b/awx/ui/tests/unit/setup-browser.js new file mode 100644 index 0000000000..a6ed4df031 --- /dev/null +++ b/awx/ui/tests/unit/setup-browser.js @@ -0,0 +1,39 @@ +var jsdom = require('jsdom').jsdom; +var document = jsdom('tower'); +var window = document.parentWindow; +var mocha = require('mocha'); +window.mocha = mocha; +window.beforeEach = beforeEach; +window.afterEach = afterEach; + +global.document = document; +global.window = window; + +require('angular/angular'); +var jquery = require('jquery'); +require('angular-mocks/angular-mocks'); + +var chai = require('chai'); +var expect = chai.expect; +var sinonChai = require('sinon-chai'); +var chaiAsPromised = require('chai-as-promised'); +var sinon = require('sinon'); +var chaiThings = require('chai-things'); + +chai.use(sinonChai); +chai.use(chaiAsPromised); +chai.use(chaiThings); + +global.$ = window.$ = jquery; +global.angular = window.angular; +global.expect = chai.expect; + +angular.module('templates', []); +require('../../templates'); + +var lodash = require('lodash'); +global._ = lodash; + +var LocalStorage = require('node-localstorage').LocalStorage; +global.localStorage = window.localStorage = new LocalStorage('./scratch'); +