thalos-service/tests/Thalos.Service.Application.UnitTests/HmacIdentitySessionTokenCodecTests.cs
2026-03-31 15:59:38 -06:00

86 lines
2.8 KiB
C#

using BuildingBlock.Identity.Contracts.Conventions;
using Thalos.Service.Application.Secrets;
using Thalos.Service.Application.Sessions;
namespace Thalos.Service.Application.UnitTests;
public class HmacIdentitySessionTokenCodecTests
{
[Fact]
public void EncodeAndTryDecode_WhenTokenValid_RoundTripsDescriptor()
{
var codec = new HmacIdentitySessionTokenCodec(new FakeSecretMaterialProvider());
var descriptor = new IdentitySessionDescriptor(
"user-9",
"tenant-9",
IdentityAuthProvider.AzureAd,
DateTimeOffset.UtcNow.AddMinutes(5));
var token = codec.Encode(descriptor);
var ok = codec.TryDecode(token, out var decoded);
Assert.True(ok);
Assert.Equal("user-9", decoded.SubjectId);
Assert.Equal("tenant-9", decoded.TenantId);
Assert.Equal(IdentityAuthProvider.AzureAd, decoded.Provider);
}
[Fact]
public void TryDecode_WhenTokenTampered_ReturnsFalse()
{
var codec = new HmacIdentitySessionTokenCodec(new FakeSecretMaterialProvider());
var descriptor = new IdentitySessionDescriptor(
"user-9",
"tenant-9",
IdentityAuthProvider.InternalJwt,
DateTimeOffset.UtcNow.AddMinutes(5));
var token = codec.Encode(descriptor) + "tamper";
var ok = codec.TryDecode(token, out _);
Assert.False(ok);
}
[Fact]
public void Encode_WhenSigningSecretUnavailable_ThrowsExplicitRuntimeError()
{
var codec = new HmacIdentitySessionTokenCodec(new MissingSecretMaterialProvider());
var descriptor = new IdentitySessionDescriptor(
"user-9",
"tenant-9",
IdentityAuthProvider.InternalJwt,
DateTimeOffset.UtcNow.AddMinutes(5));
var error = Assert.Throws<InvalidOperationException>(() => codec.Encode(descriptor));
Assert.Contains("SessionSigning", error.Message, StringComparison.Ordinal);
}
private sealed class FakeSecretMaterialProvider : IIdentitySecretMaterialProvider
{
public bool TryGetSecret(string secretKey, out string secretValue)
{
secretValue = "unit-test-secret";
return true;
}
public string GetSecret(string secretKey) => "unit-test-secret";
}
private sealed class MissingSecretMaterialProvider : IIdentitySecretMaterialProvider
{
public bool TryGetSecret(string secretKey, out string secretValue)
{
secretValue = string.Empty;
return false;
}
public string GetSecret(string secretKey)
{
throw new InvalidOperationException(
$"Identity secret '{secretKey}' is not configured for the current runtime.");
}
}
}