tests(api): add integration test for happy path when logging in

This commit is contained in:
Stevan Freeborn
2026-02-03 04:38:40 -06:00
parent 98de115259
commit 0ce97cdec8
10 changed files with 63 additions and 16 deletions
+16 -2
View File
@@ -1,3 +1,7 @@
using System.Security.Cryptography;
using FiscalOS.Infra.Authentication;
namespace FiscalOS.API.Tests.Infra;
public class TestApi : WebApplicationFactory<Program>
@@ -10,12 +14,22 @@ public class TestApi : WebApplicationFactory<Program>
builder.ConfigureTestServices(static c =>
{
var opts = Options.Create(new AppDbContextOptions()
var dbOpts = Options.Create(new AppDbContextOptions()
{
DatabaseFilePath = $"{Guid.NewGuid()}.db",
});
c.AddSingleton(opts);
c.AddSingleton(dbOpts);
var jwtOpts = Options.Create(new JwtOptions()
{
Issuer = "TestIssuer",
Audience = "TestAudience",
Secret = Convert.ToBase64String(RandomNumberGenerator.GetBytes(32)),
ExpiryInMinutes = 5,
});
c.AddSingleton(jwtOpts);
});
}
}
@@ -1,6 +1,3 @@
using FiscalOS.Core.Authentication;
using FiscalOS.Core.Identity;
namespace FiscalOS.API.Tests.Integration;
public class LoginTests(TestApi testApi) : IntegrationTest(testApi)
@@ -17,9 +14,6 @@ public class LoginTests(TestApi testApi) : IntegrationTest(testApi)
var res = await Client.PostAsJsonAsync("/login", req, TestContext.Current.CancellationToken);
var content = await res.Content.ReadAsStringAsync(TestContext.Current.CancellationToken);
Console.WriteLine(content);
res.StatusCode.Should().Be(HttpStatusCode.BadRequest);
var problem = await res.Content.ReadFromJsonAsync<ValidationProblemDetails>(TestContext.Current.CancellationToken);
@@ -63,6 +57,38 @@ public class LoginTests(TestApi testApi) : IntegrationTest(testApi)
res.StatusCode.Should().Be(HttpStatusCode.Unauthorized);
}
[Fact]
public async Task Login_WhenUserExistsAndPasswordIsCorrect_ItShouldReturn200WithJwtToken()
{
await ExecuteDbContextAsync(static async (context, sp) =>
{
var passwordHasher = sp.GetRequiredService<IPasswordHasher>();
context.Add(User.From("Stevan", passwordHasher.Hash("@Password1")));
await context.SaveChangesAsync(TestContext.Current.CancellationToken);
});
var req = new
{
username = "Stevan",
password = "@Password1",
};
var res = await Client.PostAsJsonAsync("/login", req, TestContext.Current.CancellationToken);
res.StatusCode.Should().Be(HttpStatusCode.OK);
var content = await res.Content.ReadFromJsonAsync<Login.Response>(TestContext.Current.CancellationToken);
content!.AccessToken.Should().NotBeNullOrEmpty();
res.Headers.TryGetValues("Set-Cookie", out var cookies).Should().BeTrue();
cookies.Should().NotBeNull();
}
}
+2
View File
@@ -2,6 +2,8 @@ global using System.Net;
global using System.Net.Http.Json;
global using FiscalOS.API.Tests.Infra;
global using FiscalOS.Core.Authentication;
global using FiscalOS.Core.Identity;
global using FiscalOS.Infra.Data;
global using Microsoft.AspNetCore.Hosting;
@@ -1,6 +1,3 @@
using System.Globalization;
using System.Security.Cryptography;
namespace FiscalOS.Infra.Tests.Unit;
public class TokenGeneratorTests
+4 -1
View File
@@ -1,8 +1,11 @@
global using System.Globalization;
global using System.IdentityModel.Tokens.Jwt;
global using System.Security.Cryptography;
global using AwesomeAssertions.Primitives;
global using FiscalOS.Core.Identity;
global using FiscalOS.Infra.Authentication;
global using FiscalOS.Infra.Tests.Assertions;
global using Microsoft.Extensions.Options;
global using Microsoft.Extensions.Options;