From: Tim Otten Date: Sat, 14 Feb 2015 03:52:58 +0000 (-0800) Subject: CRM-15856 - crmMailingRadioDate - Add unit test. Fix validation edge-cases. X-Git-Url: https://vcs.fsf.org/?a=commitdiff_plain;h=8ff76a1d7307d067785a0a703defa22947eff660;p=civicrm-core.git CRM-15856 - crmMailingRadioDate - Add unit test. Fix validation edge-cases. --- diff --git a/js/angular-crm-ui.js b/js/angular-crm-ui.js index 436b6e2c42..3e1242ac63 100644 --- a/js/angular-crm-ui.js +++ b/js/angular-crm-ui.js @@ -110,11 +110,11 @@ 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(' '); @@ -128,6 +128,11 @@ 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); } diff --git a/js/angular-crmMailing/directives.js b/js/angular-crmMailing/directives.js index 214ed8e5e3..4767e3ccfc 100644 --- a/js/angular-crmMailing/directives.js +++ b/js/angular-crmMailing/directives.js @@ -121,12 +121,14 @@ 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); @@ -134,8 +136,22 @@ 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 diff --git a/tests/karma.conf.js b/tests/karma.conf.js index ff8d6c3f38..a4d9053933 100644 --- a/tests/karma.conf.js +++ b/tests/karma.conf.js @@ -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 index 0000000000..e9dc448e0c --- /dev/null +++ b/tests/karma/unit/crmMailingRadioDateSpec.js @@ -0,0 +1,119 @@ +'use strict'; + +describe('crmMailingRadioDate', function() { + + beforeEach(function() { + module('crmResource'); + module('crmUtil'); + module('crmMailing'); + }); + + var standardMarkup = '
' + + '
' + + ' ' + + ' ' + + ' ' + + '
' + + '
'; + + 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); + }); + }); +});