mirror of
https://github.com/ansible/awx.git
synced 2026-05-08 01:47:35 -02:30
Merge pull request #305 from joefiorini/post-2.2--nodeTests
Post 2.2 - improve JS testing workflow
This commit is contained in:
2
.gitignore
vendored
2
.gitignore
vendored
@@ -49,6 +49,8 @@ npm-debug.log
|
|||||||
coverage.xml
|
coverage.xml
|
||||||
htmlcov
|
htmlcov
|
||||||
pep8.txt
|
pep8.txt
|
||||||
|
scratch
|
||||||
|
testem.log
|
||||||
|
|
||||||
# Mac OS X
|
# Mac OS X
|
||||||
*.DS_Store
|
*.DS_Store
|
||||||
|
|||||||
5
Makefile
5
Makefile
@@ -3,6 +3,7 @@ SITELIB=$(shell $(PYTHON) -c "from distutils.sysconfig import get_python_lib; pr
|
|||||||
OFFICIAL ?= no
|
OFFICIAL ?= no
|
||||||
PACKER ?= packer
|
PACKER ?= packer
|
||||||
GRUNT ?= $(shell [ -t 0 ] && echo "grunt" || echo "grunt --no-color")
|
GRUNT ?= $(shell [ -t 0 ] && echo "grunt" || echo "grunt --no-color")
|
||||||
|
TESTEM ?= ./node_modules/.bin/testem
|
||||||
BROCCOLI ?= ./node_modules/.bin/broccoli
|
BROCCOLI ?= ./node_modules/.bin/broccoli
|
||||||
NODE ?= node
|
NODE ?= node
|
||||||
|
|
||||||
@@ -293,8 +294,8 @@ reports/ui_code: node_modules clean-ui Brocfile.js bower.json Gruntfile.js
|
|||||||
$(BROCCOLI) build reports/ui_code -- --no-concat --no-tests --no-styles --no-sourcemaps
|
$(BROCCOLI) build reports/ui_code -- --no-concat --no-tests --no-styles --no-sourcemaps
|
||||||
|
|
||||||
# Run UI unit tests
|
# Run UI unit tests
|
||||||
test_ui: node_modules minjs_ci Gruntfile.js
|
test_ui: node_modules minjs_ci
|
||||||
$(GRUNT) karma:ci
|
$(TESTEM) ci --file testem.yml -R xunit
|
||||||
|
|
||||||
# Run API unit tests across multiple Python/Django versions with Tox.
|
# Run API unit tests across multiple Python/Django versions with Tox.
|
||||||
test_tox:
|
test_tox:
|
||||||
|
|||||||
@@ -38,6 +38,7 @@ import mainMenu from 'tower/main-menu/main';
|
|||||||
import browserData from 'tower/browser-data/main';
|
import browserData from 'tower/browser-data/main';
|
||||||
import dashboard from 'tower/dashboard/main';
|
import dashboard from 'tower/dashboard/main';
|
||||||
import moment from 'tower/shared/moment/main';
|
import moment from 'tower/shared/moment/main';
|
||||||
|
import templateUrl from 'tower/shared/template-url/main';
|
||||||
|
|
||||||
import {JobDetailController} from 'tower/controllers/JobDetail';
|
import {JobDetailController} from 'tower/controllers/JobDetail';
|
||||||
import {JobStdoutController} from 'tower/controllers/JobStdout';
|
import {JobStdoutController} from 'tower/controllers/JobStdout';
|
||||||
@@ -84,6 +85,7 @@ var tower = angular.module('Tower', [
|
|||||||
mainMenu.name,
|
mainMenu.name,
|
||||||
dashboard.name,
|
dashboard.name,
|
||||||
moment.name,
|
moment.name,
|
||||||
|
templateUrl.name,
|
||||||
'AuthService',
|
'AuthService',
|
||||||
'Utilities',
|
'Utilities',
|
||||||
'LicenseHelper',
|
'LicenseHelper',
|
||||||
|
|||||||
@@ -1,14 +1,14 @@
|
|||||||
/* jshint unused: vars */
|
/* jshint unused: vars */
|
||||||
export default
|
export default
|
||||||
[ '$rootScope',
|
[ 'templateUrl',
|
||||||
function() {
|
function(templateUrl) {
|
||||||
return {
|
return {
|
||||||
restrict: 'E',
|
restrict: 'E',
|
||||||
scope: {
|
scope: {
|
||||||
data: '='
|
data: '='
|
||||||
},
|
},
|
||||||
replace: false,
|
replace: false,
|
||||||
templateUrl: '/static/js/dashboard/counts/dashboard-counts.partial.html',
|
templateUrl: templateUrl('dashboard/counts/dashboard-counts'),
|
||||||
link: function(scope, element, attrs) {
|
link: function(scope, element, attrs) {
|
||||||
scope.$watch("data", function(data) {
|
scope.$watch("data", function(data) {
|
||||||
if (data && data.hosts) {
|
if (data && data.hosts) {
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
/* jshint unused: vars */
|
/* jshint unused: vars */
|
||||||
export default
|
export default
|
||||||
[ '$rootScope',
|
[ 'templateUrl',
|
||||||
function() {
|
function(templateUrl) {
|
||||||
return {
|
return {
|
||||||
restrict: 'E',
|
restrict: 'E',
|
||||||
scope: true,
|
scope: true,
|
||||||
templateUrl: '/static/js/dashboard/dashboard.partial.html',
|
templateUrl: templateUrl('dashboard/dashboard'),
|
||||||
link: function(scope, element, attrs) {
|
link: function(scope, element, attrs) {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
/* jshint unused: vars */
|
/* jshint unused: vars */
|
||||||
export default
|
export default
|
||||||
[ '$rootScope',
|
[ 'templateUrl',
|
||||||
function() {
|
function(templateUrl) {
|
||||||
return {
|
return {
|
||||||
restrict: 'E',
|
restrict: 'E',
|
||||||
scope: true,
|
scope: true,
|
||||||
templateUrl: '/static/js/dashboard/graphs/dashboard-graphs.partial.html',
|
templateUrl: templateUrl('dashboard/graphs/dashboard-graphs'),
|
||||||
link: function(scope, element, attrs) {
|
link: function(scope, element, attrs) {
|
||||||
function clearGraphs() {
|
function clearGraphs() {
|
||||||
scope.jobStatusSelected = false;
|
scope.jobStatusSelected = false;
|
||||||
|
|||||||
@@ -8,14 +8,15 @@
|
|||||||
[ '$compile',
|
[ '$compile',
|
||||||
'$window',
|
'$window',
|
||||||
'adjustGraphSize',
|
'adjustGraphSize',
|
||||||
|
'templateUrl',
|
||||||
HostStatusGraph,
|
HostStatusGraph,
|
||||||
];
|
];
|
||||||
|
|
||||||
function HostStatusGraph($compile, $window, adjustGraphSize) {
|
function HostStatusGraph($compile, $window, adjustGraphSize, templateUrl) {
|
||||||
return {
|
return {
|
||||||
restrict: 'E',
|
restrict: 'E',
|
||||||
link: link,
|
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) {
|
function link(scope, element, attr) {
|
||||||
|
|||||||
@@ -12,16 +12,17 @@
|
|||||||
'Wait',
|
'Wait',
|
||||||
'adjustGraphSize',
|
'adjustGraphSize',
|
||||||
'jobStatusGraphData',
|
'jobStatusGraphData',
|
||||||
|
'templateUrl',
|
||||||
JobStatusGraph
|
JobStatusGraph
|
||||||
];
|
];
|
||||||
|
|
||||||
function JobStatusGraph($rootScope, $compile , $location, $window, Wait, adjustGraphSize, graphDataService) {
|
function JobStatusGraph($rootScope, $compile , $location, $window, Wait, adjustGraphSize, graphDataService, templateUrl) {
|
||||||
return {
|
return {
|
||||||
restrict: 'E',
|
restrict: 'E',
|
||||||
scope: {
|
scope: {
|
||||||
data: '='
|
data: '='
|
||||||
},
|
},
|
||||||
templateUrl: '/static/js/dashboard/graphs/job-status/job_status_graph.partial.html',
|
templateUrl: templateUrl('dashboard/graphs/job-status/job_status_graph'),
|
||||||
link: link
|
link: link
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
import JobStatusGraphDirective from 'tower/dashboard/graphs/job-status/job-status-graph.directive';
|
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 JobStatusGraphService from 'tower/dashboard/graphs/job-status/job-status-graph.service';
|
||||||
import DashboardGraphHelpers from 'tower/dashboard/graphs/graph-helpers/main';
|
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)
|
.directive('jobStatusGraph', JobStatusGraphDirective)
|
||||||
.service('jobStatusGraphData', JobStatusGraphService);
|
.service('jobStatusGraphData', JobStatusGraphService);
|
||||||
|
|||||||
@@ -1,14 +1,15 @@
|
|||||||
/* jshint unused: vars */
|
/* jshint unused: vars */
|
||||||
export default
|
export default
|
||||||
[ "PlaybookRun",
|
[ "PlaybookRun",
|
||||||
function JobTemplatesList(PlaybookRun) {
|
'templateUrl',
|
||||||
|
function JobTemplatesList(PlaybookRun, templateUrl) {
|
||||||
return {
|
return {
|
||||||
restrict: 'E',
|
restrict: 'E',
|
||||||
link: link,
|
link: link,
|
||||||
scope: {
|
scope: {
|
||||||
data: '='
|
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) {
|
function link(scope, element, attr) {
|
||||||
|
|||||||
@@ -1,43 +1,44 @@
|
|||||||
/* jshint unused: vars */
|
/* jshint unused: vars */
|
||||||
export default
|
export default
|
||||||
['moment',
|
[ 'moment',
|
||||||
function JobsList(moment) {
|
'templateUrl',
|
||||||
return {
|
function JobsList(moment, templateUrl) {
|
||||||
restrict: 'E',
|
return {
|
||||||
link: link,
|
restrict: 'E',
|
||||||
scope: {
|
link: link,
|
||||||
data: '='
|
scope: {
|
||||||
},
|
data: '='
|
||||||
templateUrl: '/static/js/dashboard/lists/jobs/jobs-list.partial.html'
|
},
|
||||||
};
|
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");
|
|
||||||
};
|
};
|
||||||
}
|
|
||||||
|
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");
|
||||||
|
};
|
||||||
|
}
|
||||||
}];
|
}];
|
||||||
|
|||||||
@@ -1,15 +1,18 @@
|
|||||||
export default function() {
|
export default
|
||||||
return {
|
[ 'templateUrl',
|
||||||
restrict: 'E',
|
function(templateUrl) {
|
||||||
templateUrl: '/static/js/main-menu/menu-default.partial.html',
|
return {
|
||||||
link: function(scope, element) {
|
restrict: 'E',
|
||||||
var contents = element.contents();
|
templateUrl: templateUrl('main-menu/menu-default'),
|
||||||
contents.unwrap();
|
link: function(scope, element) {
|
||||||
|
var contents = element.contents();
|
||||||
|
contents.unwrap();
|
||||||
|
|
||||||
scope.$on('$destroy', function() {
|
scope.$on('$destroy', function() {
|
||||||
contents.remove();
|
contents.remove();
|
||||||
$(".MenuItem--socketStatus").remove();
|
$(".MenuItem--socketStatus").remove();
|
||||||
});
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
}
|
}
|
||||||
};
|
];
|
||||||
}
|
|
||||||
|
|||||||
@@ -1,45 +1,48 @@
|
|||||||
/* jshint unused: vars */
|
/* jshint unused: vars */
|
||||||
|
|
||||||
export default function() {
|
export default
|
||||||
return {
|
[ 'templateUrl',
|
||||||
restrict: 'E',
|
function(templateUrl) {
|
||||||
controllerAs: 'mainMenu',
|
return {
|
||||||
templateUrl: '/static/js/main-menu/main-menu.partial.html',
|
restrict: 'E',
|
||||||
controller: ['$scope', function($scope) {
|
controllerAs: 'mainMenu',
|
||||||
this.open = function() {
|
templateUrl: templateUrl('main-menu/main-menu'),
|
||||||
$scope.isOpen = true;
|
controller: ['$scope', function($scope) {
|
||||||
};
|
this.open = function() {
|
||||||
|
$scope.isOpen = true;
|
||||||
|
};
|
||||||
|
|
||||||
this.close = function() {
|
this.close = function() {
|
||||||
$scope.isOpen = false;
|
$scope.isOpen = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
this.toggle = function() {
|
this.toggle = function() {
|
||||||
$scope.isOpen = !$scope.isOpen;
|
$scope.isOpen = !$scope.isOpen;
|
||||||
};
|
};
|
||||||
|
|
||||||
$scope.isOpen = false;
|
$scope.isOpen = false;
|
||||||
}],
|
}],
|
||||||
scope: {
|
scope: {
|
||||||
menuStyle: '&menuStyle',
|
menuStyle: '&menuStyle',
|
||||||
currentUser: '='
|
currentUser: '='
|
||||||
},
|
},
|
||||||
link: function(scope, element, attrs) {
|
link: function(scope, element, attrs) {
|
||||||
scope.menuStyleClassName = 'blah';
|
scope.menuStyleClassName = 'blah';
|
||||||
scope.$watch(function() {
|
scope.$watch(function() {
|
||||||
return scope.$eval(scope.menuStyle);
|
return scope.$eval(scope.menuStyle);
|
||||||
}, function(newValue) {
|
}, function(newValue) {
|
||||||
scope.menuStyleClassName = 'MainMenu--' + newValue;
|
scope.menuStyleClassName = 'MainMenu--' + newValue;
|
||||||
});
|
});
|
||||||
scope.$watch('isOpen', function(isOpen) {
|
scope.$watch('isOpen', function(isOpen) {
|
||||||
if (isOpen) {
|
if (isOpen) {
|
||||||
element.find('.MainMenu').addClass("Menu--open");
|
element.find('.MainMenu').addClass("Menu--open");
|
||||||
element.find('menu-toggle-button').addClass("MenuToggle--open");
|
element.find('menu-toggle-button').addClass("MenuToggle--open");
|
||||||
} else {
|
} else {
|
||||||
element.find('.MainMenu').removeClass("Menu--open");
|
element.find('.MainMenu').removeClass("Menu--open");
|
||||||
element.find('menu-toggle-button').removeClass("MenuToggle--open");
|
element.find('menu-toggle-button').removeClass("MenuToggle--open");
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
});
|
};
|
||||||
}
|
}
|
||||||
};
|
];
|
||||||
}
|
|
||||||
|
|||||||
@@ -1,27 +1,30 @@
|
|||||||
/* jshint unused: vars */
|
/* jshint unused: vars */
|
||||||
|
|
||||||
export default function() {
|
export default
|
||||||
return {
|
[ 'templateUrl',
|
||||||
templateUrl: '/static/js/main-menu/menu-toggle.partial.html',
|
function(templateUrl) {
|
||||||
restrict: 'E',
|
return {
|
||||||
require: '^^mainMenu',
|
templateUrl: templateUrl('main-menu/menu-toggle'),
|
||||||
scope: {
|
restrict: 'E',
|
||||||
width: '@',
|
require: '^^mainMenu',
|
||||||
height: '@',
|
scope: {
|
||||||
barHeight: '@'
|
width: '@',
|
||||||
},
|
height: '@',
|
||||||
link: function(scope, element, attrs, mainMenuController) {
|
barHeight: '@'
|
||||||
scope.$on('$destroy', function() {
|
},
|
||||||
element.off('click');
|
link: function(scope, element, attrs, mainMenuController) {
|
||||||
});
|
scope.$on('$destroy', function() {
|
||||||
|
element.off('click');
|
||||||
|
});
|
||||||
|
|
||||||
element.on("click", function(e) {
|
element.on("click", function(e) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
scope.$apply(function() {
|
scope.$apply(function() {
|
||||||
mainMenuController.toggle();
|
mainMenuController.toggle();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
}
|
}
|
||||||
};
|
];
|
||||||
}
|
|
||||||
|
|||||||
@@ -1,15 +1,18 @@
|
|||||||
export default function() {
|
export default
|
||||||
return {
|
[ 'templateUrl',
|
||||||
restrict: 'E',
|
function(templateUrl) {
|
||||||
templateUrl: '/static/js/main-menu/menu-portal.partial.html',
|
return {
|
||||||
link: function(scope, element) {
|
restrict: 'E',
|
||||||
var contents = element.contents();
|
templateUrl: templateUrl('main-menu/menu-portal'),
|
||||||
contents.unwrap();
|
link: function(scope, element) {
|
||||||
|
var contents = element.contents();
|
||||||
|
contents.unwrap();
|
||||||
|
|
||||||
scope.$on('$destroy', function() {
|
scope.$on('$destroy', function() {
|
||||||
contents.remove();
|
contents.remove();
|
||||||
$(".MenuItem--socketStatus").remove();
|
$(".MenuItem--socketStatus").remove();
|
||||||
});
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
}
|
}
|
||||||
};
|
];
|
||||||
}
|
|
||||||
|
|||||||
@@ -1,18 +1,22 @@
|
|||||||
/* jshint unused: vars */
|
/* jshint unused: vars */
|
||||||
|
|
||||||
export default ['$rootScope', function($rootScope) {
|
export default
|
||||||
return {
|
[ '$rootScope',
|
||||||
restrict: 'E',
|
'templateUrl',
|
||||||
templateUrl: '/static/js/main-menu/web-socket-status.partial.html',
|
function($rootScope, templateUrl) {
|
||||||
link: function(scope, element, attrs) {
|
return {
|
||||||
scope.socketHelp = $rootScope.socketHelp;
|
restrict: 'E',
|
||||||
scope.socketTip = $rootScope.socketTip;
|
templateUrl: templateUrl('main-menu/web-socket-status'),
|
||||||
$rootScope.$watch('socketStatus', function(newStatus) {
|
link: function(scope, element, attrs) {
|
||||||
scope.socketStatus = newStatus;
|
scope.socketHelp = $rootScope.socketHelp;
|
||||||
});
|
scope.socketTip = $rootScope.socketTip;
|
||||||
$rootScope.$watch('socketTip', function(newTip) {
|
$rootScope.$watch('socketStatus', function(newStatus) {
|
||||||
scope.socketTip = newTip;
|
scope.socketStatus = newStatus;
|
||||||
});
|
});
|
||||||
|
$rootScope.$watch('socketTip', function(newTip) {
|
||||||
|
scope.socketTip = newTip;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
}
|
}
|
||||||
};
|
];
|
||||||
}];
|
|
||||||
|
|||||||
@@ -9,30 +9,33 @@
|
|||||||
import controller from './breadcrumbs.controller';
|
import controller from './breadcrumbs.controller';
|
||||||
import 'tower/shared/generator-helpers';
|
import 'tower/shared/generator-helpers';
|
||||||
|
|
||||||
export default function() {
|
export default
|
||||||
|
[ 'templateUrl',
|
||||||
|
function(templateUrl) {
|
||||||
|
|
||||||
return {
|
return {
|
||||||
restrict: 'E',
|
restrict: 'E',
|
||||||
controller: controller,
|
controller: controller,
|
||||||
transclude: true,
|
transclude: true,
|
||||||
templateUrl: '/static/js/shared/breadcrumbs/breadcrumbs.partial.html',
|
templateUrl: templateUrl('shared/breadcrumbs/breadcrumbs'),
|
||||||
scope: {
|
scope: {
|
||||||
},
|
},
|
||||||
link: function(scope, element, attrs, controller) {
|
link: function(scope, element, attrs, controller) {
|
||||||
// make breadcrumbs hidden until the current
|
// make breadcrumbs hidden until the current
|
||||||
// breadcrumb has a title; this avoids
|
// breadcrumb has a title; this avoids
|
||||||
// ugly rendering when an object's title
|
// ugly rendering when an object's title
|
||||||
// is fetched via ajax
|
// is fetched via ajax
|
||||||
//
|
//
|
||||||
controller.setHidden();
|
controller.setHidden();
|
||||||
|
|
||||||
scope.$watch('isHidden', function(value) {
|
scope.$watch('isHidden', function(value) {
|
||||||
if (value) {
|
if (value) {
|
||||||
element.hide();
|
element.hide();
|
||||||
} else {
|
} else {
|
||||||
element.show();
|
element.show();
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
});
|
};
|
||||||
}
|
}
|
||||||
};
|
];
|
||||||
}
|
|
||||||
|
|||||||
@@ -1,29 +1,32 @@
|
|||||||
export default function() {
|
export default
|
||||||
return {
|
[ 'templateUrl',
|
||||||
restrict: 'E',
|
function(templateUrl) {
|
||||||
templateUrl: '/static/js/shared/icon/icon.partial.html',
|
return {
|
||||||
scope: {
|
restrict: 'E',
|
||||||
},
|
templateUrl: templateUrl('shared/icon/icon'),
|
||||||
link: function(scope, element, attrs) {
|
scope: {
|
||||||
var svg = $('svg', element);
|
},
|
||||||
var iconPath = '#' + attrs.name;
|
link: function(scope, element, attrs) {
|
||||||
|
var svg = $('svg', element);
|
||||||
|
var iconPath = '#' + attrs.name;
|
||||||
|
|
||||||
// Make a copy of the <symbol> tag to insert its contents into this
|
// Make a copy of the <symbol> tag to insert its contents into this
|
||||||
// element's svg tag
|
// element's svg tag
|
||||||
var content = $(iconPath).clone();
|
var content = $(iconPath).clone();
|
||||||
|
|
||||||
// Copy classes & viewBox off the <symbol> so that we preserve any styling
|
// Copy classes & viewBox off the <symbol> so that we preserve any styling
|
||||||
// when we copy the item inline
|
// when we copy the item inline
|
||||||
var classes = $(iconPath).attr('class');
|
var classes = $(iconPath).attr('class');
|
||||||
|
|
||||||
// viewBox needs to be access via native
|
// viewBox needs to be access via native
|
||||||
// javascript's setAttribute function
|
// javascript's setAttribute function
|
||||||
var viewBox = $(iconPath)[0].getAttribute('viewBox');
|
var viewBox = $(iconPath)[0].getAttribute('viewBox');
|
||||||
|
|
||||||
svg[0].setAttribute('viewBox', viewBox);
|
svg[0].setAttribute('viewBox', viewBox);
|
||||||
svg.attr('class', classes)
|
svg.attr('class', classes)
|
||||||
.html(content.contents());
|
.html(content.contents());
|
||||||
|
|
||||||
|
}
|
||||||
|
};
|
||||||
}
|
}
|
||||||
};
|
];
|
||||||
}
|
|
||||||
|
|||||||
@@ -7,9 +7,9 @@ function moment() {
|
|||||||
// lists the user's preferred languages, the first in the array
|
// lists the user's preferred languages, the first in the array
|
||||||
// being the user's top choice. navigator.languages is currently
|
// being the user's top choice. navigator.languages is currently
|
||||||
// comptabile with chrome>v32, ffox>32, but not IE/Safari
|
// comptabile with chrome>v32, ffox>32, but not IE/Safari
|
||||||
var lang = navigator.languages ?
|
var lang = window.navigator.languages ?
|
||||||
navigator.languages[0] :
|
window.navigator.languages[0] :
|
||||||
(navigator.language || navigator.userLanguage);
|
(window.navigator.language || window.navigator.userLanguage);
|
||||||
|
|
||||||
originalMoment.locale(lang);
|
originalMoment.locale(lang);
|
||||||
return originalMoment.apply(this, arguments);
|
return originalMoment.apply(this, arguments);
|
||||||
|
|||||||
@@ -7,9 +7,10 @@
|
|||||||
import multiSelect from './multi-select-list.directive';
|
import multiSelect from './multi-select-list.directive';
|
||||||
import selectAll from './select-all.directive';
|
import selectAll from './select-all.directive';
|
||||||
import selectListItem from './select-list-item.directive';
|
import selectListItem from './select-list-item.directive';
|
||||||
|
import templateUrl from 'tower/shared/template-url/main';
|
||||||
|
|
||||||
export default
|
export default
|
||||||
angular.module('multiSelectList', [])
|
angular.module('multiSelectList', [templateUrl.name])
|
||||||
.directive('multiSelectList', multiSelect)
|
.directive('multiSelectList', multiSelect)
|
||||||
.directive('selectAll', selectAll)
|
.directive('selectAll', selectAll)
|
||||||
.directive('selectListItem', selectListItem);
|
.directive('selectListItem', selectListItem);
|
||||||
|
|||||||
@@ -129,12 +129,10 @@
|
|||||||
// // =>
|
// // =>
|
||||||
// '/static/js/shared/multi-select-list/select-all.html
|
// '/static/js/shared/multi-select-list/select-all.html
|
||||||
//
|
//
|
||||||
function template(base) {
|
|
||||||
return '/static/js/' + base + '.partial.html';
|
|
||||||
}
|
|
||||||
|
|
||||||
export default
|
export default
|
||||||
[ function() {
|
[ 'templateUrl',
|
||||||
|
function(templateUrl) {
|
||||||
return {
|
return {
|
||||||
require: '^multiSelectList',
|
require: '^multiSelectList',
|
||||||
restrict: 'E',
|
restrict: 'E',
|
||||||
@@ -145,7 +143,7 @@ export default
|
|||||||
extendedLabel: '&',
|
extendedLabel: '&',
|
||||||
isSelectionEmpty: '=selectionsEmpty'
|
isSelectionEmpty: '=selectionsEmpty'
|
||||||
},
|
},
|
||||||
templateUrl: template('shared/multi-select-list/select-all'),
|
templateUrl: templateUrl('shared/multi-select-list/select-all'),
|
||||||
link: function(scope, element, attrs, controller) {
|
link: function(scope, element, attrs, controller) {
|
||||||
|
|
||||||
scope.label = scope.label || 'All';
|
scope.label = scope.label || 'All';
|
||||||
|
|||||||
6
awx/ui/static/js/shared/template-url/main.js
Normal file
6
awx/ui/static/js/shared/template-url/main.js
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
import templateUrl from './template-url.factory';
|
||||||
|
|
||||||
|
export default
|
||||||
|
angular.module('templateUrl', [])
|
||||||
|
.factory('templateUrl', templateUrl);
|
||||||
|
|
||||||
20
awx/ui/static/js/shared/template-url/template-url.factory.js
Normal file
20
awx/ui/static/js/shared/template-url/template-url.factory.js
Normal file
@@ -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);
|
||||||
|
}
|
||||||
|
];
|
||||||
@@ -2,9 +2,10 @@ import factScanDataService from './fact-scan-data.service';
|
|||||||
import getDataForComparison from './get-data-for-comparison.factory';
|
import getDataForComparison from './get-data-for-comparison.factory';
|
||||||
import getModuleOptions from './get-module-options.factory';
|
import getModuleOptions from './get-module-options.factory';
|
||||||
import resolveEmptyVersions from './resolve-empty-versions.factory';
|
import resolveEmptyVersions from './resolve-empty-versions.factory';
|
||||||
|
import shared from 'tower/shared/main';
|
||||||
|
|
||||||
export default
|
export default
|
||||||
angular.module('systemTracking.dataServices', [])
|
angular.module('systemTracking.dataServices', [shared.name])
|
||||||
.factory('getModuleOptions', getModuleOptions)
|
.factory('getModuleOptions', getModuleOptions)
|
||||||
.factory('getDataForComparison', getDataForComparison)
|
.factory('getDataForComparison', getDataForComparison)
|
||||||
.factory('resolveEmptyVersions', resolveEmptyVersions)
|
.factory('resolveEmptyVersions', resolveEmptyVersions)
|
||||||
|
|||||||
@@ -8,7 +8,8 @@
|
|||||||
|
|
||||||
export default
|
export default
|
||||||
[ 'moment',
|
[ 'moment',
|
||||||
function(moment) {
|
'templateUrl',
|
||||||
|
function(moment, templateUrl) {
|
||||||
return {
|
return {
|
||||||
restrict: 'E',
|
restrict: 'E',
|
||||||
scope: {
|
scope: {
|
||||||
@@ -17,7 +18,7 @@ export default
|
|||||||
autoUpdate: '=?',
|
autoUpdate: '=?',
|
||||||
inputClass: '&'
|
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) {
|
link: function(scope, element, attrs) {
|
||||||
|
|
||||||
// We need to make sure this _never_ recurses, which sometimes happens
|
// We need to make sure this _never_ recurses, which sometimes happens
|
||||||
|
|||||||
@@ -1,9 +1,10 @@
|
|||||||
/* jshint unused: vars */
|
/* jshint unused: vars */
|
||||||
|
|
||||||
export default
|
export default
|
||||||
[ function() {
|
[ 'templateUrl',
|
||||||
|
function(templateUrl) {
|
||||||
return { restrict: 'E',
|
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:
|
scope:
|
||||||
{ leftHostname: '=',
|
{ leftHostname: '=',
|
||||||
rightHostname: '=',
|
rightHostname: '=',
|
||||||
|
|||||||
@@ -55,7 +55,11 @@ var define, requireModule, require, requirejs;
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!registry[name]) {
|
if (!registry[name]) {
|
||||||
throw new Error('Could not find module ' + name);
|
name = name + '/index';
|
||||||
|
|
||||||
|
if (!registry[name]) {
|
||||||
|
throw new Error('Could not find module ' + name);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var mod = registry[name];
|
var mod = registry[name];
|
||||||
|
|||||||
5
awx/ui/tests/.jshintrc
Normal file
5
awx/ui/tests/.jshintrc
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
{
|
||||||
|
"expr": true,
|
||||||
|
"esnext": true,
|
||||||
|
"node": true
|
||||||
|
}
|
||||||
@@ -1,11 +1,20 @@
|
|||||||
import Tower from 'tower/app';
|
/* jshint node: true */
|
||||||
import {describeModule} from 'tests/unit/describe-module';
|
|
||||||
import JobStatusGraph from 'tower/dashboard/graphs/job-status/main'
|
import '../support/node';
|
||||||
|
|
||||||
|
import {describeModule} from '../support/describe-module';
|
||||||
|
import 'tower/shared/Utilities';
|
||||||
|
import 'tower/shared/RestServices';
|
||||||
|
import JobStatusGraph from 'tower/dashboard/graphs/job-status/main';
|
||||||
|
|
||||||
var resizeHandler = sinon.spy();
|
var resizeHandler = sinon.spy();
|
||||||
|
|
||||||
|
window.$.fn.removeResize = angular.noop;
|
||||||
|
|
||||||
describeModule(JobStatusGraph.name)
|
describeModule(JobStatusGraph.name)
|
||||||
.mockProvider('adjustGraphSize', resizeHandler)
|
.mockProvider('adjustGraphSize', resizeHandler)
|
||||||
|
.mockProvider('Wait', angular.noop)
|
||||||
|
.mockProvider('Rest', angular.noop)
|
||||||
.testDirective('jobStatusGraph', function(directive) {
|
.testDirective('jobStatusGraph', function(directive) {
|
||||||
|
|
||||||
|
|
||||||
@@ -1,30 +0,0 @@
|
|||||||
/**********************************
|
|
||||||
* Copyright (c) 2015 Ansible, Inc.
|
|
||||||
*
|
|
||||||
* CheckLicense.js
|
|
||||||
*
|
|
||||||
* Tests the CheckLicense service- helpers/CheckLicense.js
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* global describe, it, expect, by, browser, element, beforeEach */
|
|
||||||
|
|
||||||
|
|
||||||
describe('E2E:CheckLicense', function() {
|
|
||||||
beforeEach(function() {
|
|
||||||
browser.get('http://localhost:8013');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should present login dialog', function() {
|
|
||||||
var labels = element.all(by.css('#login-modal .modal-body label'));
|
|
||||||
expect(labels.get(0).getText()).toMatch(/Username/);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should login', function() {
|
|
||||||
element(by.model('login_username')).sendKeys('admin');
|
|
||||||
element(by.model('login_password')).sendKeys('password01!');
|
|
||||||
element(by.id('login-button')).click();
|
|
||||||
var user = element(by.css('#account-menu [ng-bind="current_user.username"]'));
|
|
||||||
expect(user.getText()).toMatch(/admin/);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
@@ -1,8 +1,10 @@
|
|||||||
|
import '../support/node';
|
||||||
|
|
||||||
import featuresController from 'tower/shared/features/features.controller';
|
import featuresController from 'tower/shared/features/features.controller';
|
||||||
|
|
||||||
describe('featuresController', function() {
|
describe('featuresController', function() {
|
||||||
|
|
||||||
it('checks if a feature is enabled', inject(['$rootScope', function($rootScope) {
|
it('checks if a feature is enabled', window.inject(['$rootScope', function($rootScope) {
|
||||||
var actual;
|
var actual;
|
||||||
|
|
||||||
$rootScope.features = {
|
$rootScope.features = {
|
||||||
@@ -1,5 +1,7 @@
|
|||||||
|
import '../support/node';
|
||||||
|
|
||||||
import features from 'tower/shared/features/main';
|
import features from 'tower/shared/features/main';
|
||||||
import {describeModule} from '../describe-module';
|
import {describeModule} from '../support/describe-module';
|
||||||
|
|
||||||
//test that it returns features, as well as test that it is returned in rootScope
|
//test that it returns features, as well as test that it is returned in rootScope
|
||||||
|
|
||||||
@@ -31,7 +33,7 @@ describeModule(features.name)
|
|||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('caches in rootScope', inject(['$rootScope',
|
it('caches in rootScope', window.inject(['$rootScope',
|
||||||
function($rootScope){
|
function($rootScope){
|
||||||
var features = {},
|
var features = {},
|
||||||
result = {
|
result = {
|
||||||
@@ -1,5 +1,7 @@
|
|||||||
|
import '../support/node';
|
||||||
|
|
||||||
import jobTemplates from 'tower/job-templates/main';
|
import jobTemplates from 'tower/job-templates/main';
|
||||||
import {describeModule} from '../describe-module';
|
import {describeModule} from '../support/describe-module';
|
||||||
|
|
||||||
describeModule(jobTemplates.name)
|
describeModule(jobTemplates.name)
|
||||||
.testService('deleteJobTemplate', function(test, restStub) {
|
.testService('deleteJobTemplate', function(test, restStub) {
|
||||||
@@ -1,22 +0,0 @@
|
|||||||
// Karma configuration
|
|
||||||
// Generated on Mon Aug 04 2014 21:17:04 GMT-0400 (EDT)
|
|
||||||
|
|
||||||
var sharedConfig = require('./karma-shared.conf');
|
|
||||||
|
|
||||||
module.exports = function(config) {
|
|
||||||
var conf = sharedConfig();
|
|
||||||
|
|
||||||
// list of files / patterns to load in the browser
|
|
||||||
conf.files = conf.files.concat([
|
|
||||||
'../static/lib/angular-mocks/angular-mocks.js',
|
|
||||||
'../../../node_modules/ng-midway-tester/src/ngMidwayTester.js',
|
|
||||||
'./unit/*',
|
|
||||||
'./unit/**/*'
|
|
||||||
]);
|
|
||||||
|
|
||||||
// level of logging
|
|
||||||
// possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG
|
|
||||||
conf.logLevel = config.LOG_INFO,
|
|
||||||
|
|
||||||
config.set(conf);
|
|
||||||
};
|
|
||||||
@@ -1,88 +0,0 @@
|
|||||||
// Karma configuration
|
|
||||||
// Generated on Mon Aug 04 2014 21:17:04 GMT-0400 (EDT)
|
|
||||||
|
|
||||||
var path = require('path');
|
|
||||||
|
|
||||||
module.exports = function(config) {
|
|
||||||
config.set({
|
|
||||||
|
|
||||||
// base path that will be used to resolve all patterns (eg. files, exclude)
|
|
||||||
basePath: '',
|
|
||||||
|
|
||||||
autoWatchBatchDelay: 2000,
|
|
||||||
|
|
||||||
// frameworks to use
|
|
||||||
// available frameworks: https://npmjs.org/browse/keyword/karma-adapter
|
|
||||||
|
|
||||||
frameworks:
|
|
||||||
[ 'mocha',
|
|
||||||
'chai',
|
|
||||||
'sinon-chai',
|
|
||||||
'chai-as-promised',
|
|
||||||
'chai-things'
|
|
||||||
],
|
|
||||||
|
|
||||||
preprocessors:
|
|
||||||
{ '../dist/**/*.html': ['ng-html2js']
|
|
||||||
},
|
|
||||||
|
|
||||||
// list of files / patterns to load in the browser
|
|
||||||
files: [
|
|
||||||
'../tests/phantomjs-polyfill.js',
|
|
||||||
'../dist/tower.concat.js',
|
|
||||||
'../static/lib/angular-mocks/angular-mocks.js',
|
|
||||||
'../static/lib/ember-cli-test-loader/test-loader.js',
|
|
||||||
'../dist/tests/**/*.js',
|
|
||||||
'../tests/unit.js',
|
|
||||||
'../dist/partials/**/*.html',
|
|
||||||
'../dist/js/**/*.html'
|
|
||||||
],
|
|
||||||
|
|
||||||
ngHtml2JsPreprocessor: {
|
|
||||||
stripPrefix: path.join(process.cwd(), 'awx/ui/dist'),
|
|
||||||
prependPrefix: '/static',
|
|
||||||
moduleName: 'templates'
|
|
||||||
},
|
|
||||||
|
|
||||||
|
|
||||||
// list of files to exclude
|
|
||||||
exclude: [
|
|
||||||
'../static/js/awx.min.js'
|
|
||||||
],
|
|
||||||
|
|
||||||
|
|
||||||
// test results reporter to use
|
|
||||||
// possible values: 'dots', 'progress'
|
|
||||||
// available reporters: https://npmjs.org/browse/keyword/karma-reporter
|
|
||||||
reporters: ['dots', 'progress'],
|
|
||||||
|
|
||||||
client: {
|
|
||||||
mocha: {
|
|
||||||
ui: 'bdd'
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
|
|
||||||
// web server port
|
|
||||||
port: 9876,
|
|
||||||
|
|
||||||
|
|
||||||
// enable / disable colors in the output (reporters and logs)
|
|
||||||
colors: true,
|
|
||||||
|
|
||||||
|
|
||||||
// enable / disable watching file and executing tests whenever any file changes
|
|
||||||
autoWatch: true,
|
|
||||||
|
|
||||||
|
|
||||||
// start these browsers
|
|
||||||
// available browser launchers: https://npmjs.org/browse/keyword/karma-launcher
|
|
||||||
browsers: ['Chrome'],
|
|
||||||
|
|
||||||
|
|
||||||
// Continuous Integration mode
|
|
||||||
// if true, Karma captures browsers, runs the tests and exits
|
|
||||||
singleRun: false
|
|
||||||
|
|
||||||
});
|
|
||||||
};
|
|
||||||
@@ -1,4 +1,6 @@
|
|||||||
import {describeModule} from 'tests/unit/describe-module';
|
import '../support/node';
|
||||||
|
|
||||||
|
import {describeModule} from '../support/describe-module';
|
||||||
import mod from 'tower/shared/multi-select-list/main';
|
import mod from 'tower/shared/multi-select-list/main';
|
||||||
|
|
||||||
describeModule(mod.name)
|
describeModule(mod.name)
|
||||||
@@ -18,9 +20,9 @@ describeModule(mod.name)
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('works as an attribute on elements', function() {
|
it('works as an attribute on elements', function() {
|
||||||
inject(['$compile', function($compile) {
|
window.inject(['$compile', function($compile) {
|
||||||
var node = $compile('<div multi-select-list></div>')($scope);
|
var node = $compile('<div multi-select-list></div>')($scope);
|
||||||
var classes = Array.prototype.slice.apply(node[0].classList)
|
var classes = Array.prototype.slice.apply(node.attr('class').split(' '));
|
||||||
expect(classes).to.contain('ng-scope');
|
expect(classes).to.contain('ng-scope');
|
||||||
}]);
|
}]);
|
||||||
});
|
});
|
||||||
@@ -1,4 +1,7 @@
|
|||||||
import {describeModule} from 'tests/unit/describe-module';
|
import '../support/node';
|
||||||
|
|
||||||
|
import {describeModule} from '../support/describe-module';
|
||||||
|
import mod from 'tower/shared/multi-select-list/main';
|
||||||
|
|
||||||
var mockController = {
|
var mockController = {
|
||||||
selectAll: sinon.spy(),
|
selectAll: sinon.spy(),
|
||||||
@@ -7,7 +10,7 @@ var mockController = {
|
|||||||
deselectAllExtended: sinon.spy()
|
deselectAllExtended: sinon.spy()
|
||||||
};
|
};
|
||||||
|
|
||||||
describeModule('multiSelectList')
|
describeModule(mod.name)
|
||||||
.testDirective('selectAll', function(directive) {
|
.testDirective('selectAll', function(directive) {
|
||||||
|
|
||||||
var $scope;
|
var $scope;
|
||||||
@@ -36,7 +39,7 @@ describeModule('multiSelectList')
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('works as an element tag', function() {
|
it('works as an element tag', function() {
|
||||||
var classes = Array.prototype.slice.apply(directive.$element[0].classList);
|
var classes = directive.$element.attr('class').split(' ');
|
||||||
expect(classes).to.contain('ng-scope');
|
expect(classes).to.contain('ng-scope');
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -91,4 +94,4 @@ describeModule('multiSelectList')
|
|||||||
|
|
||||||
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@@ -1,28 +0,0 @@
|
|||||||
// Phantom.js is missing the standard Function.prototype.bind
|
|
||||||
// function. See https://code.google.com/p/phantomjs/issues/detail?id=522
|
|
||||||
// for more details.
|
|
||||||
//
|
|
||||||
if (!Function.prototype.bind) {
|
|
||||||
Function.prototype.bind = function(oThis) {
|
|
||||||
if (typeof this !== 'function') {
|
|
||||||
// closest thing possible to the ECMAScript 5
|
|
||||||
// internal IsCallable function
|
|
||||||
throw new TypeError('Function.prototype.bind - what is trying to be bound is not callable');
|
|
||||||
}
|
|
||||||
|
|
||||||
var aArgs = Array.prototype.slice.call(arguments, 1),
|
|
||||||
fToBind = this,
|
|
||||||
fNOP = function() {},
|
|
||||||
fBound = function() {
|
|
||||||
return fToBind.apply(this instanceof fNOP
|
|
||||||
? this
|
|
||||||
: oThis,
|
|
||||||
aArgs.concat(Array.prototype.slice.call(arguments)));
|
|
||||||
};
|
|
||||||
|
|
||||||
fNOP.prototype = this.prototype;
|
|
||||||
fBound.prototype = new fNOP();
|
|
||||||
|
|
||||||
return fBound;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
@@ -1,4 +0,0 @@
|
|||||||
exports.config = {
|
|
||||||
seleniumAddress: 'http://localhost:4444/wd/hub',
|
|
||||||
specs: ['e2e/*.js']
|
|
||||||
}
|
|
||||||
@@ -1,5 +1,7 @@
|
|||||||
import {describeModule} from 'tests/unit/describe-module';
|
import '../support/node';
|
||||||
import JobStatusGraph from 'tower/dashboard/graphs/job-status/main'
|
|
||||||
|
import {describeModule} from '../support/describe-module';
|
||||||
|
import JobStatusGraph from 'tower/dashboard/graphs/job-status/main';
|
||||||
|
|
||||||
var processErrors = sinon.spy();
|
var processErrors = sinon.spy();
|
||||||
|
|
||||||
@@ -1,3 +1,5 @@
|
|||||||
|
import '../support/node';
|
||||||
|
|
||||||
import 'tower/shared/main';
|
import 'tower/shared/main';
|
||||||
|
|
||||||
describe('LodashAsPromised', function() {
|
describe('LodashAsPromised', function() {
|
||||||
@@ -17,7 +19,7 @@ describe('LodashAsPromised', function() {
|
|||||||
return memo + value;
|
return memo + value;
|
||||||
}
|
}
|
||||||
|
|
||||||
beforeEach(module('shared'));
|
beforeEach(window.module('shared'));
|
||||||
|
|
||||||
beforeEach(inject(['lodashAsPromised', '$q', function(_lodash, _$q) {
|
beforeEach(inject(['lodashAsPromised', '$q', function(_lodash, _$q) {
|
||||||
_ = _lodash;
|
_ = _lodash;
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
import RestStub from 'tests/unit/rest-stub';
|
import RestStub from './rest-stub';
|
||||||
|
|
||||||
var $provide;
|
var $provide;
|
||||||
|
|
||||||
@@ -7,7 +7,7 @@ function wrapInjected(dslFn) {
|
|||||||
// }));
|
// }));
|
||||||
return function(fn) {
|
return function(fn) {
|
||||||
dslFn.apply(this,
|
dslFn.apply(this,
|
||||||
[inject(
|
[window.inject(
|
||||||
[ '$injector',
|
[ '$injector',
|
||||||
function($injector) {
|
function($injector) {
|
||||||
var $compile = $injector.get('$compile');
|
var $compile = $injector.get('$compile');
|
||||||
@@ -28,18 +28,19 @@ function TestModule(name, deps) {
|
|||||||
registerPreHooks: function() {
|
registerPreHooks: function() {
|
||||||
|
|
||||||
var self = this;
|
var self = this;
|
||||||
beforeEach("tower module", module('Tower'));
|
// beforeEach("tower module", window.module('Tower'));
|
||||||
beforeEach(name + " module", module(name));
|
beforeEach(name + " module", window.module(name));
|
||||||
beforeEach("templates module", module('templates'));
|
beforeEach("templates module", window.module('templates'));
|
||||||
beforeEach("mock app setup", module(['$provide', function(_provide_) {
|
beforeEach("mock app setup", window.module(['$provide', function(_provide_) {
|
||||||
|
|
||||||
var getBasePath = function(path) {
|
var getBasePath = function(path) {
|
||||||
return '/' + path + '/';
|
return '/' + path + '/';
|
||||||
}
|
};
|
||||||
|
|
||||||
$provide = _provide_;
|
$provide = _provide_;
|
||||||
$provide.value('LoadBasePaths', angular.noop);
|
$provide.value('LoadBasePaths', angular.noop);
|
||||||
$provide.value('GetBasePath', getBasePath);
|
$provide.value('GetBasePath', getBasePath);
|
||||||
|
$provide.value('ProcessErrors', angular.noop);
|
||||||
|
|
||||||
for (var name in self.mockedProviders) {
|
for (var name in self.mockedProviders) {
|
||||||
$provide.value(name, self.mockedProviders[name]);
|
$provide.value(name, self.mockedProviders[name]);
|
||||||
@@ -47,12 +48,12 @@ function TestModule(name, deps) {
|
|||||||
|
|
||||||
}]));
|
}]));
|
||||||
|
|
||||||
wrapInjected(beforeEach)(function($httpBackend) {
|
// wrapInjected(beforeEach)(function($httpBackend) {
|
||||||
|
|
||||||
$httpBackend
|
// $httpBackend
|
||||||
.expectGET('/static/js/local_config.js')
|
// .expectGET('/static/js/local_config.js')
|
||||||
.respond({});
|
// .respond({});
|
||||||
});
|
// });
|
||||||
},
|
},
|
||||||
mockProvider: function(name, value) {
|
mockProvider: function(name, value) {
|
||||||
this.mockedProviders[name] = value;
|
this.mockedProviders[name] = value;
|
||||||
@@ -64,7 +65,7 @@ function TestModule(name, deps) {
|
|||||||
});
|
});
|
||||||
},
|
},
|
||||||
registerPostHooks: function() {
|
registerPostHooks: function() {
|
||||||
afterEach(inject(['$httpBackend', function($httpBackend) {
|
afterEach(window.inject(['$httpBackend', function($httpBackend) {
|
||||||
$httpBackend.verifyNoOutstandingExpectation();
|
$httpBackend.verifyNoOutstandingExpectation();
|
||||||
$httpBackend.verifyNoOutstandingRequest();
|
$httpBackend.verifyNoOutstandingRequest();
|
||||||
}]));
|
}]));
|
||||||
@@ -81,7 +82,7 @@ function TestService(name) {
|
|||||||
|
|
||||||
return {
|
return {
|
||||||
withService: function(fn) {
|
withService: function(fn) {
|
||||||
beforeEach(name + " service", inject([name, function() {
|
beforeEach(name + " service", window.inject([name, function() {
|
||||||
var service = arguments[0];
|
var service = arguments[0];
|
||||||
fn(service);
|
fn(service);
|
||||||
}]));
|
}]));
|
||||||
@@ -104,7 +105,7 @@ function TestDirective(name, deps) {
|
|||||||
// by the test
|
// by the test
|
||||||
withScope: function(fn) {
|
withScope: function(fn) {
|
||||||
var self = this;
|
var self = this;
|
||||||
beforeEach("capture outer $scope", inject(['$rootScope', function($rootScope) {
|
beforeEach("capture outer $scope", window.inject(['$rootScope', function($rootScope) {
|
||||||
var $scope = self.$scope = self.$scope || $rootScope.$new();
|
var $scope = self.$scope = self.$scope || $rootScope.$new();
|
||||||
// `this` refers to mocha test suite
|
// `this` refers to mocha test suite
|
||||||
fn.apply(this, [$scope]);
|
fn.apply(this, [$scope]);
|
||||||
@@ -112,7 +113,7 @@ function TestDirective(name, deps) {
|
|||||||
},
|
},
|
||||||
withIsolateScope: function(fn) {
|
withIsolateScope: function(fn) {
|
||||||
var self = this;
|
var self = this;
|
||||||
beforeEach("capture isolate scope", inject(['$rootScope', function($rootScope) {
|
beforeEach("capture isolate scope", window.inject(['$rootScope', function($rootScope) {
|
||||||
// `this` refers to mocha test suite
|
// `this` refers to mocha test suite
|
||||||
fn.apply(this, [self.$element.isolateScope()]);
|
fn.apply(this, [self.$element.isolateScope()]);
|
||||||
}]));
|
}]));
|
||||||
@@ -165,7 +166,7 @@ function TestDirective(name, deps) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
beforeEach("compile directive element",
|
beforeEach("compile directive element",
|
||||||
inject(['$compile', '$httpBackend', '$rootScope', function($compile, $httpBackend, $rootScope) {
|
window.inject(['$compile', '$httpBackend', '$rootScope', function($compile, $httpBackend, $rootScope) {
|
||||||
|
|
||||||
if (!self.$scope) {
|
if (!self.$scope) {
|
||||||
self.$scope = $rootScope.$new();
|
self.$scope = $rootScope.$new();
|
||||||
@@ -176,13 +177,14 @@ function TestDirective(name, deps) {
|
|||||||
|
|
||||||
self.$scope.$digest();
|
self.$scope.$digest();
|
||||||
|
|
||||||
$httpBackend.flush();
|
// $httpBackend.flush();
|
||||||
|
|
||||||
}]));
|
}]));
|
||||||
|
|
||||||
afterEach("cleanup directive element", function() {
|
afterEach("cleanup directive element", function() {
|
||||||
self.$element.trigger('$destroy');
|
$(self.$element).trigger('$destroy');
|
||||||
self.$element.remove();
|
self.$element.remove();
|
||||||
|
delete self.$scope;
|
||||||
});
|
});
|
||||||
|
|
||||||
this._compileRegistered = true;
|
this._compileRegistered = true;
|
||||||
@@ -200,7 +202,7 @@ function TestDirective(name, deps) {
|
|||||||
},
|
},
|
||||||
provideTemplate: function(url, template) {
|
provideTemplate: function(url, template) {
|
||||||
var $scope = this.$scope;
|
var $scope = this.$scope;
|
||||||
beforeEach("mock template endpoint", inject(['$httpBackend', function($httpBackend) {
|
beforeEach("mock template endpoint", window.inject(['$httpBackend', function($httpBackend) {
|
||||||
$httpBackend
|
$httpBackend
|
||||||
.whenGET(url)
|
.whenGET(url)
|
||||||
.respond(template);
|
.respond(template);
|
||||||
@@ -233,7 +235,7 @@ function ModuleDescriptor(name, deps) {
|
|||||||
testModule.mockProvider('$cookieStore', { get: angular.noop });
|
testModule.mockProvider('$cookieStore', { get: angular.noop });
|
||||||
testModule.registerPreHooks();
|
testModule.registerPreHooks();
|
||||||
|
|
||||||
beforeEach("$q", inject(['$q', function($q) {
|
beforeEach("$q", window.inject(['$q', function($q) {
|
||||||
testService.restStub.$q = $q;
|
testService.restStub.$q = $q;
|
||||||
}]));
|
}]));
|
||||||
|
|
||||||
4
awx/ui/tests/support/node/export-global.js
Normal file
4
awx/ui/tests/support/node/export-global.js
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
module.exports =
|
||||||
|
function exportGlobal(varName, value) {
|
||||||
|
global[varName] = global.window[varName] = value;
|
||||||
|
};
|
||||||
26
awx/ui/tests/support/node/index.js
Normal file
26
awx/ui/tests/support/node/index.js
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
/* jshint node: true */
|
||||||
|
|
||||||
|
(function() {
|
||||||
|
var isNode = typeof window === 'undefined';
|
||||||
|
|
||||||
|
if (!isNode) {
|
||||||
|
window.expect = chai.expect;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
require('./setup/jsdom');
|
||||||
|
require('./setup/mocha');
|
||||||
|
require('./setup/jquery');
|
||||||
|
require('./setup/angular');
|
||||||
|
require('./setup/angular-mocks');
|
||||||
|
require('./setup/angular-templates');
|
||||||
|
require('./setup/sinon');
|
||||||
|
require('./setup/chai');
|
||||||
|
require('./setup/chai-plugins');
|
||||||
|
require('./setup/d3');
|
||||||
|
require('./setup/nv');
|
||||||
|
require('./setup/lodash');
|
||||||
|
require('./setup/local-storage');
|
||||||
|
require('./setup/moment');
|
||||||
|
|
||||||
|
})();
|
||||||
5
awx/ui/tests/support/node/setup/angular-mocks.js
vendored
Normal file
5
awx/ui/tests/support/node/setup/angular-mocks.js
vendored
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
var exportGlobal = require('../export-global');
|
||||||
|
require('angular-mocks/angular-mocks');
|
||||||
|
|
||||||
|
exportGlobal('inject', window.inject);
|
||||||
|
|
||||||
2
awx/ui/tests/support/node/setup/angular-templates.js
vendored
Normal file
2
awx/ui/tests/support/node/setup/angular-templates.js
vendored
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
angular.module('templates', []);
|
||||||
|
require('../../../../templates');
|
||||||
5
awx/ui/tests/support/node/setup/angular.js
vendored
Normal file
5
awx/ui/tests/support/node/setup/angular.js
vendored
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
var exportGlobal = require('../export-global');
|
||||||
|
require('angular/angular');
|
||||||
|
|
||||||
|
exportGlobal('angular', window.angular);
|
||||||
|
|
||||||
8
awx/ui/tests/support/node/setup/chai-plugins.js
Normal file
8
awx/ui/tests/support/node/setup/chai-plugins.js
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
var sinonChai = require('sinon-chai');
|
||||||
|
var chaiAsPromised = require('chai-as-promised');
|
||||||
|
var chaiThings = require('chai-things');
|
||||||
|
|
||||||
|
chai.use(sinonChai);
|
||||||
|
chai.use(chaiAsPromised);
|
||||||
|
chai.use(chaiThings);
|
||||||
|
|
||||||
5
awx/ui/tests/support/node/setup/chai.js
Normal file
5
awx/ui/tests/support/node/setup/chai.js
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
var exportGlobal = require('../export-global');
|
||||||
|
var chai = require('chai');
|
||||||
|
|
||||||
|
exportGlobal('chai', chai);
|
||||||
|
exportGlobal('expect', chai.expect);
|
||||||
6
awx/ui/tests/support/node/setup/d3.js
vendored
Normal file
6
awx/ui/tests/support/node/setup/d3.js
vendored
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
var exportGlobal = require('../export-global');
|
||||||
|
var d3 = require('d3');
|
||||||
|
|
||||||
|
exportGlobal('d3', d3);
|
||||||
|
|
||||||
|
|
||||||
7
awx/ui/tests/support/node/setup/jquery.js
vendored
Normal file
7
awx/ui/tests/support/node/setup/jquery.js
vendored
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
var exportGlobal = require('../export-global');
|
||||||
|
var jquery = require('jquery');
|
||||||
|
|
||||||
|
exportGlobal('$', jquery);
|
||||||
|
exportGlobal('jQuery', jquery);
|
||||||
|
|
||||||
|
|
||||||
6
awx/ui/tests/support/node/setup/jsdom.js
Normal file
6
awx/ui/tests/support/node/setup/jsdom.js
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
var jsdom = require('jsdom').jsdom;
|
||||||
|
var document = jsdom('tower');
|
||||||
|
var window = document.parentWindow;
|
||||||
|
|
||||||
|
global.document = document;
|
||||||
|
global.window = window;
|
||||||
7
awx/ui/tests/support/node/setup/local-storage.js
Normal file
7
awx/ui/tests/support/node/setup/local-storage.js
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
var exportGlobal = require('../export-global');
|
||||||
|
var LocalStorage = require('node-localstorage').LocalStorage;
|
||||||
|
|
||||||
|
exportGlobal('localStorage',
|
||||||
|
new LocalStorage('./scratch'));
|
||||||
|
|
||||||
|
|
||||||
4
awx/ui/tests/support/node/setup/lodash.js
Normal file
4
awx/ui/tests/support/node/setup/lodash.js
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
var exportGlobal = require('../export-global');
|
||||||
|
var lodash = require('lodash');
|
||||||
|
|
||||||
|
exportGlobal('_', lodash);
|
||||||
7
awx/ui/tests/support/node/setup/mocha.js
Normal file
7
awx/ui/tests/support/node/setup/mocha.js
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
var exportGlobal = require('../export-global');
|
||||||
|
var mocha = require('mocha');
|
||||||
|
|
||||||
|
exportGlobal('mocha', mocha);
|
||||||
|
exportGlobal('beforeEach', beforeEach);
|
||||||
|
exportGlobal('afterEach', afterEach);
|
||||||
|
|
||||||
5
awx/ui/tests/support/node/setup/moment.js
Normal file
5
awx/ui/tests/support/node/setup/moment.js
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
var exportGlobal = require('../export-global');
|
||||||
|
var moment = require('moment');
|
||||||
|
|
||||||
|
exportGlobal('moment', moment);
|
||||||
|
|
||||||
6
awx/ui/tests/support/node/setup/nv.js
Normal file
6
awx/ui/tests/support/node/setup/nv.js
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
var exportGlobal = require('../export-global');
|
||||||
|
var nv = require('nvd3');
|
||||||
|
|
||||||
|
exportGlobal('nv', nv);
|
||||||
|
|
||||||
|
|
||||||
4
awx/ui/tests/support/node/setup/sinon.js
Normal file
4
awx/ui/tests/support/node/setup/sinon.js
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
var exportGlobal = require('../export-global');
|
||||||
|
var sinon = require('sinon');
|
||||||
|
|
||||||
|
exportGlobal('sinon', sinon);
|
||||||
@@ -63,7 +63,7 @@ RestStub.prototype =
|
|||||||
inject(['$rootScope', function($rootScope) {
|
inject(['$rootScope', function($rootScope) {
|
||||||
$rootScope.$apply();
|
$rootScope.$apply();
|
||||||
}]);
|
}]);
|
||||||
}, 1000);
|
}, 10);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -1,33 +1,32 @@
|
|||||||
import compareFacts from 'tower/system-tracking/compare-facts/flat';
|
|
||||||
|
|
||||||
/* jshint node: true */
|
/* jshint node: true */
|
||||||
/* globals -expect, -_ */
|
|
||||||
|
|
||||||
var _, expect;
|
import '../../support/node';
|
||||||
|
|
||||||
|
import compareFacts from 'tower/system-tracking/compare-facts/flat';
|
||||||
|
|
||||||
// This makes this test runnable in node OR karma. The sheer
|
// This makes this test runnable in node OR karma. The sheer
|
||||||
// number of times I had to run this test made the karma
|
// number of times I had to run this test made the karma
|
||||||
// workflow just too dang slow for me. Maybe this can
|
// workflow just too dang slow for me. Maybe this can
|
||||||
// be a pattern going forward? Not sure...
|
// be a pattern going forward? Not sure...
|
||||||
//
|
//
|
||||||
(function(global) {
|
// (function(global) {
|
||||||
var chai = global.chai || require('chai');
|
// var chai = global.chai || require('chai');
|
||||||
|
|
||||||
if (typeof window === 'undefined') {
|
// if (typeof window === 'undefined') {
|
||||||
var chaiThings = global.chaiThings || require('chai-things');
|
// var chaiThings = global.chaiThings || require('chai-things');
|
||||||
chai.use(chaiThings);
|
// chai.use(chaiThings);
|
||||||
}
|
// }
|
||||||
|
|
||||||
_ = global._ || require('lodash');
|
// _ = global._ || require('lodash');
|
||||||
expect = global.expect || chai.expect;
|
// expect = global.expect || chai.expect;
|
||||||
|
|
||||||
global.expect = expect;
|
// global.expect = expect;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
global._ = _;
|
// global._ = _;
|
||||||
|
|
||||||
})(typeof window === 'undefined' ? global : window);
|
// })(typeof window === 'undefined' ? global : window);
|
||||||
|
|
||||||
describe('CompareFacts.Flat', function() {
|
describe('CompareFacts.Flat', function() {
|
||||||
|
|
||||||
@@ -1,34 +1,8 @@
|
|||||||
import compareFacts from 'tower/system-tracking/compare-facts/nested';
|
|
||||||
|
|
||||||
/* jshint node: true */
|
/* jshint node: true */
|
||||||
/* globals -expect, -_ */
|
|
||||||
|
|
||||||
var _, expect;
|
import '../../support/node';
|
||||||
|
|
||||||
// This makes this test runnable in node OR karma. The sheer
|
|
||||||
// number of times I had to run this test made the karma
|
|
||||||
// workflow just too dang slow for me. Maybe this can
|
|
||||||
// be a pattern going forward? Not sure...
|
|
||||||
//
|
|
||||||
(function(global) {
|
|
||||||
var chai = global.chai || require('chai');
|
|
||||||
|
|
||||||
if (typeof window === 'undefined') {
|
|
||||||
var chaiThings = global.chaiThings || require('chai-things');
|
|
||||||
chai.use(chaiThings);
|
|
||||||
}
|
|
||||||
|
|
||||||
_ = global._ || require('lodash');
|
|
||||||
expect = global.expect || chai.expect;
|
|
||||||
|
|
||||||
global.expect = expect;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
global._ = _;
|
|
||||||
|
|
||||||
})(typeof window === 'undefined' ? global : window);
|
|
||||||
|
|
||||||
|
import compareFacts from 'tower/system-tracking/compare-facts/nested';
|
||||||
|
|
||||||
describe('CompareFacts.Nested', function() {
|
describe('CompareFacts.Nested', function() {
|
||||||
|
|
||||||
@@ -1,5 +1,7 @@
|
|||||||
import systemTracking from 'tower/system-tracking/main';
|
import '../support/node';
|
||||||
import {describeModule} from '../describe-module';
|
|
||||||
|
import systemTracking from 'tower/system-tracking/data-services/main';
|
||||||
|
import {describeModule} from '../support/describe-module';
|
||||||
import moment from 'tower/shared/moment/moment';
|
import moment from 'tower/shared/moment/moment';
|
||||||
|
|
||||||
describeModule(systemTracking.name)
|
describeModule(systemTracking.name)
|
||||||
30
testem.yml
Normal file
30
testem.yml
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
---
|
||||||
|
framework: mocha
|
||||||
|
cwd: awx/ui/
|
||||||
|
port: 7358
|
||||||
|
src_files:
|
||||||
|
- static/js/**/*.js
|
||||||
|
- static/lib/**/*.js
|
||||||
|
- tests/**/*.js
|
||||||
|
serve_files:
|
||||||
|
- dist/tower.concat.js
|
||||||
|
- dist/tests/**/*.js
|
||||||
|
- dist/tests/unit.js
|
||||||
|
unsafe_file_serving: true
|
||||||
|
test_page: tests.html
|
||||||
|
disable_watching: true
|
||||||
|
routes:
|
||||||
|
/awx/ui/dist: /static
|
||||||
|
/tests.html: ../../packaging/grunt/testem.mustache
|
||||||
|
/test-loader.js: static/lib/ember-cli-test-loader/test-loader.js
|
||||||
|
/vendor: ../../node_modules
|
||||||
|
/angular-mocks.js: dist/lib/angular-mocks/angular-mocks.js
|
||||||
|
/templates.js: dist/node-tests/templates.js
|
||||||
|
reporter: xunit
|
||||||
|
launch_in_dev:
|
||||||
|
- Mocha
|
||||||
|
launch_in_ci:
|
||||||
|
- PhantomJS
|
||||||
|
launchers:
|
||||||
|
Mocha:
|
||||||
|
command: npm test
|
||||||
Reference in New Issue
Block a user