Repository: ambari
Updated Branches:
  refs/heads/trunk 995343371 -> 66d0b6e2c


http://git-wip-us.apache.org/repos/asf/ambari/blob/66d0b6e2/ambari-web/app/models/alerts/alert_notification.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/models/alerts/alert_notification.js 
b/ambari-web/app/models/alerts/alert_notification.js
new file mode 100644
index 0000000..c2d7570
--- /dev/null
+++ b/ambari-web/app/models/alerts/alert_notification.js
@@ -0,0 +1,33 @@
+/**
+ * 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');
+
+App.AlertNotification = DS.Model.extend({
+  id: DS.attr('number'),
+  name: DS.attr('string'),
+  type: DS.attr('string'),
+  description: DS.attr('string'),
+  groups: DS.hasMany('App.AlertGroup'),
+  global: DS.attr('boolean'),
+
+  properties: {},
+  alertStates: []
+});
+
+App.AlertNotification.FIXTURES = [];
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ambari/blob/66d0b6e2/ambari-web/app/views/main/alerts/definition_details_view.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/views/main/alerts/definition_details_view.js 
b/ambari-web/app/views/main/alerts/definition_details_view.js
index cbbded9..12b563c 100644
--- a/ambari-web/app/views/main/alerts/definition_details_view.js
+++ b/ambari-web/app/views/main/alerts/definition_details_view.js
@@ -163,7 +163,7 @@ App.AlertInstanceServiceHostView = Em.View.extend({
    * Define whether show link for transition to service page
    */
   serviceIsLink: function () {
-    return App.Service.find().someProperty('serviceName', 
this.get('instance.service.serviceName'));
+    return 
App.get('services.all').contains(this.get('instance.service.serviceName'));
   }.property('instance.service.serviceName'),
 
   /**

http://git-wip-us.apache.org/repos/asf/ambari/blob/66d0b6e2/ambari-web/app/views/main/host/host_alerts_view.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/views/main/host/host_alerts_view.js 
b/ambari-web/app/views/main/host/host_alerts_view.js
index 54b4e7c..656787b 100644
--- a/ambari-web/app/views/main/host/host_alerts_view.js
+++ b/ambari-web/app/views/main/host/host_alerts_view.js
@@ -253,10 +253,15 @@ App.MainHostAlertsView = App.TableView.extend({
    * @method tooltipsUpdater
    */
   tooltipsUpdater: function () {
+    Em.run.once(this,this.tooltipsUpdaterOnce);
+  }.observes('pageContent.@each'),
+
+  tooltipsUpdaterOnce: function() {
+    var self = this;
     Em.run.next(this, function () {
-      App.tooltip($(".enable-disable-button, .timeago, .alert-text"));
+      App.tooltip(self.$(".enable-disable-button, .timeago, .alert-text"));
     });
-  }.observes('pageContent.@each'),
+  },
 
   /**
    * Run <code>clearFilter</code> in the each child filterView
@@ -268,6 +273,10 @@ App.MainHostAlertsView = App.TableView.extend({
         childView.clearFilter();
       }
     });
+  },
+
+  willDestroyElement: function() {
+    this.$(".enable-disable-button, .timeago, .alert-text").tooltip('destroy');
   }
 
 });

http://git-wip-us.apache.org/repos/asf/ambari/blob/66d0b6e2/ambari-web/test/models/alert_config_test.js
----------------------------------------------------------------------
diff --git a/ambari-web/test/models/alert_config_test.js 
b/ambari-web/test/models/alert_config_test.js
deleted file mode 100644
index 31f2ce9..0000000
--- a/ambari-web/test/models/alert_config_test.js
+++ /dev/null
@@ -1,332 +0,0 @@
-/**
- * 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');
-
-require('models/alert_config');
-
-var model;
-
-describe('App.AlertConfigProperties', function () {
-
-  describe('Threshold', function () {
-
-    beforeEach(function () {
-      model = App.AlertConfigProperties.Threshold.create({});
-    });
-
-    describe('#apiFormattedValue', function () {
-
-      it('should be based on showInputForValue and showInputForText', function 
() {
-
-        model.setProperties({
-          value: 'value',
-          text: 'text',
-          showInputForValue: false,
-          showInputForText: false
-        });
-        expect(model.get('apiFormattedValue')).to.eql([]);
-
-        model.set('showInputForValue', true);
-        expect(model.get('apiFormattedValue')).to.eql(['value']);
-
-        model.set('showInputForText', true);
-        expect(model.get('apiFormattedValue')).to.eql(['value', 'text']);
-
-      });
-
-    });
-
-    describe('#valueWasChanged', function () {
-
-      it('value change should effect displayValue for AGGREGATE type', 
function () {
-
-        model = 
App.AlertConfigProperties.Threshold.create(App.AlertConfigProperties.Thresholds.PercentageMixin,
 {
-          value: '0.4',
-          valueMetric: '%',
-          text: 'text',
-          showInputForValue: false,
-          showInputForText: false
-        });
-
-        expect(model.get('displayValue')).to.eql('40');
-      });
-
-      it('value change should not effect displayValue for not AGGREGATE type', 
function () {
-
-        model = App.AlertConfigProperties.Threshold.create({
-          value: '0.4',
-          valueMetric: '%',
-          text: 'text',
-          showInputForValue: false,
-          showInputForText: false
-        });
-
-        expect(model.get('displayValue')).to.eql('0.4');
-      });
-
-    });
-
-    describe('#badgeCssClass', function () {
-
-      it ('should be based on badge', function () {
-
-        model.set('badge', 'OK');
-        expect(model.get('badgeCssClass')).to.equal('alert-state-OK');
-
-      });
-
-    });
-
-    describe('#wasChanged', function () {
-
-      Em.A([
-          {
-            p: {
-              previousValue: null,
-              previousText: null,
-              value: '',
-              text: ''
-            },
-            e: false
-          },
-          {
-            p: {
-              previousValue: 'not null',
-              previousText: null,
-              value: '',
-              text: ''
-            },
-            e: true
-          },
-          {
-            p: {
-              previousValue: null,
-              previousText: 'not null',
-              value: '',
-              text: ''
-            },
-            e: true
-          },
-          {
-            p: {
-              previousValue: 'not null',
-              previousText: 'not null',
-              value: '',
-              text: ''
-            },
-            e: true
-          }
-        ]).forEach(function (test, i) {
-        it('test #' + (i + 1), function () {
-          model.setProperties(test.p);
-          expect(model.get('wasChanged')).to.equal(test.e);
-        });
-      });
-
-    });
-
-    describe('#isValid', function () {
-
-      it('should be true if showInputForValue is false', function () {
-        model.set('showInputForValue', false);
-        expect(model.get('isValid')).to.be.true;
-      });
-
-      it('should be false if displayValue is null', function () {
-        model.set('displayValue', null);
-        expect(model.get('isValid')).to.be.false;
-
-        model.set('displayValue', undefined);
-        expect(model.get('isValid')).to.be.false;
-      });
-
-      it('should be false if METRIC displayValue is not valid float', function 
() {
-        model.set('displayValue', '$1234.444');
-        expect(model.get('isValid')).to.be.false;
-
-        model.set('displayValue', 'hello-world!');
-        expect(model.get('isValid')).to.be.false;
-      });
-
-      it('should be true if METRIC displayValue is valid float with at most 
one decimal', function () {
-        model.set('displayValue', '123.4');
-        expect(model.get('isValid')).to.be.true;
-
-        model.set('displayValue', '123.0');
-        expect(model.get('isValid')).to.be.true;
-
-        model.set('displayValue', '666');
-        expect(model.get('isValid')).to.be.true;
-      });
-
-      it('should be false if METRIC displayValue is valid float with more than 
one decimal', function () {
-        model.set('displayValue', '123.48');
-        expect(model.get('isValid')).to.be.false;
-      });
-
-      it('should be true for AGGREGATE percentage with precision of 1', 
function () {
-        model = 
Em.Object.create(App.AlertConfigProperties.Thresholds.PercentageMixin, {
-          displayValue: '1',
-          showInputForValue: true
-        });
-
-        expect(model.get('isValid')).to.be.true;
-
-        model.set('displayValue', '88');
-        expect(model.get('isValid')).to.be.true;
-      });
-
-      it('should be false for AGGREGATE percentage values with precision 
smaller than 1', function () {
-        model = 
Em.Object.create(App.AlertConfigProperties.Thresholds.PercentageMixin, {
-          displayValue: '70.01',
-          showInputForValue: true
-        });
-
-        expect(model.get('isValid')).to.be.false;
-
-        model.set('displayValue', '70.0');
-        expect(model.get('isValid')).to.be.false;
-
-        model.set('displayValue', '80.000');
-        expect(model.get('isValid')).to.be.false;
-      });
-
-      it('should be true for PORT percentage values with precision of 1/10th', 
function () {
-        model = App.AlertConfigProperties.Threshold.create({
-          value: '0.4',
-          showInputForValue: true
-        })
-
-        expect(model.get('isValid')).to.be.true;
-
-        model.set('value', '3');
-        expect(model.get('isValid')).to.be.true;
-
-        model.set('value', '33.0');
-        expect(model.get('isValid')).to.be.true;
-      });
-
-      it('should be false for PORT percentage values with precision greater 
than 1/10th', function() {
-        model = App.AlertConfigProperties.Threshold.create({
-          value: '4.234',
-          showInputForValue: true
-        });
-
-        expect(model.get('isValid')).to.be.false;
-
-        model.set('value', '44.001');
-        expect(model.get('isValid')).to.be.false;
-
-        model.set('value', '112.01');
-        expect(model.get('isValid')).to.be.false;
-      });
-
-    });
-
-  });
-
-  describe('App.AlertConfigProperties.Thresholds', function () {
-
-    describe('OkThreshold', function () {
-
-      beforeEach(function () {
-        model = App.AlertConfigProperties.Thresholds.OkThreshold.create();
-      });
-
-      describe('#apiProperty', function () {
-
-        it('should be based on showInputForValue and showInputForText', 
function () {
-
-          model.setProperties({
-            showInputForValue: false,
-            showInputForText: false
-          });
-          expect(model.get('apiProperty')).to.eql([]);
-
-          model.set('showInputForValue', true);
-          
expect(model.get('apiProperty')).to.eql(['source.reporting.ok.value']);
-
-          model.set('showInputForText', true);
-          
expect(model.get('apiProperty')).to.eql(['source.reporting.ok.value', 
'source.reporting.ok.text']);
-
-        });
-
-      });
-
-    });
-
-    describe('WarningThreshold', function () {
-
-      beforeEach(function () {
-        model = App.AlertConfigProperties.Thresholds.WarningThreshold.create();
-      });
-
-      describe('#apiProperty', function () {
-
-        it('should be based on showInputForValue and showInputForText', 
function () {
-
-          model.setProperties({
-            showInputForValue: false,
-            showInputForText: false
-          });
-          expect(model.get('apiProperty')).to.eql([]);
-
-          model.set('showInputForValue', true);
-          
expect(model.get('apiProperty')).to.eql(['source.reporting.warning.value']);
-
-          model.set('showInputForText', true);
-          
expect(model.get('apiProperty')).to.eql(['source.reporting.warning.value', 
'source.reporting.warning.text']);
-
-        });
-
-      });
-
-    });
-
-    describe('CriticalThreshold', function () {
-
-      beforeEach(function () {
-        model = 
App.AlertConfigProperties.Thresholds.CriticalThreshold.create();
-      });
-
-      describe('#apiProperty', function () {
-
-        it('should be based on showInputForValue and showInputForText', 
function () {
-
-          model.setProperties({
-            showInputForValue: false,
-            showInputForText: false
-          });
-          expect(model.get('apiProperty')).to.eql([]);
-
-          model.set('showInputForValue', true);
-          
expect(model.get('apiProperty')).to.eql(['source.reporting.critical.value']);
-
-          model.set('showInputForText', true);
-          
expect(model.get('apiProperty')).to.eql(['source.reporting.critical.value', 
'source.reporting.critical.text']);
-
-        });
-
-      });
-
-    });
-
-  });
-
-});

http://git-wip-us.apache.org/repos/asf/ambari/blob/66d0b6e2/ambari-web/test/models/alert_definition_test.js
----------------------------------------------------------------------
diff --git a/ambari-web/test/models/alert_definition_test.js 
b/ambari-web/test/models/alert_definition_test.js
deleted file mode 100644
index 1e349b1..0000000
--- a/ambari-web/test/models/alert_definition_test.js
+++ /dev/null
@@ -1,212 +0,0 @@
-/**
- * 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');
-
-require('models/alert_definition');
-
-var model;
-
-describe('App.AlertDefinition', function () {
-
-  beforeEach(function () {
-
-    model = App.AlertDefinition.createRecord();
-
-  });
-
-  describe('#status', function () {
-
-    Em.A([
-      {
-        summary: {OK: {count: 1, maintenanceCount: 0}, UNKNOWN: {count: 1, 
maintenanceCount: 0}, WARNING: {count: 2, maintenanceCount: 0}, CRITICAL: 
{count: 0, maintenanceCount: 0}},
-        m: 'No CRITICAL',
-        e: '<span class="alert-state-single-host label alert-state-OK">OK 
(1)</span> ' +
-        '<span class="alert-state-single-host label alert-state-WARNING">WARN 
(2)</span> ' +
-        '<span class="alert-state-single-host label alert-state-UNKNOWN">UNKWN 
(1)</span>'
-      },
-      {
-        summary: {WARNING: {count: 2, maintenanceCount: 0}, CRITICAL: {count: 
3, maintenanceCount: 0}, UNKNOWN: {count: 1, maintenanceCount: 0}, OK: {count: 
1, maintenanceCount: 0}},
-        m: 'All states exists',
-        e: '<span class="alert-state-single-host label alert-state-OK">OK 
(1)</span> ' +
-        '<span class="alert-state-single-host label alert-state-WARNING">WARN 
(2)</span> ' +
-        '<span class="alert-state-single-host label alert-state-CRITICAL">CRIT 
(3)</span> ' +
-        '<span class="alert-state-single-host label alert-state-UNKNOWN">UNKWN 
(1)</span>'
-      },
-      {
-        summary: {OK: {count: 1, maintenanceCount: 0}, UNKNOWN: {count: 0, 
maintenanceCount: 0}, WARNING: {count: 0, maintenanceCount: 0}, CRITICAL: 
{count: 0, maintenanceCount: 0}},
-        m: 'Single host',
-        e: '<span class="alert-state-single-host label 
alert-state-OK">OK</span>'
-      },
-      {
-        summary: {OK: {count: 0, maintenanceCount: 1}, UNKNOWN: {count: 0, 
maintenanceCount: 0}, WARNING: {count: 0, maintenanceCount: 0}, CRITICAL: 
{count: 0, maintenanceCount: 0}},
-        m: 'Maintenance OK alert',
-        e: '<span class="alert-state-single-host label 
alert-state-PENDING"><span class="icon-medkit"></span> OK</span>'
-      },
-      {
-        summary: {},
-        m: 'Pending',
-        e: '<span class="alert-state-single-host label 
alert-state-PENDING">NONE</span>'
-      }
-    ]).forEach(function (test) {
-      it(test.m, function () {
-        model.set('summary', test.summary);
-        expect(model.get('status')).to.equal(test.e);
-      });
-    });
-
-  });
-
-  describe('#isCriticalOrWarning', function () {
-
-    Em.A([
-      {summary: {CRITICAL: {count: 1, maintenanceCount: 0}}, e: true},
-      {summary: {CRITICAL: {count: 0, maintenanceCount: 1}}, e: false},
-      {summary: {CRITICAL: {count: 1, maintenanceCount: 1}}, e: true},
-      {summary: {WARNING: {count: 1, maintenanceCount: 0}}, e: true},
-      {summary: {OK: {count: 1, maintenanceCount: 0}}, e: false},
-      {summary: {UNKNOWN: {count: 1, maintenanceCount: 0}}, e: false},
-      {summary: {}, e: false}
-    ]).forEach(function (test, i) {
-      it('test ' + (i + 1), function () {
-        model.set('summary', test.summary);
-        expect(model.get('isCriticalOrWarning')).to.equal(test.e);
-      });
-    });
-
-  });
-
-  describe('#isCritical', function () {
-
-    Em.A([
-      {summary: {CRITICAL: {count: 1, maintenanceCount: 0}}, e: true},
-      {summary: {WARNING: {count: 1, maintenanceCount: 0}}, e: false},
-      {summary: {OK: {count: 1, maintenanceCount: 0}}, e: false},
-      {summary: {UNKNOWN: {count: 1, maintenanceCount: 0}}, e: false},
-      {summary: {}, e: false}
-    ]).forEach(function (test, i) {
-      it('test ' + (i + 1), function () {
-        model.set('summary', test.summary);
-        expect(model.get('isCritical')).to.equal(test.e);
-      });
-    });
-
-  });
-
-  describe('#isWarning', function () {
-
-    Em.A([
-      {summary: {CRITICAL: {count: 1, maintenanceCount: 0}}, e: false},
-      {summary: {WARNING: {count: 1, maintenanceCount: 0}}, e: true},
-      {summary: {OK: {count: 1, maintenanceCount: 0}}, e: false},
-      {summary: {UNKNOWN: {count: 1, maintenanceCount: 0}}, e: false},
-      {summary: {}, e: false}
-    ]).forEach(function (test, i) {
-      it('test ' + (i + 1), function () {
-        model.set('summary', test.summary);
-        expect(model.get('isWarning')).to.equal(test.e);
-      });
-    });
-
-  });
-
-  describe('#lastTriggeredAgoFormatted', function () {
-
-    it('should be empty', function () {
-      model.set('lastTriggered', 0);
-      expect(model.get('lastTriggeredAgoFormatted')).to.equal('');
-    });
-
-    it('should not be empty', function () {
-      model.set('lastTriggered', new Date().getTime() - 61000);
-      expect(model.get('lastTriggeredAgoFormatted')).to.equal('about a minute 
ago');
-    });
-
-  });
-
-  describe('#serviceDisplayName', function () {
-
-    it('should get name for non-existing service', function () {
-      model.set('serviceName', 'FOOBAR');
-      expect(model.get('serviceDisplayName')).to.equal('Foobar');
-    });
-
-  });
-
-  describe('#componentNameFormatted', function () {
-
-    beforeEach(function () {
-      sinon.stub(App.format, 'role', function (a) {
-        return 'role ' + a;
-      });
-    });
-
-    it('should wrap component name by App.format.role method', function () {
-      model.set('componentName', 'test');
-      var result = model.get('componentNameFormatted');
-      expect(result).to.equal('role test');
-    });
-
-    afterEach(function () {
-      App.format.role.restore();
-    });
-
-
-  });
-
-  describe('REOPEN', function () {
-
-    describe('#getSortDefinitionsByStatus', function () {
-
-      Em.A([
-          {
-            a: App.AlertDefinition.createRecord({summary: {OK: {count: 1, 
maintenanceCount: 0}, WARNING: {count: 1, maintenanceCount: 0}}}),
-            b: App.AlertDefinition.createRecord({summary: {WARNING: {count: 1, 
maintenanceCount: 0}}}),
-            order: true,
-            e: -1
-          },
-          {
-            a: App.AlertDefinition.createRecord({summary: {OK: {count: 1, 
maintenanceCount: 0}, WARNING: {count: 2, maintenanceCount: 0}}}),
-            b: App.AlertDefinition.createRecord({summary: {OK: {count: 1, 
maintenanceCount: 0}, WARNING: {count: 1, maintenanceCount: 0}}}),
-            order: true,
-            e: -1
-          },
-          {
-            a: App.AlertDefinition.createRecord({summary: {OK: {count: 1, 
maintenanceCount: 0}, WARNING: {count: 1, maintenanceCount: 0}}}),
-            b: App.AlertDefinition.createRecord({summary: {WARNING: {count: 1, 
maintenanceCount: 0}}}),
-            order: false,
-            e: 1
-          },
-          {
-            a: App.AlertDefinition.createRecord({summary: {OK: {count: 1, 
maintenanceCount: 0}, WARNING: {count: 2, maintenanceCount: 0}}}),
-            b: App.AlertDefinition.createRecord({summary: {OK: {count: 1, 
maintenanceCount: 0}, WARNING: {count: 1, maintenanceCount: 0}}}),
-            order: false,
-            e: 1
-          }
-        ]).forEach(function(test, i) {
-          it('test #' + (i + 1), function () {
-            var func = 
App.AlertDefinition.getSortDefinitionsByStatus(test.order);
-            expect(func(test.a, test.b)).to.equal(test.e);
-          });
-        });
-
-    });
-
-  });
-
-});

http://git-wip-us.apache.org/repos/asf/ambari/blob/66d0b6e2/ambari-web/test/models/alert_instance_test.js
----------------------------------------------------------------------
diff --git a/ambari-web/test/models/alert_instance_test.js 
b/ambari-web/test/models/alert_instance_test.js
deleted file mode 100644
index dc692e2..0000000
--- a/ambari-web/test/models/alert_instance_test.js
+++ /dev/null
@@ -1,94 +0,0 @@
-/**
- * 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');
-
-require('models/alert_instance');
-
-var model;
-
-describe('App.AlertInstance', function () {
-
-  beforeEach(function () {
-
-    model = App.AlertInstance.createRecord();
-
-  });
-
-  describe('#serviceDisplayName', function () {
-
-    it('should get name for non-existing service', function () {
-      model.set('serviceName', 'FOOBAR');
-      expect(model.get('serviceDisplayName')).to.equal('Foobar');
-    });
-
-  });
-
-  describe('#statusChangedAndLastCheckedFormatted', function () {
-
-    it('should Status Changed before Last Checked', function () {
-
-      var lastCheckedFormatted = '123',
-        lastTriggeredFormatted = '321';
-
-      model.reopen({
-        lastCheckedFormatted: lastCheckedFormatted,
-        lastTriggeredFormatted: lastTriggeredFormatted
-      });
-      var status = model.get('statusChangedAndLastCheckedFormatted');
-      expect(status.indexOf(lastCheckedFormatted) > 
status.indexOf(lastTriggeredFormatted)).to.be.true;
-
-    });
-
-  });
-
-  describe('#status', function () {
-
-    it('should show maint mode icon', function () {
-
-      model.set('maintenanceState', 'ON');
-      model.set('state', 'OK');
-      var status = model.get('status');
-
-      expect(status).to.equal('<div class="label alert-state-single-host 
alert-state-PENDING"><span class="icon-medkit"></span> OK</div>');
-
-    });
-
-    it('should not show maint mode icon', function () {
-
-      model.set('maintenanceState', 'OFF');
-      model.set('state', 'OK');
-      var status = model.get('status');
-
-      expect(status).to.equal('<div class="label alert-state-single-host 
alert-state-OK">OK</div>');
-
-    });
-
-  });
-
-  describe('#escapeSpecialCharactersFromTooltip', function () {
-    it('it Should Display Alert Without special characters "<" and ">"', 
function () {
-
-      model.set('text', '<urlopen error [Errno 111] Connection refused>');
-      var resultedText = model.get('escapeSpecialCharactersFromTooltip');
-
-      expect(resultedText).to.equal('urlopen error [Errno 111] Connection 
refused');
-    });
-  });
-
-});

http://git-wip-us.apache.org/repos/asf/ambari/blob/66d0b6e2/ambari-web/test/models/alerts/alert_config_test.js
----------------------------------------------------------------------
diff --git a/ambari-web/test/models/alerts/alert_config_test.js 
b/ambari-web/test/models/alerts/alert_config_test.js
new file mode 100644
index 0000000..ae3f859
--- /dev/null
+++ b/ambari-web/test/models/alerts/alert_config_test.js
@@ -0,0 +1,332 @@
+/**
+ * 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');
+
+require('models/alerts/alert_config');
+
+var model;
+
+describe('App.AlertConfigProperties', function () {
+
+  describe('Threshold', function () {
+
+    beforeEach(function () {
+      model = App.AlertConfigProperties.Threshold.create({});
+    });
+
+    describe('#apiFormattedValue', function () {
+
+      it('should be based on showInputForValue and showInputForText', function 
() {
+
+        model.setProperties({
+          value: 'value',
+          text: 'text',
+          showInputForValue: false,
+          showInputForText: false
+        });
+        expect(model.get('apiFormattedValue')).to.eql([]);
+
+        model.set('showInputForValue', true);
+        expect(model.get('apiFormattedValue')).to.eql(['value']);
+
+        model.set('showInputForText', true);
+        expect(model.get('apiFormattedValue')).to.eql(['value', 'text']);
+
+      });
+
+    });
+
+    describe('#valueWasChanged', function () {
+
+      it('value change should effect displayValue for AGGREGATE type', 
function () {
+
+        model = 
App.AlertConfigProperties.Threshold.create(App.AlertConfigProperties.Thresholds.PercentageMixin,
 {
+          value: '0.4',
+          valueMetric: '%',
+          text: 'text',
+          showInputForValue: false,
+          showInputForText: false
+        });
+
+        expect(model.get('displayValue')).to.eql('40');
+      });
+
+      it('value change should not effect displayValue for not AGGREGATE type', 
function () {
+
+        model = App.AlertConfigProperties.Threshold.create({
+          value: '0.4',
+          valueMetric: '%',
+          text: 'text',
+          showInputForValue: false,
+          showInputForText: false
+        });
+
+        expect(model.get('displayValue')).to.eql('0.4');
+      });
+
+    });
+
+    describe('#badgeCssClass', function () {
+
+      it ('should be based on badge', function () {
+
+        model.set('badge', 'OK');
+        expect(model.get('badgeCssClass')).to.equal('alert-state-OK');
+
+      });
+
+    });
+
+    describe('#wasChanged', function () {
+
+      Em.A([
+          {
+            p: {
+              previousValue: null,
+              previousText: null,
+              value: '',
+              text: ''
+            },
+            e: false
+          },
+          {
+            p: {
+              previousValue: 'not null',
+              previousText: null,
+              value: '',
+              text: ''
+            },
+            e: true
+          },
+          {
+            p: {
+              previousValue: null,
+              previousText: 'not null',
+              value: '',
+              text: ''
+            },
+            e: true
+          },
+          {
+            p: {
+              previousValue: 'not null',
+              previousText: 'not null',
+              value: '',
+              text: ''
+            },
+            e: true
+          }
+        ]).forEach(function (test, i) {
+        it('test #' + (i + 1), function () {
+          model.setProperties(test.p);
+          expect(model.get('wasChanged')).to.equal(test.e);
+        });
+      });
+
+    });
+
+    describe('#isValid', function () {
+
+      it('should be true if showInputForValue is false', function () {
+        model.set('showInputForValue', false);
+        expect(model.get('isValid')).to.be.true;
+      });
+
+      it('should be false if displayValue is null', function () {
+        model.set('displayValue', null);
+        expect(model.get('isValid')).to.be.false;
+
+        model.set('displayValue', undefined);
+        expect(model.get('isValid')).to.be.false;
+      });
+
+      it('should be false if METRIC displayValue is not valid float', function 
() {
+        model.set('displayValue', '$1234.444');
+        expect(model.get('isValid')).to.be.false;
+
+        model.set('displayValue', 'hello-world!');
+        expect(model.get('isValid')).to.be.false;
+      });
+
+      it('should be true if METRIC displayValue is valid float with at most 
one decimal', function () {
+        model.set('displayValue', '123.4');
+        expect(model.get('isValid')).to.be.true;
+
+        model.set('displayValue', '123.0');
+        expect(model.get('isValid')).to.be.true;
+
+        model.set('displayValue', '666');
+        expect(model.get('isValid')).to.be.true;
+      });
+
+      it('should be false if METRIC displayValue is valid float with more than 
one decimal', function () {
+        model.set('displayValue', '123.48');
+        expect(model.get('isValid')).to.be.false;
+      });
+
+      it('should be true for AGGREGATE percentage with precision of 1', 
function () {
+        model = 
Em.Object.create(App.AlertConfigProperties.Thresholds.PercentageMixin, {
+          displayValue: '1',
+          showInputForValue: true
+        });
+
+        expect(model.get('isValid')).to.be.true;
+
+        model.set('displayValue', '88');
+        expect(model.get('isValid')).to.be.true;
+      });
+
+      it('should be false for AGGREGATE percentage values with precision 
smaller than 1', function () {
+        model = 
Em.Object.create(App.AlertConfigProperties.Thresholds.PercentageMixin, {
+          displayValue: '70.01',
+          showInputForValue: true
+        });
+
+        expect(model.get('isValid')).to.be.false;
+
+        model.set('displayValue', '70.0');
+        expect(model.get('isValid')).to.be.false;
+
+        model.set('displayValue', '80.000');
+        expect(model.get('isValid')).to.be.false;
+      });
+
+      it('should be true for PORT percentage values with precision of 1/10th', 
function () {
+        model = App.AlertConfigProperties.Threshold.create({
+          value: '0.4',
+          showInputForValue: true
+        })
+
+        expect(model.get('isValid')).to.be.true;
+
+        model.set('value', '3');
+        expect(model.get('isValid')).to.be.true;
+
+        model.set('value', '33.0');
+        expect(model.get('isValid')).to.be.true;
+      });
+
+      it('should be false for PORT percentage values with precision greater 
than 1/10th', function() {
+        model = App.AlertConfigProperties.Threshold.create({
+          value: '4.234',
+          showInputForValue: true
+        });
+
+        expect(model.get('isValid')).to.be.false;
+
+        model.set('value', '44.001');
+        expect(model.get('isValid')).to.be.false;
+
+        model.set('value', '112.01');
+        expect(model.get('isValid')).to.be.false;
+      });
+
+    });
+
+  });
+
+  describe('App.AlertConfigProperties.Thresholds', function () {
+
+    describe('OkThreshold', function () {
+
+      beforeEach(function () {
+        model = App.AlertConfigProperties.Thresholds.OkThreshold.create();
+      });
+
+      describe('#apiProperty', function () {
+
+        it('should be based on showInputForValue and showInputForText', 
function () {
+
+          model.setProperties({
+            showInputForValue: false,
+            showInputForText: false
+          });
+          expect(model.get('apiProperty')).to.eql([]);
+
+          model.set('showInputForValue', true);
+          
expect(model.get('apiProperty')).to.eql(['source.reporting.ok.value']);
+
+          model.set('showInputForText', true);
+          
expect(model.get('apiProperty')).to.eql(['source.reporting.ok.value', 
'source.reporting.ok.text']);
+
+        });
+
+      });
+
+    });
+
+    describe('WarningThreshold', function () {
+
+      beforeEach(function () {
+        model = App.AlertConfigProperties.Thresholds.WarningThreshold.create();
+      });
+
+      describe('#apiProperty', function () {
+
+        it('should be based on showInputForValue and showInputForText', 
function () {
+
+          model.setProperties({
+            showInputForValue: false,
+            showInputForText: false
+          });
+          expect(model.get('apiProperty')).to.eql([]);
+
+          model.set('showInputForValue', true);
+          
expect(model.get('apiProperty')).to.eql(['source.reporting.warning.value']);
+
+          model.set('showInputForText', true);
+          
expect(model.get('apiProperty')).to.eql(['source.reporting.warning.value', 
'source.reporting.warning.text']);
+
+        });
+
+      });
+
+    });
+
+    describe('CriticalThreshold', function () {
+
+      beforeEach(function () {
+        model = 
App.AlertConfigProperties.Thresholds.CriticalThreshold.create();
+      });
+
+      describe('#apiProperty', function () {
+
+        it('should be based on showInputForValue and showInputForText', 
function () {
+
+          model.setProperties({
+            showInputForValue: false,
+            showInputForText: false
+          });
+          expect(model.get('apiProperty')).to.eql([]);
+
+          model.set('showInputForValue', true);
+          
expect(model.get('apiProperty')).to.eql(['source.reporting.critical.value']);
+
+          model.set('showInputForText', true);
+          
expect(model.get('apiProperty')).to.eql(['source.reporting.critical.value', 
'source.reporting.critical.text']);
+
+        });
+
+      });
+
+    });
+
+  });
+
+});

http://git-wip-us.apache.org/repos/asf/ambari/blob/66d0b6e2/ambari-web/test/models/alerts/alert_definition_test.js
----------------------------------------------------------------------
diff --git a/ambari-web/test/models/alerts/alert_definition_test.js 
b/ambari-web/test/models/alerts/alert_definition_test.js
new file mode 100644
index 0000000..0e8cc79
--- /dev/null
+++ b/ambari-web/test/models/alerts/alert_definition_test.js
@@ -0,0 +1,212 @@
+/**
+ * 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');
+
+require('models/alerts/alert_definition');
+
+var model;
+
+describe('App.AlertDefinition', function () {
+
+  beforeEach(function () {
+
+    model = App.AlertDefinition.createRecord();
+
+  });
+
+  describe('#status', function () {
+
+    Em.A([
+      {
+        summary: {OK: {count: 1, maintenanceCount: 0}, UNKNOWN: {count: 1, 
maintenanceCount: 0}, WARNING: {count: 2, maintenanceCount: 0}, CRITICAL: 
{count: 0, maintenanceCount: 0}},
+        m: 'No CRITICAL',
+        e: '<span class="alert-state-single-host label alert-state-OK">OK 
(1)</span> ' +
+        '<span class="alert-state-single-host label alert-state-WARNING">WARN 
(2)</span> ' +
+        '<span class="alert-state-single-host label alert-state-UNKNOWN">UNKWN 
(1)</span>'
+      },
+      {
+        summary: {WARNING: {count: 2, maintenanceCount: 0}, CRITICAL: {count: 
3, maintenanceCount: 0}, UNKNOWN: {count: 1, maintenanceCount: 0}, OK: {count: 
1, maintenanceCount: 0}},
+        m: 'All states exists',
+        e: '<span class="alert-state-single-host label alert-state-OK">OK 
(1)</span> ' +
+        '<span class="alert-state-single-host label alert-state-WARNING">WARN 
(2)</span> ' +
+        '<span class="alert-state-single-host label alert-state-CRITICAL">CRIT 
(3)</span> ' +
+        '<span class="alert-state-single-host label alert-state-UNKNOWN">UNKWN 
(1)</span>'
+      },
+      {
+        summary: {OK: {count: 1, maintenanceCount: 0}, UNKNOWN: {count: 0, 
maintenanceCount: 0}, WARNING: {count: 0, maintenanceCount: 0}, CRITICAL: 
{count: 0, maintenanceCount: 0}},
+        m: 'Single host',
+        e: '<span class="alert-state-single-host label 
alert-state-OK">OK</span>'
+      },
+      {
+        summary: {OK: {count: 0, maintenanceCount: 1}, UNKNOWN: {count: 0, 
maintenanceCount: 0}, WARNING: {count: 0, maintenanceCount: 0}, CRITICAL: 
{count: 0, maintenanceCount: 0}},
+        m: 'Maintenance OK alert',
+        e: '<span class="alert-state-single-host label 
alert-state-PENDING"><span class="icon-medkit"></span> OK</span>'
+      },
+      {
+        summary: {},
+        m: 'Pending',
+        e: '<span class="alert-state-single-host label 
alert-state-PENDING">NONE</span>'
+      }
+    ]).forEach(function (test) {
+      it(test.m, function () {
+        model.set('summary', test.summary);
+        expect(model.get('status')).to.equal(test.e);
+      });
+    });
+
+  });
+
+  describe('#isCriticalOrWarning', function () {
+
+    Em.A([
+      {summary: {CRITICAL: {count: 1, maintenanceCount: 0}}, e: true},
+      {summary: {CRITICAL: {count: 0, maintenanceCount: 1}}, e: false},
+      {summary: {CRITICAL: {count: 1, maintenanceCount: 1}}, e: true},
+      {summary: {WARNING: {count: 1, maintenanceCount: 0}}, e: true},
+      {summary: {OK: {count: 1, maintenanceCount: 0}}, e: false},
+      {summary: {UNKNOWN: {count: 1, maintenanceCount: 0}}, e: false},
+      {summary: {}, e: false}
+    ]).forEach(function (test, i) {
+      it('test ' + (i + 1), function () {
+        model.set('summary', test.summary);
+        expect(model.get('isCriticalOrWarning')).to.equal(test.e);
+      });
+    });
+
+  });
+
+  describe('#isCritical', function () {
+
+    Em.A([
+      {summary: {CRITICAL: {count: 1, maintenanceCount: 0}}, e: true},
+      {summary: {WARNING: {count: 1, maintenanceCount: 0}}, e: false},
+      {summary: {OK: {count: 1, maintenanceCount: 0}}, e: false},
+      {summary: {UNKNOWN: {count: 1, maintenanceCount: 0}}, e: false},
+      {summary: {}, e: false}
+    ]).forEach(function (test, i) {
+      it('test ' + (i + 1), function () {
+        model.set('summary', test.summary);
+        expect(model.get('isCritical')).to.equal(test.e);
+      });
+    });
+
+  });
+
+  describe('#isWarning', function () {
+
+    Em.A([
+      {summary: {CRITICAL: {count: 1, maintenanceCount: 0}}, e: false},
+      {summary: {WARNING: {count: 1, maintenanceCount: 0}}, e: true},
+      {summary: {OK: {count: 1, maintenanceCount: 0}}, e: false},
+      {summary: {UNKNOWN: {count: 1, maintenanceCount: 0}}, e: false},
+      {summary: {}, e: false}
+    ]).forEach(function (test, i) {
+      it('test ' + (i + 1), function () {
+        model.set('summary', test.summary);
+        expect(model.get('isWarning')).to.equal(test.e);
+      });
+    });
+
+  });
+
+  describe('#lastTriggeredAgoFormatted', function () {
+
+    it('should be empty', function () {
+      model.set('lastTriggered', 0);
+      expect(model.get('lastTriggeredAgoFormatted')).to.equal('');
+    });
+
+    it('should not be empty', function () {
+      model.set('lastTriggered', new Date().getTime() - 61000);
+      expect(model.get('lastTriggeredAgoFormatted')).to.equal('about a minute 
ago');
+    });
+
+  });
+
+  describe('#serviceDisplayName', function () {
+
+    it('should get name for non-existing service', function () {
+      model.set('serviceName', 'FOOBAR');
+      expect(model.get('serviceDisplayName')).to.equal('Foobar');
+    });
+
+  });
+
+  describe('#componentNameFormatted', function () {
+
+    beforeEach(function () {
+      sinon.stub(App.format, 'role', function (a) {
+        return 'role ' + a;
+      });
+    });
+
+    it('should wrap component name by App.format.role method', function () {
+      model.set('componentName', 'test');
+      var result = model.get('componentNameFormatted');
+      expect(result).to.equal('role test');
+    });
+
+    afterEach(function () {
+      App.format.role.restore();
+    });
+
+
+  });
+
+  describe('REOPEN', function () {
+
+    describe('#getSortDefinitionsByStatus', function () {
+
+      Em.A([
+          {
+            a: App.AlertDefinition.createRecord({summary: {OK: {count: 1, 
maintenanceCount: 0}, WARNING: {count: 1, maintenanceCount: 0}}}),
+            b: App.AlertDefinition.createRecord({summary: {WARNING: {count: 1, 
maintenanceCount: 0}}}),
+            order: true,
+            e: -1
+          },
+          {
+            a: App.AlertDefinition.createRecord({summary: {OK: {count: 1, 
maintenanceCount: 0}, WARNING: {count: 2, maintenanceCount: 0}}}),
+            b: App.AlertDefinition.createRecord({summary: {OK: {count: 1, 
maintenanceCount: 0}, WARNING: {count: 1, maintenanceCount: 0}}}),
+            order: true,
+            e: -1
+          },
+          {
+            a: App.AlertDefinition.createRecord({summary: {OK: {count: 1, 
maintenanceCount: 0}, WARNING: {count: 1, maintenanceCount: 0}}}),
+            b: App.AlertDefinition.createRecord({summary: {WARNING: {count: 1, 
maintenanceCount: 0}}}),
+            order: false,
+            e: 1
+          },
+          {
+            a: App.AlertDefinition.createRecord({summary: {OK: {count: 1, 
maintenanceCount: 0}, WARNING: {count: 2, maintenanceCount: 0}}}),
+            b: App.AlertDefinition.createRecord({summary: {OK: {count: 1, 
maintenanceCount: 0}, WARNING: {count: 1, maintenanceCount: 0}}}),
+            order: false,
+            e: 1
+          }
+        ]).forEach(function(test, i) {
+          it('test #' + (i + 1), function () {
+            var func = 
App.AlertDefinition.getSortDefinitionsByStatus(test.order);
+            expect(func(test.a, test.b)).to.equal(test.e);
+          });
+        });
+
+    });
+
+  });
+
+});

http://git-wip-us.apache.org/repos/asf/ambari/blob/66d0b6e2/ambari-web/test/models/alerts/alert_instance_test.js
----------------------------------------------------------------------
diff --git a/ambari-web/test/models/alerts/alert_instance_test.js 
b/ambari-web/test/models/alerts/alert_instance_test.js
new file mode 100644
index 0000000..19838a4
--- /dev/null
+++ b/ambari-web/test/models/alerts/alert_instance_test.js
@@ -0,0 +1,94 @@
+/**
+ * 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');
+
+require('models/alerts/alert_instance');
+
+var model;
+
+describe('App.AlertInstance', function () {
+
+  beforeEach(function () {
+
+    model = App.AlertInstance.createRecord();
+
+  });
+
+  describe('#serviceDisplayName', function () {
+
+    it('should get name for non-existing service', function () {
+      model.set('serviceName', 'FOOBAR');
+      expect(model.get('serviceDisplayName')).to.equal('Foobar');
+    });
+
+  });
+
+  describe('#statusChangedAndLastCheckedFormatted', function () {
+
+    it('should Status Changed before Last Checked', function () {
+
+      var lastCheckedFormatted = '123',
+        lastTriggeredFormatted = '321';
+
+      model.reopen({
+        lastCheckedFormatted: lastCheckedFormatted,
+        lastTriggeredFormatted: lastTriggeredFormatted
+      });
+      var status = model.get('statusChangedAndLastCheckedFormatted');
+      expect(status.indexOf(lastCheckedFormatted) > 
status.indexOf(lastTriggeredFormatted)).to.be.true;
+
+    });
+
+  });
+
+  describe('#status', function () {
+
+    it('should show maint mode icon', function () {
+
+      model.set('maintenanceState', 'ON');
+      model.set('state', 'OK');
+      var status = model.get('status');
+
+      expect(status).to.equal('<div class="label alert-state-single-host 
alert-state-PENDING"><span class="icon-medkit"></span> OK</div>');
+
+    });
+
+    it('should not show maint mode icon', function () {
+
+      model.set('maintenanceState', 'OFF');
+      model.set('state', 'OK');
+      var status = model.get('status');
+
+      expect(status).to.equal('<div class="label alert-state-single-host 
alert-state-OK">OK</div>');
+
+    });
+
+  });
+
+  describe('#escapeSpecialCharactersFromTooltip', function () {
+    it('it Should Display Alert Without special characters "<" and ">"', 
function () {
+
+      model.set('text', '<urlopen error [Errno 111] Connection refused>');
+      var resultedText = model.get('escapeSpecialCharactersFromTooltip');
+
+      expect(resultedText).to.equal('urlopen error [Errno 111] Connection 
refused');
+    });
+  });
+
+});

Reply via email to