using System.Text;
using File.Application.Features.Files.Handlers;
using File.Application.Features.Files.Queries;
using File.Infrastructure.Storage;
using FluentAssertions;
using Moq;
using Xunit;
namespace BuildFlow.File.Tests;
///
/// 下载文件查询处理器单元测试。覆盖正常下载、空内容两个场景。
/// Mock IS3StorageService 隔离 S3 外部依赖。
///
public class DownloadFileQueryHandlerTests
{
/// 创建 Mock S3 + Handler。
private static (Mock s3Mock, DownloadFileQueryHandler handler) Setup(string content = "hello world")
{
var s3Mock = new Mock();
var stream = new MemoryStream(Encoding.UTF8.GetBytes(content));
s3Mock
.Setup(x => x.DownloadFileAsync("test-bucket", "test-key", It.IsAny()))
.ReturnsAsync((stream, "text/plain"));
var handler = new DownloadFileQueryHandler(s3Mock.Object);
return (s3Mock, handler);
}
[Fact]
public async Task DownloadFile_WithValidPath_ReturnsContent()
{
// Arrange
var (s3Mock, handler) = Setup("hello world");
// Act
var result = await handler.Handle(
new DownloadFileQuery("test-bucket", "test-key"),
CancellationToken.None);
// Assert
result.Should().NotBeNull();
result.Data.Should().NotBeNullOrEmpty();
result.ContentType.Should().Be("application/octet-stream");
s3Mock.Verify(x => x.DownloadFileAsync("test-bucket", "test-key", It.IsAny()), Times.Once);
}
[Fact]
public async Task DownloadFile_S3ReturnsEmpty_ReturnsEmptyArray()
{
// Arrange — DownloadFileQueryHandler 不校验空内容,直接返回空 byte[]
var s3Mock = new Mock();
var emptyStream = new MemoryStream();
s3Mock
.Setup(x => x.DownloadFileAsync(It.IsAny(), It.IsAny(), It.IsAny()))
.ReturnsAsync((emptyStream, "application/octet-stream"));
var handler = new DownloadFileQueryHandler(s3Mock.Object);
// Act
var result = await handler.Handle(
new DownloadFileQuery("test-bucket", "test-key"),
CancellationToken.None);
// Assert — Handler 不做空内容校验,返回空数组
result.Data.Should().NotBeNull();
result.Data.Should().BeEmpty();
}
}