diff --git a/HintKeep.Tests/HintKeep.Tests.csproj b/HintKeep.Tests/HintKeep.Tests.csproj
index a1f0989..35370e8 100644
--- a/HintKeep.Tests/HintKeep.Tests.csproj
+++ b/HintKeep.Tests/HintKeep.Tests.csproj
@@ -10,7 +10,7 @@
-
+
runtime; build; native; contentfiles; analyzers; buildtransitive
diff --git a/HintKeep.Tests/Integration/TestEmailServiceExtensions.cs b/HintKeep.Tests/Integration/TestEmailServiceExtensions.cs
index 35b536a..6fa5e80 100644
--- a/HintKeep.Tests/Integration/TestEmailServiceExtensions.cs
+++ b/HintKeep.Tests/Integration/TestEmailServiceExtensions.cs
@@ -2,7 +2,7 @@
using Microsoft.AspNetCore.Mvc.Testing;
using Microsoft.AspNetCore.TestHost;
using Microsoft.Extensions.DependencyInjection;
-using Moq;
+using NSubstitute;
namespace HintKeep.Tests.Integration
{
@@ -12,14 +12,13 @@ public static WebApplicationFactory WithEmailService(t
where TEntryPoint : class
=> webApplicationFactory.WithEmailService(out var _);
- public static WebApplicationFactory WithEmailService(this WebApplicationFactory webApplicationFactory, out Mock emailService)
+ public static WebApplicationFactory WithEmailService(this WebApplicationFactory webApplicationFactory, out IEmailService emailService)
where TEntryPoint : class
{
- var emailServiceMock = new Mock();
- emailService = emailServiceMock;
+ var emailServiceSubstitute = emailService = Substitute.For();
return webApplicationFactory.WithWebHostBuilder(
configuration => configuration.ConfigureTestServices(
- services => services.AddSingleton(emailServiceMock.Object)
+ services => services.AddSingleton(emailServiceSubstitute)
)
);
}
diff --git a/HintKeep.Tests/Integration/TestSecurityServiceExtensions.cs b/HintKeep.Tests/Integration/TestSecurityServiceExtensions.cs
index 7ec4c7a..d1eb547 100644
--- a/HintKeep.Tests/Integration/TestSecurityServiceExtensions.cs
+++ b/HintKeep.Tests/Integration/TestSecurityServiceExtensions.cs
@@ -2,7 +2,7 @@
using Microsoft.AspNetCore.Mvc.Testing;
using Microsoft.AspNetCore.TestHost;
using Microsoft.Extensions.DependencyInjection;
-using Moq;
+using NSubstitute;
namespace HintKeep.Tests.Integration
{
@@ -12,14 +12,13 @@ public static WebApplicationFactory WithSecurityService webApplicationFactory.WithSecurityService(out var _);
- public static WebApplicationFactory WithSecurityService(this WebApplicationFactory webApplicationFactory, out Mock securityService)
+ public static WebApplicationFactory WithSecurityService(this WebApplicationFactory webApplicationFactory, out ISecurityService securityService)
where TEntryPoint : class
{
- var securityServiceMock = new Mock();
- securityService = securityServiceMock;
+ var securityServiceSubstitute = securityService = Substitute.For();
return webApplicationFactory.WithWebHostBuilder(
configuration => configuration.ConfigureTestServices(
- services => services.AddSingleton(securityServiceMock.Object)
+ services => services.AddSingleton(securityServiceSubstitute)
)
);
}
diff --git a/HintKeep.Tests/Integration/Users/PostTests.cs b/HintKeep.Tests/Integration/Users/PostTests.cs
index 93a018e..6048a9e 100644
--- a/HintKeep.Tests/Integration/Users/PostTests.cs
+++ b/HintKeep.Tests/Integration/Users/PostTests.cs
@@ -1,4 +1,5 @@
using System;
+using System.Linq;
using System.Net;
using System.Net.Http.Json;
using System.Threading.Tasks;
@@ -6,7 +7,7 @@
using HintKeep.Storage;
using HintKeep.Storage.Entities;
using Microsoft.Azure.Cosmos.Table;
-using Moq;
+using NSubstitute;
using Xunit;
namespace HintKeep.Tests.Integration.Users
@@ -63,16 +64,16 @@ public async Task Post_WhenUserDoesNotExist_ReturnsCreated()
.WithEmailService(out var emailService)
.CreateClient();
securityService
- .Setup(securityService => securityService.ComputeHash("#test@domain.com"))
+ .ComputeHash("#test@domain.com")
.Returns("#email-hash");
securityService
- .Setup(securityService => securityService.GeneratePasswordSalt())
+ .GeneratePasswordSalt()
.Returns("#password-salt");
securityService
- .Setup(securityService => securityService.ComputePasswordHash("#password-salt", "#Test-Password1"))
+ .ComputePasswordHash("#password-salt", "#Test-Password1")
.Returns("#password-hash");
securityService
- .Setup(securityService => securityService.GenerateConfirmationToken())
+ .GenerateConfirmationToken()
.Returns(new ConfirmationToken("#confirmation-token", TimeSpan.FromHours(1)));
var response = await client.PostAsJsonAsync("/api/users", new { email = "#TEST@domain.com", hint = "#Test-Hint", password = "#Test-Password1" });
@@ -103,8 +104,10 @@ public async Task Post_WhenUserDoesNotExist_ReturnsCreated()
Assert.True(DateTimeOffset.UtcNow.AddMinutes(55) < expiration);
Assert.True(expiration < DateTimeOffset.UtcNow.AddMinutes(65));
- emailService.Verify(emailService => emailService.SendAsync("#TEST@domain.com", "Welcome to HintKeep!", It.Is(body => body.Contains("#confirmation-token"))), Times.Once);
- emailService.VerifyNoOtherCalls();
+ await emailService
+ .Received()
+ .SendAsync("#TEST@domain.com", "Welcome to HintKeep!", Arg.Is(body => body.Contains("#confirmation-token")));
+ Assert.Single(emailService.ReceivedCalls());
}
[Fact]
@@ -116,10 +119,10 @@ public async Task Post_WhenUserEmailAlreadyExists_ReturnsConflict()
.WithEmailService(out var emailService)
.CreateClient();
securityService
- .Setup(securityService => securityService.ComputeHash("#test@domain.com"))
+ .ComputeHash("#test@domain.com")
.Returns("#email-hash");
securityService
- .Setup(securityService => securityService.GenerateConfirmationToken())
+ .GenerateConfirmationToken()
.Returns(new ConfirmationToken("#confirmation-token", TimeSpan.FromHours(1)));
entityTables.Users.Execute(TableOperation.Insert(new TableEntity { PartitionKey = "#email-hash".ToEncodedKeyProperty(), RowKey = "details" }));
@@ -133,7 +136,7 @@ public async Task Post_WhenUserEmailAlreadyExists_ReturnsConflict()
Assert.Equal("#email-hash".ToEncodedKeyProperty(), userEntity.PartitionKey);
Assert.Equal("details", userEntity.RowKey);
- emailService.VerifyNoOtherCalls();
+ Assert.Empty(emailService.ReceivedCalls());
}
}
}
\ No newline at end of file
diff --git a/HintKeep.Tests/Integration/UsersConfirmations/PostTests.cs b/HintKeep.Tests/Integration/UsersConfirmations/PostTests.cs
index 1f81dde..eb8ea9e 100644
--- a/HintKeep.Tests/Integration/UsersConfirmations/PostTests.cs
+++ b/HintKeep.Tests/Integration/UsersConfirmations/PostTests.cs
@@ -5,6 +5,7 @@
using HintKeep.Storage;
using HintKeep.Storage.Entities;
using Microsoft.Azure.Cosmos.Table;
+using NSubstitute;
using Xunit;
namespace HintKeep.Tests.Integration.UsersConfirmations
@@ -59,7 +60,7 @@ public async Task Post_WhenValidTokenExist_ReturnsCreated()
}
);
securityService
- .Setup(securityService => securityService.ComputeHash("#test@domain.com"))
+ .ComputeHash("#test@domain.com")
.Returns("#email-hash");
var response = await client.PostAsJsonAsync("/api/users/confirmations", new { token = "#test-token" });
@@ -109,7 +110,7 @@ public async Task Post_WhenExpiredTokenExist_ReturnsNotFound()
Expiration = DateTimeOffset.UtcNow.AddDays(-1)
}));
securityService
- .Setup(securityService => securityService.ComputeHash("#test@domain.com"))
+ .ComputeHash("#test@domain.com")
.Returns("#email-hash");
var response = await client.PostAsJsonAsync("/api/users/confirmations", new { token = "#token" });
diff --git a/HintKeep.Tests/Integration/UsersHintsNotifications/PostTests.cs b/HintKeep.Tests/Integration/UsersHintsNotifications/PostTests.cs
index 57d19b6..e4a96da 100644
--- a/HintKeep.Tests/Integration/UsersHintsNotifications/PostTests.cs
+++ b/HintKeep.Tests/Integration/UsersHintsNotifications/PostTests.cs
@@ -5,7 +5,7 @@
using HintKeep.Storage;
using HintKeep.Storage.Entities;
using Microsoft.Azure.Cosmos.Table;
-using Moq;
+using NSubstitute;
using Xunit;
namespace HintKeep.Tests.Integration.UsersHintsNotifications
@@ -51,7 +51,7 @@ public async Task Post_WhenActiveUserExists_ReturnsCreated()
}
);
securityService
- .Setup(securityService => securityService.ComputeHash("#test@domain.com"))
+ .ComputeHash("#test@domain.com")
.Returns("#email-hash");
var response = await client.PostAsJsonAsync("/api/users/hints/notifications", new { email = "#TEST@domain.com" });
@@ -60,8 +60,10 @@ public async Task Post_WhenActiveUserExists_ReturnsCreated()
Assert.Empty(await response.Content.ReadAsStringAsync());
Assert.Equal(new Uri("/api/users/sessions", UriKind.Relative), response.Headers.Location);
- emailService.Verify(emailService => emailService.SendAsync("#TEST@domain.com", "HintKeep - Account Hint", It.IsRegex("#hint")), Times.Once);
- emailService.VerifyNoOtherCalls();
+ await emailService
+ .Received()
+ .SendAsync("#TEST@domain.com", "HintKeep - Account Hint", Arg.Is(body => body.Contains("#hint")));
+ Assert.Single(emailService.ReceivedCalls());
}
[Fact]
@@ -72,7 +74,7 @@ public async Task Post_WhenUserDoesNotExist_ReturnsNotFound()
.WithSecurityService(out var securityService)
.CreateClient();
securityService
- .Setup(securityService => securityService.ComputeHash("#test@domain.com"))
+ .ComputeHash("#test@domain.com")
.Returns("#email-hash");
var response = await client.PostAsJsonAsync("/api/users/hints/notifications", new { email = "#TEST@domain.com" });
@@ -101,7 +103,7 @@ public async Task Post_WhenInactiveUserExists_ReturnsNotFound()
}
);
securityService
- .Setup(securityService => securityService.ComputeHash("#test@domain.com"))
+ .ComputeHash("#test@domain.com")
.Returns("#email-hash");
var response = await client.PostAsJsonAsync("/api/users/hints/notifications", new { email = "#TEST@domain.com" });
diff --git a/HintKeep.Tests/Integration/UsersPasswords/PostTests.cs b/HintKeep.Tests/Integration/UsersPasswords/PostTests.cs
index edd61c1..a187fe4 100644
--- a/HintKeep.Tests/Integration/UsersPasswords/PostTests.cs
+++ b/HintKeep.Tests/Integration/UsersPasswords/PostTests.cs
@@ -2,11 +2,10 @@
using System.Net;
using System.Net.Http.Json;
using System.Threading.Tasks;
-using HintKeep.Services;
using HintKeep.Storage;
using HintKeep.Storage.Entities;
using Microsoft.Azure.Cosmos.Table;
-using Moq;
+using NSubstitute;
using Xunit;
namespace HintKeep.Tests.Integration.UsersPasswords
@@ -45,7 +44,7 @@ public async Task Post_WhenTokenDoesNotExist_ReturnsNotFound()
Expiration = DateTimeOffset.UtcNow.AddDays(-1)
}));
securityService
- .Setup(securityService => securityService.ComputeHash("#test@domain.com"))
+ .ComputeHash("#test@domain.com")
.Returns("#email-hash");
var response = await client.PostAsJsonAsync("/api/users/passwords", new { email = "#TEST@domain.com", token = "#token", password = "passWORD$123" });
@@ -69,7 +68,7 @@ public async Task Post_WhenUserDoesNotExist_ReturnsNotFound()
Expiration = DateTimeOffset.UtcNow.AddDays(1)
}));
securityService
- .Setup(securityService => securityService.ComputeHash("#test@domain.com"))
+ .ComputeHash("#test@domain.com")
.Returns("#email-hash");
var response = await client.PostAsJsonAsync("/api/users/passwords", new { email = "#TEST@domain.com", token = "#token", password = "passWORD$123" });
@@ -108,13 +107,13 @@ public async Task Post_WhenValidTokenExist_ReturnsCreated()
})
});
securityService
- .Setup(securityService => securityService.ComputeHash("#test@domain.com"))
+ .ComputeHash("#test@domain.com")
.Returns("#email-hash");
securityService
- .Setup(securityService => securityService.GeneratePasswordSalt())
+ .GeneratePasswordSalt()
.Returns("#password-salt");
securityService
- .Setup(securityService => securityService.ComputePasswordHash("#password-salt", "passWORD$123"))
+ .ComputePasswordHash("#password-salt", "passWORD$123")
.Returns("#password-hash");
var response = await client.PostAsJsonAsync("/api/users/passwords", new { email = "#TEST@domain.com", token = "#token", password = "passWORD$123" });
@@ -134,8 +133,10 @@ public async Task Post_WhenValidTokenExist_ReturnsCreated()
Assert.Equal("#password-hash", userEntity.Properties[nameof(UserEntity.PasswordHash)].StringValue);
Assert.True(userEntity.Properties[nameof(UserEntity.IsActive)].BooleanValue);
- emailService.Verify(emailService => emailService.SendAsync("#TEST@domain.com", "HintKeep - Password Reset", It.IsAny()), Times.Once);
- emailService.VerifyNoOtherCalls();
+ await emailService
+ .Received()
+ .SendAsync("#TEST@domain.com", "HintKeep - Password Reset", Arg.Any());
+ Assert.Single(emailService.ReceivedCalls());
}
[Fact]
@@ -167,7 +168,7 @@ public async Task Post_WhenInactiveUserExists_ReturnsNotFound()
})
});
securityService
- .Setup(securityService => securityService.ComputeHash("#test@domain.com"))
+ .ComputeHash("#test@domain.com")
.Returns("#email-hash");
var response = await client.PostAsJsonAsync("/api/users/passwords", new { email = "#TEST@domain.com", token = "#token", password = "passWORD$123" });
diff --git a/HintKeep.Tests/Integration/UsersPasswordsResets/PostTests.cs b/HintKeep.Tests/Integration/UsersPasswordsResets/PostTests.cs
index d7e650a..e9a1d3c 100644
--- a/HintKeep.Tests/Integration/UsersPasswordsResets/PostTests.cs
+++ b/HintKeep.Tests/Integration/UsersPasswordsResets/PostTests.cs
@@ -6,7 +6,7 @@
using HintKeep.Storage;
using HintKeep.Storage.Entities;
using Microsoft.Azure.Cosmos.Table;
-using Moq;
+using NSubstitute;
using Xunit;
namespace HintKeep.Tests.Integration.UsersPasswordsResets
@@ -51,10 +51,10 @@ public async Task Post_WhenActiveUserExists_ReturnsCreated()
}
);
securityService
- .Setup(securityService => securityService.ComputeHash("#test@domain.com"))
+ .ComputeHash("#test@domain.com")
.Returns("#email-hash");
securityService
- .Setup(securityService => securityService.GenerateConfirmationToken())
+ .GenerateConfirmationToken()
.Returns(new ConfirmationToken("#confirmation-token", TimeSpan.FromHours(1)));
var response = await client.PostAsJsonAsync("/api/users/passwords/resets", new { email = "#TEST@domain.com" });
@@ -73,8 +73,10 @@ public async Task Post_WhenActiveUserExists_ReturnsCreated()
Assert.True(DateTimeOffset.UtcNow.AddMinutes(55) < expiration);
Assert.True(expiration < DateTimeOffset.UtcNow.AddMinutes(65));
- emailService.Verify(emailService => emailService.SendAsync("#TEST@domain.com", "HintKeep - Password Reset", It.Is(body => body.Contains("#confirmation-token"))), Times.Once);
- emailService.VerifyNoOtherCalls();
+ await emailService
+ .Received()
+ .SendAsync("#TEST@domain.com", "HintKeep - Password Reset", Arg.Is(body => body.Contains("#confirmation-token")));
+ Assert.Single(emailService.ReceivedCalls());
}
[Fact]
@@ -85,7 +87,7 @@ public async Task Post_WhenUserDoesNotExist_ReturnsNotFound()
.WithSecurityService(out var securityService)
.CreateClient();
securityService
- .Setup(securityService => securityService.ComputeHash("#test@domain.com"))
+ .ComputeHash("#test@domain.com")
.Returns("#email-hash");
var response = await client.PostAsJsonAsync("/api/users/passwords/resets", new { email = "#TEST@domain.com" });
@@ -114,7 +116,7 @@ public async Task Post_WhenInactiveUserExists_ReturnsNotFound()
}
);
securityService
- .Setup(securityService => securityService.ComputeHash("#test@domain.com"))
+ .ComputeHash("#test@domain.com")
.Returns("#email-hash");
var response = await client.PostAsJsonAsync("/api/users/passwords/resets", new { email = "#TEST@domain.com" });
diff --git a/HintKeep.Tests/Integration/UsersSessions/Post.cs b/HintKeep.Tests/Integration/UsersSessions/Post.cs
index fae6bd8..eaf7a67 100644
--- a/HintKeep.Tests/Integration/UsersSessions/Post.cs
+++ b/HintKeep.Tests/Integration/UsersSessions/Post.cs
@@ -5,6 +5,7 @@
using HintKeep.Storage;
using HintKeep.Storage.Entities;
using Microsoft.Azure.Cosmos.Table;
+using NSubstitute;
using Xunit;
namespace HintKeep.Tests.Integration.UsersSessions
@@ -54,7 +55,7 @@ public async Task Post_WhenInactiveUserExists_ReturnsNotFound()
IsActive = false
}));
securityService
- .Setup(securityService => securityService.ComputeHash("#test@domain.com"))
+ .ComputeHash("#test@domain.com")
.Returns("#email-hash");
var response = await client.PostAsJsonAsync("/api/users/sessions", new { email = "#TEST@domain.com", password = "#test-password" });
@@ -70,7 +71,7 @@ public async Task Post_WhenActiveUserExistButPasswordsDoNotMatch_ReturnsUnproces
.WithSecurityService(out var securityService)
.CreateClient();
securityService
- .Setup(securityService => securityService.ComputePasswordHash("#password-salt", "#test-password"))
+ .ComputePasswordHash("#password-salt", "#test-password")
.Returns("#password-hash-not-matching");
entityTables.Users.Execute(TableOperation.Insert(new UserEntity
{
@@ -81,10 +82,10 @@ public async Task Post_WhenActiveUserExistButPasswordsDoNotMatch_ReturnsUnproces
IsActive = true
}));
securityService
- .Setup(securityService => securityService.ComputeHash("#test@domain.com"))
+ .ComputeHash("#test@domain.com")
.Returns("#email-hash");
securityService
- .Setup(securityService => securityService.ComputePasswordHash("#password-salt", "#test-password"))
+ .ComputePasswordHash("#password-salt", "#test-password")
.Returns("#password-hash-not-matching");
var response = await client.PostAsJsonAsync("/api/users/sessions", new { email = "#TEST@domain.com", password = "#test-password" });
@@ -111,10 +112,10 @@ public async Task Post_WhenActiveUserExsitsWithMatchingPassword_ReturnsCreated()
IsActive = true
}));
securityService
- .Setup(securityService => securityService.ComputeHash("#test@domain.com"))
+ .ComputeHash("#test@domain.com")
.Returns("#email-hash");
securityService
- .Setup(securityService => securityService.ComputePasswordHash("#password-salt", "#test-password"))
+ .ComputePasswordHash("#password-salt", "#test-password")
.Returns("#password-hash");
var response = await client.PostAsJsonAsync("/api/users/sessions", new { email = "#TEST@domain.com", password = "#test-password" });
diff --git a/HintKeep.Tests/Unit/RequestsHandlers/Users/Commands/CreateUserSessionCommandHandlerTests.cs b/HintKeep.Tests/Unit/RequestsHandlers/Users/Commands/CreateUserSessionCommandHandlerTests.cs
index 4543d21..b7f582d 100644
--- a/HintKeep.Tests/Unit/RequestsHandlers/Users/Commands/CreateUserSessionCommandHandlerTests.cs
+++ b/HintKeep.Tests/Unit/RequestsHandlers/Users/Commands/CreateUserSessionCommandHandlerTests.cs
@@ -9,7 +9,7 @@
using HintKeep.Tests.Stubs;
using MediatR;
using Microsoft.Azure.Cosmos.Table;
-using Moq;
+using NSubstitute;
using Xunit;
namespace HintKeep.Tests.Unit.RequestsHandlers.Users.Commands
@@ -17,16 +17,16 @@ namespace HintKeep.Tests.Unit.RequestsHandlers.Users.Commands
public class CreateUserSessionCommandHandlerTests
{
private readonly IEntityTables _entityTables;
- private readonly Mock _securityService;
- private readonly Mock _sessionService;
+ private readonly ISecurityService _securityService;
+ private readonly ISessionService _sessionService;
private readonly IRequestHandler _createUserSessionCommandHandler;
public CreateUserSessionCommandHandlerTests()
{
_entityTables = new InMemoryEntityTables();
- _securityService = new Mock();
- _sessionService = new Mock();
- _createUserSessionCommandHandler = new CreateUserSessionCommandHandler(_entityTables, _securityService.Object, _sessionService.Object);
+ _securityService = Substitute.For();
+ _sessionService = Substitute.For();
+ _createUserSessionCommandHandler = new CreateUserSessionCommandHandler(_entityTables, _securityService, _sessionService);
_entityTables.Users.Create();
}
@@ -34,7 +34,7 @@ public CreateUserSessionCommandHandlerTests()
public async Task Handle_WhenUserDoesNotExist_ThrowsException()
{
_securityService
- .Setup(securityService => securityService.ComputeHash("#test@domain.com"))
+ .ComputeHash("#test@domain.com")
.Returns("#email-hash");
await Assert.ThrowsAsync(() => _createUserSessionCommandHandler.Handle(new CreateUserSessionCommand("#TEST@domain.com", "#test-password"), default));
@@ -53,7 +53,7 @@ public async Task Handle_WhenInactiveUserExists_ThrowsException()
}
));
_securityService
- .Setup(securityService => securityService.ComputeHash("#test@domain.com"))
+ .ComputeHash("#test@domain.com")
.Returns("#email-hash");
await Assert.ThrowsAsync(() => _createUserSessionCommandHandler.Handle(new CreateUserSessionCommand("#TEST@domain.com", "#test-password"), default));
@@ -74,10 +74,10 @@ public async Task Handle_WhenPasswordDoesNotMatch_ThrowsException()
}
));
_securityService
- .Setup(securityService => securityService.ComputeHash("#test@domain.com"))
+ .ComputeHash("#test@domain.com")
.Returns("#email-hash");
_securityService
- .Setup(securityService => securityService.ComputePasswordHash("#password-salt", "#test-password"))
+ .ComputePasswordHash("#password-salt", "#test-password")
.Returns("#password-hash-not-matching");
var exception = await Assert.ThrowsAsync(() => _createUserSessionCommandHandler.Handle(new CreateUserSessionCommand("#TEST@domain.com", "#test-password"), default));
@@ -101,13 +101,13 @@ public async Task Handle_WhenPasswordMatches_ReturnsJsonWebTokenAndSetsLastLogin
}
));
_securityService
- .Setup(securityService => securityService.ComputePasswordHash("#password-salt", "#test-password"))
+ .ComputePasswordHash("#password-salt", "#test-password")
.Returns("#password-hash");
_securityService
- .Setup(securityService => securityService.ComputeHash("#test@domain.com"))
+ .ComputeHash("#test@domain.com")
.Returns("#email-hash");
_sessionService
- .Setup(sessionService => sessionService.CreateJsonWebToken("#user-id", "#user-role"))
+ .CreateJsonWebToken("#user-id", "#user-role")
.Returns("#json-web-token");
var jsonWebToken = await _createUserSessionCommandHandler.Handle(new CreateUserSessionCommand("#TEST@domain.com", "#test-password"), default);
diff --git a/HintKeep.Tests/Unit/RequestsHandlers/Users/Commands/RegisterUserCommandHandlerTests.cs b/HintKeep.Tests/Unit/RequestsHandlers/Users/Commands/RegisterUserCommandHandlerTests.cs
index b562a75..98018da 100644
--- a/HintKeep.Tests/Unit/RequestsHandlers/Users/Commands/RegisterUserCommandHandlerTests.cs
+++ b/HintKeep.Tests/Unit/RequestsHandlers/Users/Commands/RegisterUserCommandHandlerTests.cs
@@ -9,7 +9,7 @@
using HintKeep.Tests.Stubs;
using MediatR;
using Microsoft.Azure.Cosmos.Table;
-using Moq;
+using NSubstitute;
using Xunit;
namespace HintKeep.Tests.Unit.RequestsHandlers.Users.Commands
@@ -17,33 +17,33 @@ namespace HintKeep.Tests.Unit.RequestsHandlers.Users.Commands
public class RegisterUserCommandHandlerTests
{
private readonly IEntityTables _entityTables;
- private readonly Mock _emailService;
- private readonly Mock _securityService;
+ private readonly IEmailService _emailService;
+ private readonly ISecurityService _securityService;
private readonly IRequestHandler _registerUserCommandHandler;
public RegisterUserCommandHandlerTests()
{
_entityTables = new InMemoryEntityTables();
- _emailService = new Mock();
- _securityService = new Mock();
+ _emailService = Substitute.For();
+ _securityService = Substitute.For();
_entityTables.Users.Create();
- _registerUserCommandHandler = new RegisterUserCommandHandler(_entityTables, _emailService.Object, _securityService.Object);
+ _registerUserCommandHandler = new RegisterUserCommandHandler(_entityTables, _emailService, _securityService);
}
[Fact]
public async Task Handle_WhenUserDoesNotExist_CreatesInactiveUserAndActivationToken()
{
_securityService
- .Setup(securityService => securityService.ComputeHash("#test@domain.com"))
+ .ComputeHash("#test@domain.com")
.Returns("#email-hash");
_securityService
- .Setup(securityService => securityService.GeneratePasswordSalt())
+ .GeneratePasswordSalt()
.Returns("#password-salt");
_securityService
- .Setup(securityService => securityService.ComputePasswordHash("#password-salt", "#test-password"))
+ .ComputePasswordHash("#password-salt", "#test-password")
.Returns("#password-hash");
_securityService
- .Setup(securityService => securityService.GenerateConfirmationToken())
+ .GenerateConfirmationToken()
.Returns(new ConfirmationToken("#activation-token", TimeSpan.FromMinutes(60)));
await _registerUserCommandHandler.Handle(
@@ -77,18 +77,20 @@ await _registerUserCommandHandler.Handle(
Assert.True(DateTimeOffset.UtcNow.AddMinutes(55) < expiration);
Assert.True(expiration < DateTimeOffset.UtcNow.AddMinutes(65));
- _emailService.Verify(emailService => emailService.SendAsync("#TEST@domain.com", "Welcome to HintKeep!", It.IsRegex("#activation-token")), Times.Once);
- _emailService.VerifyNoOtherCalls();
+ await _emailService
+ .Received()
+ .SendAsync("#TEST@domain.com", "Welcome to HintKeep!", Arg.Is(body => body.Contains("#activation-token")));
+ Assert.Single(_emailService.ReceivedCalls());
}
[Fact]
public async Task Handle_WhenUserEmailAlreadyExists_ThrowsException()
{
_securityService
- .Setup(securityService => securityService.ComputeHash("#test@domain.com"))
+ .ComputeHash("#test@domain.com")
.Returns("#email-hash");
_securityService
- .Setup(securityService => securityService.GenerateConfirmationToken())
+ .GenerateConfirmationToken()
.Returns(new ConfirmationToken("#token", TimeSpan.Zero));
_entityTables.Users.Execute(TableOperation.Insert(new TableEntity { PartitionKey = "#email-hash".ToEncodedKeyProperty(), RowKey = "details" }));
@@ -101,7 +103,7 @@ await Assert.ThrowsAsync(() => _registerUserCommandHandler.Ha
default
));
- _emailService.VerifyNoOtherCalls();
+ Assert.Empty(_emailService.ReceivedCalls());
}
}
}
\ No newline at end of file
diff --git a/HintKeep.Tests/Unit/RequestsHandlers/Users/Commands/UserPasswordResetCommandHandlerTests.cs b/HintKeep.Tests/Unit/RequestsHandlers/Users/Commands/UserPasswordResetCommandHandlerTests.cs
index 485cdf0..b529e69 100644
--- a/HintKeep.Tests/Unit/RequestsHandlers/Users/Commands/UserPasswordResetCommandHandlerTests.cs
+++ b/HintKeep.Tests/Unit/RequestsHandlers/Users/Commands/UserPasswordResetCommandHandlerTests.cs
@@ -8,7 +8,7 @@
using HintKeep.Tests.Stubs;
using MediatR;
using Microsoft.Azure.Cosmos.Table;
-using Moq;
+using NSubstitute;
using Xunit;
namespace HintKeep.Tests.Unit.RequestsHandlers.Users.Commands
@@ -16,16 +16,16 @@ namespace HintKeep.Tests.Unit.RequestsHandlers.Users.Commands
public class UserPasswordResetCommandHandlerTests
{
private readonly InMemoryEntityTables _entityTables;
- private readonly Mock _securityService;
- private readonly Mock _emailService;
+ private readonly ISecurityService _securityService;
+ private readonly IEmailService _emailService;
private readonly IRequestHandler _userPasswordResetCommandHandler;
public UserPasswordResetCommandHandlerTests()
{
_entityTables = new InMemoryEntityTables();
- _securityService = new Mock();
- _emailService = new Mock();
- _userPasswordResetCommandHandler = new UserPasswordResetCommandHandler(_entityTables, _securityService.Object, _emailService.Object);
+ _securityService = Substitute.For();
+ _emailService = Substitute.For();
+ _userPasswordResetCommandHandler = new UserPasswordResetCommandHandler(_entityTables, _securityService, _emailService);
_entityTables.Users.Create();
}
@@ -33,7 +33,7 @@ public UserPasswordResetCommandHandlerTests()
public async Task Handle_WhenTokenDoesNotExist_ThrowsException()
{
_securityService
- .Setup(securityService => securityService.ComputeHash("#test@domain.com"))
+ .ComputeHash("#test@domain.com")
.Returns("#email-hash");
await Assert.ThrowsAsync(() => _userPasswordResetCommandHandler.Handle(
@@ -50,7 +50,7 @@ await Assert.ThrowsAsync(() => _userPasswordResetCommandHandl
public async Task Handle_WhenExpiredTokenExist_ThrowsException()
{
_securityService
- .Setup(securityService => securityService.ComputeHash("#test@domain.com"))
+ .ComputeHash("#test@domain.com")
.Returns("#email-hash");
_entityTables.Users.Execute(TableOperation.Insert(new UserPasswordResetTokenEntity
{
@@ -76,7 +76,7 @@ await Assert.ThrowsAsync(() => _userPasswordResetCommandHandl
public async Task Handle_WhenUserDoesNotExist_ThrowsException()
{
_securityService
- .Setup(securityService => securityService.ComputeHash("#test@domain.com"))
+ .ComputeHash("#test@domain.com")
.Returns("#email-hash");
_entityTables.Users.Execute(TableOperation.Insert(new UserPasswordResetTokenEntity
{
@@ -122,13 +122,13 @@ public async Task Handle_WhenValidTokenExist_ResetsPassword()
})
});
_securityService
- .Setup(securityService => securityService.ComputeHash("#test@domain.com"))
+ .ComputeHash("#test@domain.com")
.Returns("#email-hash");
_securityService
- .Setup(securityService => securityService.GeneratePasswordSalt())
+ .GeneratePasswordSalt()
.Returns("#password-salt");
_securityService
- .Setup(securityService => securityService.ComputePasswordHash("#password-salt", "#password"))
+ .ComputePasswordHash("#password-salt", "#password")
.Returns("#password-hash");
await _userPasswordResetCommandHandler.Handle(
@@ -177,7 +177,7 @@ public async Task Handle_WhenInactiveUserExist_ThrowsException()
})
});
_securityService
- .Setup(securityService => securityService.ComputeHash("#test@domain.com"))
+ .ComputeHash("#test@domain.com")
.Returns("#email-hash");
await Assert.ThrowsAsync(() => _userPasswordResetCommandHandler.Handle(
diff --git a/HintKeep.Tests/Unit/RequestsHandlers/Users/Commands/UserRequestHintCommandHandlerTests.cs b/HintKeep.Tests/Unit/RequestsHandlers/Users/Commands/UserRequestHintCommandHandlerTests.cs
index 6ff3cfc..9b3d8ad 100644
--- a/HintKeep.Tests/Unit/RequestsHandlers/Users/Commands/UserRequestHintCommandHandlerTests.cs
+++ b/HintKeep.Tests/Unit/RequestsHandlers/Users/Commands/UserRequestHintCommandHandlerTests.cs
@@ -8,7 +8,7 @@
using HintKeep.Tests.Stubs;
using MediatR;
using Microsoft.Azure.Cosmos.Table;
-using Moq;
+using NSubstitute;
using Xunit;
namespace HintKeep.Tests.Unit.RequestsHandlers.Users.Commands
@@ -16,16 +16,16 @@ namespace HintKeep.Tests.Unit.RequestsHandlers.Users.Commands
public class UserRequestHintCommandHandlerTests
{
private readonly IEntityTables _entityTables;
- private readonly Mock _securityService;
- private readonly Mock _emailService;
+ private readonly ISecurityService _securityService;
+ private readonly IEmailService _emailService;
private readonly IRequestHandler _userRequestHintCommandHandler;
public UserRequestHintCommandHandlerTests()
{
_entityTables = new InMemoryEntityTables();
- _securityService = new Mock();
- _emailService = new Mock();
- _userRequestHintCommandHandler = new UserRequestHintCommandHandler(_entityTables, _securityService.Object, _emailService.Object);
+ _securityService = Substitute.For();
+ _emailService = Substitute.For();
+ _userRequestHintCommandHandler = new UserRequestHintCommandHandler(_entityTables, _securityService, _emailService);
_entityTables.Users.Create();
}
@@ -33,7 +33,7 @@ public UserRequestHintCommandHandlerTests()
public async Task Handle_WhenUserDoesNotExist_ThrowsException()
{
_securityService
- .Setup(securityService => securityService.ComputeHash("#test@domain.com"))
+ .ComputeHash("#test@domain.com")
.Returns("#email-hash");
await Assert.ThrowsAsync(() => _userRequestHintCommandHandler.Handle(new UserRequestHintCommand("#TEST@domain.com"), default));
@@ -50,7 +50,7 @@ public async Task Handle_WhenInactiveUserExist_ThrowsException()
IsActive = false
}));
_securityService
- .Setup(securityService => securityService.ComputeHash("#test@domain.com"))
+ .ComputeHash("#test@domain.com")
.Returns("#email-hash");
await Assert.ThrowsAsync(() => _userRequestHintCommandHandler.Handle(new UserRequestHintCommand("#TEST@domain.com"), default));
@@ -68,13 +68,15 @@ public async Task Handle_WhenActiveUserExist_SendsEmailNotification()
IsActive = true
}));
_securityService
- .Setup(securityService => securityService.ComputeHash("#test@domain.com"))
+ .ComputeHash("#test@domain.com")
.Returns("#email-hash");
await _userRequestHintCommandHandler.Handle(new UserRequestHintCommand("#TEST@domain.com"), default);
- _emailService.Verify(emailService => emailService.SendAsync("#TEST@domain.com", "HintKeep - Account Hint", It.IsRegex("#hint")), Times.Once);
- _emailService.VerifyNoOtherCalls();
+ await _emailService
+ .Received()
+ .SendAsync("#TEST@domain.com", "HintKeep - Account Hint", Arg.Is(body => body.Contains("#hint")));
+ Assert.Single(_emailService.ReceivedCalls());
}
}
}
\ No newline at end of file
diff --git a/HintKeep.Tests/Unit/RequestsHandlers/Users/Commands/UserRequestPasswordResetCommandHandlerTests.cs b/HintKeep.Tests/Unit/RequestsHandlers/Users/Commands/UserRequestPasswordResetCommandHandlerTests.cs
index a6177af..9ea42df 100644
--- a/HintKeep.Tests/Unit/RequestsHandlers/Users/Commands/UserRequestPasswordResetCommandHandlerTests.cs
+++ b/HintKeep.Tests/Unit/RequestsHandlers/Users/Commands/UserRequestPasswordResetCommandHandlerTests.cs
@@ -9,7 +9,7 @@
using HintKeep.Tests.Stubs;
using MediatR;
using Microsoft.Azure.Cosmos.Table;
-using Moq;
+using NSubstitute;
using Xunit;
namespace HintKeep.Tests.Unit.RequestsHandlers.Users.Commands
@@ -17,16 +17,16 @@ namespace HintKeep.Tests.Unit.RequestsHandlers.Users.Commands
public class UserRequestPasswordResetCommandHandlerTests
{
private IEntityTables _entityTables;
- private Mock _securityService;
- private Mock _emailService;
+ private ISecurityService _securityService;
+ private IEmailService _emailService;
private IRequestHandler _userRequestPasswordResetCommand;
public UserRequestPasswordResetCommandHandlerTests()
{
_entityTables = new InMemoryEntityTables();
- _securityService = new Mock();
- _emailService = new Mock();
- _userRequestPasswordResetCommand = new UserRequestPasswordResetCommandHandler(_entityTables, _securityService.Object, _emailService.Object);
+ _securityService = Substitute.For();
+ _emailService = Substitute.For();
+ _userRequestPasswordResetCommand = new UserRequestPasswordResetCommandHandler(_entityTables, _securityService, _emailService);
_entityTables.Users.Create();
}
@@ -34,7 +34,7 @@ public UserRequestPasswordResetCommandHandlerTests()
public async Task Handle_WhenUserDoesNotExist_ThrowsException()
{
_securityService
- .Setup(securityService => securityService.ComputeHash("#test@domain.com"))
+ .ComputeHash("#test@domain.com")
.Returns("#email-hash");
await Assert.ThrowsAsync(() => _userRequestPasswordResetCommand.Handle(new UserRequestPasswordResetCommand("#TEST@domain.com"), default));
@@ -51,7 +51,7 @@ public async Task Handle_WhenInactiveUserExists_ThrowsException()
IsActive = false
}));
_securityService
- .Setup(securityService => securityService.ComputeHash("#test@domain.com"))
+ .ComputeHash("#test@domain.com")
.Returns("#email-hash");
await Assert.ThrowsAsync(() => _userRequestPasswordResetCommand.Handle(new UserRequestPasswordResetCommand("#TEST@domain.com"), default));
@@ -68,10 +68,10 @@ public async Task Handle_WhenActiveUserExists_ThrowsException()
IsActive = true
}));
_securityService
- .Setup(securityService => securityService.ComputeHash("#test@domain.com"))
+ .ComputeHash("#test@domain.com")
.Returns("#email-hash");
_securityService
- .Setup(securityService => securityService.GenerateConfirmationToken())
+ .GenerateConfirmationToken()
.Returns(new ConfirmationToken("#confirmation-token", TimeSpan.FromMinutes(60)));
await _userRequestPasswordResetCommand.Handle(new UserRequestPasswordResetCommand("#TEST@domain.com"), default);
@@ -86,8 +86,10 @@ public async Task Handle_WhenActiveUserExists_ThrowsException()
Assert.True(DateTimeOffset.UtcNow.AddMinutes(55) < expiration);
Assert.True(expiration < DateTimeOffset.UtcNow.AddMinutes(65));
- _emailService.Verify(emailService => emailService.SendAsync("#TEST@domain.com", "HintKeep - Password Reset", It.IsRegex("#confirmation-token")), Times.Once);
- _emailService.VerifyNoOtherCalls();
+ await _emailService
+ .Received()
+ .SendAsync("#TEST@domain.com", "HintKeep - Password Reset", Arg.Is(body => body.Contains("#confirmation-token")));
+ Assert.Single(_emailService.ReceivedCalls());
}
}
}
\ No newline at end of file