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'); + }); + }); + +});