/*
* Copyright (c) 2014 DataTorrent, Inc. ALL Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
'use strict';
describe('Directive: dashboard-layouts', function () {
var $rootScope, element, options, childScope, DashboardState, LayoutStorage, $mockModal, $mockTimeout, toFn;
// mock UI Sortable
beforeEach(function () {
angular.module('ui.sortable', []);
});
// load the directive's module
beforeEach(module('ui.dashboard', function($provide) {
$mockModal = {
open: function() {}
};
$mockTimeout = function(fn, delay) {
toFn = fn;
};
$provide.value('$uibModal', $mockModal);
$provide.value('$timeout', $mockTimeout);
}));
beforeEach(inject(function ($compile, _$rootScope_, _DashboardState_, _LayoutStorage_) {
// services
$rootScope = _$rootScope_;
DashboardState = _DashboardState_;
LayoutStorage = _LayoutStorage_;
// options
var widgetDefinitions = [
{
name: 'wt-one',
template: '
{{2 + 2}}
'
},
{
name: 'wt-two',
template: '{{value}}'
}
];
var defaultWidgets = _.clone(widgetDefinitions);
$rootScope.dashboardOptions = options = {
widgetButtons: true,
widgetDefinitions: widgetDefinitions,
defaultLayouts: [
{
title: 'first',
active: true,
defaultWidgets: defaultWidgets
},
{
title: 'second',
active: false,
defaultWidgets: defaultWidgets
}
],
defaultWidgets: defaultWidgets,
storage: {
setItem: function(key, val) {
},
getItem: function(key) {
},
removeItem: function(key) {
}
}
};
$rootScope.value = 10;
// element setup
element = $compile('')($rootScope);
$rootScope.$digest();
childScope = element.scope();
}));
it('should not require storage', inject(function($compile) {
delete $rootScope.dashboardOptions.storage;
expect(function() {
var noStorageEl = $compile('')($rootScope);
$rootScope.$digest();
}).not.toThrow();
}));
it('should be able to use a different dashboard-layouts template', inject(function($compile, $templateCache) {
$templateCache.put(
'myCustomTemplate.html',
'' +
''
);
var customElement = $compile('')($rootScope);
$rootScope.$digest();
expect(customElement.find('ul.my-custom-tabs').length).toEqual(1);
}));
it('should set the first dashboard to active if there is not one already active', inject(function($compile) {
options.defaultLayouts[0].active = options.defaultLayouts[1].active = false;
element = $compile('')($rootScope);
$rootScope.$digest();
childScope = element.scope();
var layouts = childScope.layouts;
var active;
for (var i = 0; i < layouts.length; i++) {
if (layouts[i].active) {
active = layouts[i];
break;
}
};
expect(active).not.toBeUndefined();
}));
describe('the createNewLayout method', function() {
it('should call the add and save methods of LayoutStorage', function() {
spyOn(LayoutStorage.prototype, 'add');
spyOn(LayoutStorage.prototype, 'save');
childScope.createNewLayout();
expect(LayoutStorage.prototype.add).toHaveBeenCalled();
expect(LayoutStorage.prototype.save).toHaveBeenCalled();
});
it('should return the newly created layout object', function() {
var result = childScope.createNewLayout();
expect(typeof result).toEqual('object');
});
it('should set active=true on the newly created layout', function() {
var result = childScope.createNewLayout();
expect(result.active).toEqual(true);
});
it('should set defaultWidgets to dashboardOptions.defaultWidgets if it is present', function() {
var result = childScope.createNewLayout();
expect(result.defaultWidgets === options.defaultWidgets).toEqual(true);
});
it('should set defaultWidgets to an empty array if dashboardOptions.defaultWidgets is not present', inject(function($compile) {
delete options.defaultWidgets;
element = $compile('')($rootScope);
$rootScope.$digest();
childScope = element.scope();
var result = childScope.createNewLayout();
expect(result.defaultWidgets).toEqual([]);
}));
});
describe('the removeLayout method', function() {
it('should call the remove and save methods of LayoutStorage', function() {
spyOn(LayoutStorage.prototype, 'remove');
spyOn(LayoutStorage.prototype, 'save');
childScope.removeLayout(childScope.layouts[0]);
expect(LayoutStorage.prototype.remove).toHaveBeenCalled();
expect(LayoutStorage.prototype.save).toHaveBeenCalled();
});
it('should call remove with the layout it was passed', function() {
spyOn(LayoutStorage.prototype, 'remove');
var layout = childScope.layouts[0];
childScope.removeLayout(layout);
expect(LayoutStorage.prototype.remove.calls.argsFor(0)[0]).toEqual(layout);
});
});
describe('the makeLayoutActive method', function() {
it('should call _makeLayoutActive if there is not a currently active dashboard with unsaved changes', function() {
spyOn(childScope, '_makeLayoutActive');
var layout = childScope.layouts[1];
childScope.makeLayoutActive(layout);
expect(childScope._makeLayoutActive).toHaveBeenCalled();
});
describe('when there are unsaved changes on the current dashboard', function() {
var current, options, successCb, errorCb, layout;
beforeEach(function() {
current = childScope.layouts[0];
current.dashboard.unsavedChangeCount = 1;
spyOn($mockModal, 'open').and.callFake(function(arg) {
options = arg;
return {
result: {
then: function(success, error) {
successCb = success;
errorCb = error;
}
}
}
});
layout = childScope.layouts[1];
childScope.makeLayoutActive(layout);
});
it('should create a modal', function() {
expect($mockModal.open).toHaveBeenCalled();
});
it('should resolve layout to the layout to be made active', function() {
expect(options.resolve.layout()).toEqual(layout);
});
it('should provide a success callback that saves the current dashboard and then calls _makeLayoutActive', function() {
spyOn(current.dashboard, 'saveDashboard');
spyOn(childScope, '_makeLayoutActive');
successCb();
expect(current.dashboard.saveDashboard).toHaveBeenCalled();
expect(childScope._makeLayoutActive).toHaveBeenCalled();
expect(childScope._makeLayoutActive.calls.argsFor(0)[0]).toEqual(layout);
});
it('should provide an error callback that only calls _makeLayoutActive', function() {
spyOn(current.dashboard, 'saveDashboard');
spyOn(childScope, '_makeLayoutActive');
errorCb();
expect(current.dashboard.saveDashboard).not.toHaveBeenCalled();
expect(childScope._makeLayoutActive).toHaveBeenCalled();
expect(childScope._makeLayoutActive.calls.argsFor(0)[0]).toEqual(layout);
});
});
});
describe('the editTitle method', function() {
it('should set the editingTitle attribute to true on the layout it is passed', function() {
var layout = { id: '1' };
childScope.editTitle(layout);
$rootScope.$digest();
expect(layout.editingTitle).toEqual(true);
toFn();
});
});
describe('the saveTitleEdit method', function() {
it('should set editingTitle to false', function() {
var layout = { id: '1' };
childScope.saveTitleEdit(layout);
expect(layout.editingTitle).toEqual(false);
});
it('should call layoutStorage.save', function() {
var layout = { id: '1' };
spyOn(LayoutStorage.prototype, 'save').and.callThrough();
childScope.saveTitleEdit(layout);
expect(LayoutStorage.prototype.save).toHaveBeenCalled();
});
});
describe('the saveLayouts method', function() {
it('should call LayoutStorage.save', function() {
spyOn(LayoutStorage.prototype, 'save').and.callThrough();
$rootScope.dashboardOptions.saveLayouts();
expect(LayoutStorage.prototype.save).toHaveBeenCalled();
});
it('should call LayoutStorage.save with true as the first arg', function() {
spyOn(LayoutStorage.prototype, 'save').and.callThrough();
$rootScope.dashboardOptions.saveLayouts();
expect(LayoutStorage.prototype.save.calls.argsFor(0)[0]).toEqual(true);
});
});
describe('the proxy methods to active layout', function() {
var mockDash, galSpy;
beforeEach(function() {
mockDash = {
active: true,
dashboard: {
addWidget: function() {},
loadWidgets: function() {},
saveDashboard: function() {}
}
};
spyOn(mockDash.dashboard, 'addWidget');
spyOn(mockDash.dashboard, 'loadWidgets');
spyOn(mockDash.dashboard, 'saveDashboard');
galSpy = spyOn(LayoutStorage.prototype, 'getActiveLayout').and;
galSpy.returnValue(mockDash);
});
describe('the addWidget method', function() {
it('should call dashboard.addWidget method of the active layout', function() {
options.addWidget(1,2,3);
expect(mockDash.dashboard.addWidget).toHaveBeenCalled();
var firstCall = mockDash.dashboard.addWidget.calls.first();
expect(firstCall.object).toEqual(mockDash.dashboard);
expect(firstCall.args).toEqual([1,2,3]);
});
it('should do nothing if there is no active layout', function() {
galSpy.returnValue(null);
expect(function() {
options.addWidget();
}).not.toThrow();
});
});
describe('the loadWidgets method', function() {
it('should call dashboard.loadWidgets of the current layout', function() {
options.loadWidgets(1,2,3);
expect(mockDash.dashboard.loadWidgets).toHaveBeenCalled();
var firstCall = mockDash.dashboard.loadWidgets.calls.first();
expect(firstCall.object).toEqual(mockDash.dashboard);
expect(firstCall.args).toEqual([1,2,3]);
});
it('should do nothing if there is no active layout', function() {
galSpy.returnValue(null);
expect(function() {
options.loadWidgets();
}).not.toThrow();
});
});
describe('the saveDashboard method', function() {
it('should call dashboard.saveDashboard of the current layout', function() {
options.saveDashboard(1,2,3);
expect(mockDash.dashboard.saveDashboard).toHaveBeenCalled();
var firstCall = mockDash.dashboard.saveDashboard.calls.first();
expect(firstCall.object).toEqual(mockDash.dashboard);
expect(firstCall.args).toEqual([1,2,3]);
});
it('should do nothing if there is no active layout', function() {
galSpy.returnValue(null);
expect(function() {
options.saveDashboard();
}).not.toThrow();
});
});
});
});