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
}