using Akka.Actor; using Akka.TestKit; using Shouldly; using Xunit; using ZB.MOM.WW.OtOpcUa.Runtime.ScriptedAlarms; using ZB.MOM.WW.OtOpcUa.Runtime.Tests.Harness; namespace ZB.MOM.WW.OtOpcUa.Runtime.Tests.ScriptedAlarms; public sealed class ScriptedAlarmActorTests : RuntimeActorTestBase { [Fact] public void Full_state_cycle_publishes_StateChanged_to_parent_at_each_transition() { var parent = CreateTestProbe(); // Wrap the alarm actor under our probe as parent so StateChanged lands on the probe. var actor = parent.ChildActorOf(ScriptedAlarmActor.Props("alarm-1")); actor.Tell(new ScriptedAlarmActor.ConditionMet("threshold")); var t1 = parent.ExpectMsg(); t1.State.ShouldBe(ScriptedAlarmActorState.Active); actor.Tell(new ScriptedAlarmActor.AcknowledgeAlarm("joe")); var t2 = parent.ExpectMsg(); t2.State.ShouldBe(ScriptedAlarmActorState.Acknowledged); actor.Tell(new ScriptedAlarmActor.ConditionCleared()); var t3 = parent.ExpectMsg(); t3.State.ShouldBe(ScriptedAlarmActorState.Inactive); } [Fact] public void Duplicate_ConditionMet_in_Active_is_ignored() { var parent = CreateTestProbe(); var actor = parent.ChildActorOf(ScriptedAlarmActor.Props("alarm-1")); actor.Tell(new ScriptedAlarmActor.ConditionMet("first")); parent.ExpectMsg(); actor.Tell(new ScriptedAlarmActor.ConditionMet("second")); parent.ExpectNoMsg(TimeSpan.FromMilliseconds(200)); } }