diff --git a/awx/ui/static/js/controllers/Users.js b/awx/ui/static/js/controllers/Users.js
index 8fc6934992..bea627584e 100644
--- a/awx/ui/static/js/controllers/Users.js
+++ b/awx/ui/static/js/controllers/Users.js
@@ -481,4 +481,4 @@ export function UsersEdit($scope, $rootScope, $compile, $location, $log, $routeP
UsersEdit.$inject = ['$scope', '$rootScope', '$compile', '$location', '$log', '$routeParams', 'UserForm', 'GenerateForm',
'Rest', 'Alert', 'ProcessErrors', 'LoadBreadCrumbs', 'RelatedSearchInit', 'RelatedPaginateInit', 'ReturnToCaller', 'ClearScope',
'GetBasePath', 'Prompt', 'CheckAccess', 'ResetForm', 'Wait', 'Stream'
-];
\ No newline at end of file
+];
diff --git a/awx/ui/tests/karma.conf.js b/awx/ui/tests/karma.conf.js
index 2021c8170e..62321c9ba0 100644
--- a/awx/ui/tests/karma.conf.js
+++ b/awx/ui/tests/karma.conf.js
@@ -1,24 +1,48 @@
// 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'],
+
+ frameworks:
+ [ 'mocha',
+ 'chai',
+ 'sinon-chai',
+ 'chai-as-promised'
+ ],
+
+ 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'
+ '../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: [
diff --git a/awx/ui/tests/phantomjs-polyfill.js b/awx/ui/tests/phantomjs-polyfill.js
new file mode 100644
index 0000000000..46c4204283
--- /dev/null
+++ b/awx/ui/tests/phantomjs-polyfill.js
@@ -0,0 +1,28 @@
+// 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;
+ };
+}
diff --git a/awx/ui/tests/unit/describe-module.js b/awx/ui/tests/unit/describe-module.js
new file mode 100644
index 0000000000..47b7845a74
--- /dev/null
+++ b/awx/ui/tests/unit/describe-module.js
@@ -0,0 +1,274 @@
+import RestStub from 'tests/unit/rest-stub';
+
+var $provide;
+
+function wrapInjected(dslFn) {
+ // wrapInjected(before(inject(..., function() {
+ // }));
+ return function(fn) {
+ dslFn.apply(this,
+ [inject(
+ [ '$injector',
+ function($injector) {
+ var $compile = $injector.get('$compile');
+ var $httpBackend = $injector.get('$httpBackend');
+ var $rootScope = $injector.get('$rootScope');
+
+ return fn.apply(this, [$httpBackend, $compile, $rootScope]);
+ }.bind(this)
+ ])]);
+ };
+};
+
+function TestModule(name, deps) {
+
+ window.localStorage.setItem('zones', []);
+ return {
+ mockedProviders: {},
+ registerPreHooks: function() {
+
+ var self = this;
+ beforeEach("tower module", module('Tower'));
+ beforeEach(name + " module", module(name));
+ beforeEach("templates module", module('templates'));
+ beforeEach("mock app setup", module(['$provide', function(_provide_) {
+
+ var getBasePath = function(path) {
+ return '/' + path + '/';
+ }
+
+ $provide = _provide_;
+ $provide.value('LoadBasePaths', angular.noop);
+ $provide.value('GetBasePath', getBasePath);
+
+ for (var name in self.mockedProviders) {
+ $provide.value(name, self.mockedProviders[name]);
+ }
+
+ }]));
+
+ wrapInjected(beforeEach)(function($httpBackend) {
+
+ $httpBackend
+ .expectGET('/static/js/local_config.js')
+ .respond({});
+ });
+ },
+ mockProvider: function(name, value) {
+ this.mockedProviders[name] = value;
+ },
+ describe: function(name, describeFn) {
+
+ describe(name, function() {
+ describeFn.apply(this);
+ });
+ },
+ registerPostHooks: function() {
+ afterEach(inject(['$httpBackend', function($httpBackend) {
+ $httpBackend.verifyNoOutstandingExpectation();
+ $httpBackend.verifyNoOutstandingRequest();
+ }]));
+ }
+ };
+};
+
+function TestService(name) {
+ var restStub = new RestStub();
+
+ afterEach(function() {
+ restStub.reset();
+ });
+
+ return {
+ withService: function(fn) {
+ beforeEach(name + " service", inject([name, function() {
+ var service = arguments[0];
+ fn(service);
+ }]));
+ },
+ restStub: restStub,
+ };
+};
+
+// Note: if you need a compile step for your directive you
+// must either:
+//
+// 1. Use a before/after compile hook, which also allows
+// you to modify the scope before compiling
+// 2. If you don't use a hook, call `registerCompile`
+// prior to the first `it` in your tests
+function TestDirective(name, deps) {
+
+ return { name: name,
+ // Hooks that need to run after any hooks registered
+ // by the test
+ withScope: function(fn) {
+ var self = this;
+ beforeEach("capture outer $scope", inject(['$rootScope', function($rootScope) {
+ var $scope = self.$scope = self.$scope || $rootScope.$new();
+ // `this` refers to mocha test suite
+ fn.apply(this, [$scope]);
+ }]));
+ },
+ withIsolateScope: function(fn) {
+ var self = this;
+ beforeEach("capture isolate scope", inject(['$rootScope', function($rootScope) {
+ // `this` refers to mocha test suite
+ fn.apply(this, [self.$element.isolateScope()]);
+ }]));
+ },
+ beforeCompile: function(fn) {
+
+ var self = this;
+
+ // Run before compile step by passing in the
+ // outer scope, allowing for modifications
+ // prior to compiling
+ self.withScope(fn);
+
+ this.registerCompile();
+ },
+ afterCompile: function(fn) {
+
+ var self = this;
+
+ // Make sure compile step gets setup first
+ if (!this._compileRegistered) {
+ this.registerCompile();
+ }
+
+ // Then pre-apply the function with the outer scope
+ self.withScope(function($scope) {
+ // `this` refers to mocha test suite
+ fn = fn.bind(this, $scope);
+ });
+
+ // Finally, have it called by the isolate scope
+ // hook, which will pass in both the outer
+ // scope (since it was pre-applied) and the
+ // isolate scope (if one exists)
+ //
+ self.withIsolateScope(function($scope) {
+ // `this` refers to mocha test suite
+ fn.apply(this, [$scope]);
+ });
+
+ },
+ registerCompile: function(deps) {
+
+ var self = this;
+
+ // Only setup compile step once
+ if (this._compileRegistered) {
+ return;
+ }
+
+ beforeEach("compile directive element",
+ inject(['$compile', '$httpBackend', function($compile, $httpBackend) {
+
+ self.$element = $compile(self.element)(self.$scope);
+ $(self.$element).appendTo('body');
+
+ self.$scope.$digest();
+
+ $httpBackend.flush();
+
+ }]));
+
+ afterEach("cleanup directive element", function() {
+ self.$element.trigger('$destroy');
+ self.$element.remove();
+ });
+
+ this._compileRegistered = true;
+
+ },
+ withController: function(fn) {
+ var self = this;
+ beforeEach(function() {
+ self._ensureCompiled();
+ fn(self.$element.controller(self.name));
+ });
+ },
+ use: function(elem) {
+ this.element = angular.element(elem);
+ },
+ provideTemplate: function(url, template) {
+ var $scope = this.$scope;
+ beforeEach("mock template endpoint", inject(['$httpBackend', function($httpBackend) {
+ $httpBackend
+ .whenGET(url)
+ .respond(template);
+ }]));
+ }
+ };
+}
+
+function ModuleDescriptor(name, deps) {
+
+ var moduleTests = [];
+ var testModule =
+ Object.create(TestModule(name, deps));
+
+ var proto =
+ { mockProvider: function(name, value) {
+ testModule.mockProvider(name, value);
+ return this;
+ },
+ testService: function(name, test) {
+ testModule.describe(name, function() {
+ var testService = Object.create(TestService(name));
+
+ testModule.mockProvider('Rest', testService.restStub);
+ testModule.mockProvider('$cookieStore', { get: angular.noop });
+ testModule.registerPreHooks();
+
+ beforeEach("$q", inject(['$q', function($q) {
+ testService.restStub.$q = $q;
+ }]));
+
+ test.apply(null, [testService, testService.restStub]);
+ });
+ },
+ testDirective: function(name, test) {
+
+ testModule.describe(name, function(deps) {
+ var directiveDeps = _.clone(deps);
+
+ var testDirective =
+ Object.create(TestDirective(name));
+
+ // Hand in testDirective object & injected
+ // dependencies to the test as separate arguments
+ //
+ var args = [testDirective].concat(_.values(directiveDeps));
+ var testObj =
+ // Using Function#bind to create a new function
+ // with the arguments pre-applied (go search
+ // the web for "partial application" to know more)
+ //
+ { run: test.bind(null, testDirective, args),
+ name: name
+ };
+
+ testModule.registerPreHooks();
+
+ // testDirective.registerCompile();
+
+ testObj.run();
+
+ // testDirective.registerPostHooks();
+ });
+ }
+ };
+
+ return proto;
+}
+
+export function describeModule(name) {
+ var descriptor = null
+ descriptor = Object.create(ModuleDescriptor(name));
+
+
+ return descriptor;
+};
diff --git a/awx/ui/tests/unit/directives/job-status-graph-test.js b/awx/ui/tests/unit/directives/job-status-graph-test.js
index 573613e1c3..5f53d3681a 100644
--- a/awx/ui/tests/unit/directives/job-status-graph-test.js
+++ b/awx/ui/tests/unit/directives/job-status-graph-test.js
@@ -1,90 +1,73 @@
import Tower from 'tower/app';
+import {describeModule} from 'tests/unit/describe-module';
-describe('Job Status Graph Directive', function() {
- var element, scope, httpBackend;
+var resizeHandler = sinon.spy();
- var resizeHandler = sinon.spy();
+describeModule('DashboardGraphs')
+ .mockProvider('adjustGraphSize', resizeHandler)
+ .testDirective('jobStatusGraph', function(directive) {
- beforeEach(module('Tower'));
- beforeEach(module(['$provide', function($provide) {
- $provide.value('LoadBasePaths', angular.noop);
- $provide.value('adjustGraphSize', resizeHandler);
- }]));
+ directive.provideTemplate(
+ '/static/partials/job_status_graph.html',
+ "
");
+
+ directive.use('');
+
+ directive.beforeCompile(function($scope) {
+
+ // Takes jobs grouped by result (successful or failure
+ // Then looks at each array of arrays, where index 0 is the timestamp & index 1 is the count of jobs with that status
+ $scope.data =
+ { jobs:
+ { successful: [[1, 0], [2, 0], [3,0], [4,0], [5,0]],
+ failed: [[1,0],[2,0],[3,0],[4,0],[5,0]]
+ }
+ };
+
+ });
+
+ function filterDataSeries(key, data) {
+ return data.map(function(datum) {
+ return datum.values;
+ })[key];
+ }
+
+ it('uses successes & failures from scope', function() {
+ var chartContainer = d3.select(directive.$element.find('svg')[0]);
+ var lineData = chartContainer.datum();
+
+ var successfulSeries = filterDataSeries(0, lineData);
+ var failedSeries = filterDataSeries(1, lineData);
+
+ expect(successfulSeries).to.eql(
+ [ {x: 1, y: 0, series: 0},
+ {x: 2, y: 0, series: 0},
+ {x: 3, y: 0, series: 0},
+ {x: 4, y: 0, series: 0},
+ {x: 5, y: 0, series: 0}
+ ]);
+
+ expect(failedSeries).to.eql(
+ [ {x: 1, y: 0, series: 1},
+ {x: 2, y: 0, series: 1},
+ {x: 3, y: 0, series: 1},
+ {x: 4, y: 0, series: 1},
+ {x: 5, y: 0, series: 1}
+ ]);
+
+ });
+
+ it('cleans up external bindings', function() {
+ directive.$element.trigger('$destroy');
+
+ resizeHandler.reset();
+
+ inject(['$window', function($window) {
+ angular.element($window).trigger('resize');
+ }]);
+
+ expect(resizeHandler).not.to.have.been.called;
+ });
- beforeEach(inject(['$rootScope', '$compile', '$httpBackend', function($rootScope, $compile, $httpBackend) {
- httpBackend = $httpBackend;
- $httpBackend.expectGET('/static/js/local_config.js').respond({
});
-
- $httpBackend.whenGET('/static/partials/job_status_graph.html')
- .respond("");
-
- scope = $rootScope.$new();
-
- element = '';
-
- // Takes jobs grouped by result (successful or failure
- // Then looks at each array of arrays, where index 0 is the timestamp & index 1 is the count of jobs with that status
- scope.data =
- { jobs:
- { successful: [[1, 0], [2, 0], [3,0], [4,0], [5,0]],
- failed: [[1,0],[2,0],[3,0],[4,0],[5,0]]
- }
- };
-
- element = $compile(element)(scope);
- scope.$digest();
-
- $httpBackend.flush();
-
- }]));
-
- afterEach(function() {
- element.trigger('$destroy');
- httpBackend.verifyNoOutstandingExpectation();
- httpBackend.verifyNoOutstandingRequest();
- });
-
- function filterDataSeries(key, data) {
- return data.map(function(datum) {
- return datum.values;
- })[key];
- }
-
- it('uses successes & failures from scope', function() {
- var chartContainer = d3.select(element.find('svg')[0]);
- var lineData = chartContainer.datum();
-
- var successfulSeries = filterDataSeries(0, lineData);
- var failedSeries = filterDataSeries(1, lineData);
-
- expect(successfulSeries).to.eql(
- [ {x: 1, y: 0, series: 0},
- {x: 2, y: 0, series: 0},
- {x: 3, y: 0, series: 0},
- {x: 4, y: 0, series: 0},
- {x: 5, y: 0, series: 0}]);
-
- expect(failedSeries).to.eql(
- [ {x: 1, y: 0, series: 1},
- {x: 2, y: 0, series: 1},
- {x: 3, y: 0, series: 1},
- {x: 4, y: 0, series: 1},
- {x: 5, y: 0, series: 1}]);
- });
-
- it('cleans up external bindings', function() {
- element.trigger('$destroy');
-
- resizeHandler.reset();
-
- inject(['$window', function($window) {
- angular.element($window).trigger('resize');
- }]);
-
- expect(resizeHandler).not.to.have.been.called;
- });
-
-});
-
diff --git a/awx/ui/tests/unit/rest-stub.js b/awx/ui/tests/unit/rest-stub.js
new file mode 100644
index 0000000000..be91f1afe7
--- /dev/null
+++ b/awx/ui/tests/unit/rest-stub.js
@@ -0,0 +1,62 @@
+function assertUrlDeferred(url, obj) {
+ if (angular.isUndefined(obj[url]) ||
+ angular.isUndefined(obj[url].then) &&
+ angular.isUndefined(obj[url].promise.then)) {
+ var urls = [];
+
+ for (key in obj) {
+ if (/\//.test(key)) {
+ urls.push(key);
+ }
+ }
+
+ var registered = urls.map(function(url) {
+ return "\t\"" + url + "\"";
+ }).join("\n");
+
+ throw "Could not find a thenable registered for url \"" + url + "\". Registered URLs include:\n\n" + registered + "\n\nPerhaps you typo'd the URL?\n"
+ }
+}
+
+function RestStub() {
+}
+
+RestStub.prototype =
+ { setUrl: function(url) {
+ this[url] = this.$q.defer();
+ this.currentUrl = url;
+ },
+ reset: function() {
+ delete this.deferred;
+ },
+ get: function() {
+ // allow a single deferred on this in case we don't need URL
+ this.deferred = this[this.currentUrl];
+
+ return this.deferred.promise;
+ },
+ succeedAt: function(url, value) {
+ assertUrlDeferred(url, this);
+ this[url].resolve(value);
+ },
+ succeed: function(value) {
+ this.deferred.resolve(value);
+ },
+ failAt: function(url, value) {
+ assertUrlDeferred(url, this);
+ this[url].reject(value);
+ },
+ fail: function(value) {
+ this.deferred.reject(value);
+ },
+ flush: function() {
+ window.setTimeout(function() {
+ inject(['$rootScope', function($rootScope) {
+ $rootScope.$apply();
+ }], 1000);
+ });
+ }
+ };
+
+
+export default RestStub;
diff --git a/awx/ui/tests/unit/services/host-count-graph-data-test.js b/awx/ui/tests/unit/services/host-count-graph-data-test.js
index 16cfa525ed..7769bf7a3f 100644
--- a/awx/ui/tests/unit/services/host-count-graph-data-test.js
+++ b/awx/ui/tests/unit/services/host-count-graph-data-test.js
@@ -1,132 +1,56 @@
-describe('Host Count Graph Data Service', function() {
+import {describeModule} from 'tests/unit/describe-module';
- var q;
+var processErrors = sinon.spy();
- var hostCountGraphData, httpBackend, rootScope, timeout;
+describeModule('DashboardGraphs')
+ .mockProvider('ProcessErrors', processErrors)
+ .testService('hostCountGraphData', function(test, restStub) {
- var processErrors = sinon.spy();
+ var q;
+ var service;
- var getBasePath = function(path) {
- return '/' + path + '/';
- }
+ beforeEach(inject(['$q', function($q) {
+ q = $q;
+ }]));
- function flushPromises() {
- window.setTimeout(function() {
- inject(['$rootScope', function($rootScope) {
- $rootScope.$apply();
- }], 1000);
+
+ test.withService(function(_service_) {
+ service = _service_;
});
- }
- function assertUrlDeferred(url, obj) {
- if (angular.isUndefined(obj[url]) ||
- angular.isUndefined(obj[url].then) &&
- angular.isUndefined(obj[url].promise.then)) {
- var urls = [];
+ it('returns a promise to be fulfilled when data comes in', function() {
+ var license = "license";
+ var hostData = "hosts";
- for (key in obj) {
- if (/\//.test(key)) {
- urls.push(key);
+ var result = service.get();
+
+ restStub.succeedAt('/config/', { data: {
+ license_info: {
+ instance_count: license
+ }
}
- }
+ });
- var registered = urls.map(function(url) {
- return "\t\"" + url + "\"";
- }).join("\n");
+ restStub.succeedAt('/dashboard/graphs/inventory/', { data: hostData });
- throw "Could not find a thenable registered for url \"" + url + "\". Registered URLs include:\n\n" + registered + "\n\nPerhaps you typo'd the URL?\n"
- }
- }
+ restStub.flush();
- var restStub = {
- setUrl: function(url) {
- restStub[url] = q.defer();
- restStub.currentUrl = url;
- },
- reset: function() {
- delete restStub.deferred;
- },
- get: function() {
- // allow a single deferred on restStub in case we don't need URL
- restStub.deferred = restStub[restStub.currentUrl];
-
- return restStub.deferred.promise;
- },
- succeedAt: function(url, value) {
- assertUrlDeferred(url, restStub);
- restStub[url].resolve(value);
- },
- succeed: function(value) {
- restStub.deferred.resolve(value);
- },
- failAt: function(url, value) {
- assertUrlDeferred(url, restStub);
- restStub[url].reject(value);
- },
- fail: function(value) {
- restStub.deferred.reject(value);
- }
- };
-
- beforeEach(module("Tower"));
-
- beforeEach(module(['$provide', function($provide) {
-
- $provide.value("$cookieStore", { get: angular.noop });
-
- $provide.value('ProcessErrors', processErrors);
- $provide.value('Rest', restStub);
- $provide.value('GetBasePath', getBasePath);
- }]));
-
- afterEach(function() {
- restStub.reset();
- });
-
- beforeEach(inject(['hostCountGraphData', '$httpBackend', '$q', '$rootScope', '$timeout', function(_hostCountGraphData_, $httpBackend, $q, $rootScope, $timeout) {
- hostCountGraphData = _hostCountGraphData_;
- httpBackend = $httpBackend;
- rootScope = $rootScope;
- timeout = $timeout;
- $httpBackend.expectGET('/static/js/local_config.js').respond({
- });
- q = $q;
- }]));
-
- it('returns a promise to be fulfilled when data comes in', function() {
- var license = "license";
- var hostData = "hosts";
-
- var result = hostCountGraphData.get();
-
- restStub.succeedAt('/config/', { data: {
- license_info: {
- instance_count: license
- }
- }
+ return expect(result).to.eventually.eql({ license: license, hosts: hostData });;
});
- restStub.succeedAt('/dashboard/graphs/inventory/', { data: hostData });
+ it('processes errors through error handler', function() {
+ var expected = { data: "blah", status: "bad" };
+ var actual = service.get();
- flushPromises();
+ restStub.failAt('/config/', expected);
- return expect(result).to.eventually.eql({ license: license, hosts: hostData });;
- });
+ restStub.flush();
- it('processes errors through error handler', function() {
- var expected = { data: "blah", status: "bad" };
- var actual = hostCountGraphData.get();
+ return actual.catch(function() {
+ expect(processErrors).to
+ .have.been.calledWith(null, expected.data, expected.status);
+ });
- restStub.failAt('/config/', expected);
-
- flushPromises();
-
- return actual.catch(function() {
- expect(processErrors).to
- .have.been.calledWith(null, expected.data, expected.status);
+ });
});
- });
-
-});
-
diff --git a/awx/ui/tests/unit/services/job-status-graph-data-test.js b/awx/ui/tests/unit/services/job-status-graph-data-test.js
index dd10540aa0..9ec9e3f9be 100644
--- a/awx/ui/tests/unit/services/job-status-graph-data-test.js
+++ b/awx/ui/tests/unit/services/job-status-graph-data-test.js
@@ -1,124 +1,76 @@
-describe('Job Status Graph Data Service', function() {
+import {describeModule} from 'tests/unit/describe-module';
- var q;
+var processErrors = sinon.spy();
- var jobStatusGraphData, httpBackend, rootScope, timeout;
+describeModule('DashboardGraphs')
+ .mockProvider('ProcessErrors', processErrors)
+ .testService('jobStatusGraphData', function(test, restStub) {
+ var q;
+ var service;
- var jobStatusChange = {
- $on: sinon.spy(),
- };
+ var jobStatusChange = {
+ $on: sinon.spy(),
+ };
- var processErrors = sinon.spy();
+ beforeEach(inject(['$q', function($q) {
+ q = $q;
+ }]));
- var getBasePath = function(path) {
- return '/' + path + '/';
- }
+ test.withService(function(_service) {
+ service = _service;
+ });
- function flushPromises() {
- window.setTimeout(function() {
- inject(['$rootScope', function($rootScope) {
- $rootScope.$apply();
- }]);
- });
- }
+ it('returns a promise to be fulfilled when data comes in', function() {
+ var firstResult = "result";
- var restStub = {
- setUrl: angular.noop,
- reset: function() {
- delete restStub.deferred;
- },
- get: function() {
- if (angular.isUndefined(restStub.deferred)) {
- restStub.deferred = q.defer();
- }
+ var result = service.get('', '');
- return restStub.deferred.promise;
- },
- succeed: function(value) {
- restStub.deferred.resolve(value);
- },
- fail: function(value) {
- restStub.deferred.reject(value);
- }
- };
+ restStub.succeed({ data: firstResult });
- beforeEach(module("Tower"));
+ restStub.flush();
- beforeEach(module(['$provide', function($provide) {
+ return expect(result).to.eventually.equal(firstResult);;
+ });
- $provide.value("$cookieStore", { get: angular.noop });
+ it('processes errors through error handler', function() {
+ var expected = { data: "blah", status: "bad" };
+ var actual = service.get().catch(function() {
+ return processErrors;
+ });
- $provide.value('ProcessErrors', processErrors);
- $provide.value('Rest', restStub);
- $provide.value('GetBasePath', getBasePath);
- }]));
+ restStub.fail(expected);
- afterEach(function() {
- restStub.reset();
- });
+ restStub.flush();
- beforeEach(inject(['jobStatusGraphData', '$httpBackend', '$q', '$rootScope', '$timeout', function(_jobStatusGraphData_, $httpBackend, $q, $rootScope, $timeout) {
- jobStatusGraphData = _jobStatusGraphData_;
- httpBackend = $httpBackend;
- rootScope = $rootScope;
- timeout = $timeout;
- $httpBackend.expectGET('/static/js/local_config.js').respond({
- });
- q = $q;
- }]));
+ return actual.catch(function() {
+ expect(processErrors).to
+ .have.been.calledWith(null, expected.data, expected.status);
+ });
- it('returns a promise to be fulfilled when data comes in', function() {
- var firstResult = "result";
+ });
- var result = jobStatusGraphData.get('', '');
+ it('broadcasts event when data is received', function() {
+ var expected = "value";
+ var result = q.defer();
+ service.setupWatcher();
- restStub.succeed({ data: firstResult });
+ inject(['$rootScope', function($rootScope) {
+ $rootScope.$on('DataReceived:JobStatusGraph', function(e, data) {
+ result.resolve(data);
+ });
+ $rootScope.$emit('JobStatusChange');
+ restStub.succeed({ data: expected });
+ restStub.flush();
+ }]);
- flushPromises();
+ return expect(result.promise).to.eventually.equal(expected);
+ });
- return expect(result).to.eventually.equal(firstResult);;
- });
+ it('requests data with given period and jobType', function() {
+ restStub.setUrl = sinon.spy();
- it('processes errors through error handler', function() {
- var expected = { data: "blah", status: "bad" };
- var actual = jobStatusGraphData.get().catch(function() {
- return processErrors;
- });
-
- restStub.fail(expected);
-
- flushPromises();
-
- return actual.catch(function() {
- expect(processErrors).to
- .have.been.calledWith(null, expected.data, expected.status);
- });
-
- });
-
- it('broadcasts event when data is received', function() {
- var expected = "value";
- var result = q.defer();
- jobStatusGraphData.setupWatcher();
-
- inject(['$rootScope', function($rootScope) {
- $rootScope.$on('DataReceived:JobStatusGraph', function(e, data) {
- result.resolve(data);
- });
- $rootScope.$emit('JobStatusChange');
- restStub.succeed({ data: expected });
- flushPromises();
- }]);
-
- return expect(result.promise).to.eventually.equal(expected);
- });
-
- it('requests data with given period and jobType', function() {
- restStub.setUrl = sinon.spy();
-
- jobStatusGraphData.get('1', '2');
-
- expect(restStub.setUrl).to.have.been.calledWith('/dashboard/graphs/jobs/?period=1&job_type=2');
- });
+ service.get('1', '2');
+ expect(restStub.setUrl).to.have.been.calledWith('/dashboard/graphs/jobs/?period=1&job_type=2');
+ });
});