Skip to content

Commit

Permalink
Refactored reset password to use controllerAs syntax and default the …
Browse files Browse the repository at this point in the history
…login from the email through to the form
  • Loading branch information
zakhenry committed Aug 9, 2015
1 parent 26f2b53 commit 9eff931
Show file tree
Hide file tree
Showing 6 changed files with 163 additions and 143 deletions.
3 changes: 1 addition & 2 deletions app/src/app/guest/login/login-dialog.tpl.html
Expand Up @@ -32,10 +32,9 @@
<md-icon>face</md-icon>
<input id="loginForm.password" name="password" ng-model="user.password" type="password" ng-required="true">
<ng-messages for="loginForm.password.$error">
<ng-message when="required">This is required.</ng-message>
<ng-message when="required">This is required. <a href="#" ng-click="LoginController.resetPassword(user.email)">Forgot your password? Click Here</a></ng-message>
</ng-messages>
</md-input-container>
<a href="#" ng-click="LoginController.resetPassword()">Reset Password</a>

</form>

Expand Down
45 changes: 21 additions & 24 deletions app/src/app/guest/login/login.ts
Expand Up @@ -5,9 +5,10 @@ namespace app.guest.login {
class LoginConfig {

static $inject = ['ngJwtAuthServiceProvider'];
constructor(private ngJwtAuthServiceProvider:NgJwtAuth.NgJwtAuthServiceProvider){

let config : NgJwtAuth.INgJwtAuthServiceConfig = {
constructor(private ngJwtAuthServiceProvider:NgJwtAuth.NgJwtAuthServiceProvider) {

let config:NgJwtAuth.INgJwtAuthServiceConfig = {
refreshBeforeSeconds: 60 * 10, //10 mins
checkExpiryEverySeconds: 60, //1 min
apiEndpoints: {
Expand All @@ -27,16 +28,14 @@ namespace app.guest.login {
class LoginInit {

static $inject = ['$rootScope', 'ngJwtAuthService', '$mdDialog', '$timeout', '$window', '$state', '$q', '$location'];
constructor(
private $rootScope:global.IRootScope,
private ngJwtAuthService:NgJwtAuth.NgJwtAuthService,
private $mdDialog:ng.material.IDialogService,
private $timeout:ng.ITimeoutService,
private $window:ng.IWindowService,
private $state:ng.ui.IStateService,
private $q:ng.IQService
) {

constructor(private $rootScope:global.IRootScope,
private ngJwtAuthService:NgJwtAuth.NgJwtAuthService,
private $mdDialog:ng.material.IDialogService,
private $timeout:ng.ITimeoutService,
private $window:ng.IWindowService,
private $state:ng.ui.IStateService,
private $q:ng.IQService) {

$rootScope.socialLogin = (type:string, redirectState:string = $state.current.name, redirectStateParams:Object = $state.current.params) => {

Expand All @@ -53,19 +52,17 @@ namespace app.guest.login {

export class LoginController {


public socialLogin;

static $inject = ['$rootScope', '$mdDialog', '$mdToast', 'ngJwtAuthService', 'deferredCredentials', 'loginSuccess', 'userService'];
constructor(
private $rootScope : global.IRootScope,
private $mdDialog:ng.material.IDialogService,
private $mdToast:ng.material.IToastService,
private ngJwtAuthService:NgJwtAuth.NgJwtAuthService,
private deferredCredentials:ng.IDeferred<NgJwtAuth.ICredentials>,
private loginSuccess:{promise:ng.IPromise<NgJwtAuth.IUser>},
private userService:common.services.user.UserService
) {

constructor(private $rootScope:global.IRootScope,
private $mdDialog:ng.material.IDialogService,
private $mdToast:ng.material.IToastService,
private ngJwtAuthService:NgJwtAuth.NgJwtAuthService,
private deferredCredentials:ng.IDeferred<NgJwtAuth.ICredentials>,
private loginSuccess:{promise:ng.IPromise<NgJwtAuth.IUser>},
private userService:common.services.user.UserService) {

this.handleLoginSuccessPromise();

Expand Down Expand Up @@ -126,16 +123,16 @@ namespace app.guest.login {
/**
* Trigger reset password flow
*/
public resetPassword () {
public resetPassword(email?:string) {
this.cancelLoginDialog();
this.userService.promptResetPassword();
this.userService.promptResetPassword(email);
}

}

angular.module(namespace, [])
.config(LoginConfig)
.run(LoginInit)
.controller(namespace+'.controller', LoginController);
.controller(namespace + '.controller', LoginController);

}
27 changes: 21 additions & 6 deletions app/src/app/guest/login/reset-password-dialog.tpl.html
Expand Up @@ -3,11 +3,17 @@

<form novalidate name="resetPasswordForm">

<md-input-container class="md-icon-float" >
<label for="loginForm.email">Email</label>
<md-input-container class="md-icon-float">
<label for="resetPasswordFormEmail">Email</label>
<md-icon>face</md-icon>
<input id="loginForm.email" ng-model="user.email" name="email" type="email" ng-required="true">
<ng-messages for="loginForm.email.$error">

<input id="resetPasswordFormEmail"
ng-model="ResetPasswordController.email"
name="email"
type="email"
ng-required="true">

<ng-messages for="resetPasswordForm.email.$error">
<ng-message when="required">This is required.</ng-message>
<ng-message when="email">This is not a valid email.</ng-message>
</ng-messages>
Expand All @@ -18,8 +24,17 @@
</md-dialog-content>

<div class="md-actions">
<md-button ng-disabled="resetPasswordForm.$invalid" ng-click="resetPassword(user.email)" class="md-primary">Reset Password</md-button>
<md-button
ng-disabled="resetPasswordForm.$invalid"
ng-click="ResetPasswordController.resetPassword(email)"
class="md-primary"
>Reset Password
</md-button>

<md-button ng-click="cancelResetPasswordDialog()" class="md-warn">Cancel</md-button>
<md-button
ng-click="ResetPasswordController.cancelResetPasswordDialog()"
class="md-warn"
>Cancel
</md-button>
</div>
</md-dialog>
146 changes: 75 additions & 71 deletions app/src/app/guest/login/resetPassword.spec.ts
@@ -1,103 +1,107 @@
describe('ResetPassword', () => {

describe('Configuration', () => {

let ResetPasswordController:ng.IControllerService,
$scope:ng.IScope,
$mdDialog:ng.material.IDialogService,
$timeout:ng.ITimeoutService,
$rootScope:ng.IRootScopeService,
$q:ng.IQService,
$mdToast:ng.material.IToastService,
userService = {
resetPassword:(email:string) => {
if(email == 'invalid@email.com') {
return $q.reject({data:{message:'this failure message'}});
}
else {
return $q.when(true);
namespace app.guest.resetPassword {

describe('ResetPassword', () => {

describe('Configuration', () => {

let ResetPasswordController:ResetPasswordController,
$scope:ng.IScope,
$mdDialog:ng.material.IDialogService,
$timeout:ng.ITimeoutService,
$rootScope:ng.IRootScopeService,
$q:ng.IQService,
$mdToast:ng.material.IToastService,
userService = {
resetPassword: (email:string) => {
if (email == 'invalid@email.com') {
return $q.reject({data: {message: 'this failure message'}});
}
else {
return $q.when(true);
}
}
}
}
;

beforeEach(() => {
module('app');
});


beforeEach(()=> {
;

inject(($controller, _$rootScope_, _$mdDialog_, _$timeout_, _$q_, _$mdToast_) => {
$rootScope = _$rootScope_;
$scope = $rootScope.$new();
$mdDialog = _$mdDialog_;
$timeout = _$timeout_;
$mdToast = _$mdToast_;
$q = _$q_;
beforeEach(() => {
module('app');
});

ResetPasswordController = $controller(app.guest.resetPassword.namespace+'.controller', {
$scope: $scope,
$mdDialog: $mdDialog,
userService: userService
});
})
});
beforeEach(()=> {

inject(($controller, _$rootScope_, _$mdDialog_, _$timeout_, _$q_, _$mdToast_) => {
$rootScope = _$rootScope_;
$scope = $rootScope.$new();
$mdDialog = _$mdDialog_;
$timeout = _$timeout_;
$mdToast = _$mdToast_;
$q = _$q_;

ResetPasswordController = $controller(app.guest.resetPassword.namespace + '.controller', {
$mdDialog: $mdDialog,
userService: userService,
$mdToast: $mdToast,
defaultEmail: null,
});
})
});

beforeEach(() => {
beforeEach(() => {

sinon.spy($mdDialog, 'hide');
sinon.spy($mdDialog, 'cancel');
sinon.spy($mdDialog, 'show');
sinon.spy($mdToast, 'show');
sinon.spy($mdToast, 'simple');
sinon.spy($mdDialog, 'hide');
sinon.spy($mdDialog, 'cancel');
sinon.spy($mdDialog, 'show');
sinon.spy($mdToast, 'show');
sinon.spy($mdToast, 'simple');

});
});

afterEach(() => {
afterEach(() => {

(<any>$mdDialog).hide.restore();
(<any>$mdDialog).cancel.restore();
(<any>$mdDialog).show.restore();
(<any>$mdDialog).hide.restore();
(<any>$mdDialog).cancel.restore();
(<any>$mdDialog).show.restore();

});
});

describe('dialog interactions - reset password', () => {
describe('dialog interactions - reset password', () => {

it('should cancel dialog when requested', () => {
it('should cancel dialog when requested', () => {

(<any>$scope).cancelResetPasswordDialog();
ResetPasswordController.cancelResetPasswordDialog();

$timeout.flush(); //flush timeout as the modal is delayed
$timeout.flush(); //flush timeout as the modal is delayed

expect($mdDialog.cancel).to.have.been.called;
expect($mdDialog.cancel).to.have.been.called;

});
});

it('should display an error message when an invalid email is entered', () => {
it('should display an error message when an invalid email is entered', () => {

let email = 'invalid@email.com';
let email = 'invalid@email.com';

(<any>$scope).resetPassword(email);
ResetPasswordController.resetPassword(email);

$scope.$apply();
$scope.$apply();

expect($mdToast.show).to.have.been.calledWith(sinon.match.has("template", sinon.match(/this failure message/)));
expect($mdToast.show).to.have.been.calledWith(sinon.match.has("template", sinon.match(/this failure message/)));

});
});

it('should display a success message when a valid email is entered', () => {
it('should display a success message when a valid email is entered', () => {

let email = 'valid@email.com';
let email = 'valid@email.com';

(<any>$scope).resetPassword(email);
ResetPasswordController.resetPassword(email);

$scope.$apply();
$scope.$apply();

expect($mdToast.show).to.have.been.called.and.not.to.be.calledWith(sinon.match.has("template", sinon.match(/this failure message/)));
expect($mdToast.show).to.have.been.called.and.not.to.be.calledWith(sinon.match.has("template", sinon.match(/this failure message/)));

});
});
});

});

});
}

0 comments on commit 9eff931

Please sign in to comment.