You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ambari.apache.org by at...@apache.org on 2019/01/10 16:23:27 UTC

[ambari] branch trunk updated: AMBARI-25097 Cover views of reassign wizard with unit tests

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

atkach 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 5f329b9  AMBARI-25097 Cover views of reassign wizard with unit tests
5f329b9 is described below

commit 5f329b9f858c292f7b6aeae4d93b434489278c1b
Author: Andrii Tkach <at...@apache.org>
AuthorDate: Thu Jan 10 17:24:37 2019 +0200

    AMBARI-25097 Cover views of reassign wizard with unit tests
---
 ambari-web/app/assets/test/tests.js                |   5 +
 .../app/views/main/service/reassign/step1_view.js  |  31 ++--
 .../app/views/main/service/reassign/step3_view.js  |  16 +-
 .../app/views/main/service/reassign/step5_view.js  |   6 +-
 .../views/main/service/reassign/step1_view_test.js | 128 ++++++++++++++++
 .../views/main/service/reassign/step2_view_test.js |  74 +++++++++
 .../views/main/service/reassign/step3_view_test.js |  81 ++++++++++
 .../views/main/service/reassign/step4_view_test.js |  70 +++++++++
 .../views/main/service/reassign/step5_view_test.js | 167 +++++++++++++++++++++
 9 files changed, 549 insertions(+), 29 deletions(-)

diff --git a/ambari-web/app/assets/test/tests.js b/ambari-web/app/assets/test/tests.js
index 2f809ec..91fa7b0 100644
--- a/ambari-web/app/assets/test/tests.js
+++ b/ambari-web/app/assets/test/tests.js
@@ -377,6 +377,11 @@ var files = [
   'test/views/main/charts/heatmap_test',
   'test/views/main/charts/heatmap/heatmap_host_test',
   'test/views/main/service/item_test',
+  'test/views/main/service/reassign/step1_view_test',
+  'test/views/main/service/reassign/step2_view_test',
+  'test/views/main/service/reassign/step3_view_test',
+  'test/views/main/service/reassign/step4_view_test',
+  'test/views/main/service/reassign/step5_view_test',
   'test/views/main/service/manage_config_groups_view_test',
   'test/views/main/service/reassign_view_test',
   'test/views/main/service/reconfigure_test',
diff --git a/ambari-web/app/views/main/service/reassign/step1_view.js b/ambari-web/app/views/main/service/reassign/step1_view.js
index 5e677e2..7940810 100644
--- a/ambari-web/app/views/main/service/reassign/step1_view.js
+++ b/ambari-web/app/views/main/service/reassign/step1_view.js
@@ -21,40 +21,35 @@ var App = require('app');
 var stringUtils = require('utils/string_utils');
 
 App.ReassignMasterWizardStep1View = Em.View.extend({
-
+  
+  templateName: require('templates/main/service/reassign/step1'),
+  
   message: function () {
     var componentName = this.get('controller.content.reassign.component_name');
     var listOfServices;
     var installedServices = App.Service.find().mapProperty('serviceName');
-
-    if(this.get('controller.content.componentsToStopAllServices').contains(componentName)) {
+    
+    if (this.get('controller.content.componentsToStopAllServices').contains(componentName)) {
       listOfServices = installedServices;
     } else {
       listOfServices = this.get('controller.target.reassignMasterController.relatedServicesMap')[componentName];
-      if(!listOfServices || !listOfServices.length) {
-        listOfServices = installedServices.filter(function (service) {
-          return service != 'HDFS';
-        });
+      if (!listOfServices || !listOfServices.length) {
+        listOfServices = installedServices.reject(service => service === 'HDFS');
       } else {  //not display any service which is not installed
-        var installedServicesToStop = listOfServices.filter(function (service) {
-          return installedServices.contains(service);
-        });
-        listOfServices = installedServicesToStop;
+        listOfServices = listOfServices.filter(service => installedServices.contains(service));
       }
     }
-
+    
     var messages = [
       Em.I18n.t('services.reassign.step1.message1').format(this.get('controller.content.reassign.display_name')),
       Em.I18n.t('services.reassign.step1.message3').format(stringUtils.getFormattedStringFromArray(listOfServices),
         this.get('controller.content.reassign.display_name'))
     ];
     if (this.get('controller.content.hasManualSteps')) {
-      messages.splice(1,0, Em.I18n.t('services.reassign.step1.message2').format(this.get('controller.content.reassign.display_name')));
+      messages.splice(1, 0, Em.I18n.t('services.reassign.step1.message2').format(this.get('controller.content.reassign.display_name')));
     }
-
+    
     return messages;
-  }.property('controller.content.reassign.display_name','controller.content.hasManualSteps'),
-
-  templateName: require('templates/main/service/reassign/step1')
-
+  }.property('controller.content.reassign.display_name', 'controller.content.hasManualSteps')
+  
 });
diff --git a/ambari-web/app/views/main/service/reassign/step3_view.js b/ambari-web/app/views/main/service/reassign/step3_view.js
index b6a379e..2bed38c 100644
--- a/ambari-web/app/views/main/service/reassign/step3_view.js
+++ b/ambari-web/app/views/main/service/reassign/step3_view.js
@@ -30,16 +30,16 @@ App.ReassignMasterWizardStep3View = Em.View.extend({
   didInsertElement: function () {
     this.get('controller').loadStep();
   },
-
-  jdbcSetupMessage: function() {
-    if(['HIVE_SERVER', 'HIVE_METASTORE', 'OOZIE_SERVER'].contains(this.get('controller.content.reassign.component_name'))) {
-      if(this.get('controller.content.reassign.component_name') === 'OOZIE_SERVER' && this.get('controller.content.databaseType') === 'derby') {
-        return false;
+  
+  jdbcSetupMessage: function () {
+    if (['HIVE_SERVER', 'HIVE_METASTORE', 'OOZIE_SERVER'].contains(this.get('controller.content.reassign.component_name'))) {
+      if (this.get('controller.content.reassign.component_name') === 'OOZIE_SERVER' && this.get('controller.content.databaseType') === 'derby') {
+        return '';
       }
-
+      
       return Em.I18n.t('services.service.config.database.msg.jdbcSetup').format(this.get('controller.content.databaseType'), this.get('controller.content.databaseType'));
     }
-
-    return false;
+    
+    return '';
   }.property('controller.content.reassign.display_name', 'controller.content.databaseType')
 });
diff --git a/ambari-web/app/views/main/service/reassign/step5_view.js b/ambari-web/app/views/main/service/reassign/step5_view.js
index 9c4f39d..c0fa560 100644
--- a/ambari-web/app/views/main/service/reassign/step5_view.js
+++ b/ambari-web/app/views/main/service/reassign/step5_view.js
@@ -18,14 +18,14 @@
 
 
 var App = require('app');
-var stringUtils = require('utils/string_utils');
 
 App.ReassignMasterWizardStep5View = Em.View.extend({
 
   templateName: require('templates/main/service/reassign/step5'),
 
   manualCommands: function () {
-    if (!this.get('controller.content.componentsWithManualCommands').contains(this.get('controller.content.reassign.component_name'))) {
+    const componentName = this.get('controller.content.reassign.component_name');
+    if (!this.get('controller.content.componentsWithManualCommands').contains(componentName)) {
       return '';
     }
     var
@@ -37,7 +37,7 @@ App.ReassignMasterWizardStep5View = Em.View.extend({
       ha = '',
       user = this.get('controller.content.hdfsUser'), path;
 
-    if (this.get('controller.content.reassign.component_name') === 'NAMENODE' && App.get('isHaEnabled')) {
+    if (componentName === 'NAMENODE' && App.get('isHaEnabled')) {
       ha = '_ha';
       var nnStartedHost = this.get('controller.content.masterComponentHosts').filterProperty('component', 'NAMENODE').mapProperty('hostName').without(sourceHost).without(targetHost);
     }
diff --git a/ambari-web/test/views/main/service/reassign/step1_view_test.js b/ambari-web/test/views/main/service/reassign/step1_view_test.js
new file mode 100644
index 0000000..d071b6a
--- /dev/null
+++ b/ambari-web/test/views/main/service/reassign/step1_view_test.js
@@ -0,0 +1,128 @@
+/**
+ * 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('views/main/service/reassign/step1_view');
+var stringUtils = require('utils/string_utils');
+
+var view;
+
+function getView() {
+  return App.ReassignMasterWizardStep1View.create();
+}
+
+describe('App.ReassignMasterWizardStep1View', function () {
+  
+  beforeEach(function() {
+    view = getView();
+  });
+  
+  describe('#message', function() {
+    beforeEach(function() {
+      sinon.stub(App.Service, 'find').returns([{serviceName: 'S1'}, {serviceName: 'HDFS'}]);
+    });
+    afterEach(function() {
+      App.Service.find.restore();
+    });
+    
+    it('should return message with all installed services', function() {
+      view.set('controller', Em.Object.create({
+        content: {
+          reassign: {
+            component_name: 'C1',
+            display_name: 'c1'
+          },
+          componentsToStopAllServices: ['C1']
+        }
+      }));
+      view.propertyDidChange('message');
+      expect(view.get('message')).to.be.eql([
+        Em.I18n.t('services.reassign.step1.message1').format('c1'),
+        Em.I18n.t('services.reassign.step1.message3').format(stringUtils.getFormattedStringFromArray(['S1', 'HDFS']), 'c1')
+      ]);
+    });
+  
+    it('should return message with all installed services, has manual steps', function() {
+      view.set('controller', Em.Object.create({
+        content: {
+          reassign: {
+            component_name: 'C1',
+            display_name: 'c1'
+          },
+          componentsToStopAllServices: ['C1'],
+          hasManualSteps: true
+        }
+      }));
+      view.propertyDidChange('message');
+      expect(view.get('message')).to.be.eql([
+        Em.I18n.t('services.reassign.step1.message1').format('c1'),
+        Em.I18n.t('services.reassign.step1.message2').format('c1'),
+        Em.I18n.t('services.reassign.step1.message3').format(stringUtils.getFormattedStringFromArray(['S1', 'HDFS']), 'c1')
+      ]);
+    });
+  
+    it('should return message with non-HDFS services', function() {
+      view.set('controller', Em.Object.create({
+        content: {
+          reassign: {
+            component_name: 'C1',
+            display_name: 'c1'
+          },
+          componentsToStopAllServices: []
+        },
+        target: {
+          reassignMasterController: {
+            relatedServicesMap: {}
+          }
+        }
+      }));
+      view.propertyDidChange('message');
+      expect(view.get('message')).to.be.eql([
+        Em.I18n.t('services.reassign.step1.message1').format('c1'),
+        Em.I18n.t('services.reassign.step1.message3').format(stringUtils.getFormattedStringFromArray(['S1']), 'c1')
+      ]);
+    });
+  
+    it('should return message with related services', function() {
+      view.set('controller', Em.Object.create({
+        content: {
+          reassign: {
+            component_name: 'C1',
+            display_name: 'c1'
+          },
+          componentsToStopAllServices: []
+        },
+        target: {
+          reassignMasterController: {
+            relatedServicesMap: {
+              'C1': ['S2', 'S1']
+            }
+          }
+        }
+      }));
+      view.propertyDidChange('message');
+      expect(view.get('message')).to.be.eql([
+        Em.I18n.t('services.reassign.step1.message1').format('c1'),
+        Em.I18n.t('services.reassign.step1.message3').format(stringUtils.getFormattedStringFromArray(['S1']), 'c1')
+      ]);
+    });
+    
+  });
+  
+});
+
diff --git a/ambari-web/test/views/main/service/reassign/step2_view_test.js b/ambari-web/test/views/main/service/reassign/step2_view_test.js
new file mode 100644
index 0000000..2e72bf7
--- /dev/null
+++ b/ambari-web/test/views/main/service/reassign/step2_view_test.js
@@ -0,0 +1,74 @@
+/**
+ * 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('views/main/service/reassign/step2_view');
+
+var view;
+
+function getView() {
+  return App.ReassignMasterWizardStep2View.create();
+}
+
+describe('App.ReassignMasterWizardStep2View', function () {
+  
+  beforeEach(function() {
+    view = getView();
+  });
+  
+  describe('#alertMessage', function() {
+    beforeEach(function() {
+      sinon.stub(App, 'get').returns(true);
+    });
+    afterEach(function() {
+      App.get.restore();
+    });
+    
+    it('should return NAMENODE alert', function() {
+      view.set('controller', Em.Object.create({
+        content: {
+          reassign: {
+            component_name: 'NAMENODE',
+            display_name: 'Namenode'
+          }
+        }
+      }));
+      view.propertyDidChange('alertMessage');
+      expect(view.get('alertMessage')).to.be.equal(
+        Em.I18n.t('services.reassign.step2.body.namenodeHA').format('Namenode')
+      );
+    });
+  
+    it('should return component alert', function() {
+      view.set('controller', Em.Object.create({
+        content: {
+          reassign: {
+            component_name: 'C1',
+            display_name: 'c1'
+          }
+        }
+      }));
+      view.propertyDidChange('alertMessage');
+      expect(view.get('alertMessage')).to.be.equal(
+        Em.I18n.t('services.reassign.step2.body').format('c1')
+      );
+    });
+  });
+  
+});
+
diff --git a/ambari-web/test/views/main/service/reassign/step3_view_test.js b/ambari-web/test/views/main/service/reassign/step3_view_test.js
new file mode 100644
index 0000000..78b7ce3
--- /dev/null
+++ b/ambari-web/test/views/main/service/reassign/step3_view_test.js
@@ -0,0 +1,81 @@
+/**
+ * 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('views/main/service/reassign/step3_view');
+
+var view;
+
+function getView() {
+  return App.ReassignMasterWizardStep3View.create();
+}
+
+describe('App.ReassignMasterWizardStep3View', function () {
+  
+  beforeEach(function() {
+    view = getView();
+  });
+  
+  describe('#didInsertElement', function() {
+    
+    it('loadStep should be called', function() {
+      view.set('controller', {
+        loadStep: sinon.spy()
+      });
+      view.didInsertElement();
+      expect(view.get('controller').loadStep.calledOnce).to.be.true;
+    });
+  });
+  
+  describe('#jdbcSetupMessage', function() {
+
+    it('should return empty', function() {
+      view.propertyDidChange('jdbcSetupMessage');
+      expect(view.get('jdbcSetupMessage')).to.be.empty;
+    });
+  
+    it('should return empty for OOZIE SERVER', function() {
+      view.set('controller', {
+        content: {
+          reassign: {
+            component_name: 'OOZIE_SERVER'
+          },
+          databaseType: 'derby'
+        }
+      });
+      view.propertyDidChange('jdbcSetupMessage');
+      expect(view.get('jdbcSetupMessage')).to.be.empty;
+    });
+  
+    it('should return empty for OOZIE SERVER', function() {
+      view.set('controller', {
+        content: {
+          reassign: {
+            component_name: 'HIVE_SERVER'
+          },
+          databaseType: 'type1'
+        }
+      });
+      view.propertyDidChange('jdbcSetupMessage');
+      expect(view.get('jdbcSetupMessage')).to.be.equal(
+        Em.I18n.t('services.service.config.database.msg.jdbcSetup').format('type1', 'type1')
+      );
+    });
+  });
+  
+});
diff --git a/ambari-web/test/views/main/service/reassign/step4_view_test.js b/ambari-web/test/views/main/service/reassign/step4_view_test.js
new file mode 100644
index 0000000..928bef3
--- /dev/null
+++ b/ambari-web/test/views/main/service/reassign/step4_view_test.js
@@ -0,0 +1,70 @@
+/**
+ * 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('views/main/service/reassign/step4_view');
+
+var view;
+
+function getView() {
+  return App.ReassignMasterWizardStep4View.create();
+}
+
+describe('App.ReassignMasterWizardStep4View', function () {
+  
+  beforeEach(function() {
+    view = getView();
+  });
+  
+  describe('#noticeCompleted', function() {
+    
+    it('should return notice for manual steps', function() {
+      view.set('controller', {
+        content: {
+          hasManualSteps: true,
+          reassign: {
+            component_name: 'C1'
+          }
+        }
+      });
+      view.propertyDidChange('noticeCompleted');
+      expect(view.get('noticeCompleted')).to.be.equal(
+        Em.I18n.t('services.reassign.step4.status.success.withManualSteps').format('c1')
+      );
+    });
+  
+    it('should return notice', function() {
+      view.set('controller', {
+        content: {
+          hasManualSteps: false,
+          reassign: {
+            component_name: 'C1'
+          },
+          reassignHosts: {
+            source: 'host1',
+            target: 'host2'
+          }
+        }
+      });
+      view.propertyDidChange('noticeCompleted');
+      expect(view.get('noticeCompleted')).to.be.equal(
+        Em.I18n.t('services.reassign.step4.status.success').format('c1', 'host1', 'host2')
+      );
+    });
+  });
+});
diff --git a/ambari-web/test/views/main/service/reassign/step5_view_test.js b/ambari-web/test/views/main/service/reassign/step5_view_test.js
new file mode 100644
index 0000000..df5d9a7
--- /dev/null
+++ b/ambari-web/test/views/main/service/reassign/step5_view_test.js
@@ -0,0 +1,167 @@
+/**
+ * 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('views/main/service/reassign/step5_view');
+
+var view;
+
+function getView() {
+  return App.ReassignMasterWizardStep5View.create();
+}
+
+describe('App.ReassignMasterWizardStep5View', function () {
+  
+  beforeEach(function() {
+    view = getView();
+  });
+  
+  describe('#manualCommands', function() {
+    beforeEach(function() {
+      sinon.stub(App.StackService, 'find').returns({
+        compareCurrentVersion: function() {return 1;}
+      });
+      sinon.stub(App, 'get').returns(true);
+    });
+    afterEach(function() {
+      App.StackService.find.restore();
+      App.get.restore();
+    });
+    
+    it('should be empty', function() {
+      view.set('controller', {
+        content: {
+          reassign: {
+            component_name: 'C1'
+          },
+          componentsWithManualCommands: []
+        }
+      });
+      view.propertyDidChange('manualCommands');
+      expect(view.get('manualCommands')).to.be.empty;
+    });
+  
+    it('NAMENODE component', function() {
+      view.set('controller', {
+        content: {
+          group: 'group1',
+          masterComponentHosts: [{
+            component: 'NAMENODE',
+            hostName: 'host3'
+          }],
+          hdfsUser: 'hdfs',
+          reassign: {
+            component_name: 'NAMENODE'
+          },
+          reassignHosts: {
+            source: 'host1',
+            target: 'host2'
+          },
+          componentDir: 'dir',
+          componentsWithManualCommands: ['NAMENODE']
+        }
+      });
+      view.propertyDidChange('manualCommands');
+      expect(view.get('manualCommands')).to.be.equal(
+        Em.I18n.t('services.reassign.step5.body.namenode_ha').
+        format('dir', 'host1', 'host2', 'hdfs', 'host3', 'group1', 'dir', undefined, 'timeline-state-store.ldb')
+      );
+    });
+  
+    it('APP_TIMELINE_SERVER component', function() {
+      view.set('controller', {
+        content: {
+          configs: {
+            'yarn-env': {
+              'yarn_user': 'yarn'
+            },
+            'yarn-site': {
+              'yarn.timeline-service.leveldb-timeline-store.path': 'path'
+            }
+          },
+          group: 'group1',
+          hdfsUser: 'hdfs',
+          reassign: {
+            component_name: 'APP_TIMELINE_SERVER'
+          },
+          reassignHosts: {
+            source: 'host1',
+            target: 'host2'
+          },
+          componentDir: 'dir',
+          componentsWithManualCommands: ['APP_TIMELINE_SERVER']
+        }
+      });
+      view.propertyDidChange('manualCommands');
+      expect(view.get('manualCommands')).to.be.equal(
+        Em.I18n.t('services.reassign.step5.body.app_timeline_server').
+        format('dir', 'host1', 'host2', 'yarn', 'host3', 'group1', 'dir', 'path', 'timeline-state-store.ldb')
+      );
+    });
+  });
+  
+  describe('#securityNotice', function() {
+    
+    beforeEach(function() {
+      sinon.stub(App, 'get').returns(true);
+    });
+    afterEach(function() {
+      App.get.restore();
+    });
+    
+    it('no secure configs', function() {
+      view.set('controller', {
+        content: {
+          secureConfigs: [],
+          componentsWithoutSecurityConfigs: [],
+          reassign: {
+            component_name: 'C1'
+          }
+        }
+      });
+      view.propertyDidChange('securityNotice');
+      expect(view.get('securityNotice')).to.be.equal(Em.I18n.t('services.reassign.step5.body.proceedMsg'));
+    });
+  
+    it('has secure configs', function() {
+      view.set('controller', {
+        content: {
+          secureConfigs: [{
+            principal: '_HOST',
+            keytab: 'keytab1'
+          }],
+          componentsWithoutSecurityConfigs: [],
+          reassign: {
+            component_name: 'C1'
+          },
+          reassignHosts: {
+            target: 'host2',
+            source: 'host1'
+          }
+        }
+      });
+      view.propertyDidChange('securityNotice');
+      expect(view.get('securityNotice')).to.be.equal(
+        Em.I18n.t('services.reassign.step5.body.securityNotice').format(
+          "<ul><li>" + Em.I18n.t('services.reassign.step5.body.securityConfigsList').format('keytab1','host2', 'host2') + "</li></ul>"
+        ) + Em.I18n.t('services.reassign.step5.body.proceedMsg')
+      );
+    });
+  });
+  
+});