ambari-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From atk...@apache.org
Subject ambari git commit: AMBARI-19441 Ambari should add warning when LogSearch selected without Ambari-Infra (atkach)
Date Tue, 10 Jan 2017 13:35:12 GMT
Repository: ambari
Updated Branches:
  refs/heads/branch-2.5 b94b25f25 -> 01b0d00db


AMBARI-19441 Ambari should add warning when LogSearch selected without Ambari-Infra (atkach)


Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/01b0d00d
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/01b0d00d
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/01b0d00d

Branch: refs/heads/branch-2.5
Commit: 01b0d00dbcc22fffca875c016b00d2a705fb85e3
Parents: b94b25f
Author: Andrii Tkach <atkach@apache.org>
Authored: Tue Jan 10 13:09:46 2017 +0200
Committer: Andrii Tkach <atkach@apache.org>
Committed: Tue Jan 10 15:34:05 2017 +0200

----------------------------------------------------------------------
 ambari-web/app/controllers/wizard.js            |   2 +-
 .../app/controllers/wizard/step4_controller.js  |  22 +-
 .../app/controllers/wizard/step7_controller.js  |   4 +-
 ambari-web/app/mappers/stack_service_mapper.js  |   3 -
 ambari-web/app/messages.js                      |   1 +
 ambari-web/app/utils/configs/theme/theme.js     |   6 +-
 .../test/controllers/wizard/step4_test.js       |  90 ++-
 .../test/utils/configs/theme/theme_test.js      | 621 +++++++++++++++++++
 8 files changed, 726 insertions(+), 23 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ambari/blob/01b0d00d/ambari-web/app/controllers/wizard.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/controllers/wizard.js b/ambari-web/app/controllers/wizard.js
index 89d439a..a759235 100644
--- a/ambari-web/app/controllers/wizard.js
+++ b/ambari-web/app/controllers/wizard.js
@@ -656,7 +656,7 @@ App.WizardController = Em.Controller.extend(App.LocalStorage, App.ThemesMappingM
     this.set('content.installedServiceNames', savedInstalledServices);
     if (!savedSelectedServices) {
       jsonData.items.forEach(function (service) {
-        service.StackServices.is_selected = true;
+        service.StackServices.is_selected = !(service.StackServices.selection === "TECH_PREVIEW");
       }, this);
     } else {
       jsonData.items.forEach(function (service) {

http://git-wip-us.apache.org/repos/asf/ambari/blob/01b0d00d/ambari-web/app/controllers/wizard/step4_controller.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/controllers/wizard/step4_controller.js b/ambari-web/app/controllers/wizard/step4_controller.js
index 317c548..9e61a7d 100644
--- a/ambari-web/app/controllers/wizard/step4_controller.js
+++ b/ambari-web/app/controllers/wizard/step4_controller.js
@@ -181,11 +181,8 @@ App.WizardStep4Controller = Em.ArrayController.extend({
       this.serviceValidation(callback, 'AMBARI_METRICS', 'ambariMetricsCheck');
       this.serviceValidation(callback, 'SMARTSENSE', 'smartSenseCheck');
     }
-    var atlasService = this.findProperty('serviceName', 'ATLAS');
-    var ambariInfraService = this.findProperty('serviceName', 'AMBARI_INFRA');
-    if (atlasService && atlasService.get('isSelected') && ambariInfraService
&& !ambariInfraService.get('isSelected')) {
-      this.serviceValidation(callback, 'AMBARI_INFRA', 'ambariInfraCheck');
-    }
+    this.dependentServiceValidation('ATLAS', 'AMBARI_INFRA', 'ambariInfraCheck', callback);
+    this.dependentServiceValidation('LOGSEARCH', 'AMBARI_INFRA', 'ambariLogsearchCheck',
callback);
     this.rangerValidation(callback);
     this.sparkValidation(callback);
     if (!!this.get('errorStack').filterProperty('isShown', false).length) {
@@ -199,6 +196,21 @@ App.WizardStep4Controller = Em.ArrayController.extend({
   },
 
   /**
+   * display validation warning if dependent service not selected
+   * @param {string} selectedService
+   * @param {string} dependentService
+   * @param {string} checkId
+   * @param {Function} callback
+   */
+  dependentServiceValidation: function(selectedService, dependentService, checkId, callback)
{
+    var selected = this.findProperty('serviceName', selectedService);
+    var dependent = this.findProperty('serviceName', dependentService);
+    if (selected && selected.get('isSelected') && dependent && !dependent.get('isSelected'))
{
+      this.serviceValidation(callback, dependentService, checkId);
+    }
+  },
+
+  /**
    * Check whether user selected service to install and go to next step
    * @param callback {Function}
    * @param serviceName {string}

http://git-wip-us.apache.org/repos/asf/ambari/blob/01b0d00d/ambari-web/app/controllers/wizard/step7_controller.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/controllers/wizard/step7_controller.js b/ambari-web/app/controllers/wizard/step7_controller.js
index 3d22fe9..f6cc93b 100644
--- a/ambari-web/app/controllers/wizard/step7_controller.js
+++ b/ambari-web/app/controllers/wizard/step7_controller.js
@@ -523,7 +523,6 @@ App.WizardStep7Controller = Em.Controller.extend(App.ServerValidatorMixin,
App.E
     if (App.get('isKerberosEnabled') && this.get('wizardController.name') === 'addServiceController')
{
       this.addKerberosDescriptorConfigs(configs, this.get('wizardController.kerberosDescriptorConfigs')
|| []);
     }
-    App.configTheme.resolveConfigThemeConditions(configs);
     var stepConfigs = this.createStepConfigs();
     var serviceConfigs = this.renderConfigs(stepConfigs, configs);
     // if HA is enabled -> Make some reconfigurations
@@ -578,6 +577,9 @@ App.WizardStep7Controller = Em.Controller.extend(App.ServerValidatorMixin,
App.E
   },
 
   completeConfigLoading: function() {
+    this.get('stepConfigs').forEach(function(service) {
+      App.configTheme.resolveConfigThemeConditions(service.get('configs'));
+    });
     this.clearRecommendationsByServiceName(App.StackService.find().filter(function (s) {
       return s.get('isSelected') && !s.get('isInstalled');
     }).mapProperty('serviceName'));

http://git-wip-us.apache.org/repos/asf/ambari/blob/01b0d00d/ambari-web/app/mappers/stack_service_mapper.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/mappers/stack_service_mapper.js b/ambari-web/app/mappers/stack_service_mapper.js
index 888dcdf..0ed49c8 100644
--- a/ambari-web/app/mappers/stack_service_mapper.js
+++ b/ambari-web/app/mappers/stack_service_mapper.js
@@ -117,9 +117,6 @@ App.stackServiceMapper = App.QuickDataMapper.create({
         stackService.is_installable = false;
         stackService.is_selected = false;
       }
-      if (stackService.selection === "TECH_PREVIEW") {
-        stackService.is_selected = false;
-      }
       if(stackService.selection === "MANDATORY") {
         stackService.is_mandatory = true;
       }

http://git-wip-us.apache.org/repos/asf/ambari/blob/01b0d00d/ambari-web/app/messages.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/messages.js b/ambari-web/app/messages.js
index 6e35bd5..766542f 100644
--- a/ambari-web/app/messages.js
+++ b/ambari-web/app/messages.js
@@ -847,6 +847,7 @@ Em.I18n.translations = {
   'installer.step4.limitedFunctionality.popup.header':'Limited Functionality Warning',
   'installer.step4.ambariMetricsCheck.popup.body':'Ambari Metrics collects metrics from the
cluster and makes them available to Ambari.  If you do not install Ambari Metrics service,
metrics will not be accessible from Ambari.  Are you sure you want to proceed without Ambari
Metrics?',
   'installer.step4.ambariInfraCheck.popup.body':'Since Ambari Infra is not selected, you
must supply your own Solr to make Atlas work. Are you sure you want to proceed?',
+  'installer.step4.ambariLogsearchCheck.popup.body':'Since Ambari Infra is not selected,
you must supply your own Solr to make Log Search work. Are you sure you want to proceed?',
   'installer.step4.smartSenseCheck.popup.body':'SmartSense securely collects cluster diagnostics
in order to send you recommendations and automate analysis for ' +
   'troubleshooting support cases. If you choose not to install SmartSense, you will not receive
any recommendations, and you ' +
   'will need to collect configuration and logs manually for troubleshooting support cases.
' +

http://git-wip-us.apache.org/repos/asf/ambari/blob/01b0d00d/ambari-web/app/utils/configs/theme/theme.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/utils/configs/theme/theme.js b/ambari-web/app/utils/configs/theme/theme.js
index 07ef577..4dcd499 100644
--- a/ambari-web/app/utils/configs/theme/theme.js
+++ b/ambari-web/app/utils/configs/theme/theme.js
@@ -49,11 +49,11 @@ App.configTheme = Em.Object.create({
             if (themeResource) {
               themeResource.get('configProperties').forEach(function (_configId) {
                 configs.forEach(function (item) {
-                  if (App.config.configId(item.name, item.filename) === _configId) {
+                  if (App.config.configId(item.get('name'), item.get('filename')) === _configId)
{
                     // if config has already been hidden by condition with "subsection" or
"subsectionTab" type
                     // then ignore condition of "config" type
-                    if (configCondition.get('type') === 'config' && item.hiddenBySection)
return false;
-                    item.hiddenBySection = !valueAttributes.visible;
+                    if (configCondition.get('type') === 'config' && item.get('hiddenBySection'))
return false;
+                    item.set('hiddenBySection', !valueAttributes.visible);
                   }
                 });
               }, this);

http://git-wip-us.apache.org/repos/asf/ambari/blob/01b0d00d/ambari-web/test/controllers/wizard/step4_test.js
----------------------------------------------------------------------
diff --git a/ambari-web/test/controllers/wizard/step4_test.js b/ambari-web/test/controllers/wizard/step4_test.js
index b9b21cf..0fad0c1 100644
--- a/ambari-web/test/controllers/wizard/step4_test.js
+++ b/ambari-web/test/controllers/wizard/step4_test.js
@@ -24,11 +24,19 @@ require('controllers/wizard/step4_controller');
 describe('App.WizardStep4Controller', function () {
 
   var services = [
-    'HDFS', 'GANGLIA', 'OOZIE', 'HIVE', 'HBASE', 'PIG', 'SCOOP', 'ZOOKEEPER', 'SMARTSENSE',
+    'HDFS', 'GANGLIA', 'OOZIE', 'HIVE', 'HBASE', 'PIG', 'SCOOP', 'ZOOKEEPER', 'SMARTSENSE',
'LOGSEARCH',
     'YARN', 'MAPREDUCE2', 'FALCON', 'TEZ', 'STORM', 'AMBARI_METRICS', 'RANGER', 'SPARK',
'SLIDER', 'ATLAS', 'AMBARI_INFRA'
   ];
-
-  var controller = App.WizardStep4Controller.create();
+  var controller;
+
+  beforeEach(function() {
+    controller = App.WizardStep4Controller.create();
+    services.forEach(function(serviceName) {
+      controller.pushObject(Ember.Object.create({
+        'serviceName':serviceName, 'isSelected': true, 'isHiddenOnSelectServicePage': false,
'isInstalled': false, 'isDisabled': 'HDFS' === serviceName, isDFS: 'HDFS' === serviceName
+      }));
+    });
+  });
 
   var generateSelectedServicesContent = function(selectedServiceNames) {
     var allServices = services.slice(0);
@@ -58,12 +66,6 @@ describe('App.WizardStep4Controller', function () {
     return allServices;
   };
 
-  services.forEach(function(serviceName) {
-    controller.pushObject(Ember.Object.create({
-      'serviceName':serviceName, 'isSelected': true, 'isHiddenOnSelectServicePage': false,
'isInstalled': false, 'isDisabled': 'HDFS' === serviceName, isDFS: 'HDFS' === serviceName
-    }));
-  });
-
   describe('#isSubmitDisabled', function () {
     it('should return false if at least one selected service is not installed', function
() {
       expect(controller.get('isSubmitDisabled')).to.equal(false);
@@ -322,6 +324,10 @@ describe('App.WizardStep4Controller', function () {
         {
           services: ['ATLAS', 'AMBARI_METRICS', 'SMARTSENSE'],
           errorsExpected: ['ambariInfraCheck']
+        },
+        {
+          services: ['LOGSEARCH', 'AMBARI_METRICS', 'SMARTSENSE'],
+          errorsExpected: ['ambariLogsearchCheck']
         }
       ],
       controllerNames = ['installerController', 'addServiceController'],
@@ -979,11 +985,75 @@ describe('App.WizardStep4Controller', function () {
           this.popup.onClose();
           expect(target.clb.calledWith(id)).to.be.true;
         });
-
       });
+    });
+  });
 
+  describe('#dependentServiceValidation', function() {
+
+    beforeEach(function() {
+      sinon.stub(controller, 'serviceValidation');
     });
 
+    afterEach(function() {
+      controller.serviceValidation.restore();
+      controller.clear();
+    });
+
+    it('serviceValidation should not be called when selected service does not exist', function()
{
+      controller.dependentServiceValidation('S1', 'S2', 'check', Em.K);
+      expect(controller.serviceValidation.called).to.be.false;
+    });
+
+    it('serviceValidation should not be called when service not selected', function() {
+      controller.pushObject(Em.Object.create({
+        serviceName: 'S1',
+        isSelected: false
+      }));
+      controller.dependentServiceValidation('S1', 'S2', 'check', Em.K);
+      expect(controller.serviceValidation.called).to.be.false;
+    });
+
+    it('serviceValidation should not be called when dependent service does not exist', function()
{
+      controller.pushObjects([
+        Em.Object.create({
+          serviceName: 'S1',
+          isSelected: true
+        })
+      ]);
+      controller.dependentServiceValidation('S1', 'S2', 'check', Em.K);
+      expect(controller.serviceValidation.called).to.be.false;
+    });
+
+    it('serviceValidation should not be called when dependent service is selected', function()
{
+      controller.pushObjects([
+        Em.Object.create({
+          serviceName: 'S1',
+          isSelected: true
+        }),
+        Em.Object.create({
+          serviceName: 'S2',
+          isSelected: true
+        })
+      ]);
+      controller.dependentServiceValidation('S1', 'S2', 'check', Em.K);
+      expect(controller.serviceValidation.called).to.be.false;
+    });
+
+    it('serviceValidation should be called when dependent service is not selected', function()
{
+      controller.pushObjects([
+        Em.Object.create({
+          serviceName: 'S1',
+          isSelected: true
+        }),
+        Em.Object.create({
+          serviceName: 'S2',
+          isSelected: false
+        })
+      ]);
+      controller.dependentServiceValidation('S1', 'S2', 'check', Em.K);
+      expect(controller.serviceValidation.calledOnce).to.be.true;
+    });
   });
 
 });

http://git-wip-us.apache.org/repos/asf/ambari/blob/01b0d00d/ambari-web/test/utils/configs/theme/theme_test.js
----------------------------------------------------------------------
diff --git a/ambari-web/test/utils/configs/theme/theme_test.js b/ambari-web/test/utils/configs/theme/theme_test.js
new file mode 100644
index 0000000..6aec271
--- /dev/null
+++ b/ambari-web/test/utils/configs/theme/theme_test.js
@@ -0,0 +1,621 @@
+/**
+ * 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.
+ */
+
+require('utils/configs/theme/theme');
+
+describe('App.configTheme', function() {
+
+  describe("#resolveConfigThemeConditions()", function () {
+
+    beforeEach(function() {
+      this.mockThemeCondition = sinon.stub(App.ThemeCondition, 'find');
+      sinon.stub(App.configTheme, 'calculateConfigCondition').returns(true);
+      this.mockId = sinon.stub(App.config, 'configId');
+      sinon.stub(App.configTheme, 'getThemeResource').returns(Em.Object.create({
+        configProperties: ['conf1']
+      }));
+    });
+
+    afterEach(function() {
+      this.mockId.restore();
+      this.mockThemeCondition.restore();
+      App.configTheme.calculateConfigCondition.restore();
+      App.configTheme.getThemeResource.restore();
+    });
+
+    it("theme configs empty", function() {
+      var configs = [Em.Object.create({
+        name: 'conf1',
+        filename: 'file1',
+        hiddenBySection: false
+      })];
+      this.mockThemeCondition.returns([
+        Em.Object.create({
+          configs: []
+        })
+      ]);
+      App.configTheme.resolveConfigThemeConditions(configs);
+      expect(App.configTheme.calculateConfigCondition.called).to.be.false;
+      expect(configs[0].get('hiddenBySection')).to.be.false;
+    });
+
+    it("theme resource is not 'config'", function() {
+      var configs = [Em.Object.create({
+        name: 'conf1',
+        filename: 'file1',
+        hiddenBySection: false
+      })];
+      this.mockThemeCondition.returns([
+        Em.Object.create({
+          configs: [{}],
+          resource: ''
+        })
+      ]);
+      App.configTheme.resolveConfigThemeConditions(configs);
+      expect(App.configTheme.calculateConfigCondition.called).to.be.false;
+      expect(configs[0].get('hiddenBySection')).to.be.false;
+    });
+
+    it("property_value_attributes is null", function() {
+      var configs = [Em.Object.create({
+        name: 'conf1',
+        filename: 'file1',
+        hiddenBySection: false
+      })];
+      this.mockThemeCondition.returns([
+        Em.Object.create({
+          configs: [{}],
+          resource: 'config',
+          then: {
+            property_value_attributes: null
+          },
+          id: 'c1'
+        })
+      ]);
+      App.configTheme.resolveConfigThemeConditions(configs);
+      expect(App.configTheme.calculateConfigCondition.calledOnce).to.be.true;
+      expect(App.configTheme.getThemeResource.called).to.be.false;
+      expect(configs[0].get('hiddenBySection')).to.be.false;
+    });
+
+    it("property_value_attributes.visible is null", function() {
+      var configs = [Em.Object.create({
+        name: 'conf1',
+        filename: 'file1',
+        hiddenBySection: false
+      })];
+      this.mockThemeCondition.returns([
+        Em.Object.create({
+          configs: [{}],
+          resource: 'config',
+          then: {
+            property_value_attributes: {
+              visible: null
+            }
+          },
+          id: 'c1'
+        })
+      ]);
+      App.configTheme.resolveConfigThemeConditions(configs);
+      expect(App.configTheme.calculateConfigCondition.calledOnce).to.be.true;
+      expect(App.configTheme.getThemeResource.called).to.be.false;
+      expect(configs[0].get('hiddenBySection')).to.be.false;
+    });
+
+    it("config not in the theme", function() {
+      var configs = [Em.Object.create({
+        name: 'conf1',
+        filename: 'file1',
+        hiddenBySection: false
+      })];
+      this.mockThemeCondition.returns([
+        Em.Object.create({
+          configs: [{}],
+          resource: 'config',
+          then: {
+            property_value_attributes: {
+              visible: true
+            }
+          },
+          id: 'c1'
+        })
+      ]);
+      this.mockId.returns('conf2');
+      App.configTheme.resolveConfigThemeConditions(configs);
+      expect(App.configTheme.calculateConfigCondition.calledOnce).to.be.true;
+      expect(App.configTheme.getThemeResource.calledOnce).to.be.true;
+      expect(configs[0].get('hiddenBySection')).to.be.false;
+    });
+
+    it("configCondition type is 'config' and hiddenBySection is true", function() {
+      var configs = [Em.Object.create({
+        name: 'conf1',
+        filename: 'file1',
+        hiddenBySection: true
+      })];
+      this.mockThemeCondition.returns([
+        Em.Object.create({
+          configs: [{}],
+          resource: 'config',
+          then: {
+            property_value_attributes: {
+              visible: true
+            }
+          },
+          id: 'c1',
+          type: 'config'
+        })
+      ]);
+      this.mockId.returns('conf1');
+      App.configTheme.resolveConfigThemeConditions(configs);
+      expect(App.configTheme.calculateConfigCondition.calledOnce).to.be.true;
+      expect(App.configTheme.getThemeResource.calledOnce).to.be.true;
+      expect(configs[0].get('hiddenBySection')).to.be.true;
+    });
+
+    it("hiddenBySection should be true", function() {
+      var configs = [Em.Object.create({
+        name: 'conf1',
+        filename: 'file1',
+        hiddenBySection: false
+      })];
+      this.mockThemeCondition.returns([
+        Em.Object.create({
+          configs: [{}],
+          resource: 'config',
+          then: {
+            property_value_attributes: {
+              visible: false
+            }
+          },
+          id: 'c1',
+          type: 'config'
+        })
+      ]);
+      this.mockId.returns('conf1');
+      App.configTheme.resolveConfigThemeConditions(configs);
+      expect(App.configTheme.calculateConfigCondition.calledOnce).to.be.true;
+      expect(App.configTheme.getThemeResource.calledOnce).to.be.true;
+      expect(configs[0].get('hiddenBySection')).to.be.true;
+    });
+
+    it("hiddenBySection should be false", function() {
+      var configs = [Em.Object.create({
+        name: 'conf1',
+        filename: 'file1',
+        hiddenBySection: true
+      })];
+      this.mockThemeCondition.returns([
+        Em.Object.create({
+          configs: [{}],
+          resource: 'config',
+          then: {
+            property_value_attributes: {
+              visible: true
+            }
+          },
+          id: 'c1'
+        })
+      ]);
+      this.mockId.returns('conf1');
+      App.configTheme.resolveConfigThemeConditions(configs);
+      expect(App.configTheme.calculateConfigCondition.calledOnce).to.be.true;
+      expect(App.configTheme.getThemeResource.calledOnce).to.be.true;
+      expect(configs[0].get('hiddenBySection')).to.be.false;
+    });
+  });
+
+  describe("#getThemeResource()", function () {
+
+    beforeEach(function() {
+      sinon.stub(App.SubSection, 'find').returns([Em.Object.create({name: 'ss1'})]);
+      sinon.stub(App.SubSectionTab, 'find').returns([Em.Object.create({name: 'sst1'})]);
+    });
+
+    afterEach(function() {
+      App.SubSection.find.restore();
+      App.SubSectionTab.find.restore();
+    });
+
+    it("configCondition with unknown type", function() {
+      expect(App.configTheme.getThemeResource(Em.Object.create())).to.be.null;
+    });
+
+    it("configCondition with subsection type", function() {
+      expect(App.configTheme.getThemeResource(Em.Object.create({
+        name: 'ss1',
+        type: 'subsection'
+      }))).to.be.eql(Em.Object.create({name: 'ss1'}));
+    });
+
+    it("configCondition with subsectionTab type", function() {
+      expect(App.configTheme.getThemeResource(Em.Object.create({
+        name: 'sst1',
+        type: 'subsectionTab'
+      }))).to.be.eql(Em.Object.create({name: 'sst1'}));
+    });
+
+    it("configCondition with config type", function() {
+      expect(App.configTheme.getThemeResource(Em.Object.create({
+        configName: 'conf1',
+        fileName: 'file1',
+        type: 'config'
+      }))).to.be.eql(Em.Object.create({
+          configProperties: ['conf1__file1']
+        }));
+    });
+  });
+
+  describe("#getConfigThemeActions()", function () {
+
+    beforeEach(function() {
+      sinon.stub(App.configTheme, 'getConfigActions').returns([
+        Em.Object.create({
+          if: '',
+          then: 'add',
+          else: 'delete',
+          hostComponent: 'C1'
+        })
+      ]);
+      this.mock = sinon.stub(App.configTheme, 'calculateConfigCondition');
+    });
+
+    afterEach(function() {
+      this.mock.restore();
+      App.configTheme.getConfigActions.restore();
+    });
+
+    it("should add component", function() {
+      this.mock.returns(true);
+      expect(App.configTheme.getConfigThemeActions([], [])).to.be.eql({
+        add: ['C1'],
+        delete: []
+      });
+    });
+
+    it("should delete component", function() {
+      this.mock.returns(false);
+      expect(App.configTheme.getConfigThemeActions([], [])).to.be.eql({
+        add: [],
+        delete: ['C1']
+      });
+    });
+  });
+
+  describe("#getConfigActions()", function () {
+
+    beforeEach(function() {
+      this.mock = sinon.stub(App.ConfigAction, 'find');
+    });
+
+    afterEach(function() {
+      this.mock.restore();
+    });
+
+    it("action has empty configs", function() {
+      this.mock.returns([
+        Em.Object.create({
+          configs: []
+        })
+      ]);
+      expect(App.configTheme.getConfigActions([], [])).to.be.empty;
+    });
+
+    it("empty configs", function() {
+      this.mock.returns([
+        Em.Object.create({
+          configs: [{
+            fileName: 'file1',
+            configName: 'conf1'
+          }]
+        })
+      ]);
+      expect(App.configTheme.getConfigActions([], [])).to.be.empty;
+    });
+
+    it("empty storedConfig, config not changed", function() {
+      this.mock.returns([
+        Em.Object.create({
+          configs: [{
+            fileName: 'file1',
+            configName: 'conf1'
+          }]
+        })
+      ]);
+      var config = Em.Object.create({
+        filename: 'file1',
+        name: 'conf1',
+        savedValue: 'val1',
+        value: 'val1',
+        recommendedValue: 'val1'
+      });
+      expect(App.configTheme.getConfigActions([config], [])).to.be.empty;
+    });
+
+    it("empty storedConfig, savedValue changed", function() {
+      this.mock.returns([
+        Em.Object.create({
+          configs: [{
+            fileName: 'file1',
+            configName: 'conf1'
+          }]
+        })
+      ]);
+      var config = Em.Object.create({
+        filename: 'file1',
+        name: 'conf1',
+        savedValue: 'val1',
+        value: 'val2',
+        recommendedValue: 'val1'
+      });
+      expect(App.configTheme.getConfigActions([config], [])).to.be.eql([Em.Object.create({
+        configs: [{
+          fileName: 'file1',
+          configName: 'conf1'
+        }]
+      })]);
+    });
+
+    it("empty storedConfig, recommendedValue changed", function() {
+      this.mock.returns([
+        Em.Object.create({
+          configs: [{
+            fileName: 'file1',
+            configName: 'conf1'
+          }]
+        })
+      ]);
+      var config = Em.Object.create({
+        filename: 'file1',
+        name: 'conf1',
+        value: 'val2',
+        recommendedValue: 'val1'
+      });
+      expect(App.configTheme.getConfigActions([config], [])).to.be.eql([Em.Object.create({
+        configs: [{
+          fileName: 'file1',
+          configName: 'conf1'
+        }]
+      })]);
+    });
+
+    it("storedConfig not changed", function() {
+      this.mock.returns([
+        Em.Object.create({
+          configs: [{
+            fileName: 'file1',
+            configName: 'conf1'
+          }]
+        })
+      ]);
+      var config = Em.Object.create({
+        filename: 'file1',
+        name: 'conf1',
+        savedValue: 'val1',
+        value: 'val1',
+        recommendedValue: 'val1'
+      });
+      var storedConfig = {
+        filename: 'file1',
+        name: 'conf1',
+        value: 'val1'
+      };
+      expect(App.configTheme.getConfigActions([config], [storedConfig])).to.be.empty;
+    });
+
+    it("storedConfig changed", function() {
+      this.mock.returns([
+        Em.Object.create({
+          configs: [{
+            fileName: 'file1',
+            configName: 'conf1'
+          }]
+        })
+      ]);
+      var config = Em.Object.create({
+        filename: 'file1',
+        name: 'conf1',
+        savedValue: 'val1',
+        value: 'val1',
+        recommendedValue: 'val1'
+      });
+      var storedConfig = {
+        filename: 'file1',
+        name: 'conf1',
+        value: 'val2'
+      };
+      expect(App.configTheme.getConfigActions([config], [storedConfig])).to.be.eql([Em.Object.create({
+        configs: [{
+          fileName: 'file1',
+          configName: 'conf1'
+        }]
+      })]);
+    });
+  });
+
+  describe("#calculateConfigCondition()", function () {
+    var testCases = [
+      {
+        ifStatement: "${file1/conf1}",
+        serviceConfigs: [],
+        expected: false
+      },
+      {
+        ifStatement: "${file1/conf1}",
+        serviceConfigs: [Em.Object.create({
+          filename: 'file1.xml',
+          name: 'conf1',
+          value: 'true'
+        })],
+        expected: true
+      },
+      {
+        ifStatement: "${file1/conf1}&&${file1/conf2}",
+        serviceConfigs: [
+          Em.Object.create({
+            filename: 'file1.xml',
+            name: 'conf1',
+            value: 'true'
+          }),
+          Em.Object.create({
+            filename: 'file1.xml',
+            name: 'conf2',
+            value: 'true'
+          })
+        ],
+        expected: true
+      },
+      {
+        ifStatement: "${file1/conf1}&&${file1/conf2}",
+        serviceConfigs: [
+          Em.Object.create({
+            filename: 'file1.xml',
+            name: 'conf1',
+            value: 'false'
+          }),
+          Em.Object.create({
+            filename: 'file1.xml',
+            name: 'conf2',
+            value: 'false'
+          })
+        ],
+        expected: false
+      },
+      {
+        ifStatement: "${file1/conf1}&&${file1/conf2}===false",
+        serviceConfigs: [
+          Em.Object.create({
+            filename: 'file1.xml',
+            name: 'conf1',
+            value: 'true'
+          }),
+          Em.Object.create({
+            filename: 'file1.xml',
+            name: 'conf2',
+            value: 'false'
+          })
+        ],
+        expected: true
+      },
+      {
+        ifStatement: "${file1/conf1}&&${file1/conf2}",
+        serviceConfigs: [
+          Em.Object.create({
+            filename: 'file1.xml',
+            name: 'conf1',
+            value: 'true'
+          }),
+          Em.Object.create({
+            filename: 'file1.xml',
+            name: 'conf2',
+            value: 'false'
+          })
+        ],
+        expected: false
+      },
+      {
+        ifStatement: "${file1/conf1}===false&&${file1/conf2}===false",
+        serviceConfigs: [
+          Em.Object.create({
+            filename: 'file1.xml',
+            name: 'conf1',
+            value: 'false'
+          }),
+          Em.Object.create({
+            filename: 'file1.xml',
+            name: 'conf2',
+            value: 'false'
+          })
+        ],
+        expected: true
+      },
+      {
+        ifStatement: "${file1/conf1}||${file1/conf2}",
+        serviceConfigs: [
+          Em.Object.create({
+            filename: 'file1.xml',
+            name: 'conf1',
+            value: 'true'
+          }),
+          Em.Object.create({
+            filename: 'file1.xml',
+            name: 'conf2',
+            value: 'true'
+          })
+        ],
+        expected: true
+      },
+      {
+        ifStatement: "${file1/conf1}||${file1/conf2}",
+        serviceConfigs: [
+          Em.Object.create({
+            filename: 'file1.xml',
+            name: 'conf1',
+            value: 'false'
+          }),
+          Em.Object.create({
+            filename: 'file1.xml',
+            name: 'conf2',
+            value: 'true'
+          })
+        ],
+        expected: true
+      },
+      {
+        ifStatement: "${file1/conf1}||${file1/conf2}",
+        serviceConfigs: [
+          Em.Object.create({
+            filename: 'file1.xml',
+            name: 'conf1',
+            value: 'true'
+          }),
+          Em.Object.create({
+            filename: 'file1.xml',
+            name: 'conf2',
+            value: 'false'
+          })
+        ],
+        expected: true
+      },
+      {
+        ifStatement: "${file1/conf1}||${file1/conf2}",
+        serviceConfigs: [
+          Em.Object.create({
+            filename: 'file1.xml',
+            name: 'conf1',
+            value: 'false'
+          }),
+          Em.Object.create({
+            filename: 'file1.xml',
+            name: 'conf2',
+            value: 'false'
+          })
+        ],
+        expected: false
+      }
+    ];
+
+    testCases.forEach(function(test) {
+      it("ifStatement: " + test.ifStatement +
+         "serviceConfigs: " + JSON.stringify(test.serviceConfigs), function() {
+        expect(App.configTheme.calculateConfigCondition(test.ifStatement, test.serviceConfigs)).to.be.equal(test.expected);
+      });
+    });
+  });
+
+});


Mime
View raw message