using File.Application.Features.Files.Commands;
using File.Application.Features.Files.Handlers;
using File.Application.Features.Files.Services;
using File.Domain.Entities.FileMeta;
using File.Infrastructure.Persistence;
using File.Infrastructure.Storage;
using FluentAssertions;
using Microsoft.Extensions.Logging.Abstractions;
using Moq;
using Xunit;
namespace BuildFlow.File.Tests;
///
/// ProcessUnverifiedFileSizesCommandHandler 测试。该 Handler 仅将命令委托给
/// FileSizeVerificationProcessor,故覆盖:成功回填大小 + 委托层对越界参数的前置校验。
///
public class ProcessUnverifiedFileSizesCommandHandlerTests
{
private static FileSizeVerificationProcessor NewProcessor(FileDbContext db, Mock s3)
=> new(db, s3.Object, NullLogger.Instance);
private static FileMetaEntity NewUnverifiedFile()
=> new()
{
Name = "f.bin",
S3Key = Guid.NewGuid().ToString(),
S3Bucket = "files",
ContentType = "application/octet-stream",
OwnerId = "user-001",
Size = 0,
SizeVerified = false,
};
[Fact]
public async Task Process_存在未确认文件_经S3回填大小并标记已确认()
{
await using var db = FileTestDb.Create();
var file = NewUnverifiedFile();
db.Files.Add(file);
await db.SaveChangesAsync();
var s3 = new Mock();
s3.Setup(x => x.GetObjectSizeAsync(file.S3Bucket, file.S3Key, It.IsAny()))
.ReturnsAsync(2048L);
var handler = new ProcessUnverifiedFileSizesCommandHandler(NewProcessor(db, s3));
var processed = await handler.Handle(new ProcessUnverifiedFileSizesCommand(100, 4), CancellationToken.None);
processed.Should().Be(1, "应处理 1 个未确认文件");
// file 为同一 DbContext 跟踪的实例,处理器 SaveChangesAsync 后属性已更新
file.Size.Should().Be(2048L);
file.SizeVerified.Should().BeTrue("大小应被标记已确认");
}
[Fact]
public async Task Process_批量大小越界_委托处理器抛出参数范围异常()
{
await using var db = FileTestDb.Create();
var handler = new ProcessUnverifiedFileSizesCommandHandler(NewProcessor(db, new Mock()));
var act = async () => await handler.Handle(
new ProcessUnverifiedFileSizesCommand(0, 4), CancellationToken.None);
// 越界校验在依赖(S3/DB)调用之前,可在 InMemory 直接覆盖。
await act.Should().ThrowAsync();
}
}