Repository: ambari
Updated Branches:
  refs/heads/trunk a13e96e75 -> 917c79151


AMBARI-20507 Cover config mappers with unit tests. (atkach)


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

Branch: refs/heads/trunk
Commit: 917c79151f8eaec23b6258bcf90bdaad8926d251
Parents: a13e96e
Author: Andrii Tkach <atk...@apache.org>
Authored: Mon Mar 20 20:13:37 2017 +0200
Committer: Andrii Tkach <atk...@apache.org>
Committed: Tue Mar 21 11:36:33 2017 +0200

----------------------------------------------------------------------
 .../configs/service_config_version_mapper.js    |  56 +-
 ambari-web/app/mappers/configs/themes_mapper.js | 185 ++---
 ambari-web/test/init_test.js                    |   8 +-
 .../configs/config_groups_mapper_test.js        | 154 ++--
 .../service_config_version_mapper_test.js       | 279 ++++---
 .../test/mappers/configs/themes_mapper_test.js  | 720 ++++++++++++++-----
 6 files changed, 906 insertions(+), 496 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ambari/blob/917c7915/ambari-web/app/mappers/configs/service_config_version_mapper.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/mappers/configs/service_config_version_mapper.js 
b/ambari-web/app/mappers/configs/service_config_version_mapper.js
index e95c925..e63663f 100644
--- a/ambari-web/app/mappers/configs/service_config_version_mapper.js
+++ b/ambari-web/app/mappers/configs/service_config_version_mapper.js
@@ -41,14 +41,9 @@ App.serviceConfigVersionsMapper = 
App.QuickDataMapper.create({
     var result = [];
     var itemIds = {};
     var serviceToHostMap = {};
-    var currentVersionsMap = {};
 
     if (json && json.items) {
-      App.ServiceConfigVersion.find().forEach(function (v) {
-        if (v.get('isCurrent')) {
-          currentVersionsMap[v.get('serviceName') + "_" + v.get('groupName')] 
= v;
-        }
-      });
+      var currentVersionsMap = this.getCurrentVersionMap();
 
       json.items.forEach(function (item, index) {
         var parsedItem = this.parseIt(item, this.get('config'));
@@ -76,23 +71,7 @@ App.serviceConfigVersionsMapper = 
App.QuickDataMapper.create({
         App.router.set('mainConfigHistoryController.filteredCount', itemTotal);
       }
 
-      /**
-       * this code sets hostNames for default config group
-       * by excluding hostNames that belongs to not default groups
-       * from list of all hosts
-       */
-      Object.keys(serviceToHostMap).forEach(function(sName) {
-        var defaultHostNames = App.get('allHostNames');
-        for (var i = 0; i < serviceToHostMap[sName].length; i++) {
-          defaultHostNames = 
defaultHostNames.without(serviceToHostMap[sName][i]);
-        }
-        var defVer = result.find(function(v) {
-          return v.is_current && v.group_name === 
App.ServiceConfigGroup.defaultGroupName && v.service_name == sName;
-        });
-        if (defVer) {
-          defVer.hosts = defaultHostNames;
-        }
-      });
+      this.setHostsForDefaultCG(serviceToHostMap, result);
 
       // If on config history page, need to clear the model
       if (App.router.get('currentState.name') === 'configHistory') {
@@ -104,6 +83,37 @@ App.serviceConfigVersionsMapper = 
App.QuickDataMapper.create({
   },
 
   /**
+   * sets hostNames for default config group by excluding hostNames
+   * that belongs to not default groups from list of all hosts
+   * @param {object} serviceToHostMap
+   * @param {array} result
+   */
+  setHostsForDefaultCG: function(serviceToHostMap, result) {
+    Object.keys(serviceToHostMap).forEach(function(sName) {
+      var defaultHostNames = App.get('allHostNames');
+      for (var i = 0; i < serviceToHostMap[sName].length; i++) {
+        defaultHostNames = 
defaultHostNames.without(serviceToHostMap[sName][i]);
+      }
+      var defVer = result.find(function(v) {
+        return v.is_current && v.group_name === 
App.ServiceConfigGroup.defaultGroupName && v.service_name === sName;
+      });
+      if (defVer) {
+        defVer.hosts = defaultHostNames;
+      }
+    });
+  },
+
+  getCurrentVersionMap: function() {
+    var currentVersionsMap = {};
+    App.ServiceConfigVersion.find().forEach(function (v) {
+      if (v.get('isCurrent')) {
+        currentVersionsMap[v.get('serviceName') + "_" + v.get('groupName')] = 
v;
+      }
+    });
+    return currentVersionsMap;
+  },
+
+  /**
    * Conventional method to generate id for instances of 
<code>App.ServiceConfigVersion</code> model.
    *
    * @param {String} serviceName

http://git-wip-us.apache.org/repos/asf/ambari/blob/917c7915/ambari-web/app/mappers/configs/themes_mapper.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/mappers/configs/themes_mapper.js 
b/ambari-web/app/mappers/configs/themes_mapper.js
index 1e98b34..0bb2dfc 100644
--- a/ambari-web/app/mappers/configs/themes_mapper.js
+++ b/ambari-web/app/mappers/configs/themes_mapper.js
@@ -110,47 +110,7 @@ App.themesMapper = App.QuickDataMapper.create({
             Em.get(tab, "layout.sections").forEach(function(section) {
               var parsedSection = this.parseIt(section, 
this.get("sectionConfig"));
               parsedSection.tab_id = parsedTab.id;
-
-              if (section.subsections) {
-                var subSections = [];
-                var subSectionConditions = [];
-                section.subsections.forEach(function(subSection) {
-                  var parsedSubSection = this.parseIt(subSection, 
this.get("subSectionConfig"));
-                  parsedSubSection.section_id = parsedSection.id;
-
-                  if (subSection['subsection-tabs']) {
-                    var subSectionTabs = [];
-                    var subSectionTabConditions = [];
-
-                    subSection['subsection-tabs'].forEach(function 
(subSectionTab) {
-                      var parsedSubSectionTab = this.parseIt(subSectionTab, 
this.get("subSectionTabConfig"));
-                      parsedSubSectionTab.sub_section_id = parsedSubSection.id;
-                      if (parsedSubSectionTab['depends_on']) {
-                        subSectionTabConditions.push(parsedSubSectionTab);
-                      }
-                      subSectionTabs.push(parsedSubSectionTab);
-                    }, this);
-                    subSectionTabs[0].is_active = true;
-                    if (subSectionTabConditions.length) {
-                      var type = 'subsectionTab';
-                      this.mapThemeConditions(subSectionTabConditions, type);
-                    }
-                    App.store.safeLoadMany(this.get("subSectionTabModel"), 
subSectionTabs);
-                    parsedSubSection.sub_section_tabs = 
subSectionTabs.mapProperty("id");
-                  }
-                  if (parsedSubSection['depends_on']) {
-                    subSectionConditions.push(parsedSubSection);
-                  }
-                  subSections.push(parsedSubSection);
-                }, this);
-                if (subSectionConditions.length) {
-                  var type = 'subsection';
-                  this.mapThemeConditions(subSectionConditions, type);
-                }
-                App.store.safeLoadMany(this.get("subSectionModel"), 
subSections);
-                parsedSection.sub_sections = subSections.mapProperty("id");
-              }
-
+              this.loadSubSections(section, parsedSection);
               sections.push(parsedSection);
             }, this);
 
@@ -165,6 +125,53 @@ App.themesMapper = App.QuickDataMapper.create({
     }, this);
   },
 
+  loadSubSections: function(section, parsedSection) {
+    if (section.subsections) {
+      var subSections = [];
+      var subSectionConditions = [];
+      section.subsections.forEach(function(subSection) {
+        var parsedSubSection = this.parseIt(subSection, 
this.get("subSectionConfig"));
+        parsedSubSection.section_id = parsedSection.id;
+
+        this.loadSubSectionTabs(subSection, parsedSubSection);
+        if (parsedSubSection['depends_on']) {
+          subSectionConditions.push(parsedSubSection);
+        }
+        subSections.push(parsedSubSection);
+      }, this);
+      if (subSectionConditions.length) {
+        var type = 'subsection';
+        this.mapThemeConditions(subSectionConditions, type);
+      }
+      App.store.safeLoadMany(this.get("subSectionModel"), subSections);
+      parsedSection.sub_sections = subSections.mapProperty("id");
+    }
+  },
+
+
+  loadSubSectionTabs: function(subSection, parsedSubSection) {
+    if (subSection['subsection-tabs']) {
+      var subSectionTabs = [];
+      var subSectionTabConditions = [];
+
+      subSection['subsection-tabs'].forEach(function (subSectionTab) {
+        var parsedSubSectionTab = this.parseIt(subSectionTab, 
this.get("subSectionTabConfig"));
+        parsedSubSectionTab.sub_section_id = parsedSubSection.id;
+        if (parsedSubSectionTab['depends_on']) {
+          subSectionTabConditions.push(parsedSubSectionTab);
+        }
+        subSectionTabs.push(parsedSubSectionTab);
+      }, this);
+      subSectionTabs[0].is_active = true;
+      if (subSectionTabConditions.length) {
+        var type = 'subsectionTab';
+        this.mapThemeConditions(subSectionTabConditions, type);
+      }
+      App.store.safeLoadMany(this.get("subSectionTabModel"), subSectionTabs);
+      parsedSubSection.sub_section_tabs = subSectionTabs.mapProperty("id");
+    }
+  },
+
   /**
    * create tie between <code>stackConfigProperty<code> and 
<code>subSection<code>
    *
@@ -176,69 +183,26 @@ App.themesMapper = App.QuickDataMapper.create({
       var configId = this.getConfigId(configLink);
       var subSectionId = configLink["subsection-name"];
       var subSectionTabId = configLink["subsection-tab-name"];
+      var configProperty = App.configsCollection.getConfig(configId);
+      var dependsOnConfigs = configLink["depends-on"] || [];
+
       if (subSectionTabId) {
         var subSectionTab = App.SubSectionTab.find(subSectionTabId);
       } else if (subSectionId) {
         var subSection = App.SubSection.find(subSectionId);
       }
-      var configProperty = App.configsCollection.getConfig(configId);
 
-      var dependsOnConfigs = configLink["depends-on"] || [];
 
       if (configProperty && subSection) {
-        var cp = 
subSection.get('configProperties').contains(configProperty.id);
-        if (!cp) {
+        if (!subSection.get('configProperties').contains(configProperty.id)) {
           subSection.set('configProperties', 
subSection.get('configProperties').concat(configProperty.id));
         }
       } else if (configProperty && subSectionTab) {
-        var cp = 
subSectionTab.get('configProperties').contains(configProperty.id);
-        if (!cp) {
+        if 
(!subSectionTab.get('configProperties').contains(configProperty.id)) {
           subSectionTab.set('configProperties', 
subSectionTab.get('configProperties').concat(configProperty.id));
         }
       } else {
-        var valueAttributes = configLink["property_value_attributes"];
-        if (valueAttributes) {
-          var isUiOnlyProperty = valueAttributes["ui_only_property"];
-          var isCopy = valueAttributes["copy"] || '';
-          // UI only configs are mentioned in the themes for supporting 
widgets that is not intended for setting a value
-          // And thus is affiliated with fake config property termed as ui 
only config property
-          if (isUiOnlyProperty && subSection) {
-            var split = configLink.config.split("/");
-            var fileName =  split[0] + '.xml', configName = split[1], id = 
App.config.configId(configName, fileName);
-            var uiOnlyConfig = App.configsCollection.getConfig(id);
-            if (!uiOnlyConfig) {
-              configProperty = {
-                id: id,
-                isRequiredByAgent: false,
-                showLabel: false,
-                isOverridable: false,
-                recommendedValue: true,
-                name: configName,
-                isUserProperty: false,
-                filename: fileName,
-                fileName: fileName,
-                isNotSaved: false,
-                serviceName: serviceName,
-                copy: isCopy,
-                stackName: App.get('currentStackName'),
-                stackVersion: App.get('currentStackVersionNumber')
-              };
-              App.configsCollection.add(configProperty);
-
-              if (subSection) {
-                var cp = 
subSection.get('configProperties').contains(configProperty.id);
-                if (!cp) {
-                  subSection.set('configProperties', 
subSection.get('configProperties').concat(configProperty.id));
-                }
-              } else if (subSectionTab) {
-                var cp = 
subSectionTab.get('configProperties').contains(configProperty.id);
-                if (!cp) {
-                  subSectionTab.set('configProperties', 
subSectionTab.get('configProperties').concat(configProperty.id));
-                }
-              }
-            }
-          }
-        }
+        configProperty = this.getConfigByAttributes(configProperty, 
configLink, subSection, subSectionTab, serviceName);
       }
 
       // map all the configs which conditionally affect the value attributes 
of a config
@@ -249,6 +213,45 @@ App.themesMapper = App.QuickDataMapper.create({
     }, this);
   },
 
+  getConfigByAttributes: function(configProperty, configLink, subSection, 
subSectionTab, serviceName) {
+    var valueAttributes = configLink["property_value_attributes"];
+    if (valueAttributes) {
+      var isUiOnlyProperty = valueAttributes["ui_only_property"];
+      var isCopy = valueAttributes["copy"] || '';
+      // UI only configs are mentioned in the themes for supporting widgets 
that is not intended for setting a value
+      // And thus is affiliated with fake config property termed as ui only 
config property
+      if (isUiOnlyProperty && subSection) {
+        var split = configLink.config.split("/");
+        var fileName =  split[0] + '.xml', configName = split[1], id = 
App.config.configId(configName, fileName);
+        var uiOnlyConfig = App.configsCollection.getConfig(id);
+        if (!uiOnlyConfig) {
+          configProperty = {
+            id: id,
+            isRequiredByAgent: false,
+            showLabel: false,
+            isOverridable: false,
+            recommendedValue: true,
+            name: configName,
+            isUserProperty: false,
+            filename: fileName,
+            fileName: fileName,
+            isNotSaved: false,
+            serviceName: serviceName,
+            copy: isCopy,
+            stackName: App.get('currentStackName'),
+            stackVersion: App.get('currentStackVersionNumber')
+          };
+          App.configsCollection.add(configProperty);
+
+          if (!subSection.get('configProperties').contains(configProperty.id)) 
{
+            subSection.set('configProperties', 
subSection.get('configProperties').concat(configProperty.id));
+          }
+        }
+      }
+    }
+    return configProperty;
+  },
+
   /**
    *
    * @param configConditions: Array
@@ -328,7 +331,7 @@ App.themesMapper = App.QuickDataMapper.create({
         var configName = split[1];
         var uiOnlyProperty = App.configsCollection.getConfigByName(configName, 
fileName);
         if (uiOnlyProperty) {
-          uiOnlyProperty.widget = widget.widget;
+          uiOnlyProperty.set('widget', widget.widget);
           uiOnlyProperty.set('widgetType', Em.get(widget, 'widget.type'));
         }
       }

http://git-wip-us.apache.org/repos/asf/ambari/blob/917c7915/ambari-web/test/init_test.js
----------------------------------------------------------------------
diff --git a/ambari-web/test/init_test.js b/ambari-web/test/init_test.js
index cc97174..02188ff 100644
--- a/ambari-web/test/init_test.js
+++ b/ambari-web/test/init_test.js
@@ -93,4 +93,10 @@ if (!Array.prototype.includes) {
 
 Number.isFinite = Number.isFinite || function(value) {
   return typeof value === 'number' && isFinite(value);
-};
\ No newline at end of file
+};
+
+if (!window.performance) {
+  window.performance = {
+    now: Em.K
+  };
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ambari/blob/917c7915/ambari-web/test/mappers/configs/config_groups_mapper_test.js
----------------------------------------------------------------------
diff --git a/ambari-web/test/mappers/configs/config_groups_mapper_test.js 
b/ambari-web/test/mappers/configs/config_groups_mapper_test.js
index 08a9598..457a404 100644
--- a/ambari-web/test/mappers/configs/config_groups_mapper_test.js
+++ b/ambari-web/test/mappers/configs/config_groups_mapper_test.js
@@ -19,10 +19,8 @@
 var App = require('app');
 require('mappers/configs/config_groups_mapper');
 
-/**
- * not using this mapper
- */
-describe.skip('App.configGroupsMapper', function () {
+
+describe('App.configGroupsMapper', function () {
 
   var allHosts = App.get('allHostNames');
   var defaultAllHosts = ['host1', 'host2', 'host3'];
@@ -56,90 +54,54 @@ describe.skip('App.configGroupsMapper', function () {
             "id" : 2,
             "tag" : "Service1"
           }
-        },
-        {
-          "ConfigGroup" : {
-            "cluster_name" : "1",
-            "description" : "hdfs2",
-            "desired_configs" : [ ],
-            "group_name" : "hdfs2",
-            "hosts" : [
-              {
-                "host_name" : "host2"
-              }
-            ],
-            "id" : 3,
-            "tag" : "Service1"
-          }
-        },
-        {
-          "ConfigGroup" : {
-            "cluster_name" : "1",
-            "description" : "yarn1",
-            "desired_configs" : [ ],
-            "group_name" : "yarn1",
-            "hosts" : [
-              {
-                "host_name" : "host1"
-              },
-              {
-                "host_name" : "host2"
-              }
-            ],
-            "id" : 4,
-            "tag" : "Service2"
-          }
         }
       ]
     };
 
     beforeEach(function () {
-      App.resetDsStoreTypeMap(App.ServiceConfigGroup);
-      App.resetDsStoreTypeMap(App.Service);
-      sinon.stub(App.store, 'commit', Em.K);
+      sinon.stub(App.store, 'safeLoadMany', Em.K);
+      sinon.stub(App.configGroupsMapper, 'generateDefaultGroup').returns({id: 
'default', is_default: true});
     });
     afterEach(function(){
-      App.store.commit.restore();
+      App.store.safeLoadMany.restore();
+      App.configGroupsMapper.generateDefaultGroup.restore();
     });
 
-    it('should not do anything as there is no serviceName', function() {
+    it('should not call safeLoadMany when no service provided', function() {
       App.configGroupsMapper.map(json);
-      expect(App.ServiceConfigGroup.find().get('length')).to.equal(0);
-    });
-
-    it('should generate default groups for services', function() {
-      App.Service.createRecord({'id': 'Service1'});
-      App.configGroupsMapper.map(null, ["Service1"]);
-      expect(App.ServiceConfigGroup.find().get('length')).to.equal(1);
-      
expect(App.ServiceConfigGroup.find('Service10').get('id')).to.equal('Service10');
-      
expect(App.ServiceConfigGroup.find('Service10').get('configGroupId')).to.equal(-1);
-      
expect(App.ServiceConfigGroup.find('Service10').get('name')).to.equal('Service1 
Default');
-      
expect(App.ServiceConfigGroup.find('Service10').get('description')).to.equal('Default
 cluster level Service1 configuration');
-      
expect(App.ServiceConfigGroup.find('Service10').get('hostNames')).to.eql(defaultAllHosts);
-      
expect(App.ServiceConfigGroup.find('Service10').get('serviceName')).to.equal('Service1');
-      
expect(App.ServiceConfigGroup.find('Service10').get('service.id')).to.equal('Service1');
+      expect(App.store.safeLoadMany.called).to.be.false;
     });
 
-    it('should generate groups form json and default config groups', 
function() {
-      App.Service.createRecord({'id': 'Service1'});
-      App.Service.createRecord({'id': 'Service2'});
-      App.configGroupsMapper.map(json, ["Service1", "Service2"]);
-      expect(App.ServiceConfigGroup.find().get('length')).to.equal(5);
-      
expect(App.ServiceConfigGroup.find().mapProperty('id')).to.eql(["Service12", 
"Service13", "Service24", "Service10", "Service20"]);
+    it('should call safeLoadMany when service provided', function() {
+      App.configGroupsMapper.map(null, null, ['S1']);
+      expect(App.store.safeLoadMany.getCall(0).args[1]).to.be.eql([{id: 
'default', is_default: true}]);
     });
 
-    it('should generate groups form json and default config groups and check 
data', function() {
-      App.Service.createRecord({'id': 'Service1'});
-      App.Service.createRecord({'id': 'Service2'});
-      App.configGroupsMapper.map(json, ["Service1", "Service2"]);
-
-      
expect(App.ServiceConfigGroup.find('Service12').get('id')).to.equal('Service12');
-      
expect(App.ServiceConfigGroup.find('Service12').get('configGroupId')).to.equal(2);
-      
expect(App.ServiceConfigGroup.find('Service12').get('name')).to.equal('1');
-      
expect(App.ServiceConfigGroup.find('Service12').get('description')).to.equal('1');
-      
expect(App.ServiceConfigGroup.find('Service12').get('hostNames')).to.eql(["host1"]);
-      
expect(App.ServiceConfigGroup.find('Service12').get('serviceName')).to.equal('Service1');
-      
expect(App.ServiceConfigGroup.find('Service12').get('service.id')).to.equal('Service1');
+    it('should call safeLoadMany when json provided', function() {
+      App.configGroupsMapper.map(json, null, ['S1']);
+      expect(App.store.safeLoadMany.getCall(0).args[1]).to.be.eql([
+        {
+          "description": "1",
+          "desired_configs": [
+            {
+              "tag": "version1426088081862",
+              "type": "hadoop-env"
+            }
+          ],
+          "hosts": [
+            "host1"
+          ],
+          "id": 2,
+          "name": "1",
+          "parent_config_group_id": "Service1_Default",
+          "service_id": "Service1",
+          "service_name": "Service1"
+        },
+        {
+          id: 'default',
+          is_default: true
+        }
+      ]);
     });
   });
 
@@ -147,39 +109,51 @@ describe.skip('App.configGroupsMapper', function () {
     var tests = [
       {
         service: 's1',
-        hosts: ['h1'],
+        hosts: ['host1'],
         res: {
-          id: 's10',
-          config_group_id: '-1',
-          name: 's1 Default',
+          id: 's1_Default',
+          name: 'Default',
           service_name: 's1',
-          description: 'Default cluster level s1 configuration',
-          host_names: ['h1'],
-          service_id: 's1'
+          description: 'Default cluster level S1 configuration',
+          hosts: ['host1'],
+          child_config_groups: [],
+          service_id: 's1',
+          desired_configs: [],
+          properties: [],
+          is_default: true
         },
         m: 'with hosts'
       },
       {
         service: 's1',
+        childConfigGroups: [{}],
         res: {
-          id: 's10',
-          config_group_id: '-1',
-          name: 's1 Default',
+          id: 's1_Default',
+          name: 'Default',
           service_name: 's1',
-          description: 'Default cluster level s1 configuration',
-          host_names: defaultAllHosts,
-          service_id: 's1'
+          description: 'Default cluster level S1 configuration',
+          hosts: ['host2', 'host3', 'host1'],
+          child_config_groups: [{}],
+          service_id: 's1',
+          desired_configs: [],
+          properties: [],
+          is_default: true
         },
-        m: 'without hosts'
+        m: 'without hosts, with childConfigGroups'
       }
     ];
 
+    beforeEach(function() {
+      sinon.stub(App.configGroupsMapper, '_getAllHosts').returns(['host2', 
'host3', 'host1']);
+    });
+    afterEach(function() {
+      App.configGroupsMapper._getAllHosts.restore();
+    });
 
     tests.forEach(function(t) {
       it('generates default config group mock object ' + t.m, function() {
-        expect(App.configGroupsMapper.generateDefaultGroup(t.service, 
t.hosts)).to.be.eql(t.res);
+        expect(App.configGroupsMapper.generateDefaultGroup(t.service, t.hosts, 
t.childConfigGroups)).to.be.eql(t.res);
       });
     });
-
   });
 });

http://git-wip-us.apache.org/repos/asf/ambari/blob/917c7915/ambari-web/test/mappers/configs/service_config_version_mapper_test.js
----------------------------------------------------------------------
diff --git 
a/ambari-web/test/mappers/configs/service_config_version_mapper_test.js 
b/ambari-web/test/mappers/configs/service_config_version_mapper_test.js
index c38c5db..d99864a 100644
--- a/ambari-web/test/mappers/configs/service_config_version_mapper_test.js
+++ b/ambari-web/test/mappers/configs/service_config_version_mapper_test.js
@@ -19,140 +19,183 @@
 var App = require('app');
 require('mappers/configs/service_config_version_mapper');
 
-describe.skip('App.serviceConfigVersionsMapper', function () {
+describe('App.serviceConfigVersionsMapper', function () {
 
-  var allHosts = App.get('allHostNames');
-  var defaultAllHosts = ['host1', 'host2', 'host3'];
-  beforeEach(function () {
-    App.set('allHostNames', defaultAllHosts);
-  });
-  afterEach(function(){
-    App.set('allHostNames', allHosts);
-  });
+  describe('#map', function() {
+    var json = {
+      itemTotal: 2,
+      items: [
+        {
+          service_name: 'S1',
+          service_config_version: 'v1',
+          is_current: false,
+          createtime: 1,
+          group_id: 1,
+          user: 'admin',
+          is_cluster_compatible: true,
+          group_name: 'g1',
+          service_config_version_note: 'notes...',
+          stack_id: 'HDP-1',
+          hosts: ['host1']
+        },
+        {
+          service_name: 'S1',
+          service_config_version: 'v1',
+          is_current: true,
+          createtime: 1,
+          group_id: -1,
+          user: 'admin',
+          is_cluster_compatible: true,
+          group_name: 'g2',
+          service_config_version_note: 'notes...',
+          stack_id: 'HDP-1',
+          hosts: []
+        }
+      ]
+    };
+    var currentVersionMap;
 
-  describe("#map", function() {
+    beforeEach(function() {
+      currentVersionMap = {
+        S1_g2: Em.Object.create({
+          isCurrent: true
+        })
+      };
+      sinon.stub(App.router, 'set');
+      sinon.stub(App.serviceConfigVersionsMapper, 
'getCurrentVersionMap').returns(currentVersionMap);
+      sinon.stub(App, 'dateTimeWithTimeZone').returns(1);
+      sinon.stub(App.serviceConfigVersionsMapper, 'setHostsForDefaultCG');
+      sinon.stub(App.ServiceConfigVersion, 'find').returns({clear: Em.K});
+      sinon.stub(App.store, 'safeLoadMany');
+      sinon.stub(App.router, 'get').returns('configHistory');
+      App.serviceConfigVersionsMapper.map(json);
+    });
+    afterEach(function() {
+      App.router.set.restore();
+      App.serviceConfigVersionsMapper.getCurrentVersionMap.restore();
+      App.dateTimeWithTimeZone.restore();
+      App.serviceConfigVersionsMapper.setHostsForDefaultCG.restore();
+      App.ServiceConfigVersion.find.restore();
+      App.store.safeLoadMany.restore();
+      App.router.get.restore();
+    });
 
-    var json = { items: [
-      {
-        "cluster_name" : "1",
-        "createtime" : 1425979244738,
-        "group_id" : -1,
-        "group_name" : "default",
-        "hosts" : [ ],
-        "is_current" : true,
-        "service_config_version" : 1,
-        "service_config_version_note" : "Initial configurations for SERVICE1",
-        "service_name" : "SERVICE1",
-        "user" : "admin"
-      },
-      {
-        "cluster_name" : "1",
-        "configurations" : [
-          {
-            "Config" : {
-              "cluster_name" : "1"
-            },
-            "type" : "hadoop-env",
-            "tag" : "version1426088081862",
-            "version" : 2,
-            "properties" : {
-              "dtnode_heapsize" : "1026m"
-            },
-            "properties_attributes" : { }
-          }
-        ],
-        "createtime" : 1426088137115,
-        "group_id" : 2,
-        "group_name" : "1",
-        "hosts" : [
-          "host1"
-        ],
-        "is_current" : false,
-        "service_config_version" : 4,
-        "service_config_version_note" : "",
-        "service_name" : "SERVICE2",
-        "user" : "admin"
-      },
-    ]};
-
-    beforeEach(function () {
-      App.resetDsStoreTypeMap(App.ServiceConfigVersion);
-      sinon.stub(App.store, 'commit', Em.K);
+    it('should call safeLoadMany', function() {
+      expect(App.store.safeLoadMany.getCall(0).args[1]).to.be.eql([
+        {
+          "author": "admin",
+          "create_time": 1,
+          "group_id": 1,
+          "group_name": "g1",
+          "hosts": [
+            "host1"
+          ],
+          "id": "S1_v1",
+          "index": 0,
+          "is_compatible": true,
+          "is_current": false,
+          "is_requested": true,
+          "notes": "notes...",
+          "raw_create_time": 1,
+          "service_id": "S1",
+          "service_name": "S1",
+          "stack_version": "HDP-1",
+          "version": "v1"
+        },
+        {
+          "author": "admin",
+          "create_time": 1,
+          "group_id": 'S1_default',
+          "group_name": "g2",
+          "hosts": [],
+          "id": "S1_v1",
+          "index": 1,
+          "is_compatible": true,
+          "is_current": true,
+          "is_requested": true,
+          "notes": "notes...",
+          "raw_create_time": 1,
+          "service_id": "S1",
+          "service_name": "S1",
+          "stack_version": "HDP-1",
+          "version": "v1"
+        }
+      ]);
     });
-    afterEach(function(){
-      App.store.commit.restore();
+
+    it('currentVersionMap should have not current version', function() {
+      expect(currentVersionMap['S1_g2'].get('isCurrent')).to.be.false;
     });
 
-    it('should not do anything as there is no json', function() {
-      App.serviceConfigVersionsMapper.map(null);
-      expect(App.ServiceConfigVersion.find().get('length')).to.equal(0);
+    it('App.router.set should be called', function() {
+      
expect(App.router.set.calledWith('mainConfigHistoryController.filteredCount', 
2)).to.be.true;
     });
 
-    describe('should load data to model', function() {
+    it('setHostsForDefaultCG should be called', function() {
+      
expect(App.serviceConfigVersionsMapper.setHostsForDefaultCG.calledOnce).to.be.true;
+    });
 
-      beforeEach(function () {
-        App.serviceConfigVersionsMapper.map(json);
-      });
+    it('App.ServiceConfigVersion.find should be called', function() {
+      expect(App.ServiceConfigVersion.find.calledOnce).to.be.true;
+    });
+  });
 
-      it('two versions are mapped', function () {
-        expect(App.ServiceConfigVersion.find().get('length')).to.equal(2);
-      });
+  describe('#setHostsForDefaultCG', function() {
+    var serviceToHostMap = {
+      'S1': ['host2']
+    };
+    var result = [
+      {
+        is_current: true,
+        group_name: 'Default',
+        service_name: 'S1'
+      }
+    ];
 
-      it('services have correct ids', function () {
-        
expect(App.ServiceConfigVersion.find().mapProperty('id')).to.eql(['SERVICE1_1','SERVICE2_4']);
-      });
+    beforeEach(function() {
+      sinon.stub(App, 'get').returns(['host1', 'host2']);
+    });
+    afterEach(function() {
+      App.get.restore();
+    });
 
-      it('SERVICE1_1 createTime', function () {
-        
expect(App.ServiceConfigVersion.find('SERVICE1_1').get('createTime')).to.equal(1425979244738);
-      });
-      it('SERVICE1_1 groupId', function () {
-        
expect(App.ServiceConfigVersion.find('SERVICE1_1').get('groupId')).to.equal(-1);
-      });
-      it('SERVICE1_1 hosts', function () {
-        
expect(App.ServiceConfigVersion.find('SERVICE1_1').get('hosts')).to.eql(defaultAllHosts);
-      });
-      it('SERVICE1_1 isCurrent', function () {
-        
expect(App.ServiceConfigVersion.find('SERVICE1_1').get('isCurrent')).to.be.true;
-      });
-      it('SERVICE1_1 version', function () {
-        
expect(App.ServiceConfigVersion.find('SERVICE1_1').get('version')).to.equal(1);
-      });
-      it('SERVICE1_1 notes', function () {
-        
expect(App.ServiceConfigVersion.find('SERVICE1_1').get('notes')).to.equal("Initial
 configurations for SERVICE1");
-      });
-      it('SERVICE1_1 serviceName', function () {
-        
expect(App.ServiceConfigVersion.find('SERVICE1_1').get('serviceName')).to.equal("SERVICE1");
-      });
-      it('SERVICE1_1 author', function () {
-        
expect(App.ServiceConfigVersion.find('SERVICE1_1').get('author')).to.equal("admin");
-      });
+    it('should set hosts to default group', function() {
+      App.serviceConfigVersionsMapper.setHostsForDefaultCG(serviceToHostMap, 
result);
+      expect(result[0].hosts).to.be.eql(['host1']);
+    });
+  });
 
-      it('SERVICE2_4 createTime', function () {
-        
expect(App.ServiceConfigVersion.find('SERVICE2_4').get('createTime')).to.equal(1426088137115);
-      });
-      it('SERVICE2_4 groupId', function () {
-        
expect(App.ServiceConfigVersion.find('SERVICE2_4').get('groupId')).to.equal(2);
-      });
-      it('SERVICE2_4 hosts', function () {
-        
expect(App.ServiceConfigVersion.find('SERVICE2_4').get('hosts')).to.eql(["host1"]);
-      });
-      it('SERVICE2_4 isCurrent', function () {
-        
expect(App.ServiceConfigVersion.find('SERVICE2_4').get('isCurrent')).to.be.false;
-      });
-      it('SERVICE2_4 version', function () {
-        
expect(App.ServiceConfigVersion.find('SERVICE2_4').get('version')).to.equal(4);
-      });
-      it('SERVICE2_4 notes', function () {
-        
expect(App.ServiceConfigVersion.find('SERVICE2_4').get('notes')).to.equal("");
-      });
-      it('SERVICE2_4 serviceName', function () {
-        
expect(App.ServiceConfigVersion.find('SERVICE2_4').get('serviceName')).to.equal("SERVICE2");
-      });
-      it('SERVICE2_4 author', function () {
-        
expect(App.ServiceConfigVersion.find('SERVICE2_4').get('author')).to.equal("admin");
+  describe('#getCurrentVersionMap', function() {
+    beforeEach(function() {
+      sinon.stub(App.ServiceConfigVersion, 'find').returns([
+        Em.Object.create({
+          isCurrent: true,
+          serviceName: 'S1',
+          groupName: 'g1'
+        })
+      ]);
+    });
+    afterEach(function() {
+      App.ServiceConfigVersion.find.restore();
+    });
+
+    it('should return current version map', function() {
+      
expect(App.serviceConfigVersionsMapper.getCurrentVersionMap()).to.be.eql({
+        'S1_g1': Em.Object.create({
+          isCurrent: true,
+          serviceName: 'S1',
+          groupName: 'g1'
+        })
       });
     });
   });
 
+  describe('#makeId', function() {
+
+    it('should return id', function() {
+      expect(App.serviceConfigVersionsMapper.makeId('S1', 
'v1')).to.be.equal('S1_v1');
+    });
+  });
+
 });
 

http://git-wip-us.apache.org/repos/asf/ambari/blob/917c7915/ambari-web/test/mappers/configs/themes_mapper_test.js
----------------------------------------------------------------------
diff --git a/ambari-web/test/mappers/configs/themes_mapper_test.js 
b/ambari-web/test/mappers/configs/themes_mapper_test.js
index faf4900..b869109 100644
--- a/ambari-web/test/mappers/configs/themes_mapper_test.js
+++ b/ambari-web/test/mappers/configs/themes_mapper_test.js
@@ -24,215 +24,589 @@ require('models/configs/theme/sub_section');
 
 describe('App.themeMapper', function () {
 
-  beforeEach(function () {
-    App.resetDsStoreTypeMap(App.Tab);
-    App.resetDsStoreTypeMap(App.Section);
-    App.resetDsStoreTypeMap(App.SubSection);
-    sinon.stub(App.store, 'commit', Em.K);
-  });
+  describe('#map', function() {
+    var json = {
+      items: [
+        {}
+      ]
+    };
+    beforeEach(function() {
+      sinon.stub(App.themesMapper, 'mapThemeLayouts');
+      sinon.stub(App.themesMapper, 'mapThemeConfigs');
+      sinon.stub(App.themesMapper, 'mapThemeWidgets');
+      sinon.stub(App.themesMapper, 'generateAdvancedTabs');
+      sinon.stub(App.store, 'safeLoadMany');
+      App.themesMapper.map(json, ['S1']);
+    });
+    afterEach(function() {
+      App.store.safeLoadMany.restore();
+      App.themesMapper.mapThemeLayouts.restore();
+      App.themesMapper.mapThemeConfigs.restore();
+      App.themesMapper.mapThemeWidgets.restore();
+      App.themesMapper.generateAdvancedTabs.restore();
+      App.set('enableLogger', true);
+    });
 
-  afterEach(function () {
-    App.store.commit.restore();
+    it('mapThemeLayouts should be called', function() {
+      expect(App.themesMapper.mapThemeLayouts.calledWith({}, [])).to.be.true;
+    });
+    it('mapThemeConfigs should be called', function() {
+      expect(App.themesMapper.mapThemeConfigs.calledWith({})).to.be.true;
+    });
+    it('mapThemeWidgets should be called', function() {
+      expect(App.themesMapper.mapThemeWidgets.calledWith({})).to.be.true;
+    });
+    it('generateAdvancedTabs should be called', function() {
+      
expect(App.themesMapper.generateAdvancedTabs.calledWith(['S1'])).to.be.true;
+    });
+    it('App.store.safeLoadMany should be called', function() {
+      expect(App.store.safeLoadMany.calledOnce).to.be.true;
+    });
   });
 
-  describe("#map", function () {
-
+  describe('#mapThemeLayouts', function() {
     var json = {
-      items: [
-        {
-          ThemeInfo: {
-            service_name: "HDFS",
-            theme_data: {
-              "Theme": {
-                "name": "default",
-                "description": "Default theme for HDFS service",
-                "configuration": {
-                  "layouts": [
-                    {
-                      "name": "default",
-                      "tabs": [
-                        {
-                          "name": "settings",
-                          "display-name": "Settings",
-                          "layout": {
-                            "tab-columns": "2",
-                            "tab-rows": "1",
-                            "sections": [
-                              {
-                                "name": "Section-1",
-                                "display-name": "Section One",
-                                "row-index": "0",
-                                "column-index": "0",
-                                "row-span": "1",
-                                "column-span": "1",
-                                "section-columns": "2",
-                                "section-rows": "3",
-                                "subsections": [
-                                  {
-                                    "name": "subsection1",
-                                    "display-name": "Storage",
-                                    "border": "false",
-                                    "row-index": "0",
-                                    "column-index": "0",
-                                    "column-span": "1",
-                                    "row-span": "1"
-                                  }
-                                ]
-                              },
-                              {
-                                "name": "Section-2",
-                                "display-name": "Section Two",
-                                "row-index": "0",
-                                "column-index": "1"
-                              }
-                            ]
-                          }
-                        }
-                      ]
-                    }
-                  ],
-                  "widgets": [
+      ThemeInfo: {
+        service_name: 'S1',
+        theme_data: {
+          Theme: {
+            configuration: {
+              layouts: [
+                {
+                  tabs: [
                     {
-                      "config": "c1/p1",
-                      "widget": {
-                        "type": "slider",
-                        "units": [
+                      name: 't1',
+                      layout: {
+                        sections: [
                           {
-                            "unit-name": "MB"
-                          },
-                          {
-                            "unit-name": "GB"
-                          }
-                        ]
-                      }
-                    },
-                    {
-                      "config": "c1/p2",
-                      "widget": {
-                        "type": "slider",
-                        "units": [
-                          {
-                            "unit-name": "percent"
+                            "name": 'SEC1',
+                            "display-name": 'sec1',
+                            "row-index": 1,
+                            "column-index": 2,
+                            "row-span": 3,
+                            "column-span": 4,
+                            "section-columns": 5,
+                            "section-rows": 6,
+                            "tab_id": 1
                           }
                         ]
                       }
                     }
-                  ],
-                  "placement": {
-                    "configuration-layout": "default",
-                    "configs": [
-                      {
-                        "config": "c1/p1",
-                        "subsection-name": "subsection1"
-                      },
-                      {
-                        "config": "c1/p2",
-                        "subsection-name": "subsection1"
-                      }
-                    ]
-                  }
+                  ]
                 }
-              }
+              ]
             }
           }
         }
+      }
+    };
+    beforeEach(function() {
+      sinon.stub(App.themesMapper, 'loadSubSections');
+      sinon.stub(App.store, 'safeLoadMany');
+    });
+    afterEach(function() {
+      App.themesMapper.loadSubSections.restore();
+      App.store.safeLoadMany.restore();
+    });
+
+    it('loadSubSections should be called', function() {
+      App.themesMapper.mapThemeLayouts(json, []);
+      expect(App.themesMapper.loadSubSections.getCall(0).args).to.be.eql([
+        {
+          "name": 'SEC1',
+          "display-name": 'sec1',
+          "row-index": 1,
+          "column-index": 2,
+          "row-span": 3,
+          "column-span": 4,
+          "section-columns": 5,
+          "section-rows": 6,
+          "tab_id": 1
+        },
+        {
+          "column_index": 2,
+          "column_span": 4,
+          "display_name": "sec1",
+          "id": "SEC1",
+          "name": "SEC1",
+          "row_index": 1,
+          "row_span": 3,
+          "section_columns": 5,
+          "section_rows": 6,
+          "tab_id": "S1_t1"
+        }
+      ])
+    });
+
+    it('App.store.safeLoadMany should be called', function() {
+      App.themesMapper.mapThemeLayouts(json, []);
+      expect(App.store.safeLoadMany.getCall(0).args[1]).to.be.eql([{
+        "column_index": 2,
+        "column_span": 4,
+        "display_name": "sec1",
+        "id": "SEC1",
+        "name": "SEC1",
+        "row_index": 1,
+        "row_span": 3,
+        "section_columns": 5,
+        "section_rows": 6,
+        "tab_id": "S1_t1"
+      }]);
+    });
+
+    it('should add tab to tabs', function() {
+      var tabs = [];
+      App.themesMapper.mapThemeLayouts(json, tabs);
+      expect(tabs).to.have.length(1);
+    });
+  });
+
+  describe('#loadSubSections', function() {
+    var section = {
+      subsections: [
+        {
+          "name": 'SSEC1',
+          "display-name": 'ssec1',
+          "border": 1,
+          "row-index": 2,
+          "column-index": 3,
+          "column-span": 4,
+          "row-span": 5,
+          "config_properties": [],
+          "section_id": 1,
+          "depends-on": [],
+          "left-vertical-splitter": 6
+        }
       ]
     };
+    beforeEach(function() {
+      sinon.stub(App.themesMapper, 'loadSubSectionTabs');
+      sinon.stub(App.themesMapper, 'mapThemeConditions');
+      sinon.stub(App.store, 'safeLoadMany');
+    });
+    afterEach(function() {
+      App.store.safeLoadMany.restore();
+      App.themesMapper.loadSubSectionTabs.restore();
+      App.themesMapper.mapThemeConditions.restore();
+    });
 
-    describe('should map theme data', function () {
+    it('loadSubSectionTabs should be called', function() {
+      App.themesMapper.loadSubSections(section, {id: 1});
+      expect(App.themesMapper.loadSubSectionTabs.getCall(0).args).to.be.eql([
+        {
+          "name": 'SSEC1',
+          "display-name": 'ssec1',
+          "border": 1,
+          "row-index": 2,
+          "column-index": 3,
+          "column-span": 4,
+          "row-span": 5,
+          "config_properties": [],
+          "section_id": 1,
+          "depends-on": [],
+          "left-vertical-splitter": 6
+        },
+        {
+          "border": 1,
+          "column_index": 3,
+          "column_span": 4,
+          "configProperties": [],
+          "depends_on": [],
+          "display_name": "ssec1",
+          "id": "SSEC1",
+          "left_vertical_splitter": 6,
+          "name": "SSEC1",
+          "row_index": 2,
+          "row_span": 5,
+          "section_id": 1
+        }
+      ]);
+    });
 
-      beforeEach(function () {
-        App.themesMapper.map(json, []);
-      });
+    it('mapThemeConditions should be called', function() {
+      App.themesMapper.loadSubSections(section, {id: 1});
+      expect(App.themesMapper.mapThemeConditions.getCall(0).args).to.be.eql([
+        [{
+          "border": 1,
+          "column_index": 3,
+          "column_span": 4,
+          "configProperties": [],
+          "depends_on": [],
+          "display_name": "ssec1",
+          "id": "SSEC1",
+          "left_vertical_splitter": 6,
+          "name": "SSEC1",
+          "row_index": 2,
+          "row_span": 5,
+          "section_id": 1
+        }],
+        'subsection'
+      ]);
+    });
 
-      it('1 Tab is mapped', function () {
-        expect(App.Tab.find().get('length')).to.equal(1);
-      });
+    it('App.store.safeLoadMany should be called', function() {
+      App.themesMapper.loadSubSections(section, {id: 1});
+      expect(App.store.safeLoadMany.getCall(0).args[1]).to.be.eql([
+        {
+          "border": 1,
+          "column_index": 3,
+          "column_span": 4,
+          "configProperties": [],
+          "depends_on": [],
+          "display_name": "ssec1",
+          "id": "SSEC1",
+          "left_vertical_splitter": 6,
+          "name": "SSEC1",
+          "row_index": 2,
+          "row_span": 5,
+          "section_id": 1
+        }
+      ]);
+    });
 
-      it('2 Sections are mapped', function () {
-        expect(App.Section.find().get('length')).to.equal(2);
-      });
+    it('sub_sections should be set', function() {
+      var parsedSection = {id: 1};
+      App.themesMapper.loadSubSections(section, parsedSection);
+      expect(parsedSection.sub_sections).to.have.length(1);
+    });
+  });
+
+  describe('#loadSubSectionTabs', function() {
+    var subSection = {
+      "subsection-tabs": [
+        {
+          "name": 'SEC1',
+          "display-name": 'sec1',
+          "depends-on": [],
+          "sub_section_id": 'SUB1'
+        }
+      ]
+    };
+    beforeEach(function() {
+      sinon.stub(App.themesMapper, 'mapThemeConditions');
+      sinon.stub(App.store, 'safeLoadMany');
+    });
+    afterEach(function() {
+      App.themesMapper.mapThemeConditions.restore();
+      App.store.safeLoadMany.restore();
+    });
+
+    it('mapThemeConditions should be called', function() {
+      App.themesMapper.loadSubSectionTabs(subSection, {id: 2});
+      expect(App.themesMapper.mapThemeConditions.getCall(0).args).to.be.eql([
+        [{
+          "depends_on": [],
+          "display_name": "sec1",
+          "id": "SEC1",
+          "is_active": true,
+          "name": "SEC1",
+          "sub_section_id": 2
+        }],
+        'subsectionTab'
+      ]);
+    });
 
-      it('1 SubSection is mapped', function () {
-        expect(App.SubSection.find().get('length')).to.equal(1);
+    it('App.store.safeLoadMany should be called', function() {
+      App.themesMapper.loadSubSectionTabs(subSection, {id: 2});
+      expect(App.store.safeLoadMany.getCall(0).args[1]).to.be.eql([
+        {
+          "depends_on": [],
+          "display_name": "sec1",
+          "id": "SEC1",
+          "is_active": true,
+          "name": "SEC1",
+          "sub_section_id": 2
+        }
+      ]);
+    });
+
+    it('sub_section_tabs should be set', function() {
+      var parsedSubSection = {id: 3};
+      App.themesMapper.loadSubSectionTabs(subSection, parsedSubSection);
+      expect(parsedSubSection.sub_section_tabs).to.have.length(1);
+    });
+  });
+
+  describe('#mapThemeConfigs', function() {
+    var json;
+
+    beforeEach(function() {
+      json = {
+        ThemeInfo: {
+          service_name: 'S1',
+          theme_data: {
+            Theme: {
+              configuration: {
+                placement: {
+                  configs: [{
+                    "subsection-name": '',
+                    "subsection-tab-name": '',
+                    "depends-on": [{}]
+                  }]
+                }
+              }
+            }
+          }
+        }
+      };
+      this.mockSection = sinon.stub(App.SubSection, 'find');
+      this.mockSectionTab = sinon.stub(App.SubSectionTab, 'find');
+      sinon.stub(App.configsCollection, 'getConfig').returns({id: 'foo'});
+      sinon.stub(App.themesMapper, 'getConfigByAttributes').returns({});
+      sinon.stub(App.themesMapper, 'mapThemeConfigConditions');
+    });
+    afterEach(function() {
+      this.mockSection.restore();
+      this.mockSectionTab.restore();
+      App.configsCollection.getConfig.restore();
+      App.themesMapper.getConfigByAttributes.restore();
+      App.themesMapper.mapThemeConfigConditions.restore();
+    });
+
+    it('should call mapThemeConfigConditions', function() {
+      App.themesMapper.mapThemeConfigs(json);
+      expect(App.themesMapper.mapThemeConfigConditions.calledOnce).to.be.true;
+    });
+
+    it('should call getConfigByAttributes', function() {
+      App.themesMapper.mapThemeConfigs(json);
+      expect(App.themesMapper.getConfigByAttributes.calledOnce).to.be.true;
+    });
+
+    it('should set config to subSection', function() {
+      
json.ThemeInfo.theme_data.Theme.configuration.placement.configs[0]["subsection-name"]
 = 'ss-1';
+      var subSection = Em.Object.create({
+        configProperties: []
       });
+      this.mockSection.returns(subSection);
+      App.themesMapper.mapThemeConfigs(json);
+      expect(subSection.get('configProperties')).to.be.eql(['foo']);
+    });
 
-      it('HDFS_settings tab is mapped correctly', function () {
-        //checking tab
-        expect(App.Tab.find('HDFS_settings').toJSON()).to.eql({
-          id: 'HDFS_settings',
-          name: 'settings',
-          display_name: 'Settings',
-          columns: "2",
-          rows: "1",
-          is_advanced: false,
-          service_name: 'HDFS',
-          is_advanced_hidden: false,
-          is_rendered: false,
-          is_configs_prepared: false
-        });
+    it('should set config to SubSectionTab', function() {
+      
json.ThemeInfo.theme_data.Theme.configuration.placement.configs[0]["subsection-tab-name"]
 = 'sst-1';
+      var subSectionTab = Em.Object.create({
+        configProperties: []
       });
+      this.mockSectionTab.returns(subSectionTab);
+      App.themesMapper.mapThemeConfigs(json);
+      expect(subSectionTab.get('configProperties')).to.be.eql(['foo']);
+    });
+  });
+
+  describe('#mapThemeConfigConditions', function () {
+    beforeEach(function () {
+      sinon.stub(App.store, 'safeLoadMany');
+    });
+    afterEach(function () {
+      App.store.safeLoadMany.restore();
+    });
 
-      it('HDFS_settings section is mapped correctly', function () {
-        //checking section
-        
expect(App.Tab.find('HDFS_settings').get('sections').objectAt(0).toJSON()).to.eql({
-          "id": "Section-1",
-          "name": "Section-1",
-          "display_name": "Section One",
-          "row_index": "0",
-          "row_span": "1",
-          "column_index": "0",
-          "column_span": "1",
-          "section_columns": "2",
-          "section_rows": "3",
-          "tab_id": "HDFS_settings"
-        });
+    it('App.store.safeLoadMany should be called', function () {
+      var configConditions = [
+        {
+          configs: ['foo/bar']
+        }
+      ];
+      var configProperty = {
+        id: 'c1',
+        name: 'config1',
+        filename: 'file1.xml'
+      };
+      App.themesMapper.mapThemeConfigConditions(configConditions, 
configProperty);
+      expect(App.store.safeLoadMany.getCall(0).args[1][0]).to.be.eql({
+        "config_name": "config1",
+        "configs": [
+          {
+            "configName": "bar",
+            "fileName": "foo.xml"
+          }
+        ],
+        "file_name": "file1.xml",
+        "id": "c1_0",
+        "resource": "config",
+        "type": "config"
       });
+    });
+  });
 
-      it('HDFS_settings section subsection is mapped correctly', function () {
-        //checking subsection
-        
expect(App.Tab.find('HDFS_settings').get('sections').objectAt(0).get('subSections').objectAt(0).toJSON()).to.eql({
-          "id": "subsection1",
-          "name": "subsection1",
-          "display_name": "Storage",
-          "border": "false",
-          "row_index": "0",
-          "row_span": "1",
-          "column_index": "0",
-          "depends_on": [],
-          "config_properties": [],
-          "left_vertical_splitter": true,
-          "column_span": "1",
-          "section_id": "Section-1"
-        });
+  describe('#mapThemeConditions', function () {
+    beforeEach(function () {
+      sinon.stub(App.store, 'safeLoadMany');
+    });
+    afterEach(function () {
+      App.store.safeLoadMany.restore();
+    });
+
+    it('App.store.safeLoadMany should be called', function () {
+      var subSections = [
+        {
+          id: 'ss-1',
+          name: 'sub-section',
+          "depends_on": [
+            {
+              configs: ['foo/bar']
+            }
+          ]
+        }
+      ];
+
+      App.themesMapper.mapThemeConditions(subSections, 'type1');
+      expect(App.store.safeLoadMany.getCall(0).args[1][0]).to.be.eql({
+        "id": "ss-1_0",
+        "name": 'sub-section',
+        "configs": [
+          {
+            "configName": "bar",
+            "fileName": "foo.xml"
+          }
+        ],
+        "resource": "config",
+        "type": "type1"
       });
     });
   });
 
-  describe('#generateAdvancedTabs', function () {
-    it('generates advanced tabs', function () {
-      App.themesMapper.generateAdvancedTabs(['HDFS']);
-      expect(App.Tab.find('HDFS_advanced').toJSON()).to.eql({
-        "id": "HDFS_advanced",
-        "name": "advanced",
-        "display_name": "Advanced",
-        "columns": 1,
-        "rows": 1,
-        "is_advanced": true,
-        "service_name": "HDFS",
-        "is_advanced_hidden": false,
-        is_rendered: false,
-        is_configs_prepared: false
+  describe('#mapThemeWidgets', function() {
+    var json = {
+      ThemeInfo: {
+        theme_data: {
+          Theme: {
+            configuration: {
+              widgets: [
+                {
+                  widget: {
+                    type: 'foo'
+                  },
+                  config: 'foo/bar'
+                }
+              ]
+            }
+          }
+        }
+      }
+    };
+    beforeEach(function() {
+      this.mockConfig  = sinon.stub(App.configsCollection, 'getConfig');
+      this.mockConfigByName = sinon.stub(App.configsCollection, 
'getConfigByName');
+    });
+    afterEach(function() {
+      this.mockConfig.restore();
+      this.mockConfigByName.restore();
+    });
+
+    it('should set widget to configProperty', function() {
+      var configProperty = Em.Object.create();
+      this.mockConfig.returns(configProperty);
+      App.themesMapper.mapThemeWidgets(json);
+      expect(configProperty.get('widget')).to.be.eql({type: 'foo'});
+      expect(configProperty.get('widgetType')).to.be.equal('foo');
+    });
+    it('should set widget to uiOnlyProperty', function() {
+      var uiOnlyProperty = Em.Object.create();
+      this.mockConfigByName.returns(uiOnlyProperty);
+      App.themesMapper.mapThemeWidgets(json);
+      expect(App.configsCollection.getConfigByName.calledWith('bar', 
'foo.xml')).to.be.true;
+      expect(uiOnlyProperty.get('widget')).to.be.eql({type: 'foo'});
+      expect(uiOnlyProperty.get('widgetType')).to.be.equal('foo');
+    });
+  });
+
+  describe('#getConfigId', function() {
+    it('should return config id', function() {
+      expect(App.themesMapper.getConfigId({config: 
'foo/bar'})).to.be.equal('bar__foo');
+    });
+    it('should return null', function() {
+      expect(App.themesMapper.getConfigId(null)).to.be.null;
+    });
+  });
+
+  describe('#generateAdvancedTabs', function() {
+    beforeEach(function() {
+      sinon.stub(App.StackService, 'find').returns([]);
+      sinon.stub(App.store, 'safeLoadMany');
+    });
+    afterEach(function() {
+      App.StackService.find.restore();
+      App.store.safeLoadMany.restore();
+    });
+
+    it('App.store.safeLoadMany should be called', function() {
+      App.themesMapper.generateAdvancedTabs(['S1']);
+      expect(App.store.safeLoadMany.getCall(0).args[1][0]).to.be.eql({
+        id: 'S1_advanced',
+        name: 'advanced',
+        display_name: 'Advanced',
+        is_advanced: true,
+        service_name: 'S1'
       });
     });
   });
 
-  describe('#getConfigId', function () {
-    it('gets configs id from json', function () {
-      expect(App.themesMapper.getConfigId({config: 
"c1/p1"})).to.equal("p1__c1");
+  describe('#getConfigByAttributes', function() {
+    var configLink = {
+      "config": 'foo/bar',
+      "property_value_attributes": {
+        "ui_only_property": {}
+      }
+    };
+    beforeEach(function() {
+      sinon.stub(App.configsCollection, 'getConfig').returns(null);
+      sinon.stub(App.configsCollection, 'add');
     });
-    it('returns null as data is invalid', function () {
-      expect(App.themesMapper.getConfigId({configs: "c1/p1"})).to.equal(null);
+    afterEach(function() {
+      App.configsCollection.getConfig.restore();
+      App.configsCollection.add.restore();
+    });
+
+    it('App.configsCollection.add should be called', function() {
+      var subSection = Em.Object.create({configProperties: []});
+      var subSectionTab = Em.Object.create({configProperties: []});
+      App.themesMapper.getConfigByAttributes({}, configLink, subSection, 
subSectionTab, 'S1');
+      expect(App.configsCollection.add.getCall(0).args[0]).to.be.eql({
+        id: 'bar__foo',
+        isRequiredByAgent: false,
+        showLabel: false,
+        isOverridable: false,
+        recommendedValue: true,
+        name: 'bar',
+        isUserProperty: false,
+        filename: 'foo.xml',
+        fileName: 'foo.xml',
+        isNotSaved: false,
+        serviceName: 'S1',
+        copy: '',
+        stackName: 'HDP',
+        stackVersion: '2.3'
+      });
+    });
+
+    it('should return configProperty', function() {
+      var subSection = Em.Object.create({configProperties: []});
+      var subSectionTab = Em.Object.create({configProperties: []});
+      expect(App.themesMapper.getConfigByAttributes({}, configLink, 
subSection, subSectionTab, 'S1')).to.be.eql({
+        id: 'bar__foo',
+        isRequiredByAgent: false,
+        showLabel: false,
+        isOverridable: false,
+        recommendedValue: true,
+        name: 'bar',
+        isUserProperty: false,
+        filename: 'foo.xml',
+        fileName: 'foo.xml',
+        isNotSaved: false,
+        serviceName: 'S1',
+        copy: '',
+        stackName: 'HDP',
+        stackVersion: '2.3'
+      });
+    });
+
+    it('should add config to SubSection properties', function() {
+      var subSection = Em.Object.create({configProperties: []});
+      var subSectionTab = Em.Object.create({configProperties: []});
+      App.themesMapper.getConfigByAttributes({}, configLink, subSection, 
subSectionTab, 'S1');
+      expect(subSection.get('configProperties')).to.be.eql(['bar__foo']);
     });
   });
 });

Reply via email to