mirror of
https://github.com/ansible/awx.git
synced 2026-02-28 08:18:43 -03:30
Extract library for tests
This commit is contained in:
@@ -481,4 +481,4 @@ export function UsersEdit($scope, $rootScope, $compile, $location, $log, $routeP
|
|||||||
UsersEdit.$inject = ['$scope', '$rootScope', '$compile', '$location', '$log', '$routeParams', 'UserForm', 'GenerateForm',
|
UsersEdit.$inject = ['$scope', '$rootScope', '$compile', '$location', '$log', '$routeParams', 'UserForm', 'GenerateForm',
|
||||||
'Rest', 'Alert', 'ProcessErrors', 'LoadBreadCrumbs', 'RelatedSearchInit', 'RelatedPaginateInit', 'ReturnToCaller', 'ClearScope',
|
'Rest', 'Alert', 'ProcessErrors', 'LoadBreadCrumbs', 'RelatedSearchInit', 'RelatedPaginateInit', 'ReturnToCaller', 'ClearScope',
|
||||||
'GetBasePath', 'Prompt', 'CheckAccess', 'ResetForm', 'Wait', 'Stream'
|
'GetBasePath', 'Prompt', 'CheckAccess', 'ResetForm', 'Wait', 'Stream'
|
||||||
];
|
];
|
||||||
|
|||||||
@@ -1,24 +1,48 @@
|
|||||||
// Karma configuration
|
// Karma configuration
|
||||||
// Generated on Mon Aug 04 2014 21:17:04 GMT-0400 (EDT)
|
// Generated on Mon Aug 04 2014 21:17:04 GMT-0400 (EDT)
|
||||||
|
|
||||||
|
var path = require('path');
|
||||||
|
|
||||||
module.exports = function(config) {
|
module.exports = function(config) {
|
||||||
config.set({
|
config.set({
|
||||||
|
|
||||||
// base path that will be used to resolve all patterns (eg. files, exclude)
|
// base path that will be used to resolve all patterns (eg. files, exclude)
|
||||||
basePath: '',
|
basePath: '',
|
||||||
|
|
||||||
|
autoWatchBatchDelay: 2000,
|
||||||
|
|
||||||
// frameworks to use
|
// frameworks to use
|
||||||
// available frameworks: https://npmjs.org/browse/keyword/karma-adapter
|
// 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
|
// list of files / patterns to load in the browser
|
||||||
files: [
|
files: [
|
||||||
|
'../tests/phantomjs-polyfill.js',
|
||||||
'../dist/tower.concat.js',
|
'../dist/tower.concat.js',
|
||||||
'../static/lib/angular-mocks/angular-mocks.js',
|
'../static/lib/angular-mocks/angular-mocks.js',
|
||||||
'../static/lib/ember-cli-test-loader/test-loader.js',
|
'../static/lib/ember-cli-test-loader/test-loader.js',
|
||||||
'../dist/tests/**/*.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
|
// list of files to exclude
|
||||||
exclude: [
|
exclude: [
|
||||||
|
|||||||
28
awx/ui/tests/phantomjs-polyfill.js
Normal file
28
awx/ui/tests/phantomjs-polyfill.js
Normal file
@@ -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;
|
||||||
|
};
|
||||||
|
}
|
||||||
274
awx/ui/tests/unit/describe-module.js
Normal file
274
awx/ui/tests/unit/describe-module.js
Normal file
@@ -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;
|
||||||
|
};
|
||||||
@@ -1,90 +1,73 @@
|
|||||||
import Tower from 'tower/app';
|
import Tower from 'tower/app';
|
||||||
|
import {describeModule} from 'tests/unit/describe-module';
|
||||||
|
|
||||||
describe('Job Status Graph Directive', function() {
|
var resizeHandler = sinon.spy();
|
||||||
var element, scope, httpBackend;
|
|
||||||
|
|
||||||
var resizeHandler = sinon.spy();
|
describeModule('DashboardGraphs')
|
||||||
|
.mockProvider('adjustGraphSize', resizeHandler)
|
||||||
|
.testDirective('jobStatusGraph', function(directive) {
|
||||||
|
|
||||||
beforeEach(module('Tower'));
|
|
||||||
|
|
||||||
beforeEach(module(['$provide', function($provide) {
|
directive.provideTemplate(
|
||||||
$provide.value('LoadBasePaths', angular.noop);
|
'/static/partials/job_status_graph.html',
|
||||||
$provide.value('adjustGraphSize', resizeHandler);
|
"<div class='m'></div><div class='n'></div><div class='job-status-graph'><svg></svg></div>");
|
||||||
}]));
|
|
||||||
|
directive.use('<job-status-graph class="job-status-graph" data="data" job-type="all" period="month"></job-status-graph>');
|
||||||
|
|
||||||
|
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("<div class='m'></div><div class='n'></div><div class='job-status-graph'><svg></svg></div>");
|
|
||||||
|
|
||||||
scope = $rootScope.$new();
|
|
||||||
|
|
||||||
element = '<job-status-graph class="job-status-graph" data="data" job-type="all" period="month"></job-status-graph>';
|
|
||||||
|
|
||||||
// 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;
|
|
||||||
});
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|||||||
62
awx/ui/tests/unit/rest-stub.js
Normal file
62
awx/ui/tests/unit/rest-stub.js
Normal file
@@ -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;
|
||||||
@@ -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) {
|
beforeEach(inject(['$q', function($q) {
|
||||||
return '/' + path + '/';
|
q = $q;
|
||||||
}
|
}]));
|
||||||
|
|
||||||
function flushPromises() {
|
|
||||||
window.setTimeout(function() {
|
test.withService(function(_service_) {
|
||||||
inject(['$rootScope', function($rootScope) {
|
service = _service_;
|
||||||
$rootScope.$apply();
|
|
||||||
}], 1000);
|
|
||||||
});
|
});
|
||||||
}
|
|
||||||
|
|
||||||
function assertUrlDeferred(url, obj) {
|
it('returns a promise to be fulfilled when data comes in', function() {
|
||||||
if (angular.isUndefined(obj[url]) ||
|
var license = "license";
|
||||||
angular.isUndefined(obj[url].then) &&
|
var hostData = "hosts";
|
||||||
angular.isUndefined(obj[url].promise.then)) {
|
|
||||||
var urls = [];
|
|
||||||
|
|
||||||
for (key in obj) {
|
var result = service.get();
|
||||||
if (/\//.test(key)) {
|
|
||||||
urls.push(key);
|
restStub.succeedAt('/config/', { data: {
|
||||||
|
license_info: {
|
||||||
|
instance_count: license
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
|
|
||||||
var registered = urls.map(function(url) {
|
restStub.succeedAt('/dashboard/graphs/inventory/', { data: hostData });
|
||||||
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"
|
restStub.flush();
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var restStub = {
|
return expect(result).to.eventually.eql({ license: license, hosts: hostData });;
|
||||||
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
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
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() {
|
return actual.catch(function() {
|
||||||
var expected = { data: "blah", status: "bad" };
|
expect(processErrors).to
|
||||||
var actual = hostCountGraphData.get();
|
.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);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|||||||
@@ -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 = {
|
var jobStatusChange = {
|
||||||
$on: sinon.spy(),
|
$on: sinon.spy(),
|
||||||
};
|
};
|
||||||
|
|
||||||
var processErrors = sinon.spy();
|
beforeEach(inject(['$q', function($q) {
|
||||||
|
q = $q;
|
||||||
|
}]));
|
||||||
|
|
||||||
var getBasePath = function(path) {
|
test.withService(function(_service) {
|
||||||
return '/' + path + '/';
|
service = _service;
|
||||||
}
|
});
|
||||||
|
|
||||||
function flushPromises() {
|
it('returns a promise to be fulfilled when data comes in', function() {
|
||||||
window.setTimeout(function() {
|
var firstResult = "result";
|
||||||
inject(['$rootScope', function($rootScope) {
|
|
||||||
$rootScope.$apply();
|
|
||||||
}]);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
var restStub = {
|
var result = service.get('', '');
|
||||||
setUrl: angular.noop,
|
|
||||||
reset: function() {
|
|
||||||
delete restStub.deferred;
|
|
||||||
},
|
|
||||||
get: function() {
|
|
||||||
if (angular.isUndefined(restStub.deferred)) {
|
|
||||||
restStub.deferred = q.defer();
|
|
||||||
}
|
|
||||||
|
|
||||||
return restStub.deferred.promise;
|
restStub.succeed({ data: firstResult });
|
||||||
},
|
|
||||||
succeed: function(value) {
|
|
||||||
restStub.deferred.resolve(value);
|
|
||||||
},
|
|
||||||
fail: function(value) {
|
|
||||||
restStub.deferred.reject(value);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
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);
|
restStub.fail(expected);
|
||||||
$provide.value('Rest', restStub);
|
|
||||||
$provide.value('GetBasePath', getBasePath);
|
|
||||||
}]));
|
|
||||||
|
|
||||||
afterEach(function() {
|
restStub.flush();
|
||||||
restStub.reset();
|
|
||||||
});
|
|
||||||
|
|
||||||
beforeEach(inject(['jobStatusGraphData', '$httpBackend', '$q', '$rootScope', '$timeout', function(_jobStatusGraphData_, $httpBackend, $q, $rootScope, $timeout) {
|
return actual.catch(function() {
|
||||||
jobStatusGraphData = _jobStatusGraphData_;
|
expect(processErrors).to
|
||||||
httpBackend = $httpBackend;
|
.have.been.calledWith(null, expected.data, expected.status);
|
||||||
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 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() {
|
service.get('1', '2');
|
||||||
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');
|
|
||||||
});
|
|
||||||
|
|
||||||
|
expect(restStub.setUrl).to.have.been.calledWith('/dashboard/graphs/jobs/?period=1&job_type=2');
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user