using System.Runtime.CompilerServices; using BuildFlow.Shared.Domain.Errors; using BuildFlow.Shared.Domain.Exceptions; using FluentAssertions; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging.Abstractions; using Monitoring.Application.ExternalSystems.Commands; using Monitoring.Application.ExternalSystems.DTOs; using Monitoring.Application.ExternalSystems.Handlers; using Monitoring.Application.Sync; using Monitoring.Application.Sync.Commands; using Monitoring.Application.Sync.Handlers; using Monitoring.Infrastructure.Connectors; using Monitoring.Infrastructure.Persistence; namespace BuildFlow.Monitoring.Tests; /// /// [SOP-MONITORING] Login / TriggerSync 边界分支测试。 /// 这两个 Handler 依赖具体类 SyncProcessor(内部用原生 SQL UPSERT,需真实 PG 才能跑主路径), /// 但其"系统不存在→NotFound"与"非 UHaoZu→不支持"判断在依赖调用之前,可在 InMemory 直接覆盖。 /// 主路径(UHaoZu 登录成功 / 同步成功)需真实 PG 集成测试,见 PostgresMonitoringFixture 模式。 /// public class MonitoringEdgeHandlerTests { private static MonitoringDbContext Db([CallerMemberName] string name = "") => MonitoringTestDb.Create(name); // SyncProcessor 构造需 IServiceProvider + ILogger;此处仅构造实例传入,分支不走到 ExecuteAsync, // 因此空 DI 容器足够(ExecuteAsync 内的 Resolve 不会被触发)。 private static SyncProcessor NewProcessor(MonitoringDbContext db) => new(db, new ServiceCollection().BuildServiceProvider(), NullLogger.Instance); private static UHaoZuLoginService NewLoginService() => new(NullLogger.Instance); private static async Task SeedSystem(MonitoringDbContext db, int systemType = 1) { var created = await new CreateExternalSystemCommandHandler(db).Handle( new CreateExternalSystemCommand("u号租", systemType, "https://x", 60, null), CancellationToken.None); return created.Id; } #region Login [Fact] public async Task Login_NotFound_Throws() { await using var db = Db(); var handler = new LoginExternalSystemCommandHandler(db, NewLoginService(), NewProcessor(db)); var act = async () => await handler.Handle( new LoginExternalSystemCommand(Guid.NewGuid(), "a", "p", "t", "r"), CancellationToken.None); var ex = await act.Should().ThrowAsync(); ex.Which.Code.Should().Be(ErrorCode.NotFound); } [Fact] public async Task Login_NonUHaoZu_ReturnsUnsupported() { await using var db = Db(); var sysId = await SeedSystem(db, systemType: 100); // GenericHttp,非 UHaoZu var handler = new LoginExternalSystemCommandHandler(db, NewLoginService(), NewProcessor(db)); var result = await handler.Handle( new LoginExternalSystemCommand(sysId, "a", "p", "t", "r"), CancellationToken.None); result.Success.Should().BeFalse(); result.Message.Should().Contain("不支持"); } #endregion #region TriggerSync [Fact] public async Task TriggerSync_NotFound_Throws() { await using var db = Db(); var handler = new TriggerSyncCommandHandler(db, NewProcessor(db)); var act = async () => await handler.Handle( new TriggerSyncCommand(Guid.NewGuid()), CancellationToken.None); var ex = await act.Should().ThrowAsync(); ex.Which.Code.Should().Be(ErrorCode.NotFound); } #endregion }