using Akka.Actor;
using Akka.Cluster.Tools.PublishSubscribe;
using Akka.Hosting;
using Microsoft.AspNetCore.SignalR;
using Microsoft.Extensions.DependencyInjection;
using Moq;
using Shouldly;
using Xunit;
using ZB.MOM.WW.OtOpcUa.AdminUI.Hubs;
using ZB.MOM.WW.OtOpcUa.Commons.Messages.Drivers;
namespace ZB.MOM.WW.OtOpcUa.Host.IntegrationTests;
///
/// E2E integration coverage for the DriverStatusSignalRBridge actor โ snapshot
/// store โ SignalR hub push pipeline.
///
/// Scope note: wiring a full SignalR hub connection from inside an
/// integration test requires an HTTP listener, JWT authentication (the hub has
/// [Authorize]), and a real WebSocket upgrade โ significantly more plumbing
/// than the two-node harness provides out of the box. Full-stack hub connectivity is
/// covered by the Playwright smoke tests in the manual runbook (ยง8.3). This suite
/// instead exercises the bridge actor directly: it spawns a
/// inside the harness actor system, publishes
/// a to the driver-health DPS topic, and
/// asserts that (a) the snapshot store is updated and (b) the mock
/// receives a SendAsync call with
/// the matching DriverInstanceId. This validates the bridge actor's DPS
/// subscription, store write, and hub-push code paths without a live HTTP client.
///
[Trait("Category", "Integration")]
public sealed class DriverStatusHubE2eTests
{
private static CancellationToken Ct => TestContext.Current.CancellationToken;
///
/// Verifies that a published to the
/// driver-health DPS topic is forwarded by
/// to both the (via Upsert) and the
/// mock (via SendAsync).
///
[Fact]
public async Task StatusHub_BridgeActor_ForwardsHealthChanged_ToStoreAndHub()
{
await using var harness = await TwoNodeClusterHarness.StartAsync();
// Resolve the snapshot store that AddAdminUI() wired into DI.
var store = harness.NodeA.Services.GetRequiredService();
// Build a mock IHubContext that captures SendAsync calls.
var sentMessages = new List<(string method, object? arg)>();
var mockClients = new Mock();
var mockClientProxy = new Mock();
mockClients.Setup(c => c.Group(It.IsAny())).Returns(mockClientProxy.Object);
mockClientProxy
.Setup(p => p.SendCoreAsync(It.IsAny(), It.IsAny