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);
}