Skip to content

Commit

Permalink
Switched to NSubstitute
Browse files Browse the repository at this point in the history
  • Loading branch information
Andrei15193 committed Aug 11, 2023
1 parent 9766e5e commit 759fe7b
Show file tree
Hide file tree
Showing 14 changed files with 130 additions and 116 deletions.
2 changes: 1 addition & 1 deletion HintKeep.Tests/HintKeep.Tests.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
<PackageReference Include="CloudStub.Azure.Cosmos.Table" Version="1.0.0-alpha.1" />
<PackageReference Include="Microsoft.AspNetCore.Mvc.Testing" Version="6.0.7" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.2.0" />
<PackageReference Include="Moq" Version="4.18.1" />
<PackageReference Include="NSubstitute" Version="5.0.0" />
<PackageReference Include="xunit" Version="2.4.1" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.5">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
Expand Down
9 changes: 4 additions & 5 deletions HintKeep.Tests/Integration/TestEmailServiceExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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
{
Expand All @@ -12,14 +12,13 @@ public static WebApplicationFactory<TEntryPoint> WithEmailService<TEntryPoint>(t
where TEntryPoint : class
=> webApplicationFactory.WithEmailService(out var _);

public static WebApplicationFactory<TEntryPoint> WithEmailService<TEntryPoint>(this WebApplicationFactory<TEntryPoint> webApplicationFactory, out Mock<IEmailService> emailService)
public static WebApplicationFactory<TEntryPoint> WithEmailService<TEntryPoint>(this WebApplicationFactory<TEntryPoint> webApplicationFactory, out IEmailService emailService)
where TEntryPoint : class
{
var emailServiceMock = new Mock<IEmailService>();
emailService = emailServiceMock;
var emailServiceSubstitute = emailService = Substitute.For<IEmailService>();
return webApplicationFactory.WithWebHostBuilder(
configuration => configuration.ConfigureTestServices(
services => services.AddSingleton<IEmailService>(emailServiceMock.Object)
services => services.AddSingleton(emailServiceSubstitute)
)
);
}
Expand Down
9 changes: 4 additions & 5 deletions HintKeep.Tests/Integration/TestSecurityServiceExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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
{
Expand All @@ -12,14 +12,13 @@ public static WebApplicationFactory<TEntryPoint> WithSecurityService<TEntryPoint
where TEntryPoint : class
=> webApplicationFactory.WithSecurityService(out var _);

public static WebApplicationFactory<TEntryPoint> WithSecurityService<TEntryPoint>(this WebApplicationFactory<TEntryPoint> webApplicationFactory, out Mock<ISecurityService> securityService)
public static WebApplicationFactory<TEntryPoint> WithSecurityService<TEntryPoint>(this WebApplicationFactory<TEntryPoint> webApplicationFactory, out ISecurityService securityService)
where TEntryPoint : class
{
var securityServiceMock = new Mock<ISecurityService>();
securityService = securityServiceMock;
var securityServiceSubstitute = securityService = Substitute.For<ISecurityService>();
return webApplicationFactory.WithWebHostBuilder(
configuration => configuration.ConfigureTestServices(
services => services.AddSingleton<ISecurityService>(securityServiceMock.Object)
services => services.AddSingleton(securityServiceSubstitute)
)
);
}
Expand Down
23 changes: 13 additions & 10 deletions HintKeep.Tests/Integration/Users/PostTests.cs
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
using System;
using System.Linq;
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.Users
Expand Down Expand Up @@ -63,16 +64,16 @@ public async Task Post_WhenUserDoesNotExist_ReturnsCreated()
.WithEmailService(out var emailService)
.CreateClient();
securityService
.Setup(securityService => securityService.ComputeHash("#[email protected]"))
.ComputeHash("#[email protected]")
.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 = "#[email protected]", hint = "#Test-Hint", password = "#Test-Password1" });
Expand Down Expand Up @@ -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("#[email protected]", "Welcome to HintKeep!", It.Is<string>(body => body.Contains("#confirmation-token"))), Times.Once);
emailService.VerifyNoOtherCalls();
await emailService
.Received()
.SendAsync("#[email protected]", "Welcome to HintKeep!", Arg.Is<string>(body => body.Contains("#confirmation-token")));
Assert.Single(emailService.ReceivedCalls());
}

[Fact]
Expand All @@ -116,10 +119,10 @@ public async Task Post_WhenUserEmailAlreadyExists_ReturnsConflict()
.WithEmailService(out var emailService)
.CreateClient();
securityService
.Setup(securityService => securityService.ComputeHash("#[email protected]"))
.ComputeHash("#[email protected]")
.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" }));

Expand All @@ -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());
}
}
}
5 changes: 3 additions & 2 deletions HintKeep.Tests/Integration/UsersConfirmations/PostTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -59,7 +60,7 @@ public async Task Post_WhenValidTokenExist_ReturnsCreated()
}
);
securityService
.Setup(securityService => securityService.ComputeHash("#[email protected]"))
.ComputeHash("#[email protected]")
.Returns("#email-hash");

var response = await client.PostAsJsonAsync("/api/users/confirmations", new { token = "#test-token" });
Expand Down Expand Up @@ -109,7 +110,7 @@ public async Task Post_WhenExpiredTokenExist_ReturnsNotFound()
Expiration = DateTimeOffset.UtcNow.AddDays(-1)
}));
securityService
.Setup(securityService => securityService.ComputeHash("#[email protected]"))
.ComputeHash("#[email protected]")
.Returns("#email-hash");

var response = await client.PostAsJsonAsync("/api/users/confirmations", new { token = "#token" });
Expand Down
14 changes: 8 additions & 6 deletions HintKeep.Tests/Integration/UsersHintsNotifications/PostTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -51,7 +51,7 @@ public async Task Post_WhenActiveUserExists_ReturnsCreated()
}
);
securityService
.Setup(securityService => securityService.ComputeHash("#[email protected]"))
.ComputeHash("#[email protected]")
.Returns("#email-hash");

var response = await client.PostAsJsonAsync("/api/users/hints/notifications", new { email = "#[email protected]" });
Expand All @@ -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("#[email protected]", "HintKeep - Account Hint", It.IsRegex("#hint")), Times.Once);
emailService.VerifyNoOtherCalls();
await emailService
.Received()
.SendAsync("#[email protected]", "HintKeep - Account Hint", Arg.Is<string>(body => body.Contains("#hint")));
Assert.Single(emailService.ReceivedCalls());
}

[Fact]
Expand All @@ -72,7 +74,7 @@ public async Task Post_WhenUserDoesNotExist_ReturnsNotFound()
.WithSecurityService(out var securityService)
.CreateClient();
securityService
.Setup(securityService => securityService.ComputeHash("#[email protected]"))
.ComputeHash("#[email protected]")
.Returns("#email-hash");

var response = await client.PostAsJsonAsync("/api/users/hints/notifications", new { email = "#[email protected]" });
Expand Down Expand Up @@ -101,7 +103,7 @@ public async Task Post_WhenInactiveUserExists_ReturnsNotFound()
}
);
securityService
.Setup(securityService => securityService.ComputeHash("#[email protected]"))
.ComputeHash("#[email protected]")
.Returns("#email-hash");

var response = await client.PostAsJsonAsync("/api/users/hints/notifications", new { email = "#[email protected]" });
Expand Down
21 changes: 11 additions & 10 deletions HintKeep.Tests/Integration/UsersPasswords/PostTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -45,7 +44,7 @@ public async Task Post_WhenTokenDoesNotExist_ReturnsNotFound()
Expiration = DateTimeOffset.UtcNow.AddDays(-1)
}));
securityService
.Setup(securityService => securityService.ComputeHash("#[email protected]"))
.ComputeHash("#[email protected]")
.Returns("#email-hash");

var response = await client.PostAsJsonAsync("/api/users/passwords", new { email = "#[email protected]", token = "#token", password = "passWORD$123" });
Expand All @@ -69,7 +68,7 @@ public async Task Post_WhenUserDoesNotExist_ReturnsNotFound()
Expiration = DateTimeOffset.UtcNow.AddDays(1)
}));
securityService
.Setup(securityService => securityService.ComputeHash("#[email protected]"))
.ComputeHash("#[email protected]")
.Returns("#email-hash");

var response = await client.PostAsJsonAsync("/api/users/passwords", new { email = "#[email protected]", token = "#token", password = "passWORD$123" });
Expand Down Expand Up @@ -108,13 +107,13 @@ public async Task Post_WhenValidTokenExist_ReturnsCreated()
})
});
securityService
.Setup(securityService => securityService.ComputeHash("#[email protected]"))
.ComputeHash("#[email protected]")
.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 = "#[email protected]", token = "#token", password = "passWORD$123" });
Expand All @@ -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("#[email protected]", "HintKeep - Password Reset", It.IsAny<string>()), Times.Once);
emailService.VerifyNoOtherCalls();
await emailService
.Received()
.SendAsync("#[email protected]", "HintKeep - Password Reset", Arg.Any<string>());
Assert.Single(emailService.ReceivedCalls());
}

[Fact]
Expand Down Expand Up @@ -167,7 +168,7 @@ public async Task Post_WhenInactiveUserExists_ReturnsNotFound()
})
});
securityService
.Setup(securityService => securityService.ComputeHash("#[email protected]"))
.ComputeHash("#[email protected]")
.Returns("#email-hash");

var response = await client.PostAsJsonAsync("/api/users/passwords", new { email = "#[email protected]", token = "#token", password = "passWORD$123" });
Expand Down
16 changes: 9 additions & 7 deletions HintKeep.Tests/Integration/UsersPasswordsResets/PostTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -51,10 +51,10 @@ public async Task Post_WhenActiveUserExists_ReturnsCreated()
}
);
securityService
.Setup(securityService => securityService.ComputeHash("#[email protected]"))
.ComputeHash("#[email protected]")
.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 = "#[email protected]" });
Expand All @@ -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("#[email protected]", "HintKeep - Password Reset", It.Is<string>(body => body.Contains("#confirmation-token"))), Times.Once);
emailService.VerifyNoOtherCalls();
await emailService
.Received()
.SendAsync("#[email protected]", "HintKeep - Password Reset", Arg.Is<string>(body => body.Contains("#confirmation-token")));
Assert.Single(emailService.ReceivedCalls());
}

[Fact]
Expand All @@ -85,7 +87,7 @@ public async Task Post_WhenUserDoesNotExist_ReturnsNotFound()
.WithSecurityService(out var securityService)
.CreateClient();
securityService
.Setup(securityService => securityService.ComputeHash("#[email protected]"))
.ComputeHash("#[email protected]")
.Returns("#email-hash");

var response = await client.PostAsJsonAsync("/api/users/passwords/resets", new { email = "#[email protected]" });
Expand Down Expand Up @@ -114,7 +116,7 @@ public async Task Post_WhenInactiveUserExists_ReturnsNotFound()
}
);
securityService
.Setup(securityService => securityService.ComputeHash("#[email protected]"))
.ComputeHash("#[email protected]")
.Returns("#email-hash");

var response = await client.PostAsJsonAsync("/api/users/passwords/resets", new { email = "#[email protected]" });
Expand Down
13 changes: 7 additions & 6 deletions HintKeep.Tests/Integration/UsersSessions/Post.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -54,7 +55,7 @@ public async Task Post_WhenInactiveUserExists_ReturnsNotFound()
IsActive = false
}));
securityService
.Setup(securityService => securityService.ComputeHash("#[email protected]"))
.ComputeHash("#[email protected]")
.Returns("#email-hash");

var response = await client.PostAsJsonAsync("/api/users/sessions", new { email = "#[email protected]", password = "#test-password" });
Expand All @@ -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
{
Expand All @@ -81,10 +82,10 @@ public async Task Post_WhenActiveUserExistButPasswordsDoNotMatch_ReturnsUnproces
IsActive = true
}));
securityService
.Setup(securityService => securityService.ComputeHash("#[email protected]"))
.ComputeHash("#[email protected]")
.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 = "#[email protected]", password = "#test-password" });
Expand All @@ -111,10 +112,10 @@ public async Task Post_WhenActiveUserExsitsWithMatchingPassword_ReturnsCreated()
IsActive = true
}));
securityService
.Setup(securityService => securityService.ComputeHash("#[email protected]"))
.ComputeHash("#[email protected]")
.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 = "#[email protected]", password = "#test-password" });
Expand Down
Loading

0 comments on commit 759fe7b

Please sign in to comment.