Skip to content

Commit

Permalink
Increase coverage on v1 UserEmailService and UserSmsService for AB#16851
Browse files Browse the repository at this point in the history
  • Loading branch information
BrianMaki committed Sep 27, 2024
1 parent a4620e4 commit 7e84534
Show file tree
Hide file tree
Showing 2 changed files with 178 additions and 50 deletions.
41 changes: 39 additions & 2 deletions Apps/GatewayApi/test/unit/Services.Test/UserEmailServiceTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,41 @@ public async Task ValidateEmailAlreadyValidated()
Assert.Equal(ResultType.Error, actual.ResultStatus);
}

/// <summary>
/// ValidateEmailAsync returns error when updating user profile to the database.
/// </summary>
/// <returns>A <see cref="Task"/> representing the asynchronous unit test.</returns>
[Fact]
public async Task ValidateEmailReturnsError()
{
// Arrange
DbResult<UserProfile> dbResult = new() { Status = DbStatusCode.Error }; // Should cause error to be returned.

Guid inviteKey = Guid.NewGuid();
MessagingVerification verificationByInviteKey = new()
{
UserProfileId = HdIdMock,
VerificationAttempts = 0,
InviteKey = inviteKey,
ExpireDate = DateTime.Now.AddDays(1),
Validated = false,
Email = new Email
{
To = "[email protected]",
},
};

UserProfile userProfile = new();
IUserEmailService service = GetUserEmailService(userProfile, verificationByInviteKey, updateUserProfileResult: dbResult);

// Act
RequestResult<bool> actual = await service.ValidateEmailAsync(HdIdMock, inviteKey);

// Assert
Assert.Equal(ResultType.Error, actual.ResultStatus);
Assert.Equal(ErrorMessages.CannotPerformAction, actual.ResultError?.ResultMessage);
}

/// <summary>
/// ValidateEmailAsync - invalid invite.
/// </summary>
Expand Down Expand Up @@ -246,8 +281,10 @@ private static IUserEmailService GetUserEmailService(
Mock<IUserProfileDelegate>? userProfileDelegateMock = null,
Mock<INotificationSettingsService>? notificationSettingsServiceMock = null,
Mock<IMessageSender>? messageSenderMock = null,
bool changeFeedEnabled = false)
bool changeFeedEnabled = false,
DbResult<UserProfile>? updateUserProfileResult = null)
{
updateUserProfileResult ??= new DbResult<UserProfile> { Status = DbStatusCode.Updated };
messagingVerificationDelegateMock ??= new();
messagingVerificationDelegateMock.Setup(s => s.GetLastByInviteKeyAsync(It.IsAny<Guid>(), It.IsAny<CancellationToken>())).ReturnsAsync(verificationByInviteKey);
messagingVerificationDelegateMock.Setup(s => s.GetLastForUserAsync(It.IsAny<string>(), It.IsAny<string>(), It.IsAny<CancellationToken>()))
Expand All @@ -256,7 +293,7 @@ private static IUserEmailService GetUserEmailService(
userProfileDelegateMock ??= new();
userProfileDelegateMock.Setup(u => u.GetUserProfileAsync(It.IsAny<string>(), It.IsAny<bool>(), It.IsAny<CancellationToken>())).ReturnsAsync(userProfile);
userProfileDelegateMock.Setup(s => s.UpdateAsync(It.IsAny<UserProfile>(), It.IsAny<bool>(), It.IsAny<CancellationToken>()))
.ReturnsAsync(new DbResult<UserProfile> { Status = DbStatusCode.Updated });
.ReturnsAsync(updateUserProfileResult);

notificationSettingsServiceMock ??= new();
messageSenderMock ??= new();
Expand Down
187 changes: 139 additions & 48 deletions Apps/GatewayApi/test/unit/Services.Test/UserSmsServiceTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -101,21 +101,57 @@ public async Task ShouldValidateSms(string hdid, string smsValidationCode, bool
}
}

/// <summary>
/// ValidateSmsAsync returns error when updating user profile to the database.
/// </summary>
/// <returns>A <see cref="Task"/> representing the asynchronous unit test.</returns>
[Fact]
public async Task ValidateSmsReturnsError()
{
// Arrange
DbResult<UserProfile> dbResult = new() { Status = DbStatusCode.Error }; // Should cause error to be returned.
UserProfile userProfile = new();
MessagingVerification messagingVerification = new()
{
UserProfileId = HdIdMock,
VerificationAttempts = 0,
SmsValidationCode = SmsValidationCode,
ExpireDate = DateTime.Now.AddDays(1),
};

Mock<IMessageSender> messageSenderMock = new();
IUserSmsService service = GetUserSmsService(
messagingVerification: messagingVerification,
userProfile: userProfile,
messageSenderMock: messageSenderMock,
updateUserProfileResult: dbResult);

// Act
RequestResult<bool> actual = await service.ValidateSmsAsync(HdIdMock, SmsValidationCode, CancellationToken.None);

// Assert
Assert.False(actual.ResourcePayload);
Assert.Equal(ErrorMessages.CannotPerformAction, actual.ResultError?.ResultMessage);

// Verify
messageSenderMock.Verify(
m => m.SendAsync(
It.Is<IEnumerable<MessageEnvelope>>(
envelopes => envelopes.First().Content is NotificationChannelVerifiedEvent),
CancellationToken.None),
Times.Never);
}

/// <summary>
/// UpdateUserSmsAsync.
/// </summary>
/// <param name="userProfileExists">The bool value indicating if the user profile to be updated exists.</param>
/// <param name="sms">The sms value to update.</param>
/// <param name="smsValid">The bool value indicating if sms is valid or not.</param>
/// <returns>A <see cref="Task"/> representing the asynchronous unit test.</returns>
[Theory]
[InlineData(true, "2508801234", true)]
[InlineData(true, "0000000000", false)]
[InlineData(false, "2508801234", true)]
public async Task ShouldValidateUpdate(bool userProfileExists, string sms, bool smsValid)
[Fact]
public async Task ShouldUpdateUserSms()
{
// Arrange
UserProfile? userProfile = userProfileExists ? new UserProfile() : null;
const string sms = "2508801234";
UserProfile userProfile = new();

MessagingVerification expectedResult = new()
{
Expand All @@ -136,44 +172,97 @@ public async Task ShouldValidateUpdate(bool userProfileExists, string sms, bool
userProfile,
notificationSettingsServiceMock: notificationSettingsServiceMock);

if (userProfileExists && smsValid)
// Act and Assert
Assert.True(await service.UpdateUserSmsAsync(HdIdMock, sms));

// Verify
userProfileDelegateMock
.Verify(
s => s.UpdateAsync(It.IsAny<UserProfile>(), It.IsAny<bool>(), It.IsAny<CancellationToken>()),
Times.Once);

messagingVerificationDelegateMock
.Verify(
s => s.ExpireAsync(It.IsAny<MessagingVerification>(), It.IsAny<bool>(), It.IsAny<bool>(), It.IsAny<CancellationToken>()),
Times.Once);

messagingVerificationDelegateMock
.Verify(
s => s.InsertAsync(It.Is<MessagingVerification>(x => x.UserProfileId == HdIdMock && x.SmsNumber.All(char.IsDigit)), !ChangeFeedEnabled, It.IsAny<CancellationToken>()),
Times.Once);

notificationSettingsServiceMock
.Verify(
s => s.QueueNotificationSettingsAsync(It.IsAny<NotificationSettingsRequest>(), It.IsAny<CancellationToken>()),
Times.Once);
}

/// <summary>
/// UpdateUserSmsAsync throws NotFoundException.
/// </summary>
/// <returns>A <see cref="Task"/> representing the asynchronous unit test.</returns>
[Fact]
public async Task UpdateUserSmsThrowsNotFoundException()
{
// Arrange
const string sms = "2508801234";
UserProfile? userProfile = null; // Should cause NotFoundException

MessagingVerification expectedResult = new()
{
// Act and Assert
Assert.True(await service.UpdateUserSmsAsync(HdIdMock, sms));

// Verify
userProfileDelegateMock
.Verify(
s => s.UpdateAsync(It.IsAny<UserProfile>(), It.IsAny<bool>(), It.IsAny<CancellationToken>()),
Times.Once);

messagingVerificationDelegateMock
.Verify(
s => s.ExpireAsync(It.IsAny<MessagingVerification>(), It.IsAny<bool>(), It.IsAny<bool>(), It.IsAny<CancellationToken>()),
Times.Once);

messagingVerificationDelegateMock
.Verify(
s => s.InsertAsync(It.Is<MessagingVerification>(x => x.UserProfileId == HdIdMock && x.SmsNumber.All(char.IsDigit)), !ChangeFeedEnabled, It.IsAny<CancellationToken>()),
Times.Once);

notificationSettingsServiceMock
.Verify(
s => s.QueueNotificationSettingsAsync(It.IsAny<NotificationSettingsRequest>(), It.IsAny<CancellationToken>()),
Times.Once);
}
else
UserProfileId = HdIdMock,
VerificationAttempts = 0,
SmsValidationCode = SmsValidationCode,
ExpireDate = DateTime.Now.AddDays(1),
};

Mock<IMessagingVerificationDelegate> messagingVerificationDelegateMock = new();
Mock<INotificationSettingsService> notificationSettingsServiceMock = new();
Mock<IUserProfileDelegate> userProfileDelegateMock = new();

IUserSmsService service = GetUserSmsService(
messagingVerificationDelegateMock,
expectedResult,
userProfileDelegateMock,
userProfile,
notificationSettingsServiceMock: notificationSettingsServiceMock);

// Act and Assert
await Assert.ThrowsAsync<NotFoundException>(() => service.UpdateUserSmsAsync(HdIdMock, sms));
}

/// <summary>
/// UpdateUserSmsAsync throws ValidationException.
/// </summary>
/// <returns>A <see cref="Task"/> representing the asynchronous unit test.</returns>
[Fact]
public async Task UpdateUserSmsThrowsValidationException()
{
// Arrange
const string sms = "0000000000"; // Invalid sms should cause ValidationException
UserProfile userProfile = new();

MessagingVerification expectedResult = new()
{
// Act and Assert
if (userProfileExists)
{
await Assert.ThrowsAsync<ValidationException>(() => service.UpdateUserSmsAsync(HdIdMock, sms));
}
else
{
await Assert.ThrowsAsync<NotFoundException>(() => service.UpdateUserSmsAsync(HdIdMock, sms));
}
}
UserProfileId = HdIdMock,
VerificationAttempts = 0,
SmsValidationCode = SmsValidationCode,
ExpireDate = DateTime.Now.AddDays(1),
};

Mock<IMessagingVerificationDelegate> messagingVerificationDelegateMock = new();
Mock<INotificationSettingsService> notificationSettingsServiceMock = new();
Mock<IUserProfileDelegate> userProfileDelegateMock = new();

IUserSmsService service = GetUserSmsService(
messagingVerificationDelegateMock,
expectedResult,
userProfileDelegateMock,
userProfile,
notificationSettingsServiceMock: notificationSettingsServiceMock);

// Act and Assert
await Assert.ThrowsAsync<ValidationException>(() => service.UpdateUserSmsAsync(HdIdMock, sms));
}

/// <summary>
Expand All @@ -185,7 +274,7 @@ public async Task ShouldValidateUpdate(bool userProfileExists, string sms, bool
[InlineData("(123)4561234")]
[InlineData("123 456 1234")]
[InlineData("+1 123-456-1234")]
public void ShouldSanitizeSms(string smsNumber)
public void ShouldCreateUserSms(string smsNumber)
{
// Arrange
Mock<IMessagingVerificationDelegate> messagingVerificationDelegateMock = new();
Expand All @@ -207,8 +296,10 @@ private static IUserSmsService GetUserSmsService(
UserProfile? userProfile = null,
Mock<IMessageSender>? messageSenderMock = null,
Mock<INotificationSettingsService>? notificationSettingsServiceMock = null,
bool changeFeedEnabled = false)
bool changeFeedEnabled = false,
DbResult<UserProfile>? updateUserProfileResult = null)
{
updateUserProfileResult ??= new DbResult<UserProfile> { Status = DbStatusCode.Updated };
messagingVerificationDelegateMock ??= new();
messagingVerificationDelegateMock
.Setup(s => s.GetLastForUserAsync(It.IsAny<string>(), It.IsAny<string>(), It.IsAny<CancellationToken>()))
Expand All @@ -221,7 +312,7 @@ private static IUserSmsService GetUserSmsService(
userProfileDelegateMock ??= new();
userProfileDelegateMock.Setup(s => s.GetUserProfileAsync(It.IsAny<string>(), It.IsAny<bool>(), It.IsAny<CancellationToken>())).ReturnsAsync(userProfile);
userProfileDelegateMock.Setup(s => s.UpdateAsync(It.IsAny<UserProfile>(), It.IsAny<bool>(), It.IsAny<CancellationToken>()))
.ReturnsAsync(new DbResult<UserProfile> { Status = DbStatusCode.Updated });
.ReturnsAsync(updateUserProfileResult);

messageSenderMock ??= new();
notificationSettingsServiceMock ??= new();
Expand Down

0 comments on commit 7e84534

Please sign in to comment.