From c163db3029977b92c8350ad59a8458f998f9cec0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Ty=C5=84ski?= Date: Sun, 4 Oct 2026 02:12:00 +0200 Subject: [PATCH] test(backend): add auth token and security policy tests --- .../Auth/SecurityConstantsTests.cs | 34 ++++++++++ .../Auth/TokenServiceTests.cs | 63 +++++++++++++++++++ 2 files changed, 97 insertions(+) create mode 100644 tests/TarninaHub.Tests/Auth/SecurityConstantsTests.cs create mode 100644 tests/TarninaHub.Tests/Auth/TokenServiceTests.cs diff --git a/tests/TarninaHub.Tests/Auth/SecurityConstantsTests.cs b/tests/TarninaHub.Tests/Auth/SecurityConstantsTests.cs new file mode 100644 index 0000000..2a21bc3 --- /dev/null +++ b/tests/TarninaHub.Tests/Auth/SecurityConstantsTests.cs @@ -0,0 +1,34 @@ +using TarninaHub.Application.Security; +using TarninaHub.Infrastructure.Auth; + +namespace TarninaHub.Tests.Auth; + +public class SecurityConstantsTests +{ + [Theory] + [InlineData("user", true)] + [InlineData("jst", true)] + [InlineData("operator", true)] + [InlineData("manager", true)] + [InlineData("admin", true)] + [InlineData("guest", false)] + public void RoleNames_IsValid_RecognizesKnownRoles(string role, bool expected) + { + Assert.Equal(expected, RoleNames.IsValid(role)); + } + + [Fact] + public void AuthSettings_HasUsableSigningKey_RequiresAtLeast32Chars() + { + Assert.False(new AuthSettings { SigningKey = "short" }.HasUsableSigningKey); + Assert.True(new AuthSettings { SigningKey = new string('k', 32) }.HasUsableSigningKey); + } + + [Fact] + public void ConsentScopes_ContainsExpectedLevels() + { + Assert.Contains(ConsentScopes.ByConsent, ConsentScopes.All); + Assert.Contains(ConsentScopes.Temporary, ConsentScopes.All); + Assert.Contains(ConsentScopes.Anonymized, ConsentScopes.All); + } +} diff --git a/tests/TarninaHub.Tests/Auth/TokenServiceTests.cs b/tests/TarninaHub.Tests/Auth/TokenServiceTests.cs new file mode 100644 index 0000000..33b4410 --- /dev/null +++ b/tests/TarninaHub.Tests/Auth/TokenServiceTests.cs @@ -0,0 +1,63 @@ +using System.IdentityModel.Tokens.Jwt; +using System.Text; +using Microsoft.Extensions.Options; +using Microsoft.IdentityModel.Tokens; +using TarninaHub.Application.Models; +using TarninaHub.Infrastructure.Auth; + +namespace TarninaHub.Tests.Auth; + +public class TokenServiceTests +{ + private static AuthSettings CreateSettings() => new() + { + Issuer = "tarninahub", + Audience = "tarninahub", + SigningKey = new string('k', 40), + TokenLifetimeMinutes = 30, + }; + + [Fact] + public void CreateToken_IncludesSubjectAndRole() + { + var service = new TokenService(Options.Create(CreateSettings())); + var user = new UserAccount("user:ania", "+48000000001", "ania@example.test", "user", null); + + var result = service.CreateToken(user); + var jwt = new JwtSecurityTokenHandler().ReadJwtToken(result.AccessToken); + + Assert.Equal("user:ania", jwt.Claims.Single(claim => claim.Type == "sub").Value); + Assert.Equal("user", jwt.Claims.Single(claim => claim.Type == "role").Value); + Assert.Equal("tarninahub", jwt.Issuer); + Assert.True(result.ExpiresAt > DateTimeOffset.UtcNow); + } + + [Fact] + public void CreateToken_IsValidatedByTheSameSigningKey() + { + var settings = CreateSettings(); + var service = new TokenService(Options.Create(settings)); + var user = new UserAccount("user:jst", "+48000000010", null, "jst", "organization:mops_krakow"); + + var result = service.CreateToken(user); + + var parameters = new TokenValidationParameters + { + ValidateIssuer = true, + ValidIssuer = settings.Issuer, + ValidateAudience = true, + ValidAudience = settings.Audience, + ValidateIssuerSigningKey = true, + IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(settings.SigningKey)), + ValidateLifetime = true, + RoleClaimType = "role", + NameClaimType = "sub", + }; + + var handler = new JwtSecurityTokenHandler { MapInboundClaims = false }; + var principal = handler.ValidateToken(result.AccessToken, parameters, out _); + + Assert.Equal("jst", principal.FindFirst("role")?.Value); + Assert.Equal("user:jst", principal.FindFirst("sub")?.Value); + } +}