build-flow.api/tests/BuildFlow.Rag.Tests/PreviewDocumentChunksQueryHandlerTests.cs
xiangning 6c110b579a refactor(dependencies): 移除未使用的域实体引用
- 从文件模块的多部分上传处理器中移除未使用的实体引用
- 从即时通讯模块的群组成员处理器中移除未使用的实体引用
- 从RAG模块的AI模型配置中移除未使用的实体引用
- 从监控模块的告警规则配置中移除未使用的实体引用
- 从平台模块的角色权限处理器中移除未使用的实体引用
- 从脚本模块的执行日志实体引用中进行清理
- 从多个基础设施配置类中移除未使用的依赖项
- 优化测试文件中的导入声明,移除不必要的引用
2026-07-19 14:09:47 +08:00

117 lines
4.3 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using BuildFlow.Application.Document.Handlers;
using BuildFlow.Application.Document.Queries;
using BuildFlow.Domain.Entities.Document;
using BuildFlow.Domain.Entities.KnowledgeBase;
using BuildFlow.Domain.Enums;
using BuildFlow.Domain.Interfaces;
using BuildFlow.Infrastructure.AI;
using BuildFlow.Infrastructure.Persistence;
using Microsoft.AspNetCore.Http;
using Microsoft.EntityFrameworkCore;
using Xunit;
namespace BuildFlow.Rag.Tests;
/// <summary>
/// 文档切片预览测试。预览只提取并分块,不生成 embedding,也不写入正式分块表。
/// </summary>
public class PreviewDocumentChunksQueryHandlerTests
{
[Fact]
public async Task HandleShouldReturnDryRunChunksWithoutPersistingDocumentChunks()
{
var options = new DbContextOptionsBuilder<RagDbContext>()
.UseInMemoryDatabase($"rag-preview-{Guid.NewGuid():N}")
.Options;
await using var db = new RagDbContext(options);
var kbId = Guid.NewGuid();
var docId = Guid.NewGuid();
var filePath = Path.Combine(Path.GetTempPath(), $"preview-{Guid.NewGuid():N}.md");
await File.WriteAllTextAsync(filePath, "# 第一章\n\nBuildFlow 文档切片预览。\n\n# 第二章\n\n上传后先看切片,再手动处理向量。");
try
{
await db.KnowledgeBases.AddAsync(new KnowledgeBaseEntity
{
Id = kbId,
Name = "预览知识库",
ChunkSize = 40,
ChunkOverlap = 5,
ChunkingMode = ChunkingModeEnum.Heading,
EmbeddingModel = "text-embedding-embeddinggemma-300m",
Status = KnowledgeBaseStatusEnum.Active,
CreatedBy = "test",
UpdatedBy = "test",
OperatorIP = "127.0.0.1",
});
await db.Documents.AddAsync(new DocumentEntity
{
Id = docId,
KnowledgeBaseId = kbId,
Title = "preview.md",
FileName = "preview.md",
FilePath = filePath,
FileSize = 64,
ContentType = "text/markdown",
Status = DocumentStatusEnum.Pending,
CreatedBy = "test",
UpdatedBy = "test",
OperatorIP = "127.0.0.1",
});
await db.SaveChangesAsync();
var handler = new PreviewDocumentChunksQueryHandler(
db,
new StubDocumentExtractorFactory(),
new TextChunker(),
new StubFileStorageClient(),
new HttpContextAccessor());
var result = await handler.Handle(new PreviewDocumentChunksQuery(docId), CancellationToken.None);
Assert.Equal(2, result.Count);
Assert.All(result, chunk => Assert.False(chunk.HasEmbedding));
Assert.Contains("第一章", result[0].Content);
Assert.Contains("第二章", result[1].Content);
Assert.Equal(0, await db.DocumentChunks.CountAsync());
}
finally
{
File.Delete(filePath);
}
}
private sealed class StubDocumentExtractorFactory : IDocumentExtractorFactory
{
public IDocumentExtractor GetExtractor(string fileNameOrExtension) => new StubDocumentExtractor();
}
private sealed class StubDocumentExtractor : IDocumentExtractor
{
public IReadOnlyCollection<string> SupportedExtensions { get; init; } = ["md"];
public async Task<ExtractedDocument> ExtractAsync(string filePath, CancellationToken ct = default)
{
return new ExtractedDocument
{
Content = await File.ReadAllTextAsync(filePath, ct),
Title = Path.GetFileName(filePath),
};
}
}
private sealed class StubFileStorageClient : IFileStorageClient
{
public Task UploadAsync(
string bucket,
string objectKey,
Stream content,
string contentType,
string? authToken,
CancellationToken ct = default) => Task.CompletedTask;
public Task<Stream> DownloadAsync(string bucket, string objectKey, string? authToken, CancellationToken ct = default)
=> throw new InvalidOperationException("本用例不应下载文件服务对象");
}
}