- 添加HNSW向量索引提升检索性能 - 实现Hybrid检索模式支持向量和关键词双路召回 - 采用RRF算法融合多路召回结果 - 支持ParentChild分块模式的上下文回填 - 优化向量写入采用批量SQL操作提升性能 - 添加RAG PostgreSQL连接字符串配置 - 更新部署脚本增加PGVector集成测试 - 修正表名引用从document_chunks到b_document_chunks - 重构RagRetrievalService实现完整的检索流程 - 增加重排策略支持关键词和LLM重排 - 修改服务器部署地址配置
137 lines
4.2 KiB
C#
137 lines
4.2 KiB
C#
using BuildFlow.Application.AiModel.Commands;
|
|
using BuildFlow.Application.AiModel.Handlers;
|
|
using BuildFlow.Domain.Entities.AiModel;
|
|
using BuildFlow.Domain.Enums;
|
|
using BuildFlow.Infrastructure.Persistence;
|
|
using BuildFlow.Shared.Domain.Errors;
|
|
using BuildFlow.Shared.Domain.Exceptions;
|
|
using FluentAssertions;
|
|
using Microsoft.EntityFrameworkCore;
|
|
using Xunit;
|
|
|
|
namespace BuildFlow.Rag.Tests;
|
|
|
|
/// <summary>
|
|
/// 更新 AI 模型处理器测试。成功路径 + 不存在/参数校验异常分支。
|
|
/// </summary>
|
|
public class UpdateAiModelCommandHandlerTests
|
|
{
|
|
[Fact]
|
|
public async Task Handle_ExistingModel_UpdatesFields()
|
|
{
|
|
await using var db = CreateDb();
|
|
var modelId = Guid.NewGuid();
|
|
db.AiModels.Add(new AiModelEntity
|
|
{
|
|
Id = modelId,
|
|
Name = "Qwen",
|
|
Provider = ModelProviderEnum.LMStudio,
|
|
ModelId = "qwen2.5",
|
|
BaseUrl = "http://localhost:1234/v1",
|
|
ApiKey = "lm-studio",
|
|
ModelType = ModelTypeEnum.Chat,
|
|
IsActive = true,
|
|
CreatedBy = "test",
|
|
UpdatedBy = "test",
|
|
OperatorIP = "127.0.0.1",
|
|
});
|
|
await db.SaveChangesAsync();
|
|
|
|
var handler = new UpdateAiModelCommandHandler(db);
|
|
var command = new UpdateAiModelCommand(
|
|
modelId,
|
|
"Qwen-Updated",
|
|
(int)ModelProviderEnum.OpenAI,
|
|
"qwen3",
|
|
"https://api.openai.com/v1",
|
|
null,
|
|
(int)ModelTypeEnum.Chat,
|
|
false,
|
|
null,
|
|
null,
|
|
"系统提示词");
|
|
|
|
var result = await handler.Handle(command, CancellationToken.None);
|
|
|
|
result.Name.Should().Be("Qwen-Updated");
|
|
result.ModelId.Should().Be("qwen3");
|
|
result.IsActive.Should().BeFalse();
|
|
var persisted = await db.AiModels.FindAsync(modelId);
|
|
persisted!.Name.Should().Be("Qwen-Updated"); // 前面已断言存在
|
|
// ApiKey 传 null 时保留原值
|
|
persisted.ApiKey.Should().Be("lm-studio");
|
|
}
|
|
|
|
[Fact]
|
|
public async Task Handle_NotFound_ThrowsNotFound()
|
|
{
|
|
await using var db = CreateDb();
|
|
var handler = new UpdateAiModelCommandHandler(db);
|
|
var command = new UpdateAiModelCommand(
|
|
Guid.NewGuid(),
|
|
"Qwen",
|
|
(int)ModelProviderEnum.OpenAI,
|
|
"qwen3",
|
|
"https://api.openai.com/v1",
|
|
null,
|
|
(int)ModelTypeEnum.Chat,
|
|
false,
|
|
null,
|
|
null,
|
|
null);
|
|
|
|
var act = async () => await handler.Handle(command, CancellationToken.None);
|
|
var ex = await act.Should().ThrowAsync<NotFoundException>();
|
|
ex.Which.Code.Should().Be(ErrorCode.NotFound);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task Handle_InvalidProvider_ThrowsInvalidParam()
|
|
{
|
|
await using var db = CreateDb();
|
|
var modelId = Guid.NewGuid();
|
|
db.AiModels.Add(new AiModelEntity
|
|
{
|
|
Id = modelId,
|
|
Name = "Qwen",
|
|
Provider = ModelProviderEnum.LMStudio,
|
|
ModelId = "qwen2.5",
|
|
BaseUrl = "http://localhost:1234/v1",
|
|
ApiKey = "lm-studio",
|
|
ModelType = ModelTypeEnum.Chat,
|
|
CreatedBy = "test",
|
|
UpdatedBy = "test",
|
|
OperatorIP = "127.0.0.1",
|
|
});
|
|
await db.SaveChangesAsync();
|
|
|
|
var handler = new UpdateAiModelCommandHandler(db);
|
|
var command = new UpdateAiModelCommand(
|
|
modelId,
|
|
"Qwen",
|
|
999,
|
|
"qwen3",
|
|
"https://api.openai.com/v1",
|
|
null,
|
|
(int)ModelTypeEnum.Chat,
|
|
false,
|
|
null,
|
|
null,
|
|
null);
|
|
|
|
var act = async () => await handler.Handle(command, CancellationToken.None);
|
|
var ex = await act.Should().ThrowAsync<BusinessException>();
|
|
ex.Which.Code.Should().Be(ErrorCode.InvalidParam);
|
|
}
|
|
|
|
private static RagDbContext CreateDb()
|
|
{
|
|
var options = new DbContextOptionsBuilder<RagDbContext>()
|
|
.UseInMemoryDatabase($"rag-update-aimodel-{Guid.NewGuid():N}")
|
|
.Options;
|
|
var db = new RagDbContext(options);
|
|
db.SavingChanges += (_, _) => RagTestDb.FillAudit(db);
|
|
return db;
|
|
}
|
|
}
|