private async Task <ResultWithError <ErrorData> > Process( VerifyAccountAndSetPasswordCommand request, CancellationToken cancellationToken) { var whenHappened = this._clock.GetCurrentInstant().ToDateTimeUtc(); var userResult = await this._userRepository.FindByUserBySecurityToken(request.Token, whenHappened, cancellationToken); if (userResult.HasNoValue) { return(ResultWithError.Fail(new ErrorData(ErrorCodes.UserNotFound))); } var user = userResult.Value; if (user.IsVerified) { return(ResultWithError.Fail(new ErrorData(ErrorCodes.UserIsAlreadyVerified))); } if (!this._passwordValidator.IsValid(request.Password)) { return(ResultWithError.Fail(new ErrorData(ErrorCodes.PasswordTooWeak))); } user.VerifyAccount(whenHappened); user.ChangePasswordAndAddToHistory(this._passwordHasher.HashPassword(request.Password), whenHappened); user.CompleteTokenLifecycle(request.Token, whenHappened); this._userRepository.Update(user); return(ResultWithError.Ok <ErrorData>()); }
public async Task Handle_GivenUserExistsButIsVerified_ExpectFailedResult() { var user = new Mock <IUser>(); user.Setup(x => x.IsVerified).Returns(true); var userRepository = new Mock <IUserRepository>(); var unitOfWork = new Mock <IUnitOfWork>(); unitOfWork.Setup(x => x.SaveEntitiesAsync(It.IsAny <CancellationToken>())).ReturnsAsync(() => true); userRepository.Setup(x => x.UnitOfWork).Returns(unitOfWork.Object); userRepository.Setup(x => x.FindByUserBySecurityToken(It.IsAny <Guid>(), It.IsAny <DateTime>(), It.IsAny <CancellationToken>())) .ReturnsAsync(() => Maybe.From(user.Object)); var clock = new Mock <IClock>(); var handler = new VerifyAccountAndSetPasswordCommandHandler(userRepository.Object, clock.Object); var cmd = new VerifyAccountAndSetPasswordCommand( Convert.ToBase64String(Guid.NewGuid().ToByteArray()), "new-password"); var result = await handler.Handle(cmd, CancellationToken.None); Assert.True(result.IsFailure); Assert.Equal(ErrorCodes.UserIsAlreadyVerified, result.Error.Code); }
public async Task Handle_GivenUserExists_ExpectAccountToBeVerifiedAndPasswordChangedAndTokenCompleted() { var user = new Mock <IUser>(); var userRepository = new Mock <IUserRepository>(); var unitOfWork = new Mock <IUnitOfWork>(); unitOfWork.Setup(x => x.SaveEntitiesAsync(It.IsAny <CancellationToken>())).ReturnsAsync(() => true); userRepository.Setup(x => x.UnitOfWork).Returns(unitOfWork.Object); userRepository.Setup(x => x.FindByUserBySecurityToken(It.IsAny <Guid>(), It.IsAny <DateTime>(), It.IsAny <CancellationToken>())) .ReturnsAsync(() => Maybe.From(user.Object)); var clock = new Mock <IClock>(); var handler = new VerifyAccountAndSetPasswordCommandHandler(userRepository.Object, clock.Object); var cmd = new VerifyAccountAndSetPasswordCommand( Convert.ToBase64String(Guid.NewGuid().ToByteArray()), "new-password"); await handler.Handle(cmd, CancellationToken.None); user.Verify(x => x.VerifyAccount(It.IsAny <DateTime>()), Times.Once); user.Verify(x => x.ChangePassword(It.IsAny <string>(), It.IsAny <DateTime>()), Times.Once); user.Verify(x => x.CompleteTokenLifecycle(It.IsAny <Guid>(), It.IsAny <DateTime>()), Times.Once); userRepository.Verify(x => x.Update(It.IsAny <IUser>()), Times.Once); }
private async Task <ResultWithError <ErrorData> > Process( VerifyAccountAndSetPasswordCommand request, CancellationToken cancellationToken) { var whenHappened = this._clock.GetCurrentInstant().ToDateTimeUtc(); var convertedToken = new Guid(Convert.FromBase64String(request.Token)); var userResult = await this._userRepository.FindByUserBySecurityToken(convertedToken, whenHappened, cancellationToken); if (userResult.HasNoValue) { return(ResultWithError.Fail(new ErrorData(ErrorCodes.UserNotFound))); } var user = userResult.Value; if (user.IsVerified) { return(ResultWithError.Fail(new ErrorData(ErrorCodes.UserIsAlreadyVerified))); } user.VerifyAccount(whenHappened); user.ChangePassword(BCrypt.Net.BCrypt.HashPassword(request.NewPassword), whenHappened); user.CompleteTokenLifecycle(convertedToken, whenHappened); this._userRepository.Update(user); return(ResultWithError.Ok <ErrorData>()); }
public void Constructor_GiveValidArguments_PropertiesAreSet() { var command = new VerifyAccountAndSetPasswordCommand("token", "new-password"); Assert.Equal("token", command.Token); Assert.Equal("new-password", command.NewPassword); }
public void Validate_GivenAllPropertiesAreValid_ExpectValidationSuccess() { var cmd = new VerifyAccountAndSetPasswordCommand("token", "new-password"); var validator = new VerifyAccountAndSetPasswordCommandValidator(); var result = validator.Validate(cmd); Assert.True(result.IsValid); }
public void Validate_GivenNewPasswordIsEmpty_ExpectValidationFailure() { var cmd = new VerifyAccountAndSetPasswordCommand("token", string.Empty); var validator = new VerifyAccountAndSetPasswordCommandValidator(); var result = validator.Validate(cmd); Assert.False(result.IsValid); Assert.Contains( result.Errors, failure => failure.ErrorCode.Equals(ValidationCodes.FieldIsRequired) && failure.PropertyName == "NewPassword"); }
public void Validate_GivenTokenIsNull_ExpectValidationFailure() { var cmd = new VerifyAccountAndSetPasswordCommand(null, "new-password"); var validator = new VerifyAccountAndSetPasswordCommandValidator(); var result = validator.Validate(cmd); Assert.False(result.IsValid); Assert.Contains( result.Errors, failure => failure.ErrorCode.Equals(ValidationCodes.FieldIsRequired) && failure.PropertyName == "Token"); }
public async Task <ResultWithError <ErrorData> > Handle( VerifyAccountAndSetPasswordCommand request, CancellationToken cancellationToken) { var result = await this.Process(request, cancellationToken); var dbResult = await this._userRepository.UnitOfWork.SaveEntitiesAsync(cancellationToken); if (!dbResult) { return(ResultWithError.Fail(new ErrorData( ErrorCodes.SavingChanges, "Failed To Save Database"))); } return(result); }
public async Task Handle_GivenSavingSucceeds_ExpectSuccessfulResult() { var user = new Mock <IUser>(); var userRepository = new Mock <IUserRepository>(); var unitOfWork = new Mock <IUnitOfWork>(); unitOfWork.Setup(x => x.SaveEntitiesAsync(It.IsAny <CancellationToken>())).ReturnsAsync(() => true); userRepository.Setup(x => x.UnitOfWork).Returns(unitOfWork.Object); userRepository.Setup(x => x.FindByUserBySecurityToken(It.IsAny <Guid>(), It.IsAny <DateTime>(), It.IsAny <CancellationToken>())) .ReturnsAsync(() => Maybe.From(user.Object)); var clock = new Mock <IClock>(); var handler = new VerifyAccountAndSetPasswordCommandHandler(userRepository.Object, clock.Object); var cmd = new VerifyAccountAndSetPasswordCommand( Convert.ToBase64String(Guid.NewGuid().ToByteArray()), "new-password"); var result = await handler.Handle(cmd, CancellationToken.None); Assert.True(result.IsSuccess); }