- 新建 modules/platform 三层模块(Domain/Application/Infrastructure) - 搬入 8 个实体(User/Role/Permission/UserRole/RolePermission/RefreshToken/Menu/Notification) - 新建 PlatformDbContext(连 platform 库)+ 8 个 EF 配置 + SeedData - 搬入 92 个 Application CQRS 文件 + 57 个 Host Endpoints - RagDbContext 瘦身:只留 RAG 专属表(KnowledgeBase/Document/ChatMessage/Conversation) - Handler 注入改为 PlatformDbContext - appsettings 新增 DatabaseNames:Platform - BuildFlowHostModule 注册 PlatformDbContext + DependsOn PlatformApplicationModule - Conversation 实体去掉 User 导航(跨模块不直接引用实体) - rag SeedData 清空(平台种子归 platform) - 暂移除测 platform 功能的 Rag.Tests(后续建 platform 测试项目) - build 0/0
71 lines
2.6 KiB
C#
71 lines
2.6 KiB
C#
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;
|
||
|
||
/// <summary>
|
||
/// 下载文件查询处理器单元测试。覆盖正常下载、空内容两个场景。
|
||
/// Mock IS3StorageService 隔离 S3 外部依赖。
|
||
/// </summary>
|
||
public class DownloadFileQueryHandlerTests
|
||
{
|
||
/// <summary>创建 Mock S3 + Handler。</summary>
|
||
private static (Mock<IS3StorageService> s3Mock, DownloadFileQueryHandler handler) Setup(string content = "hello world")
|
||
{
|
||
var s3Mock = new Mock<IS3StorageService>();
|
||
var stream = new MemoryStream(Encoding.UTF8.GetBytes(content));
|
||
s3Mock
|
||
.Setup(x => x.DownloadFileAsync("test-bucket", "test-key", It.IsAny<CancellationToken>()))
|
||
.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 — 返回的是 S3 原始流,透传给调用方;ContentType 取 S3 返回的真实类型
|
||
result.Should().NotBeNull();
|
||
result.Stream.Should().NotBeNull();
|
||
result.ContentType.Should().Be("text/plain");
|
||
result.FileName.Should().Be("test-key");
|
||
s3Mock.Verify(x => x.DownloadFileAsync("test-bucket", "test-key", It.IsAny<CancellationToken>()), Times.Once);
|
||
}
|
||
|
||
[Fact]
|
||
public async Task DownloadFile_S3ReturnsEmpty_ReturnsReadableEmptyStream()
|
||
{
|
||
// Arrange — DownloadFileQueryHandler 透传 S3 流,空内容对应空 MemoryStream
|
||
var s3Mock = new Mock<IS3StorageService>();
|
||
var emptyStream = new MemoryStream();
|
||
s3Mock
|
||
.Setup(x => x.DownloadFileAsync(It.IsAny<string>(), It.IsAny<string>(), It.IsAny<CancellationToken>()))
|
||
.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 透传空流,长度为 0
|
||
result.Stream.Should().NotBeNull();
|
||
result.Stream.Length.Should().Be(0);
|
||
}
|
||
}
|