You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ambari.apache.org by on...@apache.org on 2014/09/01 12:59:41 UTC

git commit: AMBARI-7097. Add unit tests for service controller and view. (onechiporenko)

Repository: ambari
Updated Branches:
  refs/heads/trunk 7d25cb89a -> 866f5b20f


AMBARI-7097. Add unit tests for service controller and view. (onechiporenko)


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

Branch: refs/heads/trunk
Commit: 866f5b20fdb71cb18a5fbcf4207accafd69b0f22
Parents: 7d25cb8
Author: Oleg Nechiporenko <on...@apache.org>
Authored: Mon Sep 1 13:57:43 2014 +0300
Committer: Oleg Nechiporenko <on...@apache.org>
Committed: Mon Sep 1 13:57:43 2014 +0300

----------------------------------------------------------------------
 ambari-web/app/controllers/main/service.js      | 134 +++++++---
 ambari-web/app/views/main/service.js            |   1 +
 .../test/controllers/main/service_test.js       | 254 +++++++++++++++++++
 3 files changed, 351 insertions(+), 38 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ambari/blob/866f5b20/ambari-web/app/controllers/main/service.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/controllers/main/service.js b/ambari-web/app/controllers/main/service.js
index 1c9d774..0566612 100644
--- a/ambari-web/app/controllers/main/service.js
+++ b/ambari-web/app/controllers/main/service.js
@@ -19,14 +19,23 @@
 var App = require('app');
 
 App.MainServiceController = Em.ArrayController.extend({
-  name:'mainServiceController',
-  content: function(){
-    if(!App.router.get('clusterController.isLoaded')){
+
+  name: 'mainServiceController',
+
+  /**
+   * @type {Ember.Object[]}
+   */
+  content: function () {
+    if (!App.router.get('clusterController.isLoaded')) {
       return [];
     }
     return App.Service.find();
   }.property('App.router.clusterController.isLoaded').volatile(),
 
+  /**
+   * Current cluster
+   * @type {Ember.Object}
+   */
   cluster: function () {
     if (!App.router.get('clusterController.isLoaded')) {
       return null;
@@ -34,66 +43,99 @@ App.MainServiceController = Em.ArrayController.extend({
     return App.Cluster.find().objectAt(0);
   }.property('App.router.clusterController.isLoaded'),
 
-  isAllServicesInstalled: function() {
+  /**
+   * Check if all services are installed
+   * true - all installed, false - not all
+   * @type {bool}
+   */
+  isAllServicesInstalled: function () {
     if (!this.get('content.content')) return false;
-
     var availableServices = App.StackService.find().mapProperty('serviceName');
-    if (!App.supports.hue) {
+    if (!App.get('supports.hue')) {
       availableServices = availableServices.without('HUE');
     }
     return this.get('content.content').length == availableServices.length;
   }.property('content.content.@each', 'content.content.length'),
 
-  isStartAllDisabled: function(){
-    if(this.get('isStartStopAllClicked') == true) {
+  /**
+   * Should "Start All"-button be disabled
+   * @type {bool}
+   */
+  isStartAllDisabled: function () {
+    if (this.get('isStartStopAllClicked') == true) {
       return true;
     }
-    var stoppedServices =  this.get('content').filter(function(_service){
+    var stoppedServices = this.get('content').filter(function (_service) {
       return (_service.get('healthStatus') === 'red' && !App.get('services.clientOnly').contains(_service.get('serviceName')));
     });
     return (stoppedServices.length === 0); // all green status
   }.property('isStartStopAllClicked', 'content.@each.healthStatus'),
-  isStopAllDisabled: function(){
-    if(this.get('isStartStopAllClicked') == true) {
+
+  /**
+   * Should "Stop All"-button be disabled
+   * @type {bool}
+   */
+  isStopAllDisabled: function () {
+    if (this.get('isStartStopAllClicked') == true) {
       return true;
     }
-    var startedServiceLength = this.get('content').filterProperty('healthStatus','green').length;
+    var startedServiceLength = this.get('content').filterProperty('healthStatus', 'green').length;
     return (startedServiceLength === 0);
   }.property('isStartStopAllClicked', 'content.@each.healthStatus'),
-  isStartStopAllClicked: function(){
+
+  /**
+   * @type {bool}
+   */
+  isStartStopAllClicked: function () {
     return (App.router.get('backgroundOperationsController').get('allOperationsCount') !== 0);
   }.property('App.router.backgroundOperationsController.allOperationsCount'),
 
   /**
-   * callback for <code>start all service</code> button
+   * Callback for <code>start all service</code> button
+   * @return {App.ModalPopup|null}
+   * @method startAllService
    */
-  startAllService: function(event){
-    if ($(event.target).hasClass('disabled') || $(event.target.parentElement).hasClass('disabled')) {
-      return;
-    }
-    var self = this;
-    App.showConfirmationFeedBackPopup(function(query) {
-      self.allServicesCall('STARTED', query);
-    });
+  startAllService: function (event) {
+    return this.startStopAllService(event, 'STARTED');
+  },
+
+  /**
+   * Callback for <code>stop all service</code> button
+   * @return {App.ModalPopup|null}
+   * @method stopAllService
+   */
+  stopAllService: function (event) {
+    return this.startStopAllService(event, 'INSTALLED');
   },
 
   /**
-   * callback for <code>stop all service</code> button
+   * Common method for "start-all", "stop-all" calls
+   * @param {object} event
+   * @param {string} state 'STARTED|INSTALLED'
+   * @returns {App.ModalPopup|null}
+   * @method startStopAllService
    */
-  stopAllService: function(event){
+  startStopAllService: function(event, state) {
     if ($(event.target).hasClass('disabled') || $(event.target.parentElement).hasClass('disabled')) {
-      return;
+      return null;
     }
     var self = this;
-    App.showConfirmationFeedBackPopup(function(query) {
-      self.allServicesCall('INSTALLED', query);
+    return App.showConfirmationFeedBackPopup(function (query) {
+      self.allServicesCall(state, query);
     });
   },
 
-  allServicesCall: function(state, query) {
+  /**
+   * Do request to server for "start|stop" all services
+   * @param {string} state "STARTED|INSTALLED"
+   * @param {object} query
+   * @method allServicesCall
+   * @return {$.ajax}
+   */
+  allServicesCall: function (state, query) {
     var context = (state == 'INSTALLED') ? App.BackgroundOperationsController.CommandContexts.STOP_ALL_SERVICES :
-       App.BackgroundOperationsController.CommandContexts.START_ALL_SERVICES
-    App.ajax.send({
+      App.BackgroundOperationsController.CommandContexts.START_ALL_SERVICES;
+    return App.ajax.send({
       name: 'common.services.update',
       sender: this,
       data: {
@@ -108,12 +150,15 @@ App.MainServiceController = Em.ArrayController.extend({
     });
   },
 
-  allServicesCallSuccessCallback: function(data, xhr, params) {
-    console.log("TRACE: Start/Stop all service -> In success function for the start/stop all Service call");
-    console.log("TRACE: Start/Stop all service -> value of the received data is: " + data);
-    var requestId = data.Requests.id;
+  /**
+   * Success-callback for all-services request
+   * @param {object} data
+   * @param {object} xhr
+   * @param {object} params
+   * @method allServicesCallSuccessCallback
+   */
+  allServicesCallSuccessCallback: function (data, xhr, params) {
     params.query.set('status', 'SUCCESS');
-    console.log('requestId is: ' + requestId);
 
     // load data (if we need to show this background operations popup) from persist
     App.router.get('applicationController').dataLoading().done(function (initValue) {
@@ -122,12 +167,25 @@ App.MainServiceController = Em.ArrayController.extend({
       }
     });
   },
-  allServicesCallErrorCallback: function(request, ajaxOptions, error, opt, params) {
-    console.log("ERROR");
+
+  /**
+   * Error-callback for all-services request
+   * @param {object} request
+   * @param {object} ajaxOptions
+   * @param {string} error
+   * @param {object} opt
+   * @param {object} params
+   * @method allServicesCallErrorCallback
+   */
+  allServicesCallErrorCallback: function (request, ajaxOptions, error, opt, params) {
     params.query.set('status', 'FAIL');
   },
 
-  gotoAddService: function() {
+  /**
+   * "Add-service"-click handler
+   * @method gotoAddService
+   */
+  gotoAddService: function () {
     if (this.get('isAllServicesInstalled')) {
       return;
     }

http://git-wip-us.apache.org/repos/asf/ambari/blob/866f5b20/ambari-web/app/views/main/service.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/views/main/service.js b/ambari-web/app/views/main/service.js
index ae393f4..65f3357 100644
--- a/ambari-web/app/views/main/service.js
+++ b/ambari-web/app/views/main/service.js
@@ -24,6 +24,7 @@ App.MainServiceView = Em.View.extend({
     this.addToolTip();
   },
   addToolTip: function() {
+    /* istanbul ignore next */
     if (this.get('controller.isAllServicesInstalled')) {
       App.tooltip($('.add-service-button a'), {title: Em.I18n.t('services.nothingToAdd')});
     }

http://git-wip-us.apache.org/repos/asf/ambari/blob/866f5b20/ambari-web/test/controllers/main/service_test.js
----------------------------------------------------------------------
diff --git a/ambari-web/test/controllers/main/service_test.js b/ambari-web/test/controllers/main/service_test.js
index 84e9189..808bbe7 100644
--- a/ambari-web/test/controllers/main/service_test.js
+++ b/ambari-web/test/controllers/main/service_test.js
@@ -74,6 +74,11 @@ describe('App.MainServiceController', function () {
     }
 
   ]);
+
+  beforeEach(function() {
+    mainServiceController = App.MainServiceController.create();
+  });
+
   describe('#isStartAllDisabled', function () {
     tests.forEach(function (test) {
       it(test.mStart, function () {
@@ -97,4 +102,253 @@ describe('App.MainServiceController', function () {
       });
     });
   });
+
+  describe('#isStartStopAllClicked', function () {
+
+    beforeEach(function () {
+      sinon.stub(App.router, 'get', function () {
+        return Em.Object.create({
+          allOperationsCount: 1
+        });
+      });
+    });
+
+    afterEach(function () {
+      App.router.get.restore();
+    });
+
+    it('should be based on BG ops count', function () {
+      expect(mainServiceController.get('isStartStopAllClicked')).to.be.true;
+    });
+
+  });
+
+  describe('#isAllServicesInstalled', function() {
+
+    beforeEach(function() {
+      sinon.stub(App.StackService, 'find', function() {
+        return [
+          {serviceName: 's1'},
+          {serviceName: 's2'},
+          {serviceName: 'HUE'}
+        ];
+      });
+      mainServiceController.set('content', {});
+    });
+
+    afterEach(function() {
+      App.StackService.find.restore();
+    });
+
+    it('should be false if content is not loaded', function() {
+      expect(mainServiceController.get('isAllServicesInstalled')).to.be.false;
+    });
+
+    var tests = Em.A([
+      {
+        hue: false,
+        content: ['', ''],
+        m: 'no hue',
+        e: true
+      },
+      {
+        hue: false,
+        content: [''],
+        m: 'no hue (2)',
+        e: false
+      },
+      {
+        hue: true,
+        content: ['', '', ''],
+        m: 'hue',
+        e: true
+      },
+      {
+        hue: false,
+        content: ['', ''],
+        m: 'hue (2)',
+        e: true
+      }
+    ]).forEach(function(test) {
+        it(test.m, function() {
+          mainServiceController.reopen({content: {content: test.content}});
+          sinon.stub(App, 'get', function(k) {
+            if ('supports.hue' == k) return test.hue;
+            return Em.get(App, k);
+          });
+          var r = mainServiceController.get('isAllServicesInstalled');
+          App.get.restore();
+          expect(r).to.equal(test.e);
+        });
+      });
+
+  });
+
+  describe('#cluster', function() {
+
+    var tests = Em.A([
+      {
+        isLoaded: true,
+        cluster: [],
+        m: 'cluster is loaded',
+        e: {name: 'c1'}
+      },
+      {
+        isLoaded: false,
+        cluster: [],
+        m: 'cluster is not loaded',
+        e: null
+      }
+    ]).forEach(function(test) {
+        it(test.m, function() {
+          sinon.stub(App.router, 'get', function(k) {
+            if ('clusterController.isLoaded' === k) return test.isLoaded;
+            return Em.get(App.router, k);
+          });
+          sinon.stub(App.Cluster, 'find', function() {
+            return [test.e];
+          });
+          var c = mainServiceController.get('cluster');
+          App.router.get.restore();
+          App.Cluster.find.restore();
+          expect(c).to.eql(test.e);
+        });
+      });
+
+  });
+
+  describe('#startAllService', function() {
+
+    beforeEach(function() {
+      sinon.stub(mainServiceController, 'allServicesCall', Em.K);
+    });
+
+    afterEach(function() {
+      mainServiceController.allServicesCall.restore();
+    });
+
+    it('target is disabled', function() {
+      var event = {target: {className: 'disabled', nodeType: 1}};
+      var r = mainServiceController.startAllService(event);
+      expect(r).to.be.null;
+    });
+
+    it('parent is disabled', function() {
+      var event = {target: {parentElement: {className: 'disabled', nodeType: 1}}};
+      var r = mainServiceController.startAllService(event);
+      expect(r).to.be.null;
+    });
+
+    it('nothing disabled', function() {
+      var event = {target: {}}, query = 'query';
+      mainServiceController.startAllService(event).onPrimary(query);
+      expect(mainServiceController.allServicesCall.calledWith('STARTED', query));
+    });
+
+  });
+
+  describe('#stopAllService', function() {
+
+    beforeEach(function() {
+      sinon.stub(mainServiceController, 'allServicesCall', Em.K);
+    });
+
+    afterEach(function() {
+      mainServiceController.allServicesCall.restore();
+    });
+
+    it('target is disabled', function() {
+      var event = {target: {className: 'disabled', nodeType: 1}};
+      var r = mainServiceController.stopAllService(event);
+      expect(r).to.be.null;
+    });
+
+    it('parent is disabled', function() {
+      var event = {target: {parentElement: {className: 'disabled', nodeType: 1}}};
+      var r = mainServiceController.stopAllService(event);
+      expect(r).to.be.null;
+    });
+
+    it('nothing disabled', function() {
+      var event = {target: {}}, query = 'query';
+      mainServiceController.stopAllService(event).onPrimary(query);
+      expect(mainServiceController.allServicesCall.calledWith('STARTED', query));
+    });
+
+  });
+
+  describe('#allServicesCall', function() {
+
+    beforeEach(function() {
+      sinon.stub($, 'ajax', Em.K);
+      sinon.stub(App, 'get', function(k) {
+        if ('testMode' === k) return false;
+        if ('clusterName' === k) return 'tdk';
+        return Em.get(App, k);
+      });
+    });
+
+    afterEach(function() {
+      $.ajax.restore();
+      App.get.restore();
+    });
+
+    it('should do ajax-request', function() {
+      var state = 'STARTED',
+        query = 'some query';
+      mainServiceController.allServicesCall(state, query);
+      var params = $.ajax.args[0][0];
+      expect(params.type).to.equal('PUT');
+      expect(params.url.contains('/clusters/tdk/services?')).to.be.true;
+      var data = JSON.parse(params.data);
+      expect(data.Body.ServiceInfo.state).to.equal(state);
+      expect(data.RequestInfo.context).to.equal(App.BackgroundOperationsController.CommandContexts.START_ALL_SERVICES);
+    });
+
+  });
+
+  describe('#allServicesCallSuccessCallback', function() {
+
+    it('should set status to FAIL', function() {
+      var params = {query: Em.Object.create({status: ''})};
+      mainServiceController.allServicesCallSuccessCallback({Requests: {id: 1}}, {}, params);
+      expect(params.query.get('status')).to.equal('SUCCESS');
+    });
+
+  });
+
+  describe('#allServicesCallErrorCallback', function() {
+
+    it('should set status to FAIL', function() {
+      var params = {query: Em.Object.create({status: ''})};
+      mainServiceController.allServicesCallErrorCallback({}, {}, '', {}, params);
+      expect(params.query.get('status')).to.equal('FAIL');
+    });
+
+  });
+
+  describe('#gotoAddService', function() {
+
+    beforeEach(function() {
+      sinon.stub(App.router, 'transitionTo', Em.K);
+    });
+
+    afterEach(function() {
+      App.router.transitionTo.restore();
+    });
+
+    it('should not go to wizard', function() {
+      mainServiceController.reopen({isAllServicesInstalled: true});
+      mainServiceController.gotoAddService();
+      expect(App.router.transitionTo.called).to.be.false;
+    });
+
+    it('should go to wizard', function() {
+      mainServiceController.reopen({isAllServicesInstalled: false});
+      mainServiceController.gotoAddService();
+      expect(App.router.transitionTo.calledWith('main.serviceAdd')).to.be.true;
+    });
+
+  });
+
 });