tests: add jwt token builder for testing protected endpoints

This commit is contained in:
Stevan Freeborn
2026-02-03 11:34:58 -06:00
parent e6c5863180
commit cf4b4849c7
3 changed files with 68 additions and 17 deletions
@@ -0,0 +1,60 @@
namespace FiscalOS.API.Tests.Infra;
internal sealed class JwtTokenBuilder
{
private const string Issuer = "TestIssuer";
private const string Audience = "TestAudience";
private const int ExpiryInMinutes = 5;
private static readonly string Secret = Convert.ToBase64String(RandomNumberGenerator.GetBytes(32));
private readonly List<Claim> _claims = [];
private DateTimeOffset _issuedAt = DateTimeOffset.UtcNow;
public static JwtOptions DefaultJwtOptions => new()
{
Issuer = Issuer,
Audience = Audience,
Secret = Secret,
ExpiryInMinutes = ExpiryInMinutes,
};
public static JwtTokenBuilder New()
{
return new JwtTokenBuilder();
}
public JwtTokenBuilder WithClaim(string type, string value)
{
_claims.Add(new(type, value));
return this;
}
public JwtTokenBuilder IssuedAt(DateTimeOffset issuedAt)
{
_issuedAt = issuedAt;
return this;
}
public string Build()
{
var tokenHandler = new JwtSecurityTokenHandler();
var expiresAt = _issuedAt.AddMinutes(ExpiryInMinutes);
var descriptor = new SecurityTokenDescriptor()
{
Subject = new(_claims),
IssuedAt = _issuedAt.UtcDateTime,
Expires = expiresAt.UtcDateTime,
Issuer = Issuer,
Audience = Audience,
SigningCredentials = new(
DefaultJwtOptions.Key,
SecurityAlgorithms.HmacSha256Signature
),
};
var securityToken = tokenHandler.CreateJwtSecurityToken(descriptor);
var jwtToken = tokenHandler.WriteToken(securityToken);
return jwtToken;
}
}
+3 -17
View File
@@ -1,7 +1,3 @@
using System.Security.Cryptography;
using FiscalOS.Infra.Authentication;
namespace FiscalOS.API.Tests.Infra;
public class TestApi : WebApplicationFactory<Program>
@@ -14,22 +10,12 @@ public class TestApi : WebApplicationFactory<Program>
builder.ConfigureTestServices(static c =>
{
var dbOpts = Options.Create(new AppDbContextOptions()
c.AddSingleton(Options.Create(new AppDbContextOptions()
{
DatabaseFilePath = $"{Guid.NewGuid()}.db",
});
}));
c.AddSingleton(dbOpts);
var jwtOpts = Options.Create(new JwtOptions()
{
Issuer = "TestIssuer",
Audience = "TestAudience",
Secret = Convert.ToBase64String(RandomNumberGenerator.GetBytes(32)),
ExpiryInMinutes = 5,
});
c.AddSingleton(jwtOpts);
c.AddSingleton(Options.Create(JwtTokenBuilder.DefaultJwtOptions));
});
}
}
+5
View File
@@ -1,9 +1,13 @@
global using System.IdentityModel.Tokens.Jwt;
global using System.Net;
global using System.Net.Http.Json;
global using System.Security.Claims;
global using System.Security.Cryptography;
global using FiscalOS.API.Tests.Infra;
global using FiscalOS.Core.Authentication;
global using FiscalOS.Core.Identity;
global using FiscalOS.Infra.Authentication;
global using FiscalOS.Infra.Data;
global using Microsoft.AspNetCore.Hosting;
@@ -14,5 +18,6 @@ global using Microsoft.EntityFrameworkCore;
global using Microsoft.Extensions.DependencyInjection;
global using Microsoft.Extensions.Logging;
global using Microsoft.Extensions.Options;
global using Microsoft.IdentityModel.Tokens;
global using Xunit.Sdk;