using Microsoft.Extensions.DependencyInjection;
using Shouldly;
using Xunit;
using ZB.MOM.WW.OtOpcUa.Core.Abstractions;
using ZB.MOM.WW.OtOpcUa.Core.Resilience;
using ZB.MOM.WW.OtOpcUa.Host.Drivers;
namespace ZB.MOM.WW.OtOpcUa.Host.IntegrationTests;
///
/// Guards the production DI wiring for the Phase 6.1 resilience dispatch pipeline (arch-review #10 +
/// #13). AddOtOpcUaDriverFactories (the driver-node bootstrap) must bind the real
/// — not the
/// pass-through — and that factory must mint a real per driver instance.
/// This is the DI half of the #10 live gate: without it a refactor could silently drop back to the
/// pass-through and the retry/breaker/bulkhead pipeline would go inert in production (the exact
/// "built-but-never-wired" failure the whole review targets), while every unit test — which defaults to
/// the pass-through — stays green.
///
public sealed class ResilienceInvokerFactoryRegistrationTests
{
[Fact]
public void AddOtOpcUaDriverFactories_binds_the_real_invoker_factory_not_the_pass_through()
{
var services = new ServiceCollection();
services.AddLogging();
services.AddOtOpcUaDriverFactories();
using var sp = services.BuildServiceProvider();
var factory = sp.GetRequiredService();
factory.ShouldBeOfType(
"the driver-node bootstrap must bind the real resilience factory — a NullDriverCapabilityInvokerFactory here means the pipeline is inert in production");
}
[Fact]
public void The_registered_factory_mints_a_real_CapabilityInvoker_per_instance()
{
var services = new ServiceCollection();
services.AddLogging();
services.AddOtOpcUaDriverFactories();
using var sp = services.BuildServiceProvider();
var factory = sp.GetRequiredService();
var invoker = factory.Create("drv-1", "Modbus");
invoker.ShouldBeOfType(
"the real factory must produce a real CapabilityInvoker (not the NullDriverCapabilityInvoker pass-through)");
}
[Fact]
public void The_resilience_singletons_the_factory_depends_on_are_registered()
{
var services = new ServiceCollection();
services.AddLogging();
services.AddOtOpcUaDriverFactories();
using var sp = services.BuildServiceProvider();
// The pipeline builder + status tracker are process singletons the factory closes over — the same
// instance must be shared so pipelines cache + telemetry aggregate across all driver instances.
sp.GetService().ShouldNotBeNull();
sp.GetService().ShouldNotBeNull();
sp.GetRequiredService()
.ShouldBeSameAs(sp.GetRequiredService(), "builder must be a singleton");
}
}