router_test.js 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531
  1. /**
  2. * Licensed to the Apache Software Foundation (ASF) under one
  3. * or more contributor license agreements. See the NOTICE file
  4. * distributed with this work for additional information
  5. * regarding copyright ownership. The ASF licenses this file
  6. * to you under the Apache License, Version 2.0 (the
  7. * "License"); you may not use this file except in compliance
  8. * with the License. You may obtain a copy of the License at
  9. *
  10. * http://www.apache.org/licenses/LICENSE-2.0
  11. *
  12. * Unless required by applicable law or agreed to in writing, software
  13. * distributed under the License is distributed on an "AS IS" BASIS,
  14. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  15. * See the License for the specific language governing permissions and
  16. * limitations under the License.
  17. */
  18. var App = require('app');
  19. require('router');
  20. describe('App.Router', function () {
  21. var router = App.Router.create();
  22. describe.skip('#loginSuccessCallback()', function() {
  23. beforeEach(function () {
  24. sinon.stub(App.usersMapper, 'map');
  25. sinon.stub(router, 'setUserLoggedIn');
  26. sinon.stub(App.ajax, 'send');
  27. });
  28. afterEach(function() {
  29. App.usersMapper.map.restore();
  30. router.setUserLoggedIn.restore();
  31. App.ajax.send.restore();
  32. });
  33. it('should log in user and load views', function () {
  34. var userName = 'test';
  35. router.loginSuccessCallback({},{},{loginName: userName});
  36. expect(router.setUserLoggedIn.calledOnce).to.be.true;
  37. expect(router.setUserLoggedIn.calledWith(userName)).to.be.true;
  38. })
  39. });
  40. describe('#initAdmin()', function () {
  41. var cases = [
  42. {
  43. user: {
  44. admin: true
  45. },
  46. isAdmin: true,
  47. isOperator: false,
  48. isPermissionDataLoaded: true,
  49. title: 'admin'
  50. },
  51. {
  52. user: {
  53. operator: true
  54. },
  55. isAdmin: false,
  56. isOperator: true,
  57. isPermissionDataLoaded: true,
  58. title: 'operator'
  59. },
  60. {
  61. user: {},
  62. isAdmin: false,
  63. isOperator: false,
  64. isPermissionDataLoaded: true,
  65. title: 'read only access'
  66. },
  67. {
  68. user: null,
  69. isAdmin: false,
  70. isOperator: false,
  71. isPermissionDataLoaded: false,
  72. title: 'no user'
  73. }
  74. ];
  75. beforeEach(function () {
  76. this.getUser = sinon.stub(App.db, 'getUser');
  77. App.setProperties({
  78. isAdmin: false,
  79. isOperator: false,
  80. isPermissionDataLoaded: false
  81. });
  82. });
  83. afterEach(function () {
  84. this.getUser.restore();
  85. });
  86. cases.forEach(function (item) {
  87. it(item.title, function () {
  88. this.getUser.returns(item.user);
  89. router.initAdmin();
  90. expect(App.get('isAdmin')).to.equal(item.isAdmin);
  91. expect(App.get('isOperator')).to.equal(item.isOperator);
  92. expect(App.get('isPermissionDataLoaded')).to.equal(item.isPermissionDataLoaded);
  93. });
  94. });
  95. });
  96. describe('#adminViewInfoSuccessCallback', function() {
  97. beforeEach(function() {
  98. sinon.stub(window.location, 'replace', Em.K);
  99. });
  100. afterEach(function() {
  101. window.location.replace.restore();
  102. });
  103. it('should redirect to the latest version of admin view', function() {
  104. var tests = [{
  105. mockData: {
  106. components: [{
  107. 'RootServiceComponents': {
  108. 'component_version': '1.9.0'
  109. }
  110. }, {
  111. 'RootServiceComponents': {
  112. 'component_version': '2.0.0'
  113. }
  114. }]
  115. },
  116. expected: '/views/ADMIN_VIEW/2.0.0/INSTANCE/#/'
  117. }, {
  118. mockData: {
  119. components: [{
  120. 'RootServiceComponents': {
  121. 'component_version': '1.9.0'
  122. }
  123. }, {
  124. 'RootServiceComponents': {
  125. 'component_version': '2.1.0'
  126. }
  127. }, {
  128. 'RootServiceComponents': {
  129. 'component_version': '2.0.0'
  130. }
  131. }]
  132. },
  133. expected: '/views/ADMIN_VIEW/2.1.0/INSTANCE/#/'
  134. }, {
  135. mockData: {
  136. versions: [{
  137. 'RootServiceComponents': {
  138. version: '2.1.0'
  139. }
  140. }]
  141. },
  142. expected: '/views/ADMIN_VIEW/2.1.0/INSTANCE/#/'
  143. }];
  144. tests.forEach(function(data) {
  145. router.adminViewInfoSuccessCallback(data.mockData);
  146. expect(window.location.replace.calledWith(data.expected)).to.be.true;
  147. });
  148. });
  149. });
  150. describe.skip("#savePreferedPath()", function() {
  151. beforeEach(function () {
  152. router.set('preferedPath', null);
  153. });
  154. it("has no key", function() {
  155. router.savePreferedPath('path');
  156. expect(router.get('preferedPath')).to.equal('path');
  157. });
  158. it("path does not contain key", function() {
  159. router.savePreferedPath('path', 'key');
  160. expect(router.get('preferedPath')).to.be.null;
  161. });
  162. it("path contains key", function() {
  163. router.savePreferedPath('key=path', 'key=');
  164. expect(router.get('preferedPath')).to.equal('path');
  165. });
  166. });
  167. describe.skip("#restorePreferedPath()", function() {
  168. it("preferedPath is null", function() {
  169. router.set('preferedPath', null);
  170. expect(router.restorePreferedPath()).to.be.false;
  171. expect(router.get('preferedPath')).to.be.null;
  172. });
  173. it("preferedPath is '/relativeURL'", function() {
  174. router.set('preferedPath', '/relativeURL');
  175. expect(router.restorePreferedPath()).to.be.true;
  176. expect(router.get('preferedPath')).to.be.null;
  177. });
  178. it("preferedPath is '#/relativeURL'", function() {
  179. router.set('preferedPath', '#/relativeURL');
  180. expect(router.restorePreferedPath()).to.be.true;
  181. expect(router.get('preferedPath')).to.be.null;
  182. });
  183. it("preferedPath is '#/login'", function() {
  184. router.set('preferedPath', '#/login');
  185. expect(router.restorePreferedPath()).to.be.false;
  186. expect(router.get('preferedPath')).to.be.null;
  187. });
  188. it("preferedPath is 'http://absoluteURL'", function() {
  189. router.set('preferedPath', 'http://absoluteURL');
  190. expect(router.restorePreferedPath()).to.be.false;
  191. expect(router.get('preferedPath')).to.be.null;
  192. });
  193. });
  194. describe.skip("#loginGetClustersSuccessCallback()", function () {
  195. var mock = {dataLoading: Em.K};
  196. beforeEach(function () {
  197. sinon.stub(router, 'setClusterInstalled', Em.K);
  198. sinon.stub(router, 'transitionToApp', Em.K);
  199. sinon.stub(router, 'transitionToViews', Em.K);
  200. sinon.stub(router, 'transitionToAdminView', Em.K);
  201. sinon.stub(App.router, 'get').returns(mock);
  202. sinon.spy(mock, 'dataLoading');
  203. App.setProperties({
  204. isAdmin: false,
  205. isOperator: false,
  206. isPermissionDataLoaded: false
  207. });
  208. });
  209. afterEach(function () {
  210. router.setClusterInstalled.restore();
  211. router.transitionToApp.restore();
  212. router.transitionToViews.restore();
  213. router.transitionToAdminView.restore();
  214. App.router.get.restore();
  215. mock.dataLoading.restore();
  216. });
  217. it("cluster exists, OPERATOR privileges", function () {
  218. var clusterData = {
  219. items: [{
  220. Clusters: {
  221. cluster_name: 'c1'
  222. }
  223. }]
  224. };
  225. var params = {
  226. loginData: {
  227. privileges: [{
  228. PrivilegeInfo: {
  229. cluster_name: 'c1',
  230. permission_name: 'CLUSTER.ADMINISTRATOR'
  231. }
  232. }]
  233. }
  234. };
  235. router.loginGetClustersSuccessCallback(clusterData, {}, params);
  236. expect(router.setClusterInstalled.calledWith(clusterData)).to.be.true;
  237. expect(router.transitionToApp.calledOnce).to.be.true;
  238. expect(App.get('isAdmin')).to.be.true;
  239. expect(App.get('isOperator')).to.be.true;
  240. expect(App.get('isPermissionDataLoaded')).to.be.true;
  241. expect(mock.dataLoading.calledOnce).to.be.true;
  242. });
  243. it("cluster exists, READ privileges", function () {
  244. var clusterData = {
  245. items: [{
  246. Clusters: {
  247. cluster_name: 'c1'
  248. }
  249. }]
  250. };
  251. var params = {
  252. loginData: {
  253. privileges: [{
  254. PrivilegeInfo: {
  255. cluster_name: 'c1',
  256. permission_name: 'CLUSTER.USER'
  257. }
  258. }]
  259. }
  260. };
  261. router.loginGetClustersSuccessCallback(clusterData, {}, params);
  262. expect(router.setClusterInstalled.calledWith(clusterData)).to.be.true;
  263. expect(router.transitionToApp.calledOnce).to.be.true;
  264. expect(App.get('isAdmin')).to.be.false;
  265. expect(App.get('isOperator')).to.be.false;
  266. expect(App.get('isPermissionDataLoaded')).to.be.true;
  267. expect(mock.dataLoading.calledOnce).to.be.true;
  268. });
  269. it("cluster exists, ADMIN privileges", function () {
  270. var clusterData = {
  271. items: [{
  272. Clusters: {
  273. cluster_name: 'c1'
  274. }
  275. }]
  276. };
  277. var params = {
  278. loginData: {
  279. privileges: [{
  280. PrivilegeInfo: {
  281. cluster_name: 'c1',
  282. permission_name: 'AMBARI.ADMINISTRATOR'
  283. }
  284. }]
  285. }
  286. };
  287. router.loginGetClustersSuccessCallback(clusterData, {}, params);
  288. expect(router.setClusterInstalled.calledWith(clusterData)).to.be.true;
  289. expect(router.transitionToApp.calledOnce).to.be.true;
  290. expect(App.get('isAdmin')).to.be.true;
  291. expect(App.get('isOperator')).to.be.false;
  292. expect(App.get('isPermissionDataLoaded')).to.be.true;
  293. expect(mock.dataLoading.calledOnce).to.be.true;
  294. });
  295. it("cluster exists, no privileges", function () {
  296. var clusterData = {
  297. items: [{
  298. Clusters: {
  299. cluster_name: 'c1'
  300. }
  301. }]
  302. };
  303. var params = {
  304. loginData: {
  305. privileges: []
  306. }
  307. };
  308. router.loginGetClustersSuccessCallback(clusterData, {}, params);
  309. expect(router.setClusterInstalled.calledWith(clusterData)).to.be.true;
  310. expect(router.transitionToViews.calledOnce).to.be.true;
  311. expect(App.get('isAdmin')).to.be.false;
  312. expect(App.get('isOperator')).to.be.false;
  313. expect(App.get('isPermissionDataLoaded')).to.be.true;
  314. expect(mock.dataLoading.calledOnce).to.be.true;
  315. });
  316. it("cluster not installed, ADMIN privileges", function () {
  317. var clusterData = {
  318. items: []
  319. };
  320. var params = {
  321. loginData: {
  322. privileges: [{
  323. PrivilegeInfo: {
  324. cluster_name: 'c1',
  325. permission_name: 'AMBARI.ADMINISTRATOR'
  326. }
  327. }]
  328. }
  329. };
  330. router.loginGetClustersSuccessCallback(clusterData, {}, params);
  331. expect(router.transitionToAdminView.calledOnce).to.be.true;
  332. expect(App.get('isAdmin')).to.be.true;
  333. expect(App.get('isOperator')).to.be.false;
  334. expect(App.get('isPermissionDataLoaded')).to.be.true;
  335. expect(mock.dataLoading.calledOnce).to.be.true;
  336. });
  337. it("cluster not installed, non-admin privileges", function () {
  338. var clusterData = {
  339. items: []
  340. };
  341. var params = {
  342. loginData: {
  343. privileges: []
  344. }
  345. };
  346. router.loginGetClustersSuccessCallback(clusterData, {}, params);
  347. expect(router.transitionToViews.calledOnce).to.be.true;
  348. expect(App.get('isAdmin')).to.be.false;
  349. expect(App.get('isOperator')).to.be.false;
  350. expect(App.get('isPermissionDataLoaded')).to.be.true;
  351. expect(mock.dataLoading.calledOnce).to.be.true;
  352. });
  353. });
  354. describe("#transitionToAdminView()", function () {
  355. beforeEach(function () {
  356. sinon.stub(App.ajax, 'send');
  357. });
  358. afterEach(function () {
  359. App.ajax.send.restore();
  360. });
  361. it("valid request is sent", function () {
  362. router.transitionToAdminView();
  363. expect(App.ajax.send.calledWith({
  364. name: 'ambari.service.load_server_version',
  365. sender: router,
  366. success: 'adminViewInfoSuccessCallback',
  367. error: 'adminViewInfoErrorCallback'
  368. })).to.be.true;
  369. });
  370. });
  371. describe("#transitionToApp()", function () {
  372. beforeEach(function () {
  373. this.mock = sinon.stub(router, 'restorePreferedPath');
  374. sinon.stub(router, 'getSection', function (callback) {
  375. callback('route');
  376. });
  377. sinon.stub(router, 'transitionTo');
  378. });
  379. afterEach(function () {
  380. this.mock.restore();
  381. router.getSection.restore();
  382. router.transitionTo.restore();
  383. });
  384. it("has restore path", function () {
  385. this.mock.returns(true);
  386. router.transitionToApp();
  387. expect(router.getSection.called).to.be.false;
  388. expect(router.transitionTo.called).to.be.false;
  389. });
  390. it("does not have restore path", function () {
  391. this.mock.returns(false);
  392. router.transitionToApp();
  393. expect(router.getSection.calledOnce).to.be.true;
  394. expect(router.transitionTo.calledWith('route')).to.be.true;
  395. });
  396. });
  397. describe("#transitionToViews()", function () {
  398. var mock = {loadAmbariViews: Em.K};
  399. beforeEach(function () {
  400. sinon.stub(App.router, 'get').returns(mock);
  401. sinon.stub(router, 'transitionTo');
  402. sinon.spy(mock, 'loadAmbariViews');
  403. });
  404. afterEach(function () {
  405. App.router.get.restore();
  406. router.transitionTo.restore();
  407. mock.loadAmbariViews.restore();
  408. });
  409. it("transitionTo called with corrent route", function () {
  410. router.transitionToViews();
  411. expect(mock.loadAmbariViews.calledOnce).to.be.true;
  412. expect(router.transitionTo.calledWith('main.views.index')).to.be.true;
  413. });
  414. });
  415. describe("#adminViewInfoErrorCallback()", function () {
  416. beforeEach(function () {
  417. sinon.stub(router, 'transitionToViews');
  418. });
  419. afterEach(function () {
  420. router.transitionToViews.restore();
  421. });
  422. it("transitionToViews called once", function () {
  423. router.adminViewInfoErrorCallback();
  424. expect(router.transitionToViews.calledOnce).to.be.true;
  425. });
  426. });
  427. describe("#getAuthenticated", function() {
  428. var router;
  429. beforeEach(function () {
  430. router = App.Router.create();
  431. this.mockGetCurrentLocationUrl = sinon.stub(router, 'getCurrentLocationUrl');
  432. sinon.stub(router, 'redirectByURL', Em.K);
  433. });
  434. afterEach(function () {
  435. App.ajax.send.restore();
  436. router.getCurrentLocationUrl.restore();
  437. router.redirectByURL.restore();
  438. this.mockGetCurrentLocationUrl.restore();
  439. });
  440. [
  441. {
  442. lastSetURL: '/login/local',
  443. isResolved: false,
  444. responseData: {
  445. responseText: "",
  446. status: 403
  447. },
  448. redirectCalled: false,
  449. m: 'no jwtProviderUrl in auth response, no redirect'
  450. },
  451. {
  452. lastSetURL: '/main/dashboard',
  453. isResolved: false,
  454. responseData: {
  455. responseText: JSON.stringify({ jwtProviderUrl: 'http://some.com?originalUrl=' }),
  456. status: 403
  457. },
  458. redirectCalled: true,
  459. m: 'jwtProviderUrl is present, current location not local login url, redirect according to jwtProviderUrl value'
  460. },
  461. {
  462. lastSetURL: '/login/local',
  463. isResolved: false,
  464. responseData: {
  465. responseText: JSON.stringify({ jwtProviderUrl: 'http://some.com?originalUrl=' }),
  466. status: 403
  467. },
  468. redirectCalled: false,
  469. m: 'jwtProviderUrl is present, current location is local login url, no redirect'
  470. }
  471. ].forEach(function(test) {
  472. describe(test.m, function() {
  473. var mockCurrentUrl;
  474. beforeEach(function () {
  475. mockCurrentUrl = 'http://localhost:3333/#/some/hash';
  476. router.set('location.lastSetURL', test.lastSetURL);
  477. sinon.stub(App.ajax, 'send', function() {
  478. if (!test.isResolved) {
  479. router.onAuthenticationError(test.responseData);
  480. }
  481. return {
  482. complete: function() {}
  483. };
  484. });
  485. this.mockGetCurrentLocationUrl.returns(mockCurrentUrl);
  486. router.getAuthenticated();
  487. });
  488. it('redirectByURL is ' + (test.redirectCalled ? '' : 'not') + ' called', function () {
  489. expect(router.redirectByURL.calledOnce).to.be.eql(test.redirectCalled);
  490. });
  491. if (test.redirectCalled) {
  492. it('redirectByURL is correct', function () {
  493. expect(router.redirectByURL.args[0][0]).to.be.eql(JSON.parse(test.responseData.responseText).jwtProviderUrl + encodeURIComponent(mockCurrentUrl));
  494. });
  495. }
  496. });
  497. });
  498. });
  499. });