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; /// /// 更新 AI 模型处理器测试。成功路径 + 不存在/参数校验异常分支。 /// 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(); 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(); ex.Which.Code.Should().Be(ErrorCode.InvalidParam); } private static RagDbContext CreateDb() { var options = new DbContextOptionsBuilder() .UseInMemoryDatabase($"rag-update-aimodel-{Guid.NewGuid():N}") .Options; var db = new RagDbContext(options); db.SavingChanges += (_, _) => RagTestDb.FillAudit(db); return db; } }