using System.Text; using ClaudeDo.Worker.Online; namespace ClaudeDo.Worker.Tests.Online; public sealed class JwtClaimsTests { // Builds a fake JWT (header.payload.signature) carrying the given JSON payload. internal static string MakeToken(string payloadJson) { static string B64Url(string s) => Convert.ToBase64String(Encoding.UTF8.GetBytes(s)) .TrimEnd('=').Replace('+', '-').Replace('/', '_'); return $"{B64Url("{\"alg\":\"RS256\"}")}.{B64Url(payloadJson)}.sig"; } [Fact] public void GetSubject_ReturnsSub() { var token = MakeToken("{\"sub\":\"user-123\",\"email\":\"a@b.c\"}"); Assert.Equal("user-123", JwtClaims.GetSubject(token)); } [Fact] public void GetSubject_Null_WhenNoSub() { var token = MakeToken("{\"email\":\"a@b.c\"}"); Assert.Null(JwtClaims.GetSubject(token)); } [Theory] [InlineData(null)] [InlineData("")] [InlineData("not-a-jwt")] [InlineData("opaque.token")] public void GetSubject_Null_ForUnparseableInput(string? token) { Assert.Null(JwtClaims.GetSubject(token)); } }