mirror of
https://github.com/ZwareBear/awx.git
synced 2026-04-12 02:51:49 -05:00
Separate node test build from browser build
This commit is contained in:
@@ -1,5 +0,0 @@
|
||||
{
|
||||
"expr": true,
|
||||
"esnext": true,
|
||||
"node": true
|
||||
}
|
||||
@@ -1,83 +0,0 @@
|
||||
/* jshint node: true */
|
||||
|
||||
import '../support/node';
|
||||
|
||||
import {describeModule} from '../support/describe-module';
|
||||
import '../../src/shared/Utilities';
|
||||
import '../../src/shared/RestServices';
|
||||
import JobStatusGraph from '../../src/dashboard/graphs/job-status/main';
|
||||
|
||||
var resizeHandler = sinon.spy();
|
||||
|
||||
window.$.fn.removeResize = angular.noop;
|
||||
|
||||
describeModule(JobStatusGraph.name)
|
||||
.mockProvider('adjustGraphSize', resizeHandler)
|
||||
.mockProvider('Wait', angular.noop)
|
||||
.mockProvider('Rest', angular.noop)
|
||||
.testDirective('jobStatusGraph', function(directive) {
|
||||
|
||||
|
||||
directive.provideTemplate(
|
||||
'/static/partials/job_status_graph.html',
|
||||
"<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;
|
||||
});
|
||||
|
||||
});
|
||||
@@ -1,27 +0,0 @@
|
||||
import '../support/node';
|
||||
|
||||
import featuresController from '../../src/shared/features/features.controller';
|
||||
|
||||
describe('featuresController', function() {
|
||||
|
||||
it('checks if a feature is enabled', window.inject(['$rootScope', function($rootScope) {
|
||||
var actual;
|
||||
|
||||
$rootScope.features = {
|
||||
activity_streams: true,
|
||||
ldap: false
|
||||
};
|
||||
|
||||
// TODO: extract into test controller in describeModule
|
||||
var Controller = featuresController[1];
|
||||
var controller = new Controller($rootScope);
|
||||
|
||||
actual = controller.isFeatureEnabled('activity_streams');
|
||||
expect(actual).to.be.true;
|
||||
|
||||
actual = controller.isFeatureEnabled('ldap');
|
||||
expect(actual).to.be.false;
|
||||
|
||||
|
||||
}]));
|
||||
})
|
||||
@@ -1,57 +0,0 @@
|
||||
import '../support/node';
|
||||
|
||||
import features from '../../src/shared/features/main';
|
||||
import {describeModule} from '../support/describe-module';
|
||||
|
||||
//test that it returns features, as well as test that it is returned in rootScope
|
||||
|
||||
describeModule(features.name)
|
||||
.testService('FeaturesService', function(test, restStub) {
|
||||
|
||||
var service;
|
||||
|
||||
test.withService(function(_service) {
|
||||
service = _service;
|
||||
});
|
||||
|
||||
it('returns list of features', function() {
|
||||
var features = {},
|
||||
result = {
|
||||
data: {
|
||||
license_info: {
|
||||
features: features
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
var actual = service.get();
|
||||
|
||||
restStub.succeed(result);
|
||||
restStub.flush();
|
||||
|
||||
return expect(actual).to.eventually.equal(features);
|
||||
|
||||
});
|
||||
|
||||
it('caches in rootScope', window.inject(['$rootScope',
|
||||
function($rootScope){
|
||||
var features = {},
|
||||
result = {
|
||||
data: {
|
||||
license_info: {
|
||||
features: features
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
var actual = service.get();
|
||||
|
||||
restStub.succeed(result);
|
||||
restStub.flush();
|
||||
|
||||
return actual.then(function(){
|
||||
expect($rootScope.features).to.equal(features);
|
||||
});
|
||||
}]));
|
||||
|
||||
});
|
||||
@@ -1,26 +0,0 @@
|
||||
import '../support/node';
|
||||
|
||||
import jobTemplates from '../../src/job-templates/main';
|
||||
import {describeModule} from '../support/describe-module';
|
||||
|
||||
describeModule(jobTemplates.name)
|
||||
.testService('deleteJobTemplate', function(test, restStub) {
|
||||
|
||||
var service;
|
||||
|
||||
test.withService(function(_service) {
|
||||
service = _service;
|
||||
});
|
||||
|
||||
it('deletes the job template', function() {
|
||||
var result = {};
|
||||
|
||||
var actual = service();
|
||||
|
||||
restStub.succeedOn('destroy', result);
|
||||
restStub.flush();
|
||||
|
||||
expect(actual).to.eventually.equal(result);
|
||||
|
||||
});
|
||||
});
|
||||
@@ -1,199 +0,0 @@
|
||||
import '../support/node';
|
||||
|
||||
import {describeModule} from '../support/describe-module';
|
||||
import mod from '../../src/shared/multi-select-list/main';
|
||||
|
||||
describeModule(mod.name)
|
||||
.testDirective('multiSelectList', function(test) {
|
||||
|
||||
var $scope;
|
||||
var controller;
|
||||
|
||||
test.use('<div multi-select-list></div>');
|
||||
|
||||
test.afterCompile(function(outerScope, scope) {
|
||||
$scope = scope;
|
||||
});
|
||||
|
||||
test.withController(function(_controller) {
|
||||
controller = _controller;
|
||||
});
|
||||
|
||||
it('works as an attribute on elements', function() {
|
||||
window.inject(['$compile', function($compile) {
|
||||
var node = $compile('<div multi-select-list></div>')($scope);
|
||||
var classes = Array.prototype.slice.apply(node.attr('class').split(' '));
|
||||
expect(classes).to.contain('ng-scope');
|
||||
}]);
|
||||
});
|
||||
|
||||
context('controller init', function() {
|
||||
|
||||
it('initializes items and selection', function() {
|
||||
expect($scope.items).to.be.empty;
|
||||
expect($scope.selection.selectedItems).to.be.empty;
|
||||
expect($scope.selection.deselectedItems).to.be.empty;
|
||||
expect($scope.selection.isExtended).to.be.false;
|
||||
});
|
||||
|
||||
it('wraps items when they are registered', function() {
|
||||
var item = { name: 'blah' };
|
||||
var wrapped = controller.registerItem(item);
|
||||
|
||||
expect(wrapped.hasOwnProperty('isSelected')).to.be.true;
|
||||
expect(wrapped.hasOwnProperty('value')).to.be.true;
|
||||
|
||||
expect(wrapped.isSelected).to.be.false;
|
||||
expect(wrapped.value).to.eql(item);
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
context('single select/deselect', function() {
|
||||
|
||||
it('marks item as selected/not selected', function() {
|
||||
var item = controller.registerItem({ name: 'blah' });
|
||||
controller.selectItem(item);
|
||||
|
||||
expect(item.isSelected).to.be.true;
|
||||
|
||||
controller.deselectItem(item);
|
||||
expect(item.isSelected).to.be.false;
|
||||
});
|
||||
|
||||
context('selectionChanged event', function() {
|
||||
|
||||
it('triggers on select/deselect', function() {
|
||||
var item = controller.registerItem({ name: 'blah' });
|
||||
var spy = sinon.spy();
|
||||
|
||||
$scope.$on('multiSelectList.selectionChanged', spy);
|
||||
|
||||
controller.selectItem(item);
|
||||
controller.deselectItem(item);
|
||||
|
||||
expect(spy).to.have.been.calledTwice;
|
||||
});
|
||||
|
||||
it('is called with the current selection', function() {
|
||||
var item = controller.registerItem({ name: 'blah' });
|
||||
var spy = sinon.spy();
|
||||
|
||||
$scope.$on('multiSelectList.selectionChanged', spy);
|
||||
|
||||
controller.selectItem(item);
|
||||
|
||||
expect(spy).to.have.been.calledWith(sinon.match.object,
|
||||
{ selectedItems:
|
||||
[ item.value
|
||||
],
|
||||
deselectedItems: [],
|
||||
isExtended: false
|
||||
});
|
||||
});
|
||||
|
||||
it('is called with deselections', function() {
|
||||
var item = controller.registerItem({ name: 'blah' });
|
||||
controller.selectItem(item);
|
||||
|
||||
var spy = sinon.spy();
|
||||
|
||||
|
||||
$scope.$on('multiSelectList.selectionChanged', spy);
|
||||
controller.deselectItem(item);
|
||||
|
||||
expect(spy).to.have.been.calledWith(sinon.match.object,
|
||||
{ selectedItems: [],
|
||||
deselectedItems:
|
||||
[ item.value
|
||||
],
|
||||
isExtended: false
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
context('select/deselect all items', function() {
|
||||
|
||||
it('marks all items as selected/deselected', function() {
|
||||
var item1 = controller.registerItem({ name: 'blah' });
|
||||
var item2 = controller.registerItem({ name: 'diddy' });
|
||||
var item3 = controller.registerItem({ name: 'doo' });
|
||||
|
||||
controller.selectAll();
|
||||
|
||||
expect([item1, item2, item3]).to.all.have.property('isSelected', true);
|
||||
|
||||
controller.deselectAll();
|
||||
|
||||
expect([item1, item2, item3]).to.all.have.property('isSelected', false);
|
||||
});
|
||||
|
||||
context('selectionChanged event', function() {
|
||||
|
||||
it('triggers with selections set to all the items', function() {
|
||||
var item1 = controller.registerItem({ name: 'blah' });
|
||||
var item2 = controller.registerItem({ name: 'diddy' });
|
||||
var item3 = controller.registerItem({ name: 'doo' });
|
||||
var spy = sinon.spy();
|
||||
|
||||
$scope.$on('multiSelectList.selectionChanged', spy);
|
||||
|
||||
controller.selectAll();
|
||||
|
||||
expect(spy).to.have.been.calledWith(
|
||||
sinon.match.object,
|
||||
{ selectedItems: _.pluck([item1, item2, item3], "value"),
|
||||
deselectedItems: [],
|
||||
isExtended: false
|
||||
});
|
||||
|
||||
controller.deselectAll();
|
||||
|
||||
expect(spy).to.have.been.calledWith(
|
||||
sinon.match.object,
|
||||
{ selectedItems: [],
|
||||
deselectedItems: _.pluck([item1, item2, item3], "value"),
|
||||
isExtended: false
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
|
||||
it('tracks extended selection state', function() {
|
||||
var spy = sinon.spy();
|
||||
var item1 = controller.registerItem({ name: 'blah' });
|
||||
var item2 = controller.registerItem({ name: 'diddy' });
|
||||
var item3 = controller.registerItem({ name: 'doo' });
|
||||
var allItems = _.pluck([item1, item2, item3], 'value');
|
||||
|
||||
controller.selectAll();
|
||||
controller.selectAllExtended();
|
||||
|
||||
expect($scope.selection).to.have.property('isExtended', true);
|
||||
|
||||
controller.deselectAllExtended();
|
||||
|
||||
expect($scope.selection).to.have.property('isExtended', false);
|
||||
expect($scope.selection)
|
||||
.to.have.property('selectedItems')
|
||||
.that.is.an('array')
|
||||
.deep.equals(allItems);
|
||||
});
|
||||
|
||||
|
||||
it('toggles extended state on deselectAll', function() {
|
||||
controller.selectAllExtended();
|
||||
|
||||
controller.deselectAll();
|
||||
|
||||
expect($scope.selection).to.have.property('isExtended', false);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,97 +0,0 @@
|
||||
import '../support/node';
|
||||
|
||||
import {describeModule} from '../support/describe-module';
|
||||
import mod from '../../src/shared/multi-select-list/main';
|
||||
|
||||
var mockController = {
|
||||
selectAll: sinon.spy(),
|
||||
deselectAll: sinon.spy(),
|
||||
selectAllExtended: sinon.spy(),
|
||||
deselectAllExtended: sinon.spy()
|
||||
};
|
||||
|
||||
describeModule(mod.name)
|
||||
.testDirective('selectAll', function(directive) {
|
||||
|
||||
var $scope;
|
||||
|
||||
directive.use('<fake-parent><select-all selections-empty="isEmpty" extended-items-length="numItems"></select-all></fake-parent>');
|
||||
|
||||
beforeEach(function() {
|
||||
directive.element.data('$multiSelectListController', mockController);
|
||||
});
|
||||
|
||||
afterEach(function() {
|
||||
mockController.selectAll.reset();
|
||||
mockController.deselectAll.reset();
|
||||
mockController.selectAllExtended.reset();
|
||||
mockController.deselectAllExtended.reset();
|
||||
});
|
||||
|
||||
directive.afterCompile(function() {
|
||||
|
||||
// Since we had to wrap select-all in a fake directive
|
||||
// to mock the controller, we have to reach down to
|
||||
// get it's isolate scope
|
||||
//
|
||||
$scope =
|
||||
directive.$element.find('select-all').isolateScope();
|
||||
});
|
||||
|
||||
it('works as an element tag', function() {
|
||||
var classes = directive.$element.attr('class').split(' ');
|
||||
expect(classes).to.contain('ng-scope');
|
||||
});
|
||||
|
||||
it('calls select all when isSelected is true', function() {
|
||||
$scope.isSelected = true;
|
||||
$scope.doSelectAll();
|
||||
expect(mockController.selectAll).to.have.been.calledOnce;
|
||||
});
|
||||
|
||||
it('calls deselect all when isSelected is false', function() {
|
||||
$scope.isSelected = false;
|
||||
$scope.doSelectAll();
|
||||
|
||||
expect(mockController.deselectAll).to.have.been.calledOnce;
|
||||
});
|
||||
|
||||
it('calls deselect all extended when deselecting all', function() {
|
||||
$scope.isSelected = false;
|
||||
$scope.isSelectionExtended = true;
|
||||
$scope.doSelectAll();
|
||||
|
||||
expect(mockController.deselectAllExtended).to.have.been.calledOnce;
|
||||
});
|
||||
|
||||
context('input parameters', function() {
|
||||
|
||||
var $outerScope;
|
||||
|
||||
// We need to grab the parent scope object so we can control
|
||||
// the parameters that are passed into the directive in the
|
||||
// `use` call above
|
||||
directive.withScope(function(_outerScope) {
|
||||
$outerScope = _outerScope;
|
||||
});
|
||||
|
||||
it('when true sets isSelected to false', function() {
|
||||
|
||||
$scope.isSelected = true;
|
||||
$outerScope.isEmpty = true;
|
||||
$outerScope.$apply();
|
||||
|
||||
expect($scope).to.have.property('isSelected', false);
|
||||
});
|
||||
|
||||
it('sets supportsExtendedItems when extendedItemsLength is given', function() {
|
||||
$scope.supportsExtendedItems = false;
|
||||
$outerScope.numItems = 5;
|
||||
$outerScope.$apply();
|
||||
|
||||
expect($scope).to.have.property('supportsExtendedItems', true);
|
||||
});
|
||||
|
||||
|
||||
});
|
||||
});
|
||||
@@ -1,79 +0,0 @@
|
||||
import '../support/node';
|
||||
|
||||
import {describeModule} from '../support/describe-module';
|
||||
import JobStatusGraph from '../../src/dashboard/graphs/job-status/main';
|
||||
|
||||
var processErrors = sinon.spy();
|
||||
|
||||
describeModule(JobStatusGraph.name)
|
||||
.mockProvider('ProcessErrors', processErrors)
|
||||
.testService('jobStatusGraphData', function(test, restStub) {
|
||||
var q;
|
||||
var service;
|
||||
|
||||
var jobStatusChange = {
|
||||
$on: sinon.spy(),
|
||||
};
|
||||
|
||||
beforeEach(inject(['$q', function($q) {
|
||||
q = $q;
|
||||
}]));
|
||||
|
||||
test.withService(function(_service) {
|
||||
service = _service;
|
||||
});
|
||||
|
||||
it('returns a promise to be fulfilled when data comes in', function() {
|
||||
var firstResult = "result";
|
||||
|
||||
var result = service.get('', '');
|
||||
|
||||
restStub.succeed({ data: firstResult });
|
||||
|
||||
restStub.flush();
|
||||
|
||||
return expect(result).to.eventually.equal(firstResult);;
|
||||
});
|
||||
|
||||
it('processes errors through error handler', function() {
|
||||
var expected = { data: "blah", status: "bad" };
|
||||
var actual = service.get().catch(function() {
|
||||
return processErrors;
|
||||
});
|
||||
|
||||
restStub.fail(expected);
|
||||
|
||||
restStub.flush();
|
||||
|
||||
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();
|
||||
service.setupWatcher();
|
||||
|
||||
inject(['$rootScope', function($rootScope) {
|
||||
$rootScope.$on('DataReceived:JobStatusGraph', function(e, data) {
|
||||
result.resolve(data);
|
||||
});
|
||||
$rootScope.$emit('JobStatusChange-home');
|
||||
restStub.succeed({ data: expected });
|
||||
restStub.flush();
|
||||
}]);
|
||||
|
||||
return expect(result.promise).to.eventually.equal(expected);
|
||||
});
|
||||
|
||||
it('requests data with given period and jobType', function() {
|
||||
restStub.setUrl = sinon.spy();
|
||||
|
||||
service.get('1', '2');
|
||||
|
||||
expect(restStub.setUrl).to.have.been.calledWith('/dashboard/graphs/jobs/?period=1&job_type=2');
|
||||
});
|
||||
});
|
||||
@@ -1,77 +0,0 @@
|
||||
import '../support/node';
|
||||
|
||||
import '../../src/shared/main';
|
||||
|
||||
describe('LodashAsPromised', function() {
|
||||
|
||||
var _;
|
||||
var $q;
|
||||
|
||||
function addOne(num) {
|
||||
return num + 1;
|
||||
}
|
||||
|
||||
function isEven(value) {
|
||||
return value % 2 === 0;
|
||||
}
|
||||
|
||||
function sum(memo, value) {
|
||||
return memo + value;
|
||||
}
|
||||
|
||||
beforeEach(window.module('shared'));
|
||||
|
||||
beforeEach(inject(['lodashAsPromised', '$q', function(_lodash, _$q) {
|
||||
_ = _lodash;
|
||||
$q = _$q;
|
||||
}]));
|
||||
|
||||
function checkPromiseAndArray(fnName, cb, coll, result) {
|
||||
context(fnName, function() {
|
||||
// var itFn = fnName === 'compact' ? it : xit;
|
||||
var itFn = it;
|
||||
|
||||
itFn('works with a promise', function() {
|
||||
var values = coll.map($q.when);
|
||||
var methodName = 'then' + _.capitalize(fnName);
|
||||
var promise;
|
||||
// _.log('promises for _', values);
|
||||
if (fnName === 'reduce') {
|
||||
promise = _[methodName](values, cb, 0);
|
||||
} else {
|
||||
promise = _[methodName](values, cb);
|
||||
}
|
||||
|
||||
inject(['$rootScope', function($rootScope) {
|
||||
setTimeout(function() {
|
||||
$rootScope.$apply();
|
||||
}, 1);
|
||||
}]);
|
||||
|
||||
return expect(promise).to.eventually.deep.equal(result);
|
||||
});
|
||||
|
||||
itFn('works with an array', function() {
|
||||
var value = _[fnName](coll, cb, 0);
|
||||
expect(value).to.deep.equal(result);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
checkPromiseAndArray('map', addOne, [1,2,3,4], [2,3,4,5]);
|
||||
checkPromiseAndArray('filter', isEven, [1,2,3,4,5,6,7,8], [2,4,6,8]);
|
||||
checkPromiseAndArray('reduce', sum, [1,2,3,4], 10);
|
||||
checkPromiseAndArray('pluck', 'blah', [{ blah: 'diddy' }, { blah: 'doo' }], ['diddy', 'doo']);
|
||||
checkPromiseAndArray('compact', null, ['blah', null, 'diddy', false, 'doo', undefined], ['blah', 'diddy', 'doo']);
|
||||
checkPromiseAndArray('xor', [4,2], [1,2], [1,4]);
|
||||
checkPromiseAndArray('groupBy', Math.floor, [4.2,6.1,6.4], { '4': [4.2], '6': [6.1,6.4] } );
|
||||
|
||||
it('allows chaining', function() {
|
||||
function dub(n) { return n * 2; }
|
||||
|
||||
var arr = [1,2,3,4].map($q.when);
|
||||
|
||||
expect(_(arr).thenMap(dub)).to.eventually.deep.equal([2,4,6,8]);
|
||||
});
|
||||
|
||||
});
|
||||
@@ -1,6 +0,0 @@
|
||||
window.$AnsibleConfig = null;
|
||||
window.$basePath = '/static/';
|
||||
|
||||
var testLoader = require('ember-cli/test-loader');
|
||||
|
||||
testLoader.default.load();
|
||||
@@ -1,286 +0,0 @@
|
||||
import RestStub from './rest-stub';
|
||||
|
||||
var $provide;
|
||||
|
||||
function wrapInjected(dslFn) {
|
||||
// wrapInjected(before(inject(..., function() {
|
||||
// }));
|
||||
return function(fn) {
|
||||
dslFn.apply(this,
|
||||
[window.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", window.module('Tower'));
|
||||
beforeEach(name + " module", window.module(name));
|
||||
beforeEach("templates module", window.module('templates'));
|
||||
beforeEach("mock app setup", window.module(['$provide', function(_provide_) {
|
||||
|
||||
var getBasePath = function(path) {
|
||||
return '/' + path + '/';
|
||||
};
|
||||
|
||||
$provide = _provide_;
|
||||
$provide.value('LoadBasePaths', angular.noop);
|
||||
$provide.value('GetBasePath', getBasePath);
|
||||
$provide.value('ProcessErrors', angular.noop);
|
||||
|
||||
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(window.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", window.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", window.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", window.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;
|
||||
var $outerScope;
|
||||
|
||||
// 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
|
||||
$outerScope = $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, [$outerScope, $scope]);
|
||||
});
|
||||
|
||||
},
|
||||
registerCompile: function(deps) {
|
||||
|
||||
var self = this;
|
||||
|
||||
// Only setup compile step once
|
||||
if (this._compileRegistered) {
|
||||
return;
|
||||
}
|
||||
|
||||
beforeEach("compile directive element",
|
||||
window.inject(['$compile', '$httpBackend', '$rootScope', function($compile, $httpBackend, $rootScope) {
|
||||
|
||||
if (!self.$scope) {
|
||||
self.$scope = $rootScope.$new();
|
||||
}
|
||||
|
||||
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();
|
||||
delete self.$scope;
|
||||
});
|
||||
|
||||
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", window.inject(['$httpBackend', function($httpBackend) {
|
||||
$httpBackend
|
||||
.whenGET(url)
|
||||
.respond(template);
|
||||
}]));
|
||||
},
|
||||
_ensureCompiled: function() {
|
||||
if (typeof this.$element === 'undefined') {
|
||||
throw "Can only call withController after registerPostHooks on directive test";
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
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", window.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,4 +0,0 @@
|
||||
module.exports =
|
||||
function exportGlobal(varName, value) {
|
||||
global[varName] = global.window[varName] = value;
|
||||
};
|
||||
@@ -1,26 +0,0 @@
|
||||
/* 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');
|
||||
|
||||
})();
|
||||
@@ -1,5 +0,0 @@
|
||||
var exportGlobal = require('../export-global');
|
||||
require('angular-mocks/angular-mocks');
|
||||
|
||||
exportGlobal('inject', window.inject);
|
||||
|
||||
@@ -1,2 +0,0 @@
|
||||
angular.module('templates', []);
|
||||
require('../../../../templates');
|
||||
5
awx/ui/tests/support/node/setup/angular.js
vendored
5
awx/ui/tests/support/node/setup/angular.js
vendored
@@ -1,5 +0,0 @@
|
||||
var exportGlobal = require('../export-global');
|
||||
require('angular/angular');
|
||||
|
||||
exportGlobal('angular', window.angular);
|
||||
|
||||
@@ -1,8 +0,0 @@
|
||||
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);
|
||||
|
||||
@@ -1,5 +0,0 @@
|
||||
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
6
awx/ui/tests/support/node/setup/d3.js
vendored
@@ -1,6 +0,0 @@
|
||||
var exportGlobal = require('../export-global');
|
||||
var d3 = require('d3');
|
||||
|
||||
exportGlobal('d3', d3);
|
||||
|
||||
|
||||
7
awx/ui/tests/support/node/setup/jquery.js
vendored
7
awx/ui/tests/support/node/setup/jquery.js
vendored
@@ -1,7 +0,0 @@
|
||||
var exportGlobal = require('../export-global');
|
||||
var jquery = require('jquery');
|
||||
|
||||
exportGlobal('$', jquery);
|
||||
exportGlobal('jQuery', jquery);
|
||||
|
||||
|
||||
@@ -1,6 +0,0 @@
|
||||
var jsdom = require('jsdom').jsdom;
|
||||
var document = jsdom('tower');
|
||||
var window = document.parentWindow;
|
||||
|
||||
global.document = document;
|
||||
global.window = window;
|
||||
@@ -1,7 +0,0 @@
|
||||
var exportGlobal = require('../export-global');
|
||||
var LocalStorage = require('node-localstorage').LocalStorage;
|
||||
|
||||
exportGlobal('localStorage',
|
||||
new LocalStorage('./scratch'));
|
||||
|
||||
|
||||
@@ -1,4 +0,0 @@
|
||||
var exportGlobal = require('../export-global');
|
||||
var lodash = require('lodash');
|
||||
|
||||
exportGlobal('_', lodash);
|
||||
@@ -1,7 +0,0 @@
|
||||
var exportGlobal = require('../export-global');
|
||||
var mocha = require('mocha');
|
||||
|
||||
exportGlobal('mocha', mocha);
|
||||
exportGlobal('beforeEach', beforeEach);
|
||||
exportGlobal('afterEach', afterEach);
|
||||
|
||||
@@ -1,5 +0,0 @@
|
||||
var exportGlobal = require('../export-global');
|
||||
var moment = require('moment');
|
||||
|
||||
exportGlobal('moment', moment);
|
||||
|
||||
@@ -1,6 +0,0 @@
|
||||
var exportGlobal = require('../export-global');
|
||||
var nv = require('nvd3');
|
||||
|
||||
exportGlobal('nv', nv);
|
||||
|
||||
|
||||
@@ -1,4 +0,0 @@
|
||||
var exportGlobal = require('../export-global');
|
||||
var sinon = require('sinon');
|
||||
|
||||
exportGlobal('sinon', sinon);
|
||||
@@ -1,71 +0,0 @@
|
||||
function assertUrlDeferred(url, obj) {
|
||||
if (angular.isUndefined(obj[url]) ||
|
||||
angular.isUndefined(obj[url].then) &&
|
||||
angular.isUndefined(obj[url].promise.then)) {
|
||||
var urls = [];
|
||||
|
||||
for (var 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;
|
||||
},
|
||||
destroy: function() {
|
||||
this.deferred = this.deferred || {};
|
||||
this.deferred.destroy = this[this.currentUrl];
|
||||
|
||||
return this.deferred.destroy.promise;
|
||||
},
|
||||
succeedAt: function(url, value) {
|
||||
assertUrlDeferred(url, this);
|
||||
this[url].resolve(value);
|
||||
},
|
||||
succeedOn: function(method, value) {
|
||||
this.deferred[method] = 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();
|
||||
}]);
|
||||
}, 10);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
export default RestStub;
|
||||
@@ -1,590 +0,0 @@
|
||||
/* jshint node: true */
|
||||
|
||||
import '../../support/node';
|
||||
|
||||
import compareFacts from '../../../src/system-tracking/compare-facts/flat';
|
||||
|
||||
// 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);
|
||||
|
||||
describe('CompareFacts.Flat', function() {
|
||||
|
||||
function options(overrides) {
|
||||
return _.merge({}, defaultOptions, overrides);
|
||||
}
|
||||
|
||||
var defaultTemplate =
|
||||
{ hasTemplate: function() { return false; }
|
||||
};
|
||||
|
||||
var defaultOptions =
|
||||
{ factTemplate: defaultTemplate,
|
||||
nameKey: 'name'
|
||||
};
|
||||
|
||||
it('returns empty array with empty basis facts', function() {
|
||||
var result = compareFacts({ facts: [] }, { facts: [] }, defaultOptions);
|
||||
|
||||
expect(result).to.deep.equal([]);
|
||||
});
|
||||
|
||||
it('returns empty array when no differences', function() {
|
||||
var result = compareFacts(
|
||||
{ facts:
|
||||
[{ 'name': 'foo',
|
||||
'value': 'bar'
|
||||
}]
|
||||
},
|
||||
{ facts:
|
||||
[{ 'name': 'foo',
|
||||
'value': 'bar'
|
||||
}]
|
||||
}, options({ nameKey: 'name',
|
||||
compareKey: ['value'],
|
||||
}));
|
||||
|
||||
expect(result).to.deep.equal([]);
|
||||
});
|
||||
|
||||
it('returns empty array with multiple compare keys and no differences', function() {
|
||||
var result = compareFacts(
|
||||
{ facts:
|
||||
[{ 'name': 'foo',
|
||||
'value': 'bar'
|
||||
}]
|
||||
},
|
||||
{ facts:
|
||||
[{ 'name': 'foo',
|
||||
'value': 'bar'
|
||||
}]
|
||||
}, options({ compareKey: ['name', 'value']
|
||||
}));
|
||||
|
||||
expect(result).to.deep.equal([]);
|
||||
});
|
||||
|
||||
context('when both collections contain facts', function() {
|
||||
it('includes each compare key value when a compareKey differs', function() {
|
||||
var result = compareFacts(
|
||||
{ position: 'left',
|
||||
facts:
|
||||
[{ 'name': 'foo',
|
||||
'value': 'bar',
|
||||
'extra': 'doo'
|
||||
}]
|
||||
},
|
||||
{ position: 'right',
|
||||
facts:
|
||||
[{ 'name': 'foo',
|
||||
'value': 'baz',
|
||||
'extra': 'doo'
|
||||
}]
|
||||
}, options({ compareKey: ['value', 'extra'] }));
|
||||
|
||||
expect(result).to.deep.equal(
|
||||
[{ displayKeyPath: 'foo',
|
||||
containsValueArray: false,
|
||||
nestingLevel: 0,
|
||||
facts:
|
||||
[{ keyName: 'value',
|
||||
value1: 'bar',
|
||||
value2: 'baz',
|
||||
isDivergent: true
|
||||
},
|
||||
{ keyName: 'extra',
|
||||
value1: 'doo',
|
||||
value2: 'doo',
|
||||
isDivergent: false
|
||||
}]
|
||||
}]);
|
||||
});
|
||||
|
||||
it('ignores compare keys with no values in fact', function() {
|
||||
var result = compareFacts(
|
||||
{ position: 'left',
|
||||
facts:
|
||||
[{ 'name': 'foo',
|
||||
'value': 'bar',
|
||||
'extra': 'doo'
|
||||
}]
|
||||
},
|
||||
{ position: 'right',
|
||||
facts:
|
||||
[{ 'name': 'foo',
|
||||
'value': 'baz',
|
||||
'extra': 'doo'
|
||||
}]
|
||||
}, options({ compareKey: ['value', 'extra', 'blah'] }));
|
||||
|
||||
expect(result).to.deep.equal(
|
||||
[{ displayKeyPath: 'foo',
|
||||
containsValueArray: false,
|
||||
nestingLevel: 0,
|
||||
facts:
|
||||
[{ keyName: 'value',
|
||||
value1: 'bar',
|
||||
value2: 'baz',
|
||||
isDivergent: true
|
||||
},
|
||||
{ keyName: 'extra',
|
||||
value1: 'doo',
|
||||
value2: 'doo',
|
||||
isDivergent: false
|
||||
}]
|
||||
}]);
|
||||
|
||||
});
|
||||
|
||||
it('allows mapping key names with keyNameMap parameter', function() {
|
||||
var keyNameMap =
|
||||
{ 'extra': 'blah'
|
||||
};
|
||||
|
||||
var result = compareFacts(
|
||||
{ position: 'left',
|
||||
facts:
|
||||
[{ 'name': 'foo',
|
||||
'value': 'bar',
|
||||
'extra': 'doo'
|
||||
}]
|
||||
},
|
||||
{ position: 'right',
|
||||
facts:
|
||||
[{ 'name': 'foo',
|
||||
'value': 'baz',
|
||||
'extra': 'doo'
|
||||
}]
|
||||
}, options({ compareKey: ['value', 'extra', 'blah'],
|
||||
keyNameMap: keyNameMap
|
||||
}));
|
||||
|
||||
expect(result[0].facts).to.include.something.that.deep.equals(
|
||||
{ keyName: 'blah',
|
||||
value1: 'doo',
|
||||
value2: 'doo',
|
||||
isDivergent: false
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
it('allows flattening values with factTemplate parameter', function() {
|
||||
var factTemplate =
|
||||
{ hasTemplate:
|
||||
function() {
|
||||
return true;
|
||||
},
|
||||
render: function(fact) {
|
||||
return 'value: ' + fact.value;
|
||||
}
|
||||
};
|
||||
|
||||
var result = compareFacts(
|
||||
{ position: 'left',
|
||||
facts:
|
||||
[{ 'name': 'foo',
|
||||
'value': 'bar',
|
||||
'extra': 'doo'
|
||||
}]
|
||||
},
|
||||
{ position: 'right',
|
||||
facts:
|
||||
[{ 'name': 'foo',
|
||||
'value': 'baz',
|
||||
'extra': 'doo'
|
||||
}]
|
||||
}, options({ compareKey: ['value'],
|
||||
factTemplate: factTemplate
|
||||
}));
|
||||
|
||||
expect(result[0].facts).to.deep.equal(
|
||||
{ keyName: 'foo',
|
||||
value1: 'value: bar',
|
||||
value2: 'value: baz'
|
||||
});
|
||||
});
|
||||
|
||||
it('allows formatting values with factTemplate parameter', function() {
|
||||
var values = ['value1', 'value2'];
|
||||
var factTemplate =
|
||||
{ 'value':
|
||||
{ hasTemplate: function() {
|
||||
return true;
|
||||
},
|
||||
render: function() {
|
||||
return values.shift();
|
||||
}
|
||||
},
|
||||
'extra': true
|
||||
};
|
||||
|
||||
var result = compareFacts(
|
||||
{ position: 'left',
|
||||
facts:
|
||||
[{ 'name': 'foo',
|
||||
'value': 'bar',
|
||||
'extra': 'doo'
|
||||
}]
|
||||
},
|
||||
{ position: 'right',
|
||||
facts:
|
||||
[{ 'name': 'foo',
|
||||
'value': 'baz',
|
||||
'extra': 'doo'
|
||||
}]
|
||||
}, options({ compareKey: ['value'],
|
||||
factTemplate: factTemplate
|
||||
}));
|
||||
|
||||
expect(result[0].facts).to.include.something.that.deep.equals(
|
||||
{ keyName: 'value',
|
||||
value1: 'value1',
|
||||
value2: 'value2',
|
||||
isDivergent: true
|
||||
},
|
||||
{ keyName: 'extra',
|
||||
value1: 'doo',
|
||||
value2: 'doo',
|
||||
isDivergent: false
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
it('compares values using the formatted values, not the raw ones', function() {
|
||||
var values = ['value1', 'value2'];
|
||||
var factTemplate =
|
||||
{ 'extra':
|
||||
{ render: function() {
|
||||
return values.shift();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
var result = compareFacts(
|
||||
{ position: 'left',
|
||||
facts:
|
||||
[{ 'name': 'foo',
|
||||
'value': 'bar',
|
||||
'extra': 'doo'
|
||||
}]
|
||||
},
|
||||
{ position: 'right',
|
||||
facts:
|
||||
[{ 'name': 'foo',
|
||||
'value': 'bar',
|
||||
'extra': 'doo'
|
||||
}]
|
||||
}, options({ factTemplate: factTemplate,
|
||||
compareKey: ['extra']
|
||||
}));
|
||||
|
||||
expect(result.length).to.be.greaterThan(0);
|
||||
expect(result[0].facts).to.include.something.that.deep.equals(
|
||||
{ keyName: 'extra',
|
||||
value1: 'value1',
|
||||
value2: 'value2',
|
||||
isDivergent: true
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
context('when value for nameKey is present in one collection but not the other', function() {
|
||||
|
||||
function factData(leftFacts) {
|
||||
var facts = [{ position: 'left',
|
||||
facts: leftFacts
|
||||
},
|
||||
{ position: 'right',
|
||||
facts: []
|
||||
}];
|
||||
|
||||
return facts;
|
||||
}
|
||||
|
||||
it('keeps missing values as undefined', function() {
|
||||
|
||||
var facts = factData([{ 'name': 'foo',
|
||||
'value': 'bar'
|
||||
}]);
|
||||
|
||||
var result = compareFacts(facts[0], facts[1],
|
||||
options({ compareKey: ['value']
|
||||
}));
|
||||
|
||||
expect(result).to.deep.equal(
|
||||
[{ displayKeyPath: 'foo',
|
||||
containsValueArray: false,
|
||||
nestingLevel: 0,
|
||||
facts:
|
||||
[{ keyName: 'value',
|
||||
value1: 'bar',
|
||||
value2: undefined,
|
||||
isDivergent: true
|
||||
}]
|
||||
}]);
|
||||
});
|
||||
|
||||
it('still keeps missing values as undefined when using a template', function() {
|
||||
|
||||
var factTemplate =
|
||||
{ hasTemplate:
|
||||
function() {
|
||||
return true;
|
||||
},
|
||||
render:
|
||||
function(fact) {
|
||||
return fact.value;
|
||||
}
|
||||
};
|
||||
|
||||
var facts = factData([{ 'name': 'foo',
|
||||
'value': 'bar'
|
||||
}]);
|
||||
|
||||
var result = compareFacts(facts[0], facts[1],
|
||||
options({ compareKey: ['value'],
|
||||
factTemplate: factTemplate
|
||||
}));
|
||||
|
||||
expect(result).to.deep.equal(
|
||||
[{ displayKeyPath: 'foo',
|
||||
containsValueArray: false,
|
||||
nestingLevel: 0,
|
||||
facts:
|
||||
{ keyName: 'foo',
|
||||
value1: 'bar',
|
||||
value2: undefined
|
||||
}
|
||||
}]);
|
||||
});
|
||||
|
||||
it('includes given compare keys from basisFacts', function() {
|
||||
var facts = factData([{ 'name': 'foo',
|
||||
'value': 'bar',
|
||||
'extra': 'doo'
|
||||
}]);
|
||||
|
||||
var result = compareFacts(facts[0], facts[1],
|
||||
options({ compareKey: ['value', 'extra']
|
||||
}));
|
||||
|
||||
expect(result).to.deep.equal(
|
||||
[{ displayKeyPath: 'foo',
|
||||
containsValueArray: false,
|
||||
nestingLevel: 0,
|
||||
facts:
|
||||
[{ keyName: 'value',
|
||||
value1: 'bar',
|
||||
value2: undefined,
|
||||
isDivergent: true
|
||||
},
|
||||
{ keyName: 'extra',
|
||||
value1: 'doo',
|
||||
value2: undefined,
|
||||
isDivergent: true
|
||||
}]
|
||||
}]);
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe('when value for nameKey exists multiple times in a single collection', function() {
|
||||
|
||||
context('with differences between any of the values', function() {
|
||||
|
||||
it('includes rendered values as array for value properties', function() {
|
||||
|
||||
var factTemplate =
|
||||
{ hasTemplate:
|
||||
function() {
|
||||
return true;
|
||||
},
|
||||
render: function(fact) {
|
||||
return fact.version;
|
||||
}
|
||||
};
|
||||
|
||||
var result = compareFacts(
|
||||
{ position: 'left',
|
||||
facts:
|
||||
[{ 'name': 'some-package',
|
||||
'version': 'abcd'
|
||||
},
|
||||
{ 'name': 'some-package',
|
||||
'version': 'efgh'
|
||||
}]
|
||||
},
|
||||
{ position: 'right',
|
||||
facts:
|
||||
[{ 'name': 'some-package',
|
||||
'version': 'abcd'
|
||||
},
|
||||
{ 'name': 'some-package',
|
||||
'version': 'ijkl'
|
||||
}]
|
||||
|
||||
}, options({ compareKey: ['value'],
|
||||
factTemplate: factTemplate,
|
||||
supportsValueArray: true
|
||||
}));
|
||||
|
||||
expect(result[0].containsValueArray).to.equal(true);
|
||||
expect(result[0].facts).to.deep.equal(
|
||||
{ keyName: 'some-package',
|
||||
value1: ['abcd', 'efgh'],
|
||||
value2: ['abcd', 'ijkl']
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
context('with no differences between any of the values', function() {
|
||||
|
||||
it('does not include the property at all', function() {
|
||||
var expectation;
|
||||
var factTemplate =
|
||||
{ hasTemplate:
|
||||
function() {
|
||||
return true;
|
||||
},
|
||||
render: function(fact) {
|
||||
return fact.version;
|
||||
}
|
||||
};
|
||||
|
||||
var result = compareFacts(
|
||||
{ position: 'left',
|
||||
facts:
|
||||
[{ 'name': 'some-package',
|
||||
'version': 'abcd'
|
||||
},
|
||||
{ 'name': 'some-package',
|
||||
'version': 'efgh'
|
||||
}]
|
||||
},
|
||||
{ position: 'right',
|
||||
facts:
|
||||
[{ 'name': 'some-package',
|
||||
'version': 'abcd'
|
||||
},
|
||||
{ 'name': 'some-package',
|
||||
'version': 'efgh'
|
||||
}]
|
||||
|
||||
}, options({ compareKey: ['value'],
|
||||
factTemplate: factTemplate,
|
||||
supportsValueArray: true
|
||||
}));
|
||||
|
||||
// Use assignment to avoid jshint warning
|
||||
expectation = expect(result).to.be.empty;
|
||||
});
|
||||
|
||||
it('is insensitive to the order of the facts', function() {
|
||||
var expectation;
|
||||
var factTemplate =
|
||||
{ hasTemplate:
|
||||
function() {
|
||||
return true;
|
||||
},
|
||||
render: function(fact) {
|
||||
return fact.version;
|
||||
}
|
||||
};
|
||||
|
||||
var result = compareFacts(
|
||||
{ position: 'left',
|
||||
facts:
|
||||
[{ 'name': 'some-package',
|
||||
'version': 'efgh'
|
||||
},
|
||||
{ 'name': 'some-package',
|
||||
'version': 'abcd'
|
||||
}]
|
||||
},
|
||||
{ position: 'right',
|
||||
facts:
|
||||
[{ 'name': 'some-package',
|
||||
'version': 'abcd'
|
||||
},
|
||||
{ 'name': 'some-package',
|
||||
'version': 'efgh'
|
||||
}]
|
||||
|
||||
}, options({ compareKey: ['value'],
|
||||
factTemplate: factTemplate,
|
||||
supportsValueArray: true
|
||||
}));
|
||||
|
||||
// Use assignment to avoid jshint warning
|
||||
expectation = expect(result).to.be.empty;
|
||||
});
|
||||
|
||||
|
||||
});
|
||||
});
|
||||
|
||||
context('with factTemplate', function() {
|
||||
var factData;
|
||||
|
||||
beforeEach(function() {
|
||||
factData = [{ position: 'left',
|
||||
facts:
|
||||
[{ 'name': 'foo',
|
||||
'value': 'bar'
|
||||
}]
|
||||
},
|
||||
{ position: 'right',
|
||||
facts:
|
||||
[{ 'name': 'foo',
|
||||
'value': 'baz'
|
||||
}]
|
||||
}];
|
||||
});
|
||||
|
||||
it('renders the template with each provided fact', function() {
|
||||
|
||||
var renderCalledWith = [];
|
||||
var factTemplate =
|
||||
{ render: function(fact) {
|
||||
renderCalledWith.push(fact);
|
||||
},
|
||||
hasTemplate: function() { return true; },
|
||||
template: ""
|
||||
};
|
||||
|
||||
compareFacts(factData[0], factData[1],
|
||||
options({ compareKey: ['value'],
|
||||
factTemplate: factTemplate
|
||||
}));
|
||||
|
||||
expect(renderCalledWith).to.include(factData[0].facts[0]);
|
||||
expect(renderCalledWith).to.include(factData[1].facts[0]);
|
||||
});
|
||||
|
||||
|
||||
});
|
||||
});
|
||||
@@ -1,153 +0,0 @@
|
||||
/* jshint node: true */
|
||||
|
||||
import '../../support/node';
|
||||
|
||||
import compareFacts from '../../../src/system-tracking/compare-facts/nested';
|
||||
|
||||
describe('CompareFacts.Nested', function() {
|
||||
|
||||
it('returns empty array with no fact data', function() {
|
||||
var result = compareFacts({ facts: [] }, { facts: [] });
|
||||
|
||||
expect(result).to.deep.equal([]);
|
||||
});
|
||||
|
||||
it('returns empty array when no differences', function() {
|
||||
var result = compareFacts(
|
||||
{ facts:
|
||||
{ 'testing_facts':
|
||||
{ 'foo': 'bar'
|
||||
}
|
||||
}
|
||||
},
|
||||
{ facts:
|
||||
{ 'testing_facts':
|
||||
{ 'foo': 'bar'
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
expect(result).to.deep.equal([]);
|
||||
});
|
||||
|
||||
context('when only left set has data', function() {
|
||||
|
||||
it('returns values with data for value1 and "absent" for value2', function() {
|
||||
|
||||
var result = compareFacts(
|
||||
{ position: 'left',
|
||||
facts:
|
||||
{ 'testing_facts':
|
||||
{ 'foo': 'bar'
|
||||
}
|
||||
}
|
||||
},
|
||||
{ position: 'right',
|
||||
facts:
|
||||
{}
|
||||
});
|
||||
|
||||
expect(result[0].facts).to.contain
|
||||
.an.item
|
||||
.with.property('value1', 'bar');
|
||||
|
||||
expect(result[0].facts).to.contain
|
||||
.an.item
|
||||
.with.property('value2', 'absent');
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
context('when only right set has data', function() {
|
||||
|
||||
it('returns values with data for value2 and "absent" for value1', function() {
|
||||
|
||||
var result = compareFacts(
|
||||
{ position: 'left',
|
||||
facts:
|
||||
{}
|
||||
},
|
||||
{ position: 'right',
|
||||
facts:
|
||||
{ 'testing_facts':
|
||||
{ 'foo': 'bar'
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
expect(result).not.to.be.empty;
|
||||
|
||||
expect(result[0].facts).to.contain
|
||||
.an.item
|
||||
.with.property('value1', 'absent');
|
||||
|
||||
expect(result[0].facts).to.contain
|
||||
.an.item
|
||||
.with.property('value2', 'bar');
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
context('when both sets have fact data and differences exist', function() {
|
||||
|
||||
it('does not consider false values "absent"', function() {
|
||||
var result = compareFacts(
|
||||
{ position: 'left',
|
||||
facts:
|
||||
{ 'testing_facts':
|
||||
{ 'foo': false
|
||||
}
|
||||
}
|
||||
},
|
||||
{ position: 'right',
|
||||
facts:
|
||||
{ 'testing_facts':
|
||||
{ 'foo': true
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
expect(result[0].facts).to.contain
|
||||
.an.item
|
||||
.with.property('value1', false);
|
||||
|
||||
expect(result[0].facts).to.contain
|
||||
.an.item
|
||||
.with.property('value2', true);
|
||||
});
|
||||
|
||||
it('uses "absent" for both values when neither has data', function() {
|
||||
var result = compareFacts(
|
||||
{ position: 'left',
|
||||
facts:
|
||||
{ 'testing_facts':
|
||||
{ 'foo': 'baz',
|
||||
'blah': null
|
||||
}
|
||||
}
|
||||
},
|
||||
{ position: 'right',
|
||||
facts:
|
||||
{ 'testing_facts':
|
||||
{ 'foo': 'bar',
|
||||
'blah': null
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
expect(result[0].facts).to.contain
|
||||
.an.item
|
||||
.with.property('value1', 'absent');
|
||||
|
||||
expect(result[0].facts).to.contain
|
||||
.an.item
|
||||
.with.property('value2', 'absent');
|
||||
|
||||
|
||||
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
@@ -1,77 +0,0 @@
|
||||
import '../support/node';
|
||||
|
||||
import systemTracking from '../../src/system-tracking/data-services/main';
|
||||
import {describeModule} from '../support/describe-module';
|
||||
import moment from '../../src/shared/moment/moment';
|
||||
|
||||
describeModule(systemTracking.name)
|
||||
.testService('factScanDataService', function(test, restStub) {
|
||||
|
||||
var service;
|
||||
|
||||
test.withService(function(_service) {
|
||||
service = _service;
|
||||
});
|
||||
|
||||
it('returns list of versions with search parameters', function() {
|
||||
var version = { result: 'test' };
|
||||
var host_id = 1;
|
||||
var module = 'packages';
|
||||
var start = moment('2015-05-05');
|
||||
var end = moment('2015-05-06');
|
||||
var result = {
|
||||
data: {
|
||||
results: [version]
|
||||
}
|
||||
};
|
||||
var actual, expected;
|
||||
|
||||
var searchParams =
|
||||
{ hostId: host_id,
|
||||
dateRange:
|
||||
{ from: start,
|
||||
to: end
|
||||
},
|
||||
endDate: end,
|
||||
moduleName: module
|
||||
};
|
||||
|
||||
actual = service.getVersion(searchParams);
|
||||
|
||||
expected = _.clone(searchParams);
|
||||
expected.versions = [version];
|
||||
|
||||
restStub.succeed(result);
|
||||
restStub.flush();
|
||||
|
||||
return expect(actual).to.eventually.deep.equal(expected);
|
||||
|
||||
});
|
||||
|
||||
it('returns list of facts', function() {
|
||||
var facts = [{}],
|
||||
version = {
|
||||
"module" : "package",
|
||||
"timestamp": '2015-05-07T14:57:37',
|
||||
"related" : {
|
||||
"fact_view" : "/hosts/1/fact_versions/?module=packages&from=2015-05-05T00:00:00-04:00&to=2015-05-06T00:00:00-04:00"
|
||||
}
|
||||
},
|
||||
result = {
|
||||
data: {
|
||||
fact: facts
|
||||
}
|
||||
};
|
||||
|
||||
var actual = service.getFacts(version)
|
||||
.then(function(response) {
|
||||
return response.fact;
|
||||
});
|
||||
|
||||
restStub.succeedAt(version.related.fact_view, result);
|
||||
restStub.flush();
|
||||
|
||||
return expect(actual).to.eventually.equal(facts);
|
||||
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user