build-flow.api/tests/BuildFlow.Rag.Tests/KnowledgeBaseCrudTests.cs
xiangning 7ecd78550f test: 补充 platform/rag/file 模块单元测试
- platform: 通知与权限模块 handler 测试
- rag: Chat 端到端、知识库 CRUD、嵌入与查询测试
- file: 文件分享下载与文件夹/桶设置测试
2026-07-09 12:52:00 +08:00

122 lines
4.8 KiB
C#

using BuildFlow.Application.KnowledgeBase.Commands;
using BuildFlow.Application.KnowledgeBase.Handlers;
using BuildFlow.Application.KnowledgeBase.Queries;
using BuildFlow.Domain.Enums;
using BuildFlow.Infrastructure.Persistence;
using BuildFlow.Rag.Tests.Stub;
using BuildFlow.Shared.Domain.Exceptions;
using BuildFlow.Shared.Infrastructure;
using FluentAssertions;
using Microsoft.EntityFrameworkCore;
using Xunit;
namespace BuildFlow.Rag.Tests;
/// <summary>
/// [SOP-RAG] 知识库 CRUD + 列表查询 Handler 全覆盖。
/// 飞书矩阵: rag/KnowledgeBase 子域(Create/Update/Delete/GetList 缺口→全补)
/// </summary>
public class KnowledgeBaseCrudTests
{
private static RagDbContext CreateDb([System.Runtime.CompilerServices.CallerMemberName] string name = "")
{
var userContext = new TestCurrentUserContext();
var options = new DbContextOptionsBuilder<RagDbContext>()
.UseInMemoryDatabase($"rag-kb-{name}-{Guid.NewGuid():N}")
.AddInterceptors(new AuditInterceptor(userContext))
.Options;
return new RagDbContext(options);
}
[Fact]
public async Task Create_Valid_ReturnsDtoWithDefaults()
{
var db = CreateDb();
var handler = new CreateKnowledgeBaseCommandHandler(db);
var result = await handler.Handle(
new CreateKnowledgeBaseCommand("我的知识库", "描述", null, null, null, null, null, null, null, null, null, null, null),
CancellationToken.None);
result.Name.Should().Be("我的知识库");
result.ChunkSize.Should().Be(500, "默认值");
result.RetrievalMode.Should().Be((int)RetrievalMode.Hybrid);
result.VectorWeight.Should().Be(0.7);
(await db.KnowledgeBases.CountAsync()).Should().Be(1);
}
[Fact]
public async Task Create_EmptyName_ThrowsBusiness()
{
var db = CreateDb();
var handler = new CreateKnowledgeBaseCommandHandler(db);
var act = async () => await handler.Handle(
new CreateKnowledgeBaseCommand(" ", null, null, null, null, null, null, null, null, null, null, null, null),
CancellationToken.None);
await act.Should().ThrowAsync<BusinessException>("空名称应拒绝");
}
[Fact]
public async Task Update_Existing_OverwritesFields()
{
var db = CreateDb();
var createHandler = new CreateKnowledgeBaseCommandHandler(db);
var created = await createHandler.Handle(
new CreateKnowledgeBaseCommand("原名", null, null, null, null, null, null, null, null, null, null, null, null),
CancellationToken.None);
var updateHandler = new UpdateKnowledgeBaseCommandHandler(db);
var result = await updateHandler.Handle(
new UpdateKnowledgeBaseCommand(created.Id, "新名", "新描述", 800, 100, null, null, null, null, null, null, 0.8, 0.9),
CancellationToken.None);
result.Name.Should().Be("新名");
result.ChunkSize.Should().Be(800);
result.VectorWeight.Should().Be(0.9);
}
[Fact]
public async Task Update_NonExistent_ThrowsNotFound()
{
var db = CreateDb();
var handler = new UpdateKnowledgeBaseCommandHandler(db);
var act = async () => await handler.Handle(
new UpdateKnowledgeBaseCommand(Guid.NewGuid(), "x", null, null, null, null, null, null, null, null, null, null, null),
CancellationToken.None);
await act.Should().ThrowAsync<NotFoundException>();
}
[Fact]
public async Task Delete_Existing_RemovesSoftly()
{
var db = CreateDb();
var createHandler = new CreateKnowledgeBaseCommandHandler(db);
var created = await createHandler.Handle(
new CreateKnowledgeBaseCommand("待删", null, null, null, null, null, null, null, null, null, null, null, null),
CancellationToken.None);
var deleteHandler = new DeleteKnowledgeBaseCommandHandler(db);
await deleteHandler.Handle(new DeleteKnowledgeBaseCommand(created.Id), CancellationToken.None);
(await db.KnowledgeBases.AnyAsync(k => k.Id == created.Id)).Should().BeFalse("软删后不可见");
}
[Fact]
public async Task GetList_ReturnsAllActive()
{
var db = CreateDb();
var createHandler = new CreateKnowledgeBaseCommandHandler(db);
await createHandler.Handle(new CreateKnowledgeBaseCommand("KB1", null, null, null, null, null, null, null, null, null, null, null, null), CancellationToken.None);
await createHandler.Handle(new CreateKnowledgeBaseCommand("KB2", null, null, null, null, null, null, null, null, null, null, null, null), CancellationToken.None);
var queryHandler = new GetKnowledgeBasesQueryHandler(db);
var result = await queryHandler.Handle(new GetKnowledgeBasesQuery(), CancellationToken.None);
result.Should().HaveCount(2);
}
}