blob: 7e58ad03a714f2d6ed5162563ab7255d83d95854 [file] [log] [blame]
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.
*/
var App = require('app');
var testHelpers = require('test/helpers');
require('router');
describe('App.Router', function () {
var router = App.Router.create();
describe('#initAdmin()', function () {
var cases = [
{
user: {
admin: true
},
isAdmin: true,
isOperator: false,
isPermissionDataLoaded: true,
title: 'admin'
},
{
user: {
operator: true
},
isAdmin: false,
isOperator: true,
isPermissionDataLoaded: true,
title: 'operator'
},
{
user: {},
isAdmin: false,
isOperator: false,
isPermissionDataLoaded: true,
title: 'read only access'
},
{
user: null,
isAdmin: false,
isOperator: false,
isPermissionDataLoaded: false,
title: 'no user'
}
];
beforeEach(function () {
this.getUser = sinon.stub(App.db, 'getUser');
App.setProperties({
isAdmin: false,
isOperator: false,
isPermissionDataLoaded: false
});
});
afterEach(function () {
this.getUser.restore();
});
cases.forEach(function (item) {
it(item.title, function () {
this.getUser.returns(item.user);
router.initAdmin();
expect(App.get('isAdmin')).to.equal(item.isAdmin);
expect(App.get('isOperator')).to.equal(item.isOperator);
expect(App.get('isPermissionDataLoaded')).to.equal(item.isPermissionDataLoaded);
});
});
});
describe('#adminViewInfoSuccessCallback', function () {
beforeEach(function () {
sinon.stub(window.location, 'replace', Em.K);
});
afterEach(function () {
window.location.replace.restore();
});
var tests = [{
mockData: {
components: [{
'RootServiceComponents': {
'component_version': '1.9.0'
}
}, {
'RootServiceComponents': {
'component_version': '2.0.0_MyBuild'
}
}]
},
expected: '/views/ADMIN_VIEW/2.0.0/INSTANCE/#/'
}, {
mockData: {
components: [{
'RootServiceComponents': {
'component_version': '1.9.0'
}
}, {
'RootServiceComponents': {
'component_version': '2.1.0'
}
}, {
'RootServiceComponents': {
'component_version': '2.0.0'
}
}]
},
expected: '/views/ADMIN_VIEW/2.1.0/INSTANCE/#/'
}, {
mockData: {
components: [{
'RootServiceComponents': {
component_version: '2.1.0_MyBuild'
}
}]
},
expected: '/views/ADMIN_VIEW/2.1.0/INSTANCE/#/'
}];
tests.forEach(function (data, index) {
it('should redirect to the latest version of admin view ("' + data.expected + '") #' + (index + 1), function () {
router.adminViewInfoSuccessCallback(data.mockData);
expect(window.location.replace.calledWith(data.expected)).to.be.true;
});
});
});
describe.skip("#savePreferedPath()", function () {
beforeEach(function () {
router.set('preferedPath', null);
});
it("has no key", function () {
router.savePreferedPath('path');
expect(router.get('preferedPath')).to.equal('path');
});
it("path does not contain key", function () {
router.savePreferedPath('path', 'key');
expect(router.get('preferedPath')).to.be.null;
});
it("path contains key", function () {
router.savePreferedPath('key=path', 'key=');
expect(router.get('preferedPath')).to.equal('path');
});
});
describe.skip("#restorePreferedPath()", function () {
it("preferedPath is null", function () {
router.set('preferedPath', null);
expect(router.restorePreferedPath()).to.be.false;
expect(router.get('preferedPath')).to.be.null;
});
it("preferedPath is '/relativeURL'", function () {
router.set('preferedPath', '/relativeURL');
expect(router.restorePreferedPath()).to.be.true;
expect(router.get('preferedPath')).to.be.null;
});
it("preferedPath is '#/relativeURL'", function () {
router.set('preferedPath', '#/relativeURL');
expect(router.restorePreferedPath()).to.be.true;
expect(router.get('preferedPath')).to.be.null;
});
it("preferedPath is '#/login'", function () {
router.set('preferedPath', '#/login');
expect(router.restorePreferedPath()).to.be.false;
expect(router.get('preferedPath')).to.be.null;
});
it("preferedPath is 'http://absoluteURL'", function () {
router.set('preferedPath', 'http://absoluteURL');
expect(router.restorePreferedPath()).to.be.false;
expect(router.get('preferedPath')).to.be.null;
});
});
describe.skip("#loginGetClustersSuccessCallback()", function () {
var mock = {dataLoading: Em.K};
beforeEach(function () {
sinon.stub(router, 'setClusterInstalled', Em.K);
sinon.stub(router, 'transitionToApp', Em.K);
sinon.stub(router, 'transitionToViews', Em.K);
sinon.stub(router, 'transitionToAdminView', Em.K);
sinon.stub(App.router, 'get').returns(mock);
sinon.spy(mock, 'dataLoading');
App.setProperties({
isAdmin: false,
isOperator: false,
isPermissionDataLoaded: false
});
});
afterEach(function () {
router.setClusterInstalled.restore();
router.transitionToApp.restore();
router.transitionToViews.restore();
router.transitionToAdminView.restore();
App.router.get.restore();
mock.dataLoading.restore();
});
it("cluster exists, OPERATOR privileges", function () {
var clusterData = {
items: [{
Clusters: {
cluster_name: 'c1'
}
}]
};
var params = {
loginData: {
privileges: [{
PrivilegeInfo: {
cluster_name: 'c1',
permission_name: 'CLUSTER.ADMINISTRATOR'
}
}]
}
};
router.loginGetClustersSuccessCallback(clusterData, {}, params);
expect(router.setClusterInstalled.calledWith(clusterData)).to.be.true;
expect(router.transitionToApp.calledOnce).to.be.true;
expect(App.get('isAdmin')).to.be.true;
expect(App.get('isOperator')).to.be.true;
expect(App.get('isPermissionDataLoaded')).to.be.true;
expect(mock.dataLoading.calledOnce).to.be.true;
});
it("cluster exists, READ privileges", function () {
var clusterData = {
items: [{
Clusters: {
cluster_name: 'c1'
}
}]
};
var params = {
loginData: {
privileges: [{
PrivilegeInfo: {
cluster_name: 'c1',
permission_name: 'CLUSTER.USER'
}
}]
}
};
router.loginGetClustersSuccessCallback(clusterData, {}, params);
expect(router.setClusterInstalled.calledWith(clusterData)).to.be.true;
expect(router.transitionToApp.calledOnce).to.be.true;
expect(App.get('isAdmin')).to.be.false;
expect(App.get('isOperator')).to.be.false;
expect(App.get('isPermissionDataLoaded')).to.be.true;
expect(mock.dataLoading.calledOnce).to.be.true;
});
it("cluster exists, ADMIN privileges", function () {
var clusterData = {
items: [{
Clusters: {
cluster_name: 'c1'
}
}]
};
var params = {
loginData: {
privileges: [{
PrivilegeInfo: {
cluster_name: 'c1',
permission_name: 'AMBARI.ADMINISTRATOR'
}
}]
}
};
router.loginGetClustersSuccessCallback(clusterData, {}, params);
expect(router.setClusterInstalled.calledWith(clusterData)).to.be.true;
expect(router.transitionToApp.calledOnce).to.be.true;
expect(App.get('isAdmin')).to.be.true;
expect(App.get('isOperator')).to.be.false;
expect(App.get('isPermissionDataLoaded')).to.be.true;
expect(mock.dataLoading.calledOnce).to.be.true;
});
it("cluster exists, no privileges", function () {
var clusterData = {
items: [{
Clusters: {
cluster_name: 'c1'
}
}]
};
var params = {
loginData: {
privileges: []
}
};
router.loginGetClustersSuccessCallback(clusterData, {}, params);
expect(router.setClusterInstalled.calledWith(clusterData)).to.be.true;
expect(router.transitionToViews.calledOnce).to.be.true;
expect(App.get('isAdmin')).to.be.false;
expect(App.get('isOperator')).to.be.false;
expect(App.get('isPermissionDataLoaded')).to.be.true;
expect(mock.dataLoading.calledOnce).to.be.true;
});
it("cluster not installed, ADMIN privileges", function () {
var clusterData = {
items: []
};
var params = {
loginData: {
privileges: [{
PrivilegeInfo: {
cluster_name: 'c1',
permission_name: 'AMBARI.ADMINISTRATOR'
}
}]
}
};
router.loginGetClustersSuccessCallback(clusterData, {}, params);
expect(router.transitionToAdminView.calledOnce).to.be.true;
expect(App.get('isAdmin')).to.be.true;
expect(App.get('isOperator')).to.be.false;
expect(App.get('isPermissionDataLoaded')).to.be.true;
expect(mock.dataLoading.calledOnce).to.be.true;
});
it("cluster not installed, non-admin privileges", function () {
var clusterData = {
items: []
};
var params = {
loginData: {
privileges: []
}
};
router.loginGetClustersSuccessCallback(clusterData, {}, params);
expect(router.transitionToViews.calledOnce).to.be.true;
expect(App.get('isAdmin')).to.be.false;
expect(App.get('isOperator')).to.be.false;
expect(App.get('isPermissionDataLoaded')).to.be.true;
expect(mock.dataLoading.calledOnce).to.be.true;
});
});
describe("#transitionToAdminView()", function () {
it("valid request is sent", function () {
router.transitionToAdminView();
var args = testHelpers.findAjaxRequest('name', 'ambari.service.load_server_version');
expect(args[0]).to.exists;
});
});
describe("#transitionToApp()", function () {
beforeEach(function () {
this.mock = sinon.stub(router, 'restorePreferedPath');
sinon.stub(router, 'getSection', function (callback) {
callback('route');
});
sinon.stub(router, 'transitionTo');
});
afterEach(function () {
this.mock.restore();
router.getSection.restore();
router.transitionTo.restore();
});
it("has restore path", function () {
this.mock.returns(true);
router.transitionToApp();
expect(router.getSection.called).to.be.false;
expect(router.transitionTo.called).to.be.false;
});
it("does not have restore path", function () {
this.mock.returns(false);
router.transitionToApp();
expect(router.getSection.calledOnce).to.be.true;
expect(router.transitionTo.calledWith('route')).to.be.true;
});
});
describe("#transitionToViews()", function () {
var mock = {loadAmbariViews: Em.K};
beforeEach(function () {
sinon.stub(App.router, 'get').returns(mock);
sinon.stub(router, 'transitionTo');
sinon.spy(mock, 'loadAmbariViews');
});
afterEach(function () {
App.router.get.restore();
router.transitionTo.restore();
mock.loadAmbariViews.restore();
});
it("transitionTo called with corrent route", function () {
router.transitionToViews();
expect(mock.loadAmbariViews.calledOnce).to.be.true;
expect(router.transitionTo.calledWith('main.views.index')).to.be.true;
});
});
describe("#adminViewInfoErrorCallback()", function () {
beforeEach(function () {
sinon.stub(router, 'transitionToViews');
});
afterEach(function () {
router.transitionToViews.restore();
});
it("transitionToViews called once", function () {
router.adminViewInfoErrorCallback();
expect(router.transitionToViews.calledOnce).to.be.true;
});
});
describe("#getAuthenticated", function () {
beforeEach(function () {
router = App.Router.create();
this.mockGetCurrentLocationUrl = sinon.stub(router, 'getCurrentLocationUrl');
sinon.stub(router, 'redirectByURL', Em.K);
});
afterEach(function () {
router.getCurrentLocationUrl.restore();
router.redirectByURL.restore();
this.mockGetCurrentLocationUrl.restore();
});
[
{
lastSetURL: '/login/local',
isResolved: false,
responseData: {
responseText: "",
status: 403
},
redirectCalled: false,
m: 'no jwtProviderUrl in auth response, no redirect'
},
{
lastSetURL: '/main/dashboard',
isResolved: false,
responseData: {
responseText: JSON.stringify({jwtProviderUrl: 'http://some.com?originalUrl='}),
status: 403
},
redirectCalled: true,
m: 'jwtProviderUrl is present, current location not local login url, redirect according to jwtProviderUrl value'
},
{
lastSetURL: '/login/local',
isResolved: false,
responseData: {
responseText: JSON.stringify({jwtProviderUrl: 'http://some.com?originalUrl='}),
status: 403
},
redirectCalled: false,
m: 'jwtProviderUrl is present, current location is local login url, no redirect'
}
].forEach(function (test) {
describe(test.m, function () {
var mockCurrentUrl;
beforeEach(function () {
mockCurrentUrl = 'http://localhost:3333/#/some/hash';
router.set('location.lastSetURL', test.lastSetURL);
App.ajax.send.restore(); // default ajax-mock can't be used here
sinon.stub(App.ajax, 'send', function () {
if (!test.isResolved) {
router.onAuthenticationError(test.responseData);
}
return {
complete: function () {
}
};
});
this.mockGetCurrentLocationUrl.returns(mockCurrentUrl);
router.getAuthenticated();
});
it('redirectByURL is ' + (test.redirectCalled ? '' : 'not') + ' called', function () {
expect(router.redirectByURL.calledOnce).to.be.eql(test.redirectCalled);
});
if (test.redirectCalled) {
it('redirectByURL is correct', function () {
expect(router.redirectByURL.args[0][0]).to.be.eql(JSON.parse(test.responseData.responseText).jwtProviderUrl + encodeURIComponent(mockCurrentUrl));
});
}
});
});
});
describe('#setClusterData', function () {
var data = {
loginName: 'user',
loginData: {
PrivilegeInfo: {}
}
},
clusterData = {
items: []
},
cases = [
{
clusterData: clusterData,
callbackCallCount: 1,
isAjaxCalled: false,
title: 'cluster data available'
},
{
clusterData: null,
callbackCallCount: 0,
isAjaxCalled: true,
title: 'no cluster data'
}
];
beforeEach(function () {
sinon.stub(router, 'loginGetClustersSuccessCallback', Em.K);
});
afterEach(function () {
router.loginGetClustersSuccessCallback.restore();
});
cases.forEach(function (item) {
describe(item.title, function () {
var ajaxCallArgs;
beforeEach(function () {
router.set('clusterData', item.clusterData);
router.setClusterData({}, {}, data);
ajaxCallArgs = testHelpers.findAjaxRequest('name', 'router.login.clusters');
});
it('loginGetClustersSuccessCallback', function () {
expect(router.loginGetClustersSuccessCallback.callCount).to.equal(item.callbackCallCount);
});
if (item.isAjaxCalled) {
it('App.ajax.send is called', function () {
expect(ajaxCallArgs).to.have.length(1);
});
it('data for AJAX request', function () {
expect(ajaxCallArgs).to.eql([
{
name: 'router.login.clusters',
sender: router,
data: data,
success: 'loginGetClustersSuccessCallback'
}
]);
});
} else {
it('App.ajax.send is not called', function () {
expect(ajaxCallArgs).to.be.undefined;
});
it('arguments for callback', function () {
expect(router.loginGetClustersSuccessCallback.firstCall.args).to.eql([clusterData, {}, data]);
});
}
});
});
});
});
describe('App.StepRoute', function () {
beforeEach(function () {
this.route = App.StepRoute.create();
this.nextTransitionSpy = sinon.spy(this.route, 'nextTransition');
this.backTransitionSpy = sinon.spy(this.route, 'backTransition');
this.appGetStub = sinon.stub(App, 'get');
this.appSetStub = sinon.stub(App, 'set');
this.runNextStub = sinon.stub(Em.run, 'next', Em.clb);
});
afterEach(function () {
this.nextTransitionSpy.restore();
this.backTransitionSpy.restore();
this.appGetStub.restore();
this.appSetStub.restore();
this.runNextStub.restore();
});
describe('#back', function () {
[
{
btnClickInProgress: true,
backBtnClickInProgressIsSet: false,
backTransitionIsCalled: false,
m: 'backTransition is not called'
},
{
btnClickInProgress: false,
backBtnClickInProgressIsSet: true,
backTransitionIsCalled: true,
m: 'backTransition is called'
}
].forEach(function (test) {
describe(test.m, function () {
beforeEach(function () {
this.appGetStub.withArgs('router.btnClickInProgress').returns(test.btnClickInProgress);
this.route.back({});
});
it('backTransition call', function () {
expect(this.backTransitionSpy.called).to.be.equal(test.backTransitionIsCalled);
});
it('backBtnClickInProgress is set', function () {
expect(this.appSetStub.calledWith('router.backBtnClickInProgress')).to.be.equal(test.backBtnClickInProgressIsSet);
});
});
});
});
describe('#next', function () {
[
{
btnClickInProgress: true,
nextBtnClickInProgressIsSet: false,
nextTransitionIsCalled: false,
m: 'nextTransition is not called'
},
{
btnClickInProgress: false,
nextBtnClickInProgressIsSet: true,
nextTransitionIsCalled: true,
m: 'nextTransition is called'
}
].forEach(function (test) {
describe(test.m, function () {
beforeEach(function () {
this.appGetStub.withArgs('router.btnClickInProgress').returns(test.btnClickInProgress);
this.route.next({});
});
it('nextTransition call', function () {
expect(this.nextTransitionSpy.called).to.be.equal(test.nextTransitionIsCalled);
});
it('nextBtnClickInProgress is set', function () {
expect(this.appSetStub.calledWith('router.nextBtnClickInProgress')).to.be.equal(test.nextBtnClickInProgressIsSet);
});
});
});
});
});