CRM-15856 - crmMailingRadioDate - Add unit test. Fix validation edge-cases.
authorTim Otten <totten@civicrm.org>
Sat, 14 Feb 2015 03:52:58 +0000 (19:52 -0800)
committerTim Otten <totten@civicrm.org>
Sat, 14 Feb 2015 03:53:49 +0000 (19:53 -0800)
js/angular-crm-ui.js
js/angular-crmMailing/directives.js
tests/karma.conf.js
tests/karma/unit/crmMailingRadioDateSpec.js [new file with mode: 0644]

index 436b6e2c42acc5f0734c30d25d3c04092620ce77..3e1242ac63869d96b48585c13e70a7cf2efaaa2f 100644 (file)
             else {
               scope.dtparts = {date: '', time: ''};
             }
+            validate();
           };
 
           function updateParent() {
-            var incompleteDateTime = _.isEmpty(scope.dtparts.date) ^ _.isEmpty(scope.dtparts.time);
-            ngModel.$setValidity('incompleteDateTime', !incompleteDateTime);
+            validate();
 
             if (_.isEmpty(scope.dtparts.date) && _.isEmpty(scope.dtparts.time)) {
               ngModel.$setViewValue(' ');
           scope.$watch('dtparts.date', updateParent);
           scope.$watch('dtparts.time', updateParent);
 
+          function validate() {
+            var incompleteDateTime = _.isEmpty(scope.dtparts.date) ^ _.isEmpty(scope.dtparts.time);
+            ngModel.$setValidity('incompleteDateTime', !incompleteDateTime);
+          }
+
           function updateRequired() {
             scope.required = scope.$parent.$eval(attrs.ngRequired);
           }
index 214ed8e5e319d89e78a9d8020b57d2832f807686..4767e3ccfc5201b4f7a9fe21462bbffc00b54974 100644 (file)
           else {
             schedule.mode = 'now';
           }
+          validate();
         };
 
         var updateParent = (function () {
           switch (schedule.mode) {
             case 'now':
               ngModel.$setViewValue(null);
+              schedule.datetime = ' ';
               break;
             case 'at':
               ngModel.$setViewValue(schedule.datetime);
             default:
               throw 'Unrecognized schedule mode: ' + schedule.mode;
           }
+          validate();
         });
 
+        function validate() {
+          switch (schedule.mode) {
+            case 'now':
+              ngModel.$setValidity('empty', true);
+              break;
+            case 'at':
+              ngModel.$setValidity('empty', !_.isEmpty(schedule.datetime) && schedule.datetime !== ' ');
+              break;
+            default:
+              throw 'Unrecognized schedule mode: ' + schedule.mode;
+          }
+        }
+
         $scope.$watch(attrs.crmMailingRadioDate + '.mode', updateParent);
         $scope.$watch(attrs.crmMailingRadioDate + '.datetime', function (newValue, oldValue) {
           // automatically switch mode based on datetime entry
index ff8d6c3f3878941db7b5d33e99c1520b6b378682..a4d9053933a56e7fb01683f6ca29b2033b2554e3 100644 (file)
@@ -25,6 +25,7 @@ module.exports = function(config) {
       'tests/karma/modules.js',
       'js/crm.ajax.js',
       'js/angular-*.js',
+      'js/angular-crmMailing/*.js',
       'tests/karma/lib/*.js',
       'tests/karma/**/*.js',
       'partials/**/*.html'
diff --git a/tests/karma/unit/crmMailingRadioDateSpec.js b/tests/karma/unit/crmMailingRadioDateSpec.js
new file mode 100644 (file)
index 0000000..e9dc448
--- /dev/null
@@ -0,0 +1,119 @@
+'use strict';
+
+describe('crmMailingRadioDate', function() {
+
+  beforeEach(function() {
+    module('crmResource');
+    module('crmUtil');
+    module('crmMailing');
+  });
+
+  var standardMarkup = '<form name="myForm">' +
+    '  <div crm-mailing-radio-date="mySchedule" ng-model="model.the_date" name="myRadioDate">' +
+    '    <input ng-model="mySchedule.mode" type="radio" name="send" value="now" class="radio-now" />' +
+    '    <input ng-model="mySchedule.mode" type="radio" name="send" value="at" class="radio-at" />' +
+    '    <span crm-ui-date-time ng-model="mySchedule.datetime" ng-required="mySchedule.mode == \'at\'"/>' +
+    '  </div>' +
+    '</form>';
+
+  describe('crmMailingRadioDate directive', function() {
+    var $compile,
+      $rootScope,
+      $interval,
+      $timeout,
+      model,
+      element;
+
+    beforeEach(inject(function(_$compile_, _$rootScope_, _$interval_, _$timeout_) {
+      $compile = _$compile_;
+      $rootScope = _$rootScope_;
+      $interval = _$interval_;
+      $timeout = _$timeout_;
+
+      $rootScope.model = model = {
+        the_date: ''
+      };
+    }));
+
+    it('should update the UI after changing the model', function() {
+      element = $compile(standardMarkup)($rootScope);
+
+      model.the_date = '';
+      $rootScope.$digest();
+      expect($rootScope.myForm.$valid).toBe(true);
+      expect(element.find('.radio-now').prop('checked')).toBe(true);
+      expect(element.find('.radio-at').prop('checked')).toBe(false);
+      expect(element.find('.dateplugin').datepicker('getDate')).toBe(null);
+      expect(element.find('.hasTimeEntry').timeEntry('getTime')).toBe(null);
+
+      model.the_date = ' ';
+      $rootScope.$digest();
+      expect($rootScope.myForm.$valid).toBe(false);
+      expect(element.find('.radio-now').prop('checked')).toBe(false);
+      expect(element.find('.radio-at').prop('checked')).toBe(true);
+      expect(element.find('.dateplugin').datepicker('getDate')).toBe(null);
+      expect(element.find('.hasTimeEntry').timeEntry('getTime')).toBe(null);
+
+      model.the_date = '2014-01-01 ';
+      $rootScope.$digest();
+      expect($rootScope.myForm.$valid).toBe(false);
+      expect(element.find('.radio-now').prop('checked')).toBe(false);
+      expect(element.find('.radio-at').prop('checked')).toBe(true);
+      expect(element.find('.dateplugin').datepicker('getDate').toDateString()).toEqual('Wed Jan 01 2014');
+      expect(element.find('.hasTimeEntry').timeEntry('getTime')).toBe(null);
+
+      model.the_date = ' 02:03:04';
+      $rootScope.$digest();
+      expect($rootScope.myForm.$valid).toBe(false);
+      expect(element.find('.radio-now').prop('checked')).toBe(false);
+      expect(element.find('.radio-at').prop('checked')).toBe(true);
+      expect(element.find('.dateplugin').datepicker('getDate')).toBe(null);
+      expect(element.find('.hasTimeEntry').timeEntry('getTime').getMinutes()).toBe(3);
+
+      model.the_date = '2014-01-02 02:03:04';
+      $rootScope.$digest();
+      expect($rootScope.myForm.$valid).toBe(true);
+      expect(element.find('.radio-now').prop('checked')).toBe(false);
+      expect(element.find('.radio-at').prop('checked')).toBe(true);
+      expect(element.find('.dateplugin').datepicker('getDate').toDateString()).toEqual('Thu Jan 02 2014');
+      expect(element.find('.hasTimeEntry').timeEntry('getTime').getMinutes()).toBe(3);
+    });
+
+    it('should update the model after changing the date and time', function() {
+      element = $compile(standardMarkup)($rootScope);
+      model.the_date = '';
+      $rootScope.$digest();
+      expect($rootScope.myForm.$valid).toBe(true);
+      expect(element.find('.radio-now').prop('checked')).toBe(true);
+      expect(element.find('.radio-at').prop('checked')).toBe(false);
+
+      element.find('.dateplugin').datepicker('setDate', '2014-01-03').trigger('change');
+      $rootScope.$digest();
+      expect(model.the_date).toBe('2014-01-03 ');
+      expect($rootScope.myForm.$valid).toBe(false);
+      expect(element.find('.radio-now').prop('checked')).toBe(false);
+      expect(element.find('.radio-at').prop('checked')).toBe(true);
+
+      element.find('.hasTimeEntry').timeEntry('setTime', '04:05').trigger('change');
+      $rootScope.$digest();
+      expect(model.the_date).toBe('2014-01-03 04:05');
+      expect($rootScope.myForm.$valid).toBe(true);
+      expect(element.find('.radio-now').prop('checked')).toBe(false);
+      expect(element.find('.radio-at').prop('checked')).toBe(true);
+
+      element.find('.dateplugin').datepicker('setDate', '').trigger('change');
+      $rootScope.$digest();
+      expect(model.the_date).toBe(' 04:05');
+      expect($rootScope.myForm.$valid).toBe(false);
+      expect(element.find('.radio-now').prop('checked')).toBe(false);
+      expect(element.find('.radio-at').prop('checked')).toBe(true);
+
+      element.find('.radio-now').click().trigger('click').trigger('change');
+      $rootScope.$digest();
+      expect(model.the_date).toBe(null);
+      expect($rootScope.myForm.$valid).toBe(true);
+      expect(element.find('.radio-now').prop('checked')).toBe(true);
+      expect(element.find('.radio-at').prop('checked')).toBe(false);
+    });
+  });
+});