-
-
Notifications
You must be signed in to change notification settings - Fork 11
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Completed PasswordCredentials API. #4
- Loading branch information
1 parent
dd17fe5
commit fbd9dc6
Showing
43 changed files
with
1,341 additions
and
292 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -170,7 +170,7 @@ public async Task WhenRegisterPersonAsyncAndWasInvitedAsGuest_ThenCompletesRegis | |
cc.CallId == "acallid" | ||
&& cc.IsServiceAccount | ||
), "anid", It.IsAny<CancellationToken>())); | ||
_notificationsService.Verify(ns => ns.NotifyReRegistrationCourtesyAsync(It.IsAny<ICallerContext>(), | ||
_notificationsService.Verify(ns => ns.NotifyPasswordRegistrationRepeatCourtesyAsync(It.IsAny<ICallerContext>(), | ||
It.IsAny<string>(), | ||
It.IsAny<string>(), It.IsAny<string>(), It.IsAny<string>(), It.IsAny<string>(), | ||
It.IsAny<CancellationToken>()), Times.Never); | ||
|
@@ -259,7 +259,7 @@ await invitee.InviteGuestAsync(tokensService.Object, "aninviterid".ToId(), | |
cc.CallId == "acallid" | ||
&& cc.IsServiceAccount | ||
), "anid", It.IsAny<CancellationToken>())); | ||
_notificationsService.Verify(ns => ns.NotifyReRegistrationCourtesyAsync(It.IsAny<ICallerContext>(), | ||
_notificationsService.Verify(ns => ns.NotifyPasswordRegistrationRepeatCourtesyAsync(It.IsAny<ICallerContext>(), | ||
It.IsAny<string>(), | ||
It.IsAny<string>(), It.IsAny<string>(), It.IsAny<string>(), It.IsAny<string>(), | ||
It.IsAny<CancellationToken>()), Times.Never); | ||
|
@@ -337,7 +337,7 @@ public async Task WhenRegisterPersonAsyncAndAcceptingAnUnknownInvitation_ThenReg | |
cc.CallId == "acallid" | ||
&& cc.IsServiceAccount | ||
), "anid", It.IsAny<CancellationToken>())); | ||
_notificationsService.Verify(ns => ns.NotifyReRegistrationCourtesyAsync(It.IsAny<ICallerContext>(), | ||
_notificationsService.Verify(ns => ns.NotifyPasswordRegistrationRepeatCourtesyAsync(It.IsAny<ICallerContext>(), | ||
It.IsAny<string>(), | ||
It.IsAny<string>(), It.IsAny<string>(), It.IsAny<string>(), It.IsAny<string>(), | ||
It.IsAny<CancellationToken>()), Times.Never); | ||
|
@@ -391,7 +391,7 @@ public async Task | |
It.IsAny<CancellationToken>()), | ||
Times.Never); | ||
_notificationsService.Verify( | ||
ns => ns.NotifyReRegistrationCourtesyAsync(It.IsAny<ICallerContext>(), It.IsAny<string>(), | ||
ns => ns.NotifyPasswordRegistrationRepeatCourtesyAsync(It.IsAny<ICallerContext>(), It.IsAny<string>(), | ||
It.IsAny<string>(), It.IsAny<string>(), It.IsAny<string>(), It.IsAny<string>(), | ||
It.IsAny<CancellationToken>()), Times.Never); | ||
} | ||
|
@@ -429,7 +429,7 @@ public async Task WhenRegisterPersonAsyncAndAlreadyRegistered_ThenSendsCourtesyE | |
rep.LoadAsync(It.IsAny<Identifier>(), It.IsAny<CancellationToken>())) | ||
.ReturnsAsync(endUser); | ||
_notificationsService.Setup(ns => | ||
ns.NotifyReRegistrationCourtesyAsync(It.IsAny<ICallerContext>(), It.IsAny<string>(), | ||
ns.NotifyPasswordRegistrationRepeatCourtesyAsync(It.IsAny<ICallerContext>(), It.IsAny<string>(), | ||
It.IsAny<string>(), It.IsAny<string>(), It.IsAny<string>(), It.IsAny<string>(), | ||
It.IsAny<CancellationToken>())) | ||
.ReturnsAsync(Result.Ok); | ||
|
@@ -459,7 +459,7 @@ public async Task WhenRegisterPersonAsyncAndAlreadyRegistered_ThenSendsCourtesyE | |
ups.GetProfilePrivateAsync(It.IsAny<ICallerContext>(), It.IsAny<string>(), | ||
It.IsAny<CancellationToken>()), | ||
Times.Never); | ||
_notificationsService.Verify(ns => ns.NotifyReRegistrationCourtesyAsync(_caller.Object, "anid", | ||
_notificationsService.Verify(ns => ns.NotifyPasswordRegistrationRepeatCourtesyAsync(_caller.Object, "anid", | ||
"[email protected]", "afirstname", "atimezone", "acountrycode", CancellationToken.None)); | ||
} | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -25,6 +25,7 @@ namespace IdentityApplication.UnitTests; | |
[Trait("Category", "Unit")] | ||
public class PasswordCredentialsApplicationSpec | ||
{ | ||
private const string TestingToken = "Ll4qhv77XhiXSqsTUc6icu56ZLrqu5p1gH9kT5IlHio"; | ||
private readonly PasswordCredentialsApplication _application; | ||
private readonly Mock<IAuthTokensService> _authTokensService; | ||
private readonly Mock<ICallerContext> _caller; | ||
|
@@ -398,7 +399,7 @@ public async Task WhenRegisterPersonAsyncAndNotExists_ThenCreatesAndSendsConfirm | |
&& uc.Registration.Value.EmailAddress == "[email protected]" | ||
&& uc.Password.PasswordHash == "apasswordhash" | ||
&& uc.Login.Exists() | ||
&& !uc.Verification.IsVerified | ||
&& !uc.VerificationKeep.IsVerified | ||
), It.IsAny<CancellationToken>())); | ||
_notificationsService.Verify(ns => | ||
ns.NotifyPasswordRegistrationConfirmationAsync(_caller.Object, "[email protected]", "adisplayname", | ||
|
@@ -411,7 +412,9 @@ public async Task WhenRegisterPersonAsyncAndNotExists_ThenCreatesAndSendsConfirm | |
[Fact] | ||
public async Task WhenConfirmPersonRegistrationAsyncAndTokenUnknown_ThenReturnsError() | ||
{ | ||
_repository.Setup(s => s.FindCredentialsByTokenAsync(It.IsAny<string>(), It.IsAny<CancellationToken>())) | ||
_repository.Setup(s => | ||
s.FindCredentialsByRegistrationVerificationTokenAsync(It.IsAny<string>(), | ||
It.IsAny<CancellationToken>())) | ||
.Returns(Task.FromResult<Result<Optional<PasswordCredentialRoot>, Error>>(Optional<PasswordCredentialRoot> | ||
.None)); | ||
|
||
|
@@ -427,7 +430,9 @@ public async Task WhenConfirmPersonRegistrationAsyncAndTokenUnknown_ThenReturnsE | |
public async Task WhenConfirmPersonRegistrationAsync_ThenReturnsSuccess() | ||
{ | ||
var credential = CreateUnVerifiedCredential(); | ||
_repository.Setup(s => s.FindCredentialsByTokenAsync(It.IsAny<string>(), It.IsAny<CancellationToken>())) | ||
_repository.Setup(s => | ||
s.FindCredentialsByRegistrationVerificationTokenAsync(It.IsAny<string>(), | ||
It.IsAny<CancellationToken>())) | ||
.Returns(Task.FromResult<Result<Optional<PasswordCredentialRoot>, Error>>(credential.ToOptional())); | ||
|
||
var result = | ||
|
@@ -440,10 +445,174 @@ public async Task WhenConfirmPersonRegistrationAsync_ThenReturnsSuccess() | |
), It.IsAny<CancellationToken>())); | ||
} | ||
|
||
[Fact] | ||
public async Task WhenInitiatePasswordRequestAndUnknownEmailAddress_ThenSendsCourtesyNotification() | ||
{ | ||
_repository.Setup(s => s.FindCredentialsByUsernameAsync(It.IsAny<string>(), It.IsAny<CancellationToken>())) | ||
.ReturnsAsync(Optional<PasswordCredentialRoot>.None); | ||
|
||
var result = | ||
await _application.InitiatePasswordResetAsync(_caller.Object, "[email protected]", CancellationToken.None); | ||
|
||
result.Should().BeSuccess(); | ||
_repository.Verify(s => s.SaveAsync(It.IsAny<PasswordCredentialRoot>(), It.IsAny<CancellationToken>()), | ||
Times.Never); | ||
_notificationsService.Verify(ns => | ||
ns.NotifyPasswordResetInitiatedAsync(It.IsAny<ICallerContext>(), It.IsAny<string>(), It.IsAny<string>(), | ||
It.IsAny<string>(), It.IsAny<CancellationToken>()), Times.Never); | ||
_notificationsService.Verify(ns => | ||
ns.NotifyPasswordResetUnknownUserCourtesyAsync(_caller.Object, "[email protected]", CancellationToken.None)); | ||
} | ||
|
||
[Fact] | ||
public async Task WhenInitiatePasswordRequest_ThenSendsNotification() | ||
{ | ||
_tokensService.Setup(ts => ts.CreatePasswordResetToken()) | ||
.Returns(TestingToken); | ||
_repository.Setup(s => s.FindCredentialsByUsernameAsync(It.IsAny<string>(), It.IsAny<CancellationToken>())) | ||
.ReturnsAsync(CreateVerifiedCredential().ToOptional()); | ||
|
||
var result = | ||
await _application.InitiatePasswordResetAsync(_caller.Object, "[email protected]", CancellationToken.None); | ||
|
||
result.Should().BeSuccess(); | ||
_repository.Verify(s => s.SaveAsync(It.Is<PasswordCredentialRoot>(cred => | ||
cred.IsPasswordSet | ||
), It.IsAny<CancellationToken>())); | ||
_notificationsService.Verify(ns => | ||
ns.NotifyPasswordResetInitiatedAsync(_caller.Object, "aname", "[email protected]", TestingToken, | ||
It.IsAny<CancellationToken>())); | ||
_notificationsService.Verify(ns => | ||
ns.NotifyPasswordResetUnknownUserCourtesyAsync(It.IsAny<ICallerContext>(), "[email protected]", | ||
CancellationToken.None), Times.Never); | ||
} | ||
|
||
[Fact] | ||
public async Task WhenResendPasswordRequestAndUnknownToken_ThenReturnsError() | ||
{ | ||
_repository.Setup(s => | ||
s.FindCredentialsByPasswordResetTokenAsync(It.IsAny<string>(), It.IsAny<CancellationToken>())) | ||
.ReturnsAsync(Optional<PasswordCredentialRoot>.None); | ||
|
||
var result = | ||
await _application.ResendPasswordResetAsync(_caller.Object, "atoken", CancellationToken.None); | ||
|
||
result.Should().BeError(ErrorCode.EntityNotFound); | ||
_repository.Verify(s => s.SaveAsync(It.IsAny<PasswordCredentialRoot>(), It.IsAny<CancellationToken>()), | ||
Times.Never); | ||
_notificationsService.Verify(ns => | ||
ns.NotifyPasswordResetInitiatedAsync(It.IsAny<ICallerContext>(), It.IsAny<string>(), It.IsAny<string>(), | ||
It.IsAny<string>(), It.IsAny<CancellationToken>()), Times.Never); | ||
} | ||
|
||
[Fact] | ||
public async Task WhenResendPasswordRequest_ThenResendsNotification() | ||
{ | ||
_tokensService.Setup(ts => ts.CreatePasswordResetToken()) | ||
.Returns(TestingToken); | ||
_repository.Setup(s => | ||
s.FindCredentialsByPasswordResetTokenAsync(It.IsAny<string>(), It.IsAny<CancellationToken>())) | ||
.ReturnsAsync(CreateVerifiedCredential().ToOptional()); | ||
|
||
var result = | ||
await _application.ResendPasswordResetAsync(_caller.Object, "atoken", CancellationToken.None); | ||
|
||
result.Should().BeSuccess(); | ||
_repository.Verify(s => s.SaveAsync(It.Is<PasswordCredentialRoot>(cred => | ||
cred.IsPasswordResetInitiated | ||
), It.IsAny<CancellationToken>())); | ||
_notificationsService.Verify(ns => | ||
ns.NotifyPasswordResetInitiatedAsync(_caller.Object, "aname", "[email protected]", | ||
TestingToken, It.IsAny<CancellationToken>())); | ||
} | ||
|
||
[Fact] | ||
public async Task WhenVerifyPasswordResetAsyncAndUnknownToken_ThenReturnsError() | ||
{ | ||
_repository.Setup(s => | ||
s.FindCredentialsByPasswordResetTokenAsync(It.IsAny<string>(), It.IsAny<CancellationToken>())) | ||
.ReturnsAsync(Optional<PasswordCredentialRoot>.None); | ||
|
||
var result = | ||
await _application.VerifyPasswordResetAsync(_caller.Object, "atoken", CancellationToken.None); | ||
|
||
result.Should().BeError(ErrorCode.EntityNotFound); | ||
_repository.Verify(s => s.SaveAsync(It.IsAny<PasswordCredentialRoot>(), It.IsAny<CancellationToken>()), | ||
Times.Never); | ||
_notificationsService.Verify(ns => | ||
ns.NotifyPasswordResetInitiatedAsync(It.IsAny<ICallerContext>(), It.IsAny<string>(), It.IsAny<string>(), | ||
It.IsAny<string>(), It.IsAny<CancellationToken>()), Times.Never); | ||
} | ||
|
||
[Fact] | ||
public async Task WhenVerifyPasswordResetAsync_ThenVerifies() | ||
{ | ||
_tokensService.Setup(ts => ts.CreatePasswordResetToken()) | ||
.Returns(TestingToken); | ||
var credential = CreateVerifiedCredential(); | ||
credential.InitiatePasswordReset(); | ||
_repository.Setup(s => | ||
s.FindCredentialsByPasswordResetTokenAsync(It.IsAny<string>(), It.IsAny<CancellationToken>())) | ||
.ReturnsAsync(credential.ToOptional()); | ||
|
||
var result = | ||
await _application.VerifyPasswordResetAsync(_caller.Object, TestingToken, CancellationToken.None); | ||
|
||
result.Should().BeSuccess(); | ||
_repository.Verify(s => s.SaveAsync(It.IsAny<PasswordCredentialRoot>(), It.IsAny<CancellationToken>()), | ||
Times.Never); | ||
} | ||
|
||
[Fact] | ||
public async Task WhenCompletePasswordResetAsyncAndUnknownToken_ThenReturnsError() | ||
{ | ||
_repository.Setup(s => | ||
s.FindCredentialsByPasswordResetTokenAsync(It.IsAny<string>(), It.IsAny<CancellationToken>())) | ||
.ReturnsAsync(Optional<PasswordCredentialRoot>.None); | ||
|
||
var result = | ||
await _application.CompletePasswordResetAsync(_caller.Object, "atoken", "apassword", | ||
CancellationToken.None); | ||
|
||
result.Should().BeError(ErrorCode.EntityNotFound); | ||
_repository.Verify(s => s.SaveAsync(It.IsAny<PasswordCredentialRoot>(), It.IsAny<CancellationToken>()), | ||
Times.Never); | ||
_notificationsService.Verify(ns => | ||
ns.NotifyPasswordResetInitiatedAsync(It.IsAny<ICallerContext>(), It.IsAny<string>(), It.IsAny<string>(), | ||
It.IsAny<string>(), It.IsAny<CancellationToken>()), Times.Never); | ||
} | ||
|
||
[Fact] | ||
public async Task WhenCompletePasswordResetAsync_ThenCompletes() | ||
{ | ||
_tokensService.Setup(ts => ts.CreatePasswordResetToken()) | ||
.Returns(TestingToken); | ||
_passwordHasherService.Setup(phs => phs.VerifyPassword(It.IsAny<string>(), It.IsAny<string>())) | ||
.Returns(false); | ||
|
||
var credential = CreateVerifiedCredential(); | ||
credential.InitiatePasswordReset(); | ||
_repository.Setup(s => | ||
s.FindCredentialsByPasswordResetTokenAsync(It.IsAny<string>(), It.IsAny<CancellationToken>())) | ||
.ReturnsAsync(credential.ToOptional()); | ||
|
||
var result = | ||
await _application.CompletePasswordResetAsync(_caller.Object, TestingToken, "2Password!", | ||
CancellationToken.None); | ||
|
||
result.Should().BeSuccess(); | ||
_repository.Verify(s => s.SaveAsync(It.Is<PasswordCredentialRoot>(creds => | ||
!creds.IsPasswordResetInitiated | ||
), It.IsAny<CancellationToken>())); | ||
_notificationsService.Verify(ns => | ||
ns.NotifyPasswordResetInitiatedAsync(It.IsAny<ICallerContext>(), It.IsAny<string>(), It.IsAny<string>(), | ||
It.IsAny<string>(), It.IsAny<CancellationToken>()), Times.Never); | ||
} | ||
|
||
private PasswordCredentialRoot CreateUnVerifiedCredential() | ||
{ | ||
var credential = CreateCredential(); | ||
credential.SetCredential("apassword"); | ||
credential.SetPasswordCredential("apassword"); | ||
credential.SetRegistrationDetails(EmailAddress.Create("[email protected]").Value, | ||
PersonDisplayName.Create("aname").Value); | ||
credential.InitiateRegistrationVerification(); | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.