diff --git a/tests/FiscalOS.API.Tests/Integration/IntegrationTest.cs b/tests/FiscalOS.API.Tests/Integration/IntegrationTest.cs index 844a659..52cb7be 100644 --- a/tests/FiscalOS.API.Tests/Integration/IntegrationTest.cs +++ b/tests/FiscalOS.API.Tests/Integration/IntegrationTest.cs @@ -1,39 +1,39 @@ - -using FiscalOS.API.Data; - -using Microsoft.EntityFrameworkCore; -using Microsoft.Extensions.DependencyInjection; - namespace FiscalOS.API.Tests.Integration; public abstract class IntegrationTest(TestApi testApi) : IClassFixture, IAsyncLifetime { - protected TestApi TestApi { get; } = testApi; + public HttpClient Client => testApi.CreateClient(); - // TODO: This seems not correct - // would need to dispose of scope - // we need to clean up the test - // database files when the test ends - - protected DbContext TestDbContext + public async ValueTask InitializeAsync() { - get + await ExecuteDbContextAsync(static async context => { - var scopeFactory = TestApi.Services.GetRequiredService(); - var scope = scopeFactory.CreateScope(); - return scope.ServiceProvider.GetRequiredService(); - } + await context.Database.EnsureCreatedAsync(); + }); } - public ValueTask InitializeAsync() + protected async Task ExecuteDbContextAsync(Func action) { - return new(TestDbContext.Database.EnsureCreatedAsync()); + await using var scope = testApi.Services.CreateAsyncScope(); + var context = scope.ServiceProvider.GetRequiredService(); + await action(context); } - public ValueTask DisposeAsync() + protected async Task ExecuteDbContextAsync(Func> action) { + await using var scope = testApi.Services.CreateAsyncScope(); + var context = scope.ServiceProvider.GetRequiredService(); + return await action(context); + } + + public async ValueTask DisposeAsync() + { + await ExecuteDbContextAsync(static async context => + { + await context.Database.EnsureDeletedAsync(); + }); + GC.SuppressFinalize(this); - return new(TestDbContext.Database.EnsureDeletedAsync()); } } \ No newline at end of file diff --git a/tests/FiscalOS.API.Tests/Integration/LoginTests.cs b/tests/FiscalOS.API.Tests/Integration/LoginTests.cs index d0d4267..06dd386 100644 --- a/tests/FiscalOS.API.Tests/Integration/LoginTests.cs +++ b/tests/FiscalOS.API.Tests/Integration/LoginTests.cs @@ -1,3 +1,5 @@ +using FiscalOS.API.Identity; + namespace FiscalOS.API.Tests.Integration; public class LoginTests(TestApi testApi) : IntegrationTest(testApi) @@ -6,15 +8,13 @@ public class LoginTests(TestApi testApi) : IntegrationTest(testApi) [ClassData] public async Task Login_WhenUserSubmitsInvalidRequest_ItShouldReturn400WithProblemDetails(LoginValidationTestCase tc) { - var client = TestApi.CreateClient(); - var req = new { username = tc.Username, password = tc.Password, }; - var res = await client.PostAsJsonAsync("/login", req, TestContext.Current.CancellationToken); + var res = await Client.PostAsJsonAsync("/login", req, TestContext.Current.CancellationToken); res.StatusCode.Should().Be(HttpStatusCode.BadRequest); @@ -24,17 +24,39 @@ public class LoginTests(TestApi testApi) : IntegrationTest(testApi) } [Fact] - public async Task Login_WhenUserCredentialsAreIncorrect_ItShouldReturn401WithProblemDetails() + public async Task Login_WhenUserDoesNotExist_ItShouldReturn401WithProblemDetails() { - var client = TestApi.CreateClient(); - var req = new { username = "Test", password = "@Password2", }; - var res = await client.PostAsJsonAsync("/login", req, TestContext.Current.CancellationToken); + var res = await Client.PostAsJsonAsync("/login", req, TestContext.Current.CancellationToken); + + res.StatusCode.Should().Be(HttpStatusCode.Unauthorized); + } + + [Fact] + public async Task Login_WhenUserExistsButPasswordIsIncorrect_ItShouldReturn401WithProblemDetails() + { + await ExecuteDbContextAsync(static async context => + { + context.Add(new User + { + Username = "Stevan", + }); + + await context.SaveChangesAsync(TestContext.Current.CancellationToken); + }); + + var req = new + { + username = "Stevan", + password = "@Password2", + }; + + var res = await Client.PostAsJsonAsync("/login", req, TestContext.Current.CancellationToken); res.StatusCode.Should().Be(HttpStatusCode.Unauthorized); } diff --git a/tests/FiscalOS.API.Tests/Usings.cs b/tests/FiscalOS.API.Tests/Usings.cs index a6a235e..9f763fe 100644 --- a/tests/FiscalOS.API.Tests/Usings.cs +++ b/tests/FiscalOS.API.Tests/Usings.cs @@ -1,11 +1,14 @@ global using System.Net; global using System.Net.Http.Json; +global using FiscalOS.API.Data; global using FiscalOS.API.Tests.Infra; global using Microsoft.AspNetCore.Hosting; global using Microsoft.AspNetCore.Mvc; global using Microsoft.AspNetCore.Mvc.Testing; +global using Microsoft.EntityFrameworkCore; +global using Microsoft.Extensions.DependencyInjection; global using Microsoft.Extensions.Logging; -global using Xunit.Sdk; +global using Xunit.Sdk; \ No newline at end of file