config_recommendation_parser_test.js 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479
  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. var helpers = require('test/helpers');
  20. describe('App.ConfigRecommendationParser', function() {
  21. var mixinObject = Em.Controller.extend(App.ConfigRecommendationParser, {});
  22. var instanceObject = mixinObject.create({});
  23. var recommendationObject = {
  24. 'fileName1': {
  25. 'properties': {
  26. 'p1': 'v1'
  27. },
  28. 'property_attributes': {
  29. 'p2': {
  30. 'delete': true
  31. },
  32. 'p3': {
  33. 'maximum': 100,
  34. 'minimum': 1
  35. }
  36. }
  37. }
  38. };
  39. var configs = [
  40. Em.Object.create({
  41. name: 'p1',
  42. filename: 'fileName1'
  43. }),
  44. Em.Object.create({
  45. name: 'p2',
  46. filename: 'fileName1'
  47. }),
  48. Em.Object.create({
  49. name: 'p3',
  50. filename: 'fileName1'
  51. })
  52. ];
  53. beforeEach(function() {
  54. instanceObject.set('stepConfigs', []);
  55. });
  56. describe('#parseRecommendations', function() {
  57. describe('#recommendartion parsed', function() {
  58. beforeEach(function() {
  59. instanceObject.reopen({
  60. updateCallback: Em.K,
  61. removeCallback: Em.K,
  62. updateBoundariesCallback: Em.K
  63. });
  64. sinon.stub(App.configsCollection, 'getConfigByName', function(name, fileName) {
  65. return { name: name, filename: fileName };
  66. });
  67. sinon.stub(instanceObject, 'allowUpdateProperty').returns(true);
  68. sinon.spy(instanceObject, 'updateCallback');
  69. sinon.spy(instanceObject, 'removeCallback');
  70. sinon.spy(instanceObject, 'updateBoundariesCallback');
  71. instanceObject.parseRecommendations(recommendationObject, configs, null, null,
  72. instanceObject.updateCallback, instanceObject.removeCallback, instanceObject.updateBoundariesCallback);
  73. });
  74. afterEach(function() {
  75. App.configsCollection.getConfigByName.restore();
  76. instanceObject.allowUpdateProperty.restore();
  77. instanceObject.updateCallback.restore();
  78. instanceObject.removeCallback.restore();
  79. instanceObject.updateBoundariesCallback.restore();
  80. });
  81. it('updateCallback', function() {
  82. expect(instanceObject.updateCallback.calledWith(configs[0], 'v1', null, null)).to.be.true;
  83. });
  84. it('removeCallback', function() {
  85. expect(instanceObject.removeCallback.calledWith(configs[1], configs, null, null)).to.be.true;
  86. });
  87. it('updateBoundariesCallback maximum', function() {
  88. expect(instanceObject.updateBoundariesCallback.calledWith({ name: 'p3', filename: 'fileName1' },
  89. 'maximum', 100, 'p3', 'fileName1', null)).to.be.true;
  90. });
  91. it('updateBoundariesCallback minimum', function() {
  92. expect(instanceObject.updateBoundariesCallback.calledWith({ name: 'p3', filename: 'fileName1' },
  93. 'minimum', 1, 'p3', 'fileName1', null)).to.be.true;
  94. });
  95. });
  96. it('#recommendation parsing failed', function() {
  97. expect(instanceObject.parseRecommendations.bind(instanceObject, null)).to.throw(App.ObjectTypeError);
  98. });
  99. it('#recommendation parsing failed', function() {
  100. expect(instanceObject.parseRecommendations.bind(instanceObject, {}, null)).to.throw(App.ArrayTypeError);
  101. });
  102. it('#recommendation parsing failed', function() {
  103. expect(instanceObject.parseRecommendations.bind(instanceObject, {}, [Em.Object.create({name: 'cfg1'})])).to.throw(App.FunctionTypeError);
  104. });
  105. });
  106. describe('#addByRecommendations', function(){
  107. var _recommendationObject = {
  108. 'file-name': {
  109. 'properties': {
  110. 'p1': 'v1'
  111. }
  112. }
  113. };
  114. var stepConfig = App.ServiceConfig.create({
  115. serviceName: 'serviceName1',
  116. configs: []
  117. });
  118. var cases = [
  119. {
  120. m: 'allowUpdateProperty true',
  121. allowUpdateProperty: true
  122. },
  123. {
  124. m: 'allowUpdateProperty false',
  125. allowUpdateProperty: false
  126. }
  127. ];
  128. cases.forEach(function (c) {
  129. describe('non error case', function() {
  130. beforeEach(function() {
  131. sinon.stub(App.config, 'getStepConfigForProperty').returns(stepConfig);
  132. sinon.stub(instanceObject, 'allowUpdateProperty').returns(c.allowUpdateProperty);
  133. sinon.stub(instanceObject, '_createNewProperty').returns(App.ServiceConfigProperty.create({
  134. 'name': 'p1',
  135. 'filename': 'file-name'
  136. }));
  137. instanceObject.addByRecommendations(_recommendationObject, []);
  138. });
  139. afterEach(function() {
  140. App.config.getStepConfigForProperty.restore();
  141. instanceObject.allowUpdateProperty.restore();
  142. instanceObject._createNewProperty.restore();
  143. });
  144. if (c.allowUpdateProperty) {
  145. it ('adds new property', function() {
  146. expect(instanceObject._createNewProperty.calledWith('p1', 'file-name', 'serviceName1', 'v1', [])).to.be.true;
  147. expect(stepConfig.get('configs.0.name')).to.equal('p1');
  148. expect(stepConfig.get('configs.0.filename')).to.equal('file-name');
  149. });
  150. } else {
  151. it('does not add property error', function() {
  152. expect(instanceObject._createNewProperty.called).to.be.false;
  153. });
  154. }
  155. });
  156. });
  157. it('throws error', function() {
  158. expect(instanceObject.addByRecommendations.bind(instanceObject, null)).to.throw(App.ObjectTypeError);
  159. });
  160. });
  161. describe('#_updateConfigByRecommendation', function() {
  162. var cases = [
  163. {
  164. 'allowUpdateProperty': true,
  165. 'updateInitialOnRecommendations': true,
  166. 'm': 'allowUpdateProperty and update init on recommendation',
  167. 'result': {
  168. 'recommendedValue': 'recommendedValue',
  169. 'value': 'recommendedValue',
  170. 'initialValue': 'recommendedValue'
  171. }
  172. },
  173. {
  174. 'allowUpdateProperty': true,
  175. 'updateInitialOnRecommendations': false,
  176. 'm': 'allowUpdateProperty and do not update init on recommendation',
  177. 'result': {
  178. 'recommendedValue': 'recommendedValue',
  179. 'value': 'recommendedValue',
  180. 'initialValue': null
  181. }
  182. },
  183. {
  184. 'allowUpdateProperty': false,
  185. 'updateInitialOnRecommendations': false,
  186. 'm': 'do not allowUpdateProperty and do not update init on recommendation',
  187. 'result': {
  188. 'recommendedValue': 'recommendedValue',
  189. 'value': null,
  190. 'initialValue': null
  191. }
  192. }
  193. ];
  194. cases.forEach(function(c) {
  195. describe('update recommendation', function() {
  196. beforeEach(function() {
  197. sinon.spy(instanceObject, 'applyRecommendation');
  198. sinon.stub(instanceObject, 'allowUpdateProperty').returns(c.allowUpdateProperty);
  199. sinon.stub(instanceObject, 'updateInitialOnRecommendations').returns(c.updateInitialOnRecommendations);
  200. });
  201. afterEach(function() {
  202. instanceObject.allowUpdateProperty.restore();
  203. instanceObject.updateInitialOnRecommendations.restore();
  204. instanceObject.applyRecommendation.restore();
  205. });
  206. it(c.m, function() {
  207. expect(instanceObject._updateConfigByRecommendation({
  208. 'recommendedValue': null,
  209. 'value': null,
  210. 'initialValue': null
  211. }, 'recommendedValue')).to.eql(c.result);
  212. });
  213. if(c.allowUpdateProperty) {
  214. it('runs applyRecommendation', function() {
  215. instanceObject._updateConfigByRecommendation({}, 'recommendedValue');
  216. expect(instanceObject.applyRecommendation.calledOnce).to.be.true;
  217. });
  218. }
  219. });
  220. });
  221. it('throws error for configs', function() {
  222. expect(instanceObject._updateConfigByRecommendation.bind(instanceObject, null)).to.throw(App.ObjectTypeError);
  223. });
  224. });
  225. describe('#_createNewProperty', function() {
  226. beforeEach(function() {
  227. sinon.spy(instanceObject, 'applyRecommendation');
  228. sinon.stub(instanceObject, '_getCoreProperties').returns({
  229. 'value': 'recommendedValue',
  230. 'recommendedValue': 'recommendedValue',
  231. 'initialValue': 'initialValue',
  232. 'savedValue': null
  233. });
  234. sinon.stub(App.config, 'getDefaultConfig', function(name, fileName, coreObject) {
  235. coreObject.name = name;
  236. coreObject.filename = fileName;
  237. return coreObject;
  238. });
  239. });
  240. afterEach(function() {
  241. instanceObject.applyRecommendation.restore();
  242. instanceObject._getCoreProperties.restore();
  243. App.config.getDefaultConfig.restore();
  244. });
  245. it('adds new config', function() {
  246. var res = {
  247. 'value': 'recommendedValue',
  248. 'recommendedValue': 'recommendedValue',
  249. 'savedValue': null,
  250. 'name': 'name',
  251. 'filename': 'fileName',
  252. 'errorMessage': ''
  253. };
  254. var test = instanceObject._createNewProperty('name', 'fileName', 'recommendedValue', null);
  255. helpers.nestedExpect([res], [test]);
  256. expect(instanceObject.applyRecommendation.calledOnce).to.be.true;
  257. });
  258. it('throws error for name/fileName/serviceName', function() {
  259. expect(instanceObject._createNewProperty.bind(instanceObject)).to.throw(App.NotNullTypeError);
  260. expect(instanceObject._createNewProperty.bind(instanceObject, 'name')).to.throw(App.NotNullTypeError);
  261. });
  262. });
  263. describe('#_removeConfigByRecommendation', function() {
  264. beforeEach(function() {
  265. sinon.spy(instanceObject, 'applyRecommendation');
  266. });
  267. afterEach(function() {
  268. instanceObject.applyRecommendation.restore();
  269. });
  270. it('removes config', function() {
  271. var configCollection = [
  272. {'name': 'cfg1'},
  273. {'name': 'cfg2'}
  274. ];
  275. instanceObject._removeConfigByRecommendation(configCollection[0], configCollection);
  276. expect(configCollection[0]).to.eql({'name': 'cfg2'});
  277. expect(instanceObject.applyRecommendation.calledOnce).to.be.true;
  278. });
  279. it('throws error', function() {
  280. expect(instanceObject._removeConfigByRecommendation.bind(instanceObject, null)).to.throw(App.ObjectTypeError);
  281. });
  282. it('throws error (2)', function() {
  283. expect(instanceObject._removeConfigByRecommendation.bind(instanceObject, {}, null)).to.throw(App.ArrayTypeError);
  284. });
  285. });
  286. describe('#_updateBoundaries', function() {
  287. it('sets appropriate attribute', function() {
  288. expect(instanceObject._updateBoundaries({}, 'attr1', 'v1')).to.eql({ valueAttributes: {'attr1': 'v1'}});
  289. });
  290. });
  291. describe('#_getCoreProperties', function() {
  292. var cases = [
  293. {
  294. 'useInitialValue': true,
  295. 'updateInitialOnRecommendations': true,
  296. 'm': 'use init and update init on recommendation',
  297. 'result': {
  298. 'value': 'recommendedValue',
  299. 'recommendedValue': 'recommendedValue',
  300. 'initialValue': 'recommendedValue',
  301. 'savedValue': null
  302. }
  303. },
  304. {
  305. 'useInitialValue': true,
  306. 'updateInitialOnRecommendations': false,
  307. 'm': 'use init and do not update init on recommendation',
  308. 'result': {
  309. 'value': 'recommendedValue',
  310. 'recommendedValue': 'recommendedValue',
  311. 'initialValue': 'initValue',
  312. 'savedValue': null
  313. }
  314. },
  315. {
  316. 'useInitialValue': false,
  317. 'updateInitialOnRecommendations': false,
  318. 'm': 'do not use init and do not update init on recommendation',
  319. 'result': {
  320. 'value': 'recommendedValue',
  321. 'recommendedValue': 'recommendedValue',
  322. 'initialValue': 'initValue',
  323. 'savedValue': 'initValue'
  324. }
  325. }
  326. ];
  327. cases.forEach(function(c) {
  328. describe('get core object for different cases', function() {
  329. beforeEach(function() {
  330. sinon.stub(instanceObject, 'useInitialValue').returns(c.useInitialValue);
  331. sinon.stub(instanceObject, 'updateInitialOnRecommendations').returns(c.updateInitialOnRecommendations);
  332. });
  333. afterEach(function() {
  334. instanceObject.useInitialValue.restore();
  335. instanceObject.updateInitialOnRecommendations.restore();
  336. });
  337. it(c.m, function() {
  338. expect(instanceObject._getCoreProperties('serviceName', 'recommendedValue', 'initValue')).to.eql(c.result);
  339. })
  340. })
  341. });
  342. });
  343. describe('#_getInitialFromRecommendations', function() {
  344. beforeEach(function() {
  345. instanceObject.set('recommendations', [
  346. {
  347. propertyName: 'p1',
  348. propertyFileName: 'f1',
  349. configGroup: 'Default',
  350. initialValue: 'initValue'
  351. }
  352. ])
  353. });
  354. it('get init value from recommendations', function() {
  355. expect(instanceObject._getInitialFromRecommendations('p1','f1')).to.equal('initValue');
  356. });
  357. it('recommendation does not exist', function() {
  358. expect(instanceObject._getInitialFromRecommendations('p2','f2')).to.equal(null);
  359. });
  360. });
  361. describe('#_getInitialValue', function() {
  362. beforeEach(function() {
  363. sinon.stub(instanceObject, 'useInitialValue', function(serviceName) {
  364. return serviceName !== 'serviceNameInstalled'
  365. })
  366. });
  367. afterEach(function() {
  368. instanceObject.useInitialValue.restore();
  369. });
  370. it('use initialValue', function() {
  371. expect(instanceObject._getInitialValue({
  372. serviceName: 'serviceNameNotInstalled',
  373. initialValue: 'initV',
  374. savedValue: 'savedV'
  375. })).to.equal('initV');
  376. });
  377. it('use savedValue', function() {
  378. expect(instanceObject._getInitialValue({
  379. serviceName: 'serviceNameInstalled',
  380. initialValue: 'initV',
  381. savedValue: 'savedV'
  382. })).to.equal('savedV');
  383. });
  384. it('wrong params', function() {
  385. expect(instanceObject._getInitialValue()).to.be.null;
  386. });
  387. });
  388. describe('#updateInitialOnRecommendations', function() {
  389. it('default value for updateInitialOnRecommendations is true', function() {
  390. expect(instanceObject.updateInitialOnRecommendations()).to.be.false;
  391. })
  392. });
  393. describe('#useInitialValue', function() {
  394. it('default value for useInitialValue is false', function() {
  395. expect(instanceObject.useInitialValue()).to.be.false;
  396. })
  397. });
  398. describe('#allowUpdateProperty', function() {
  399. var cases = [{
  400. saveRecommended: true
  401. },{
  402. saveRecommended: false
  403. }];
  404. cases.forEach(function(c) {
  405. describe('allowUpdateProperty based on saveRecommended:' + c.saveRecommended, function() {
  406. beforeEach(function() {
  407. sinon.stub(instanceObject, 'getRecommendation').returns({saveRecommended: c.saveRecommended});
  408. });
  409. afterEach(function() {
  410. instanceObject.getRecommendation.restore();
  411. });
  412. it('default value for allowUpdateProperty is true', function() {
  413. expect(instanceObject.allowUpdateProperty()).to.equal(c.saveRecommended);
  414. });
  415. });
  416. });
  417. it('default value for allowUpdateProperty is true', function() {
  418. expect(instanceObject.allowUpdateProperty()).to.be.true;
  419. });
  420. });
  421. });