This is an automated email from the ASF dual-hosted git repository.

ababiichuk pushed a commit to branch trunk
in repository https://gitbox.apache.org/repos/asf/ambari.git


The following commit(s) were added to refs/heads/trunk by this push:
     new 100fa13  AMBARI-25138 Cover mappers files with unit tests. (ababiichuk)
100fa13 is described below

commit 100fa13734d223cb0ddd9a3dbae3ec8dc24f7cb1
Author: ababiichuk <ababiic...@hortonworks.com>
AuthorDate: Fri Feb 1 20:40:26 2019 +0200

    AMBARI-25138 Cover mappers files with unit tests. (ababiichuk)
---
 ambari-web/app/assets/test/tests.js                |   4 +
 .../app/mappers/alert_notification_mapper.js       |   1 -
 ambari-web/app/mappers/quicklinks_mapper.js        |  16 -
 ambari-web/app/models/widget.js                    |   5 +-
 ambari-web/test/helpers.js                         |  13 +-
 .../test/mappers/alert_groups_mapper_test.js       |   1 +
 .../test/mappers/alert_notification_mapper_test.js | 429 +++++++++++++++++++++
 ambari-web/test/mappers/cluster_mapper_test.js     |  97 +++++
 .../test/mappers/stack_version_mapper_test.js      | 333 ++++++++++++++++
 ambari-web/test/mappers/widget_mapper_test.js      | 162 ++++++++
 10 files changed, 1038 insertions(+), 23 deletions(-)

diff --git a/ambari-web/app/assets/test/tests.js 
b/ambari-web/app/assets/test/tests.js
index d42fbfb..c20a839 100644
--- a/ambari-web/app/assets/test/tests.js
+++ b/ambari-web/app/assets/test/tests.js
@@ -163,6 +163,8 @@ var files = [
   'test/mappers/alert_instances_mapper_test',
   'test/mappers/alert_definitions_mapper_test',
   'test/mappers/alert_definition_summary_mapper_test',
+  'test/mappers/alert_notification_mapper_test',
+  'test/mappers/cluster_mapper_test',
   'test/mappers/server_data_mapper_test',
   'test/mappers/hosts_mapper_test',
   'test/mappers/service_mapper_test',
@@ -171,8 +173,10 @@ var files = [
   'test/mappers/users_mapper_test',
   'test/mappers/stack_mapper_test',
   'test/mappers/stack_service_mapper_test',
+  'test/mappers/stack_version_mapper_test',
   'test/mappers/repository_version_mapper_test',
   'test/mappers/stack_upgrade_history_mapper_test',
+  'test/mappers/widget_mapper_test',
   'test/mappers/configs/config_groups_mapper_test',
   'test/mappers/configs/service_config_version_mapper_test',
   'test/mappers/configs/themes_mapper_test',
diff --git a/ambari-web/app/mappers/alert_notification_mapper.js 
b/ambari-web/app/mappers/alert_notification_mapper.js
index 8c7f50f..e0ca8d2 100644
--- a/ambari-web/app/mappers/alert_notification_mapper.js
+++ b/ambari-web/app/mappers/alert_notification_mapper.js
@@ -77,7 +77,6 @@ App.alertNotificationMapper = App.QuickDataMapper.create({
    * @private
    */
   _setPropertiesToEachModel: function (propertyName, propertiesMap) {
-    var modelsMap = this.get('modelsMap');
     for (var recordId in propertiesMap) {
       if (propertiesMap.hasOwnProperty(recordId)) {
         App.AlertNotification.find(recordId).set(propertyName, 
propertiesMap[recordId]);
diff --git a/ambari-web/app/mappers/quicklinks_mapper.js 
b/ambari-web/app/mappers/quicklinks_mapper.js
index 6de9b34..05cd5b9 100644
--- a/ambari-web/app/mappers/quicklinks_mapper.js
+++ b/ambari-web/app/mappers/quicklinks_mapper.js
@@ -29,21 +29,5 @@ App.quicklinksMapper = App.QuickDataMapper.create({
     "name" : "QuickLinkInfo.quicklink_data.QuickLinksConfiguration.name",
     "protocol" : 
"QuickLinkInfo.quicklink_data.QuickLinksConfiguration.configuration.protocol",
     "links" : 
"QuickLinkInfo.quicklink_data.QuickLinksConfiguration.configuration.links"
-  },
-
-  map: function(json){
-    console.time('App.quicklinksMapper execution time');
-
-    var result = [];
-    var linkResult = [];
-
-    json.items.forEach(function(item) {
-      var parseResult = this.parseIt(item, this.get('config'));
-      console.log("parseResult", parseResult);
-      result.push(parseResult);
-    }, this);
-
-    App.store.safeLoadMany(this.get('model'), result);
-    console.timeEnd('App.quicklinksMapper execution time');
   }
 });
diff --git a/ambari-web/app/models/widget.js b/ambari-web/app/models/widget.js
index 8c76123..64fd566 100644
--- a/ambari-web/app/models/widget.js
+++ b/ambari-web/app/models/widget.js
@@ -45,10 +45,13 @@ App.Widget = DS.Model.extend({
   tag: DS.attr('string'),
   isVisible: DS.attr('boolean', {defaultValue: true}),
   /**
+   * This field is not derived from API but needs to be filled in the mapper 
on the client side
    * @type {number}
    * @default 0
    */
-  defaultOrder: 0, // This field is not derived from API but needs to be 
filled in the mapper on the client side
+  defaultOrder: DS.attr('number', {
+    defaultValue: 0
+  }),
 
   /**
    * @type Em.View
diff --git a/ambari-web/test/helpers.js b/ambari-web/test/helpers.js
index b843189..5327ba2 100644
--- a/ambari-web/test/helpers.js
+++ b/ambari-web/test/helpers.js
@@ -37,11 +37,14 @@ module.exports = {
   nestedExpect: function (expected, actual) {
     expected.forEach(function (group, i) {
       Em.keys(group).forEach(function (key) {
-        if (Em.isArray(actual[i][key])) {
-          expect(group[key]).to.eql(actual[i][key].toArray());
-        }
-        else {
-          expect(group[key]).to.equal(actual[i][key]);
+        var expectedValue = Em.get(group, key),
+          actualValue = Em.get(actual[i], key);
+        if (Em.isArray(actualValue)) {
+          expect(expectedValue).to.eql(actualValue.toArray());
+        } else if (Em.typeOf(actualValue) === 'object') {
+          expect(expectedValue).to.eql(actualValue);
+        } else {
+          expect(expectedValue).to.equal(actualValue);
         }
       });
     });
diff --git a/ambari-web/test/mappers/alert_groups_mapper_test.js 
b/ambari-web/test/mappers/alert_groups_mapper_test.js
index 60fee6f..7ebf0fd 100644
--- a/ambari-web/test/mappers/alert_groups_mapper_test.js
+++ b/ambari-web/test/mappers/alert_groups_mapper_test.js
@@ -103,6 +103,7 @@ describe('App.alertGroupsMapper', function () {
       App.store.loadMany.restore();
       App.alertGroupsMapper.set('model', App.AlertGroup);
       App.cache.previousAlertGroupsMap = {};
+      App.cache.alertNotificationsGroupsMap = {};
 
     });
 
diff --git a/ambari-web/test/mappers/alert_notification_mapper_test.js 
b/ambari-web/test/mappers/alert_notification_mapper_test.js
new file mode 100644
index 0000000..0831982
--- /dev/null
+++ b/ambari-web/test/mappers/alert_notification_mapper_test.js
@@ -0,0 +1,429 @@
+/**
+ * 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.
+ */
+
+var App = require('app');
+var testHelpers = require('test/helpers');
+require('mappers/alert_notification_mapper');
+
+describe('App.alertNotificationMapper', function () {
+  var mapper = App.alertNotificationMapper,
+    model = App.AlertNotification,
+    records = model.find();
+
+  before(function () {
+    records.clear();
+  });
+
+  afterEach(function () {
+    records.clear();
+  });
+
+  describe('#map', function () {
+    var cases = [
+      {
+        previousAlertNotificationsFullMapBefore: null,
+        modelJSONBefore: [],
+        json: {},
+        previousAlertNotificationsFullMapAfter: {},
+        modelContentAfter: [],
+        title: 'no cached items, empty JSON'
+      },
+      {
+        previousAlertNotificationsFullMapBefore: {
+          '1': {}
+        },
+        modelJSONBefore: [],
+        json: {},
+        previousAlertNotificationsFullMapAfter: {
+          '1': {}
+        },
+        modelContentAfter: [],
+        title: 'cached items present, empty JSON passed'
+      },
+      {
+        previousAlertNotificationsFullMapBefore: null,
+        modelJSONBefore: [],
+        json: {
+          items: []
+        },
+        previousAlertNotificationsFullMapAfter: {},
+        modelContentAfter: [],
+        title: 'no cached items, empty records array'
+      },
+      {
+        previousAlertNotificationsFullMapBefore: {
+          '1': {}
+        },
+        modelJSONBefore: [],
+        json: {
+          items: []
+        },
+        previousAlertNotificationsFullMapAfter: {},
+        modelContentAfter: [],
+        title: 'cached items present, empty records array'
+      },
+      {
+        previousAlertNotificationsFullMapBefore: null,
+        modelJSONBefore: [],
+        json: {
+          items: [
+            {
+              AlertTarget: {
+                id: 1,
+                name: 'n1',
+                notification_type: 'SNMP',
+                description: 'd1',
+                global: true,
+                enabled: true,
+                properties: {
+                  p: 'v'
+                }
+              }
+            },
+            {
+              AlertTarget: {
+                id: 2,
+                name: 'n2',
+                notification_type: 'EMAIL',
+                description: 'd2',
+                global: false,
+                enabled: false,
+                alert_states: ['OK', 'WARNING', 'CRITICAL', 'UNKNOWN']
+              }
+            }
+          ]
+        },
+        previousAlertNotificationsFullMapAfter: {
+          '1': {
+            id: 1,
+            name: 'n1',
+            type: 'SNMP',
+            description: 'd1',
+            global: true,
+            enabled: true,
+            groups: [1, 2]
+          },
+          '2': {
+            id: 2,
+            name: 'n2',
+            type: 'EMAIL',
+            description: 'd2',
+            global: false,
+            enabled: false
+          }
+        },
+        modelContentAfter: [
+          {
+            id: 1,
+            name: 'n1',
+            type: 'SNMP',
+            description: 'd1',
+            global: true,
+            enabled: true,
+            properties: {
+              p: 'v'
+            }
+          },
+          {
+            id: 2,
+            name: 'n2',
+            type: 'EMAIL',
+            description: 'd2',
+            global: false,
+            enabled: false,
+            alertStates: ['OK', 'WARNING', 'CRITICAL', 'UNKNOWN']
+          }
+        ],
+        title: 'no cached items, non-empty records array'
+      },
+      {
+        previousAlertNotificationsFullMapBefore: {
+          '1': {}
+        },
+        modelJSONBefore: [],
+        json: {
+          items: []
+        },
+        previousAlertNotificationsFullMapAfter: {},
+        modelContentAfter: [],
+        title: 'cached items present, empty records array'
+      },
+      {
+        previousAlertNotificationsFullMapBefore: null,
+        modelJSONBefore: [
+          {
+            id: 3,
+            name: 'n3',
+            type: 'SNMP',
+            description: 'd3',
+            global: false,
+            enabled: true
+          }
+        ],
+        json: {
+          items: [
+            {
+              AlertTarget: {
+                id: 1,
+                name: 'n1',
+                notification_type: 'SNMP',
+                description: 'd1',
+                global: true,
+                enabled: true,
+                properties: {
+                  p: 'v'
+                }
+              }
+            },
+            {
+              AlertTarget: {
+                id: 2,
+                name: 'n2',
+                notification_type: 'EMAIL',
+                description: 'd2',
+                global: false,
+                enabled: false,
+                alert_states: ['OK', 'WARNING', 'CRITICAL', 'UNKNOWN']
+              }
+            }
+          ]
+        },
+        previousAlertNotificationsFullMapAfter: {
+          '1': {
+            id: 1,
+            name: 'n1',
+            type: 'SNMP',
+            description: 'd1',
+            global: true,
+            enabled: true,
+            groups: [1, 2]
+          },
+          '2': {
+            id: 2,
+            name: 'n2',
+            type: 'EMAIL',
+            description: 'd2',
+            global: false,
+            enabled: false
+          }
+        },
+        modelContentAfter: [
+          {
+            id: 3,
+            name: 'n3',
+            type: 'SNMP',
+            description: 'd3',
+            global: false,
+            enabled: true
+          },
+          {
+            id: 1,
+            name: 'n1',
+            type: 'SNMP',
+            description: 'd1',
+            global: true,
+            enabled: true,
+            properties: {
+              p: 'v'
+            }
+          },
+          {
+            id: 2,
+            name: 'n2',
+            type: 'EMAIL',
+            description: 'd2',
+            global: false,
+            enabled: false,
+            alertStates: ['OK', 'WARNING', 'CRITICAL', 'UNKNOWN']
+          }
+        ],
+        title: 'previous model records present, no cached items, non-empty 
records array'
+      },
+      {
+        previousAlertNotificationsFullMapBefore: {
+          '1': {
+            name: 'n1'
+          },
+          '2': {
+            id: 2,
+            name: 'n2',
+            type: 'EMAIL',
+            description: 'd2',
+            global: true,
+            enabled: true
+          }
+        },
+        modelJSONBefore: [
+          {
+            id: 1,
+            name: 'n1',
+            notification_type: 'EMAIL',
+            global: true,
+            enabled: true,
+            properties: {
+              p0: 'v0'
+            }
+          }
+        ],
+        json: {
+          items: [
+            {
+              AlertTarget: {
+                id: 1,
+                name: 'n1',
+                notification_type: 'SNMP',
+                description: 'd1',
+                global: true,
+                enabled: true,
+                properties: {
+                  p: 'v'
+                }
+              }
+            },
+            {
+              AlertTarget: {
+                id: 2,
+                name: 'n2',
+                notification_type: 'EMAIL',
+                description: 'd2',
+                global: false,
+                enabled: false,
+                alert_states: ['OK', 'WARNING', 'CRITICAL', 'UNKNOWN']
+              }
+            }
+          ]
+        },
+        previousAlertNotificationsFullMapAfter: {
+          1: {
+            id: 1,
+            name: 'n1',
+            type: 'SNMP',
+            description: 'd1',
+            global: true,
+            enabled: true,
+            groups: [1, 2]
+          },
+          2: {
+            id: 2,
+            name: 'n2',
+            type: 'EMAIL',
+            description: 'd2',
+            global: false,
+            enabled: false
+          }
+        },
+        modelContentAfter: [
+          {
+            id: 1,
+            name: 'n1',
+            type: 'SNMP',
+            description: 'd1',
+            global: true,
+            enabled: true,
+            properties: {
+              p: 'v'
+            }
+          },
+          {
+            id: 2,
+            name: 'n2',
+            type: 'EMAIL',
+            description: 'd2',
+            global: false,
+            enabled: false,
+            alertStates: ['OK', 'WARNING', 'CRITICAL', 'UNKNOWN']
+          }
+        ],
+        title: 'update cache and model'
+      }
+    ];
+
+    cases.forEach(function (test) {
+      describe(test.title, function () {
+        before(function () {
+          App.cache.alertNotificationsGroupsMap = {
+            1: [1, 2]
+          };
+        });
+
+        beforeEach(function () {
+          App.store.safeLoadMany(model, test.modelJSONBefore);
+          App.cache.previousAlertNotificationsFullMap = 
test.previousAlertNotificationsFullMapBefore;
+          mapper.map(test.json);
+        });
+
+        after(function () {
+          App.cache.previousAlertNotificationsFullMap = {};
+          App.cache.alertNotificationsGroupsMap = {};
+        });
+
+        it('previousAlertNotificationsFullMap', function () {
+          
expect(App.cache.previousAlertNotificationsFullMap).to.eql(test.previousAlertNotificationsFullMapAfter);
+        });
+
+        it('records count', function () {
+          
expect(records.get('length')).to.equal(test.modelContentAfter.length);
+        });
+
+        it('records', function () {
+          testHelpers.nestedExpect(test.modelContentAfter, records.toArray());
+        });
+      });
+    });
+  });
+
+  describe('#_setPropertiesToEachModel', function () {
+    beforeEach(function () {
+      App.store.safeLoadMany(model, [
+        {
+          id: 1,
+          properties: {
+            p: 'v'
+          }
+        },
+        {
+          id: 2
+        }
+      ]);
+    });
+    it('should set and update specified property', function () {
+      mapper._setPropertiesToEachModel('properties', {
+        '1': {
+          p1: 'v1'
+        },
+        '2': {
+          p2: 'v2'
+        }
+      });
+      testHelpers.nestedExpect([
+        {
+          id: 1,
+          properties: {
+            p1: 'v1'
+          }
+        },
+        {
+          id: 2,
+          properties: {
+            p2: 'v2'
+          }
+        }
+      ], records.toArray());
+    });
+  });
+});
diff --git a/ambari-web/test/mappers/cluster_mapper_test.js 
b/ambari-web/test/mappers/cluster_mapper_test.js
new file mode 100644
index 0000000..61eced9
--- /dev/null
+++ b/ambari-web/test/mappers/cluster_mapper_test.js
@@ -0,0 +1,97 @@
+/**
+ * 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.
+ */
+
+var App = require('app');
+var testHelpers = require('test/helpers');
+require('mappers/cluster_mapper');
+
+describe('App.clusterMapper', function () {
+  var records = App.Cluster.find();
+
+  before(function () {
+    records.clear();
+  });
+
+  afterEach(function () {
+    records.clear();
+  });
+
+  describe('#map', function () {
+    it('should load mapped data to model', function () {
+      App.clusterMapper.map({
+        Clusters: {
+          cluster_id: 'c',
+          cluster_name: 'c',
+          stack_name: 'HDP',
+          version: '3.0.0',
+          security_type: 'NONE',
+          total_hosts: 3,
+          credential_store_properties: {
+            p: 'v'
+          },
+          desired_configs: {
+            'core-site': {
+              tag: 't0'
+            },
+            'hdfs-site': {
+              tag: 't1',
+              host_overrides: [
+                {
+                  host_name: 'h0',
+                  tag: 't2'
+                },
+                {
+                  host_name: 'h1',
+                  tag: 't3'
+                }
+              ]
+            }
+          }
+        }
+      });
+      testHelpers.nestedExpect([
+        {
+          id: 'c',
+          clusterName: 'c',
+          stackName: 'HDP',
+          version: '3.0.0',
+          securityType: 'NONE',
+          totalHosts: 3,
+          credentialStoreProperties: {
+            p: 'v'
+          },
+          desiredConfigs: [
+            App.ConfigSiteTag.create({
+              site: 'core-site',
+              tag: 't0',
+              hostOverrides: {}
+            }),
+            App.ConfigSiteTag.create({
+              site: 'hdfs-site',
+              tag: 't1',
+              hostOverrides: {
+                h0: 't2',
+                h1: 't3'
+              }
+            })
+          ]
+        }
+      ], records.toArray());
+    });
+  });
+});
diff --git a/ambari-web/test/mappers/stack_version_mapper_test.js 
b/ambari-web/test/mappers/stack_version_mapper_test.js
new file mode 100644
index 0000000..0741bb2
--- /dev/null
+++ b/ambari-web/test/mappers/stack_version_mapper_test.js
@@ -0,0 +1,333 @@
+/**
+ * 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.
+ */
+
+var App = require('app');
+var testHelpers = require('test/helpers');
+require('mappers/stack_version_mapper');
+
+describe('App.stackVersionMapper', function () {
+  var stackVersionRecords = App.StackVersion.find(),
+    repoVersionRecords = App.RepositoryVersion.find(),
+    clearModels = function () {
+      stackVersionRecords.clear();
+      repoVersionRecords.clear();
+    };
+
+  before(clearModels);
+
+  afterEach(clearModels);
+
+  describe('#map', function () {
+    beforeEach(function () {
+      App.stackVersionMapper.map({
+        items: [
+          {
+            ClusterStackVersions: {
+              id: 1,
+              cluster_name: 'c',
+              stack: 'HDP',
+              version: '3.0',
+              repository_version: 11,
+              state: 'OUT_OF_SYNC',
+              supports_revert: false,
+              host_states: {
+                CURRENT: ['h0, h1'],
+                INSTALLED: ['h2', 'h3'],
+                INSTALLING: ['h4', 'h5'],
+                INSTALL_FAILED: ['h6', 'h7'],
+                NOT_REQUIRED: ['h8', 'h9'],
+                OUT_OF_SYNC: ['h10', 'h11'],
+                UPGRADING: ['h12', 'h13'],
+                UPGRADED: ['h14', 'h15'],
+                UPGRADE_FAILED: ['h16', 'h17']
+              },
+              repository_summary: {
+                services: {
+                  ZOOKEEPER: {
+                    version: '4.0.0',
+                    release_version: '3.0.1.1',
+                    upgrade: true
+                  }
+                }
+              }
+            },
+            repository_versions: [
+              {
+                RepositoryVersions: {
+                  id: 11,
+                  repository_version: '3.0.1.1'
+                }
+              }
+            ]
+          },
+          {
+            ClusterStackVersions: {
+              id: 2,
+              cluster_name: 'c',
+              stack: 'HDP',
+              version: '3.0',
+              repository_version: 12,
+              state: 'INSTALL_FAILED',
+              supports_revert: false,
+              host_states: {
+                CURRENT: [],
+                INSTALLED: [],
+                INSTALLING: [],
+                INSTALL_FAILED: [],
+                NOT_REQUIRED: [],
+                OUT_OF_SYNC: [],
+                UPGRADING: [],
+                UPGRADED: [],
+                UPGRADE_FAILED: []
+              },
+              repository_summary: {
+                services: {
+                  ZOOKEEPER: {
+                    version: '3.8.0',
+                    release_version: '3.0.0.0',
+                    upgrade: true
+                  }
+                }
+              }
+            },
+            repository_versions: [
+              {
+                RepositoryVersions: {
+                  id: 12,
+                  repository_version: '3.0.0.0'
+                }
+              }
+            ]
+          },
+          {
+            ClusterStackVersions: {
+              id: 3,
+              cluster_name: 'c',
+              stack: 'HDP',
+              version: '3.0',
+              repository_version: 13,
+              state: 'COMPLETED',
+              supports_revert: false,
+              host_states: {
+                CURRENT: [],
+                INSTALLED: [],
+                INSTALLING: [],
+                INSTALL_FAILED: [],
+                NOT_REQUIRED: [],
+                OUT_OF_SYNC: [],
+                UPGRADING: [],
+                UPGRADED: [],
+                UPGRADE_FAILED: []
+              },
+              repository_summary: {
+                services: {
+                  ZOOKEEPER: {
+                    version: '3.9.0',
+                    release_version: '3.0.1.0',
+                    upgrade: true
+                  }
+                }
+              }
+            },
+            repository_versions: [
+              {
+                RepositoryVersions: {
+                  id: 13,
+                  repository_version: '3.0.1.0'
+                }
+              }
+            ]
+          },
+          {
+            ClusterStackVersions: {
+              id: 4,
+              cluster_name: 'c',
+              stack: 'HDP',
+              version: '3.0',
+              repository_version: 14,
+              state: 'INSTALLING',
+              supports_revert: true,
+              revert_upgrade_id: 1,
+              host_states: {
+                CURRENT: [],
+                INSTALLED: [],
+                INSTALLING: [],
+                INSTALL_FAILED: [],
+                NOT_REQUIRED: [],
+                OUT_OF_SYNC: [],
+                UPGRADING: [],
+                UPGRADED: [],
+                UPGRADE_FAILED: []
+              },
+              repository_summary: {
+                services: {
+                  ZOOKEEPER: {
+                    version: '4.1.0',
+                    release_version: '3.1.1.0',
+                    upgrade: true
+                  }
+                }
+              }
+            },
+            repository_versions: [
+              {
+                RepositoryVersions: {
+                  id: 14,
+                  repository_version: '3.1.1.0'
+                }
+              }
+            ]
+          },
+          {
+            ClusterStackVersions: {
+              id: 5,
+              cluster_name: 'c',
+              stack: 'HDP',
+              version: '3.0',
+              repository_version: 15,
+              state: 'NOT_REQUIRED',
+              supports_revert: false,
+              host_states: {
+                CURRENT: [],
+                INSTALLED: [],
+                INSTALLING: [],
+                INSTALL_FAILED: [],
+                NOT_REQUIRED: [],
+                OUT_OF_SYNC: [],
+                UPGRADING: [],
+                UPGRADED: [],
+                UPGRADE_FAILED: []
+              },
+              repository_summary: {
+                services: {
+                  ZOOKEEPER: {
+                    version: '3.7.0',
+                    release_version: '2.99.99.0',
+                    upgrade: true
+                  }
+                }
+              }
+            },
+            repository_versions: [
+              {
+                RepositoryVersions: {
+                  id: 15,
+                  repository_version: '2.99.99.0'
+                }
+              }
+            ]
+          }
+        ]
+      });
+    });
+
+    it('should load sorted and mapped data to App.StackVersion', function () {
+      testHelpers.nestedExpect([
+        {
+          id: 5,
+          clusterName: 'c',
+          stack: 'HDP',
+          version: '3.0',
+          state: 'NOT_REQUIRED',
+          notInstalledHosts: [],
+          installingHosts: [],
+          installedHosts: [],
+          installFailedHosts: [],
+          outOfSyncHosts: [],
+          upgradingHosts: [],
+          upgradedHosts: [],
+          upgradeFailedHosts: [],
+          currentHosts: [],
+          supportsRevert: false
+        },
+        {
+          id: 2,
+          clusterName: 'c',
+          stack: 'HDP',
+          version: '3.0',
+          state: 'INSTALL_FAILED',
+          notInstalledHosts: [],
+          installingHosts: [],
+          installedHosts: [],
+          installFailedHosts: [],
+          outOfSyncHosts: [],
+          upgradingHosts: [],
+          upgradedHosts: [],
+          upgradeFailedHosts: [],
+          currentHosts: [],
+          supportsRevert: false
+        },
+        {
+          id: 3,
+          clusterName: 'c',
+          stack: 'HDP',
+          version: '3.0',
+          state: 'COMPLETED',
+          notInstalledHosts: [],
+          installingHosts: [],
+          installedHosts: [],
+          installFailedHosts: [],
+          outOfSyncHosts: [],
+          upgradingHosts: [],
+          upgradedHosts: [],
+          upgradeFailedHosts: [],
+          currentHosts: [],
+          supportsRevert: false
+        },
+        {
+          id: 1,
+          clusterName: 'c',
+          stack: 'HDP',
+          version: '3.0',
+          state: 'OUT_OF_SYNC',
+          notInstalledHosts: ['h4', 'h5', 'h6', 'h7', 'h10', 'h11'],
+          installingHosts: ['h4', 'h5'],
+          installedHosts: ['h2', 'h3', 'h12', 'h13', 'h14', 'h15', 'h16', 
'h17'],
+          installFailedHosts: ['h6', 'h7'],
+          outOfSyncHosts: ['h10', 'h11'],
+          upgradingHosts: ['h12', 'h13'],
+          upgradedHosts: ['h14', 'h15'],
+          upgradeFailedHosts: ['h16', 'h17'],
+          currentHosts: ['h0, h1'],
+          supportsRevert: false
+        },
+        {
+          id: 4,
+          clusterName: 'c',
+          stack: 'HDP',
+          version: '3.0',
+          state: 'INSTALLING',
+          notInstalledHosts: [],
+          installingHosts: [],
+          installedHosts: [],
+          installFailedHosts: [],
+          outOfSyncHosts: [],
+          upgradingHosts: [],
+          upgradedHosts: [],
+          upgradeFailedHosts: [],
+          currentHosts: [],
+          supportsRevert: true
+        },
+      ], stackVersionRecords.toArray());
+    });
+
+    it('should set relations to App.RepositoryVersion', function () {
+      
testHelpers.nestedExpect(stackVersionRecords.mapProperty('repositoryVersion'), 
repoVersionRecords.toArray());
+    })
+  });
+});
diff --git a/ambari-web/test/mappers/widget_mapper_test.js 
b/ambari-web/test/mappers/widget_mapper_test.js
new file mode 100644
index 0000000..22d3586
--- /dev/null
+++ b/ambari-web/test/mappers/widget_mapper_test.js
@@ -0,0 +1,162 @@
+/**
+ * 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.
+ */
+
+var App = require('app');
+var testHelpers = require('test/helpers');
+require('mappers/widget_mapper');
+
+describe('App.widgetMapper', function () {
+  var widgetModel = App.Widget,
+    layoutModel = App.WidgetLayout,
+    widgetRecords = widgetModel.find(),
+    layoutRecords = layoutModel.find(),
+    clearData = function () {
+      widgetRecords.clear();
+      layoutRecords.clear();
+    };
+
+  beforeEach(function () {
+    clearData();
+    App.store.safeLoad(layoutModel, {
+      id: 1,
+      section_name: 's0'
+    });
+    App.widgetMapper.map({
+      id: 1,
+      section_name: 's0',
+      widgets: [
+        {
+          WidgetInfo: {
+            id: 11,
+            widget_name: 'wn0',
+            widget_type: 'GRAPH',
+            service_name: 'HDFS',
+            time_created: 1,
+            author: 'a0',
+            properties: '{"graph_type":"LINE","time_range":"1"}',
+            metrics: 
'[{"name":"m0","metric_path":"p0/m0"},{"name":"m1","metric_path":"p1/m1"}]',
+            values: '[{"name":"n0","value":"v0"},{"name":"n1","value":"v1"}]',
+            description: 'd0',
+            scope: 'CLUSTER',
+            tag: 't0'
+          }
+        },
+        {
+          WidgetInfo: {
+            id: 12,
+            widget_name: 'wn1',
+            widget_type: 'NUMBER',
+            service_name: 'YARN',
+            time_created: 2,
+            author: 'a1',
+            properties: '{"warning_threshold":"1","error_threshold":"2"}',
+            metrics: 
'[{"name":"m2","metric_path":"p2/m2"},{"name":"m3","metric_path":"p3/m3"}]',
+            values: '[{"name":"n2","value":"v2"},{"name":"n3","value":"v3"}]',
+            description: 'd1',
+            scope: 'CLUSTER',
+            tag: 't1'
+          }
+        }
+      ]
+    });
+  });
+
+  afterEach(clearData);
+
+  describe('#map', function () {
+    it('should load mapped data to App.Widget', function () {
+      testHelpers.nestedExpect([
+        {
+          id: 11,
+          widgetName: 'wn0',
+          widgetType: 'GRAPH',
+          serviceName: 'HDFS',
+          timeCreated: 1,
+          author: 'a0',
+          properties: {
+            graph_type: 'LINE',
+            time_range: '1'
+          },
+          metrics: [
+            {
+              name: 'm0',
+              metric_path: 'p0/m0'
+            }, {
+              name: 'm1',
+              metric_path: 'p1/m1'
+            }
+          ],
+          values: [
+            {
+              name: 'n0',
+              value: 'v0'
+            },
+            {
+              name: 'n1',
+              value: 'v1'
+            }
+          ],
+          description: 'd0',
+          scope: 'CLUSTER',
+          tag: 't0',
+          defaultOrder: 1
+        },
+        {
+          id: 12,
+          widgetName: 'wn1',
+          widgetType: 'NUMBER',
+          serviceName: 'YARN',
+          timeCreated: 2,
+          author: 'a1',
+          properties: {
+            warning_threshold: '1',
+            error_threshold: '2'
+          },
+          metrics: [
+            {
+              name: 'm2',
+              metric_path: 'p2/m2'
+            },
+            {
+              name: 'm3',
+              metric_path: 'p3/m3'
+            }
+          ],
+          values: [
+            {
+              name: 'n2',
+              value: 'v2'
+            },
+            {
+              name: 'n3',
+              value: 'v3'
+            }
+          ],
+          description: 'd1',
+          scope: 'CLUSTER',
+          tag: 't1',
+          defaultOrder: 2
+        }
+      ], widgetRecords.toArray());
+    });
+
+    it('should set relations to App.WidgetLayout', function () {
+      testHelpers.nestedExpect(widgetRecords.mapProperty('layout').uniq(), 
layoutRecords.toArray());
+    });
+  });
+});

Reply via email to