step5_view_test.js 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499
  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('views/wizard/step5_view');
  20. var stringUtils = require('utils/string_utils');
  21. var view;
  22. describe('App.WizardStep5View', function() {
  23. beforeEach(function() {
  24. view = App.WizardStep5View.create({
  25. controller: App.WizardStep5Controller.create({})
  26. });
  27. });
  28. describe("#title", function() {
  29. beforeEach(function () {
  30. view.set('controller.content', Em.Object.create());
  31. });
  32. it("controller name is reassignMasterController", function() {
  33. view.set('controller.content.controllerName', 'reassignMasterController');
  34. view.propertyDidChange('title');
  35. expect(view.get('title')).to.equal(Em.I18n.t('installer.step5.reassign.header'));
  36. });
  37. it("controller name is ''", function() {
  38. view.set('controller.content.controllerName', '');
  39. view.propertyDidChange('title');
  40. expect(view.get('title')).to.equal(Em.I18n.t('installer.step5.header'));
  41. });
  42. });
  43. describe("#setCoHostedComponentText()", function () {
  44. beforeEach(function () {
  45. sinon.stub(App.StackServiceComponent, 'find').returns([
  46. Em.Object.create({
  47. componentName: 'C1',
  48. displayName: 'c1',
  49. isOtherComponentCoHosted: true,
  50. stackService: {
  51. isSelected: true
  52. },
  53. coHostedComponents: ['C2']
  54. }),
  55. Em.Object.create({
  56. componentName: 'C2',
  57. displayName: 'c2',
  58. isOtherComponentCoHosted: false,
  59. stackService: {
  60. isSelected: true
  61. }
  62. })
  63. ]);
  64. sinon.stub(stringUtils, 'getFormattedStringFromArray', function(str){
  65. return str;
  66. });
  67. });
  68. afterEach(function () {
  69. App.StackServiceComponent.find.restore();
  70. stringUtils.getFormattedStringFromArray.restore();
  71. });
  72. it("isReassignWizard - true", function () {
  73. view.set('controller.isReassignWizard', true);
  74. view.setCoHostedComponentText();
  75. expect(view.get('coHostedComponentText')).to.be.empty;
  76. });
  77. it("isReassignWizard - false", function () {
  78. view.set('controller.isReassignWizard', false);
  79. view.setCoHostedComponentText();
  80. expect(view.get('coHostedComponentText')).to.equal('<br/>' + Em.I18n.t('installer.step5.body.coHostedComponents').format(['c1', 'c2']));
  81. });
  82. });
  83. describe('#didInsertElement', function() {
  84. beforeEach(function () {
  85. sinon.stub(view.get('controller'), 'loadStep', Em.K);
  86. });
  87. afterEach(function () {
  88. view.get('controller').loadStep.restore();
  89. });
  90. it('should call controller.loadStep', function() {
  91. view.didInsertElement();
  92. expect(view.get('controller').loadStep.calledOnce).to.equal(true);
  93. });
  94. });
  95. describe('#shouldUseInputs', function() {
  96. Em.A([
  97. {range: 25, e: false},
  98. {range: 26, e: true},
  99. {range: 24, e: false}
  100. ]).forEach(function (test) {
  101. it(test.e + ' for ' + test.range + ' hosts', function () {
  102. view.set('controller.hosts', d3.range(0, test.range).map(function() {return {};}));
  103. expect(view.get('shouldUseInputs')).to.be.equal(test.e);
  104. });
  105. });
  106. });
  107. });
  108. describe('App.SelectHostView', function() {
  109. var models = require('test/init_model_test');
  110. beforeEach(function() {
  111. view = App.SelectHostView.create({
  112. controller: App.WizardStep5Controller.create({}),
  113. $: function() {return {typeahead: function(){return {on: Em.K}}}},
  114. updateErrorStatus: Em.K
  115. });
  116. });
  117. describe('#change', function() {
  118. beforeEach(function() {
  119. sinon.stub(view, 'initContent', Em.K);
  120. sinon.stub(view, 'changeHandler', Em.K);
  121. models.setupStackServiceComponent();
  122. });
  123. afterEach(function() {
  124. view.initContent.restore();
  125. view.changeHandler.restore();
  126. models.cleanStackServiceComponent();
  127. });
  128. it('should call initContent', function() {
  129. view.change();
  130. expect(view.initContent.calledOnce).to.be.true;
  131. });
  132. });
  133. describe('#didInsertElement', function() {
  134. it('should set value', function() {
  135. view.set('value', '');
  136. view.set('component', {selectedHost: 'h1'});
  137. view.didInsertElement();
  138. expect(view.get('value')).to.equal('h1');
  139. });
  140. });
  141. describe('#changeHandler', function() {
  142. beforeEach(function() {
  143. view.get('controller').reopen({multipleComponents: ['HBASE_MASTER', 'ZOOKEEPER_SERVER']});
  144. view.set('component', {component_name: 'ZOOKEEPER_SERVER', serviceComponentId: 1});
  145. view.set('controller.hosts', [Em.Object.create({host_info: 'h1 info', host_name: 'h1'})]);
  146. view.set('value', 'h1 info');
  147. view.set('controller.rebalanceComponentHostsCounter', 0);
  148. view.set('controller.componentToRebalance', '');
  149. sinon.stub(view.get('controller'), 'assignHostToMaster', Em.K);
  150. sinon.stub(view.get('controller'), 'updateIsHostNameValidFlag', Em.K);
  151. sinon.stub(view, 'shouldChangeHandlerBeCalled', function() {return true;});
  152. });
  153. afterEach(function() {
  154. view.get('controller').assignHostToMaster.restore();
  155. view.get('controller').updateIsHostNameValidFlag.restore();
  156. view.shouldChangeHandlerBeCalled.restore();
  157. });
  158. it('shouldn\'t do nothing if view is destroyed', function() {
  159. view.set('state', 'destroyed');
  160. expect(view.get('controller').assignHostToMaster.called).to.be.false;
  161. });
  162. it('should call assignHostToMaster', function() {
  163. view.changeHandler();
  164. expect(view.get('controller').assignHostToMaster.args[0]).to.be.eql(['ZOOKEEPER_SERVER', 'h1 info', 1]);
  165. });
  166. it('should increment rebalanceComponentHostsCounter if component it is multiple', function() {
  167. view.set('component', {component_name: 'ZOOKEEPER_SERVER'});
  168. view.changeHandler();
  169. expect(view.get('controller.rebalanceComponentHostsCounter')).to.equal(1);
  170. });
  171. it('should set componentToRebalance', function() {
  172. view.changeHandler();
  173. expect(view.get('controller.componentToRebalance')).to.equal('ZOOKEEPER_SERVER');
  174. });
  175. });
  176. });
  177. describe('App.InputHostView', function() {
  178. beforeEach(function() {
  179. view = App.InputHostView.create({
  180. controller: App.WizardStep5Controller.create({}),
  181. $: function() {return {typeahead: function(){return {on: Em.K}}}},
  182. updateErrorStatus: Em.K
  183. });
  184. });
  185. describe('#didInsertElement', function() {
  186. beforeEach(function() {
  187. sinon.stub(view, 'initContent', Em.K);
  188. view.set('content', [Em.Object.create({host_name: 'h1', host_info: 'h1 info'})]);
  189. view.set('component', {selectedHost: 'h1'});
  190. });
  191. afterEach(function() {
  192. view.initContent.restore();
  193. });
  194. it('should call initContent', function() {
  195. view.didInsertElement();
  196. expect(view.initContent.calledOnce).to.equal(true);
  197. });
  198. it('should set selectedHost host_name to value', function() {
  199. view.set('value', '');
  200. view.didInsertElement();
  201. expect(view.get('value')).to.equal('h1');
  202. });
  203. });
  204. describe('#changeHandler', function() {
  205. beforeEach(function() {
  206. view.get('controller').reopen({multipleComponents: ['HBASE_MASTER', 'ZOOKEEPER_SERVER']});
  207. view.set('component', {component_name: 'ZOOKEEPER_SERVER', serviceComponentId: 1});
  208. view.set('controller.hosts', [Em.Object.create({host_info: 'h1 info', host_name: 'h1'})]);
  209. view.set('value', 'h1');
  210. view.set('controller.rebalanceComponentHostsCounter', 0);
  211. view.set('controller.componentToRebalance', '');
  212. sinon.stub(view.get('controller'), 'assignHostToMaster', Em.K);
  213. sinon.stub(view.get('controller'), 'updateIsHostNameValidFlag', Em.K);
  214. sinon.stub(view, 'shouldChangeHandlerBeCalled', function() {return true;});
  215. });
  216. afterEach(function() {
  217. view.get('controller').assignHostToMaster.restore();
  218. view.get('controller').updateIsHostNameValidFlag.restore();
  219. view.shouldChangeHandlerBeCalled.restore();
  220. });
  221. it('shouldn\'t do nothing if view is destroyed', function() {
  222. view.set('state', 'destroyed');
  223. expect(view.get('controller').assignHostToMaster.called).to.be.false;
  224. });
  225. it('should call assignHostToMaster', function() {
  226. view.changeHandler();
  227. expect(view.get('controller').assignHostToMaster.args[0]).to.be.eql(['ZOOKEEPER_SERVER', 'h1', 1]);
  228. });
  229. it('should increment rebalanceComponentHostsCounter if component it is multiple', function() {
  230. view.set('component', {component_name: 'ZOOKEEPER_SERVER'});
  231. view.changeHandler();
  232. expect(view.get('controller.rebalanceComponentHostsCounter')).to.equal(1);
  233. });
  234. it('should set componentToRebalance', function() {
  235. view.changeHandler();
  236. expect(view.get('controller.componentToRebalance')).to.equal('ZOOKEEPER_SERVER');
  237. });
  238. });
  239. describe('#getAvailableHosts', function() {
  240. var tests = Em.A([
  241. {
  242. hosts: Em.A([]),
  243. selectedHost: 'h2',
  244. componentName: 'ZOOKEEPER_SERVER',
  245. selectedServicesMasters: Em.A([
  246. Em.Object.create({component_name: 'ZOOKEEPER_SERVER', selectedHost: 'h1'})
  247. ]),
  248. m: 'Empty hosts',
  249. e: []
  250. },
  251. {
  252. hosts: Em.A([
  253. Em.Object.create({host_name: 'h1'}),
  254. Em.Object.create({host_name: 'h2'})
  255. ]),
  256. selectedHost: 'h2',
  257. componentName: 'c1',
  258. selectedServicesMasters: Em.A([
  259. Em.Object.create({component_name: 'c2', selectedHost: 'h1'})
  260. ]),
  261. m: 'Two hosts',
  262. e: ['h1', 'h2']
  263. },
  264. {
  265. hosts: Em.A([
  266. Em.Object.create({host_name: 'h1'}),
  267. Em.Object.create({host_name: 'h2'})
  268. ]),
  269. selectedHost: 'h2',
  270. componentName: 'ZOOKEEPER_SERVER',
  271. selectedServicesMasters: Em.A([
  272. Em.Object.create({component_name: 'ZOOKEEPER_SERVER', selectedHost: 'h1'})
  273. ]),
  274. m: 'Two hosts, ZOOKEEPER_SERVER',
  275. e: ['h2']
  276. },
  277. {
  278. hosts: Em.A([
  279. Em.Object.create({host_name: 'h1'}),
  280. Em.Object.create({host_name: 'h2'})
  281. ]),
  282. selectedHost: 'h2',
  283. componentName: 'HBASE_MASTER',
  284. selectedServicesMasters: Em.A([
  285. Em.Object.create({component_name: 'HBASE_MASTER', selectedHost: 'h1'})
  286. ]),
  287. m: 'Two hosts, HBASE_MASTER',
  288. e: ['h2']
  289. }
  290. ]);
  291. tests.forEach(function(test) {
  292. it(test.m, function() {
  293. view.set('controller.hosts', test.hosts);
  294. view.get('controller').reopen({multipleComponents: ['HBASE_MASTER', 'ZOOKEEPER_SERVER']});
  295. view.set('component', {component_name: test.componentName});
  296. view.set('controller.selectedServicesMasters', test.selectedServicesMasters);
  297. var r = view.getAvailableHosts();
  298. expect(r.mapProperty('host_name')).to.eql(test.e);
  299. });
  300. });
  301. });
  302. describe('#rebalanceComponentHostsOnce', function() {
  303. var tests = Em.A([
  304. {
  305. componentName: 'c1',
  306. componentToRebalance: 'c2',
  307. content: [{}],
  308. m: 'componentName not equal to componentToRebalance',
  309. e: {
  310. initContent: false
  311. }
  312. },
  313. {
  314. componentName: 'c2',
  315. componentToRebalance: 'c2',
  316. content: [{}],
  317. m: 'componentName equal to componentToRebalance',
  318. e: {
  319. initContent: true
  320. }
  321. }
  322. ]);
  323. beforeEach(function () {
  324. sinon.stub(view, 'initContent', Em.K);
  325. });
  326. afterEach(function () {
  327. view.initContent.restore();
  328. });
  329. tests.forEach(function(test) {
  330. it(test.m, function() {
  331. view.set('content', test.content);
  332. view.set('component', {component_name: test.componentName});
  333. view.set('controller.componentToRebalance', test.componentToRebalance);
  334. view.rebalanceComponentHostsOnce();
  335. expect(view.initContent.calledOnce).to.equal(test.e.initContent);
  336. });
  337. });
  338. });
  339. describe('#initContent', function() {
  340. var tests = Em.A([
  341. {
  342. hosts: 25,
  343. m: 'not lazy loading, 25 hosts, no selected host',
  344. e: 25
  345. },
  346. {
  347. hosts: 25,
  348. h: 4,
  349. m: 'not lazy loading, 25 hosts, one selected host',
  350. e: 25
  351. }
  352. ]);
  353. tests.forEach(function(test) {
  354. it(test.m, function() {
  355. view.reopen({getAvailableHosts: function() {return d3.range(0, test.hosts).map(function(indx){return Em.Object.create({host_name: indx})});}});
  356. if (test.h) {
  357. view.set('selectedHost', test.h);
  358. }
  359. view.initContent();
  360. expect(view.get('content.length')).to.equal(test.e);
  361. });
  362. });
  363. });
  364. describe('#change', function() {
  365. beforeEach(function() {
  366. sinon.stub(view, 'changeHandler', Em.K);
  367. });
  368. afterEach(function() {
  369. view.changeHandler.restore();
  370. });
  371. it('shouldn\'t do nothing if view is destroyed', function() {
  372. view.set('controller.hostNameCheckTrigger', false);
  373. view.set('state', 'destroyed');
  374. view.change();
  375. expect(view.get('controller.hostNameCheckTrigger')).to.equal(false);
  376. });
  377. it('should toggle hostNameCheckTrigger', function() {
  378. view.set('controller.hostNameCheckTrigger', false);
  379. view.change();
  380. expect(view.get('controller.hostNameCheckTrigger')).to.equal(true);
  381. });
  382. });
  383. });
  384. describe('App.RemoveControlView', function() {
  385. beforeEach(function() {
  386. view = App.RemoveControlView.create({
  387. controller: App.WizardStep5Controller.create({})
  388. });
  389. });
  390. describe('#click', function() {
  391. beforeEach(function() {
  392. sinon.stub(view.get('controller'), 'removeComponent', Em.K);
  393. });
  394. afterEach(function() {
  395. view.get('controller').removeComponent.restore();
  396. });
  397. it('should call removeComponent', function() {
  398. view.set('serviceComponentId', 1);
  399. view.set('componentName', 'c1');
  400. view.click();
  401. expect(view.get('controller').removeComponent.calledWith('c1', 1)).to.equal(true);
  402. });
  403. });
  404. });
  405. describe('App.AddControlView', function() {
  406. beforeEach(function() {
  407. view = App.AddControlView.create({
  408. controller: App.WizardStep5Controller.create({})
  409. });
  410. });
  411. describe('#click', function() {
  412. beforeEach(function() {
  413. sinon.stub(view.get('controller'), 'addComponent', Em.K);
  414. });
  415. afterEach(function() {
  416. view.get('controller').addComponent.restore();
  417. });
  418. it('should call addComponent', function() {
  419. view.set('componentName', 'c1');
  420. view.click();
  421. expect(view.get('controller').addComponent.calledWith('c1')).to.equal(true);
  422. });
  423. });
  424. });