using Akka.Actor; using Akka.TestKit.Xunit2; using Microsoft.Extensions.DependencyInjection; using NSubstitute; using ZB.MOM.WW.ScadaBridge.Commons.Entities.Sites; using ZB.MOM.WW.ScadaBridge.Commons.Interfaces.Repositories; using ZB.MOM.WW.ScadaBridge.Commons.Messages.Health; using ZB.MOM.WW.ScadaBridge.Commons.Types; using ZB.MOM.WW.ScadaBridge.Commons.Types.Enums; using ZB.MOM.WW.ScadaBridge.Communication.Actors; using ZB.MOM.WW.ScadaBridge.HealthMonitoring; namespace ZB.MOM.WW.ScadaBridge.Communication.Tests; /// /// Review 01 [Medium]: site→central health reports were fire-and-forget, so a lost /// report was invisible to the sender. These tests pin the new end-to-end ack: /// the site actor replies not-accepted when it has no central ClusterClient, and the /// central actor processes + acks a report it receives. /// public class HealthReportAckTests : TestKit { private readonly CommunicationOptions _options = new(); private static SiteHealthReport SampleReport(long seq, string siteId = "site-a") => new(siteId, seq, DateTimeOffset.UtcNow, new Dictionary(), new Dictionary(), 0, 0, new Dictionary(), 0, 0, 0, 0); [Fact] public void SiteCommunicationActor_NoCentralClient_RepliesNotAccepted() { var dmProbe = CreateTestProbe(); var siteComm = Sys.ActorOf(Props.Create(() => new SiteCommunicationActor("site-a", _options, dmProbe.Ref))); // No RegisterCentralClient sent => _centralClient is null. siteComm.Tell(SampleReport(seq: 7)); var ack = ExpectMsg(); Assert.False(ack.Accepted); Assert.Equal(7, ack.SequenceNumber); Assert.Equal("site-a", ack.SiteId); } [Fact] public void CentralCommunicationActor_OnReport_ProcessesAndAcks() { var mockRepo = Substitute.For(); mockRepo.GetAllSitesAsync(Arg.Any()).Returns(new List()); var aggregator = Substitute.For(); var services = new ServiceCollection(); services.AddScoped(_ => mockRepo); services.AddSingleton(aggregator); var sp = services.BuildServiceProvider(); var siteClientFactory = Substitute.For(); var actor = Sys.ActorOf(Props.Create(() => new CentralCommunicationActor(sp, siteClientFactory))); actor.Tell(SampleReport(seq: 3)); var ack = ExpectMsg(); Assert.True(ack.Accepted); Assert.Equal(3, ack.SequenceNumber); AwaitAssert(() => aggregator.Received().ProcessReport(Arg.Is(r => r.SequenceNumber == 3))); } }