diff --git a/app/directives/account/toggle-password-with-tips/toggle-password-with-tips.directive.js b/app/directives/account/toggle-password-with-tips/toggle-password-with-tips.directive.js index 6fac88a50..338ec1fcc 100644 --- a/app/directives/account/toggle-password-with-tips/toggle-password-with-tips.directive.js +++ b/app/directives/account/toggle-password-with-tips/toggle-password-with-tips.directive.js @@ -11,7 +11,7 @@ link: function(scope, element, attrs, formController) { var vm = scope.vm; vm.passwordField = formController.password; - vm.defaultPlaceholder = attrs.placeholder || 'Pick a new password'; + vm.defaultPlaceholder = attrs.placeholder || 'Create new password'; vm.placeholder = vm.defaultPlaceholder; vm.password = ''; @@ -41,6 +41,7 @@ if (relatedTarget.attr('type') === 'checkbox' && relatedTarget.attr('id') === 'passwordCheckbox') { vm.passwordFocus = true; vm.placeholder = ''; + passwordInput.focus(); } else { // If you are blurring from the password input and clicking anywhere but the checkbox vm.passwordFocus = false; diff --git a/app/directives/account/toggle-password-with-tips/toggle-password-with-tips.jade b/app/directives/account/toggle-password-with-tips/toggle-password-with-tips.jade index 8968dde9a..a2d2597d8 100644 --- a/app/directives/account/toggle-password-with-tips/toggle-password-with-tips.jade +++ b/app/directives/account/toggle-password-with-tips/toggle-password-with-tips.jade @@ -1,8 +1,7 @@ input#password-input( ng-model="vm.password", ng-model-options="{allowInvalid: true}", - - focus-on="focusOnInput", + ng-focus="vm.onFocus($event)", ng-blur="vm.onBlur($event)", @@ -17,4 +16,4 @@ input#password-input( has-symbol-or-number, required) -label(ng-show="vm.passwordFocus || vm.passwordField.$dirty") #[input(type="checkbox", id="passwordCheckbox", ng-model="focusOnInput", ng-change="vm.toggleInputType()")] Show +label #[input(type="checkbox", id="passwordCheckbox", ng-model="focusOnInput", ng-change="vm.toggleInputType()")] Show diff --git a/app/directives/account/toggle-password-with-tips/toggle-password-with-tips.spec.js b/app/directives/account/toggle-password-with-tips/toggle-password-with-tips.spec.js index 46e901015..61372a218 100644 --- a/app/directives/account/toggle-password-with-tips/toggle-password-with-tips.spec.js +++ b/app/directives/account/toggle-password-with-tips/toggle-password-with-tips.spec.js @@ -9,7 +9,145 @@ describe('Toggle Password With Tips Directive', function() { bard.appModule('topcoder'); bard.inject(this, '$compile', '$rootScope'); scope = $rootScope.$new(); + scope.vm = {}; }); bard.verifyNoOutstandingHttpRequests(); + + describe('Toggle Password Directive', function() { + var togglePassword, controller, formController, passwordFormFieldSpy; + + beforeEach(function() { + var form = angular.element('
)'); + element = form.find('toggle-password-with-tips'); + var formElement = $compile(form)(scope); + scope.$digest(); + + // controller = element.controller('togglePassword'); + formController = form.controller('form'); + passwordFormFieldSpy = sinon.spy(formController.password, '$setPristine'); + }); + + afterEach(function() { + // do nohting + }); + + it('should have password default placeholder', function() { + expect(scope.vm.defaultPlaceholder).to.exist.to.equal('Create new password'); + expect(scope.vm.placeholder).to.exist.to.equal('Create new password'); + }); + + it('should not have focus class', function() { + expect(element.hasClass('focus')).to.be.false; + }); + + it('should trigger click handler ', function() { + var mockFocus = sinon.spy(element.find('input')[0], 'focus'); + element.trigger('click'); + expect(mockFocus).to.be.calledOnce; + }); + + it('should trigger focus handler ', function() { + var pwsIntputElement = angular.element(element.find('input')[0]); + pwsIntputElement.triggerHandler('focus'); + expect(element.hasClass('focus')).to.be.true; + }); + + it('should trigger blur handler with form field pristine ', function() { + var pwsIntputElement = angular.element(element.find('input')[0]); + // focus it first + pwsIntputElement.triggerHandler('focus'); + // verifies if focus class is added + expect(element.hasClass('focus')).to.be.true; + // now blurs from it + pwsIntputElement.triggerHandler('blur'); + // focus class should not be there + expect(element.hasClass('focus')).to.be.false; + // password field's setPristine method should be called once because currentPassword is empty + expect(passwordFormFieldSpy).to.be.calledOnce; + }); + + it('should trigger blur handler without form field pristine ', function() { + scope.vm.password = 'some-password'; + scope.$digest(); + var pwsIntputElement = angular.element(element.find('input')[0]); + // focus it first + pwsIntputElement.triggerHandler('focus'); + // verifies if focus class is added + expect(element.hasClass('focus')).to.be.true; + // now blurs from it + pwsIntputElement.triggerHandler('blur'); + // focus class should not be there + expect(element.hasClass('focus')).to.be.false; + // password field's setPristine method should not be called because currentPassword is non-empty + expect(passwordFormFieldSpy).not.to.be.called; + }); + + it('should keep focus on password field on blurring to checkbox ', function() { + + var pwsIntputElement = angular.element(element.find('input')[0]); + // focus it first + pwsIntputElement.triggerHandler('focus'); + // verifies if focus class is added + expect(element.hasClass('focus')).to.be.true; + // now blurs from it + + var e = jQuery.Event("blur"); + e.relatedTarget = { + getAttribute: function(name) { + if (name === 'type') return 'checkbox'; + if (name === 'id') return 'passwordCheckbox'; + } + }; + //mock focus event + var mockFocus = sinon.spy(element.find('input')[0], 'focus'); + // trigger event + pwsIntputElement.trigger(e); + + // focus should be called once + expect(mockFocus).to.be.calledOnce; + // password field placeholde should be empty + expect(scope.vm.placeholder).to.exist.to.equal(''); + }); + + it('should change type of input field to be text ', function() { + var pwsIntputElement = angular.element(element.find('input')[0]); + var checkbox = angular.element(element.find('input')[1]); + // before clicking on checkbox, it should have password type + expect(pwsIntputElement.attr('type')).to.equal('password'); + checkbox.trigger('click'); + // after clicking on checkbox, it should have text type + expect(pwsIntputElement.attr('type')).to.equal('text'); + }); + + it('should change type of input field to be password ', function() { + var pwsIntputElement = angular.element(element.find('input')[0]); + var checkbox = angular.element(element.find('input')[1]); + // before clicking on checkbox, it should have password type + expect(pwsIntputElement.attr('type')).to.equal('password'); + checkbox.trigger('click'); + // after clicking on checkbox, it should have text type + expect(pwsIntputElement.attr('type')).to.equal('text'); + // click again to uncheck the checkbox + checkbox.trigger('click'); + // after unchecking the checkbox, it should have password type + expect(pwsIntputElement.attr('type')).to.equal('password'); + }); + + it('should trigger keyup handler with enter/return key ', function() { + var mockBlur = sinon.spy(element.find('input')[0], 'blur'); + var e = jQuery.Event("keyup"); + e.keyCode = 13; + element.trigger(e); + expect(mockBlur).to.be.calledOnce; + }); + + it('should NOT trigger keyup handler with non enter/return key ', function() { + var mockBlur = sinon.spy(element.find('input')[0], 'blur'); + var e = jQuery.Event("keyup"); + e.keyCode = 14; + element.trigger(e); + expect(mockBlur).not.to.be.called; + }); + }); }); diff --git a/app/directives/account/toggle-password/toggle-password.spec.js b/app/directives/account/toggle-password/toggle-password.spec.js index 9503d1aa7..ed19113a4 100644 --- a/app/directives/account/toggle-password/toggle-password.spec.js +++ b/app/directives/account/toggle-password/toggle-password.spec.js @@ -1,5 +1,5 @@ /* jshint -W117, -W030 */ -xdescribe('Toggle Password Directive', function() { +describe('Toggle Password Directive', function() { var scope; var element; diff --git a/app/settings/account-info/account-info.jade b/app/settings/account-info/account-info.jade index 11b40aaac..53809c685 100644 --- a/app/settings/account-info/account-info.jade +++ b/app/settings/account-info/account-info.jade @@ -26,14 +26,14 @@ .form-label New Password .validation-bar - toggle-password-with-tips.topcoder-input.password(placeholder="Pick a new password") + toggle-password-with-tips.topcoder-input.password(placeholder="Create new password") .tips.password-tips(ng-show="vm.passwordFocus") .arrow - h3 Password Tips: + //- h3 Password Tips: - p Your password must have: + H3 Your password must have: p(ng-class="{ 'has-length-between-range': (vm.newPasswordForm.password.$dirty && !vm.newPasswordForm.password.$error.minlength && !vm.newPasswordForm.password.$error.maxlength && !vm.newPasswordForm.password.$error.required) }") At least 8 characters