using ClaudeDo.Worker.Config; using ClaudeDo.Worker.External; using Microsoft.AspNetCore.Http; namespace ClaudeDo.Worker.Tests.External; public sealed class ExternalMcpAuthMiddlewareTests { private const int RemotePort = 47_823; private static async Task<(int Status, bool Passed)> Run(WorkerConfig cfg, RemoteSessionTokenRegistry tokens, int localPort, string? remoteToken = null, string? apiKey = null) { var passed = false; var mw = new ExternalMcpAuthMiddleware(_ => { passed = true; return Task.CompletedTask; }); var ctx = new DefaultHttpContext(); ctx.Connection.LocalPort = localPort; if (remoteToken is not null) ctx.Request.Headers[ExternalMcpAuthMiddleware.RemoteTokenHeader] = remoteToken; if (apiKey is not null) ctx.Request.Headers["X-ClaudeDo-Key"] = apiKey; await mw.InvokeAsync(ctx, cfg, tokens); return (ctx.Response.StatusCode, passed); } private static WorkerConfig Cfg(string? key = null) => new() { ExternalMcpPort = 47_822, RemoteMcpPort = RemotePort, ExternalMcpApiKey = key }; [Fact] public async Task RemotePort_WithoutToken_Is401() { var (status, passed) = await Run(Cfg(), new RemoteSessionTokenRegistry(), RemotePort); Assert.Equal(401, status); Assert.False(passed); } [Fact] public async Task RemotePort_WithUnknownToken_Is401() { var (status, passed) = await Run(Cfg(), new RemoteSessionTokenRegistry(), RemotePort, remoteToken: "nope"); Assert.Equal(401, status); Assert.False(passed); } [Fact] public async Task RemotePort_WithIssuedToken_PassesEvenWhenApiKeyConfigured() { var tokens = new RemoteSessionTokenRegistry(); var token = tokens.Issue(); var (_, passed) = await Run(Cfg(key: "secret"), tokens, RemotePort, remoteToken: token); Assert.True(passed); } [Fact] public async Task RemotePort_ApiKeyAlone_DoesNotPass() { var (status, passed) = await Run(Cfg(key: "secret"), new RemoteSessionTokenRegistry(), RemotePort, apiKey: "secret"); Assert.Equal(401, status); Assert.False(passed); } [Fact] public async Task NormalPort_WithoutKeyConfigured_StillPasses() { var (_, passed) = await Run(Cfg(), new RemoteSessionTokenRegistry(), 47_822); Assert.True(passed); } [Fact] public async Task Issue_ReturnsDistinct64HexTokens() { var tokens = new RemoteSessionTokenRegistry(); var a = tokens.Issue(); var b = tokens.Issue(); Assert.NotEqual(a, b); Assert.Matches("^[0-9A-F]{64}$", a); Assert.True(tokens.IsValid(a)); Assert.False(tokens.IsValid("")); await Task.CompletedTask; } }