using Flyshot.Server.Host.Middleware; using Microsoft.AspNetCore.Http; using Microsoft.Extensions.Logging; namespace Flyshot.Server.IntegrationTests; /// /// HTTP 请求响应日志中间件测试。 /// public sealed class RequestResponseLoggingMiddlewareTests { /// /// 高频状态快照路径命中忽略前缀时,不应写入请求和响应日志。 /// [Fact] public async Task InvokeAsync_WhenPathMatchesIgnoredPrefix_DoesNotWriteRequestResponseLogs() { var logger = new CapturingLogger(); var nextWasCalled = false; var middleware = new RequestResponseLoggingMiddleware( async context => { nextWasCalled = true; context.Response.StatusCode = StatusCodes.Status200OK; await context.Response.WriteAsync("ok"); }, logger); var context = new DefaultHttpContext(); context.Request.Method = HttpMethods.Get; context.Request.Path = "/api/status/snapshot/current"; context.Response.Body = new MemoryStream(); await middleware.InvokeAsync(context); Assert.True(nextWasCalled); Assert.Empty(logger.Entries); } /// /// 捕获中间件写出的日志条目,避免测试依赖真实 NLog 目标。 /// private sealed class CapturingLogger : ILogger { /// /// 已捕获的日志条目。 /// public List Entries { get; } = new(); /// public IDisposable? BeginScope(TState state) where TState : notnull { return null; } /// public bool IsEnabled(LogLevel logLevel) { return true; } /// public void Log( LogLevel logLevel, EventId eventId, TState state, Exception? exception, Func formatter) { Entries.Add(new LogEntry(logLevel, formatter(state, exception))); } } /// /// 测试用日志条目。 /// /// 日志级别。 /// 格式化后的日志消息。 private sealed record LogEntry(LogLevel Level, string Message); }