diff --git a/src/Api/PubnubApi/EventEngine/Presence/Common/PresenceInput.cs b/src/Api/PubnubApi/EventEngine/Presence/Common/PresenceInput.cs index d1023f128..b3d5874c8 100644 --- a/src/Api/PubnubApi/EventEngine/Presence/Common/PresenceInput.cs +++ b/src/Api/PubnubApi/EventEngine/Presence/Common/PresenceInput.cs @@ -5,15 +5,15 @@ namespace PubnubApi.EventEngine.Presence.Common { public class PresenceInput { - public IEnumerable Channels { get; set; } - public IEnumerable ChannelGroups { get; set; } + public IEnumerable Channels { get; set; } = Enumerable.Empty(); + public IEnumerable ChannelGroups { get; set; } = Enumerable.Empty(); public static PresenceInput operator +(PresenceInput a, PresenceInput b) { return new PresenceInput { - Channels = a.Channels?.Union(b.Channels ?? new string[0]), - ChannelGroups = a.ChannelGroups?.Union(b.ChannelGroups ?? new string[0]), + Channels = a.Channels?.Union(b.Channels ?? new string[0]).ToArray(), + ChannelGroups = a.ChannelGroups?.Union(b.ChannelGroups ?? new string[0]).ToArray(), }; } @@ -21,8 +21,8 @@ public class PresenceInput { return new PresenceInput { - Channels = a.Channels?.Except(b.Channels ?? new string[0]), - ChannelGroups = a.ChannelGroups?.Except(b.ChannelGroups ?? new string[0]), + Channels = a.Channels?.Except(b.Channels ?? new string[0]).ToArray(), + ChannelGroups = a.ChannelGroups?.Except(b.ChannelGroups ?? new string[0]).ToArray(), }; } @@ -32,5 +32,15 @@ public bool IsEmpty() || ((Channels != null && Channels.Count() == 0) && (ChannelGroups != null && ChannelGroups.Count() == 0)); } + + public override bool Equals(object obj) + { + if (obj is null || obj is not PresenceInput) + return false; + + var typedObj = obj as PresenceInput; + return this.Channels.SequenceEqual(typedObj.Channels) + && this.ChannelGroups.SequenceEqual(typedObj.ChannelGroups); + } } } diff --git a/src/Api/PubnubApi/EventEngine/Presence/States/APresenceState.cs b/src/Api/PubnubApi/EventEngine/Presence/States/APresenceState.cs index e1b3002f8..473452faf 100644 --- a/src/Api/PubnubApi/EventEngine/Presence/States/APresenceState.cs +++ b/src/Api/PubnubApi/EventEngine/Presence/States/APresenceState.cs @@ -6,7 +6,7 @@ namespace PubnubApi.EventEngine.Presence.States { public abstract class APresenceState : Core.State { - public PresenceInput Input { get; set; } + public PresenceInput Input { get; set; } = new PresenceInput(); // empty by default public bool IsEmpty() { @@ -26,5 +26,13 @@ protected TransitionResult HandleLeftEvent(Events.LeftEvent e) return state.With(new LeaveInvocation(){ Input = e.Input }); } + + public override bool Equals(object obj) + { + if (obj is null || obj is not APresenceState) + return false; + + return this.Input.Equals(((APresenceState)obj).Input); + } } } diff --git a/src/Api/PubnubApi/EventEngine/Presence/States/InactiveState.cs b/src/Api/PubnubApi/EventEngine/Presence/States/InactiveState.cs index 74f4f238c..74aeace2d 100644 --- a/src/Api/PubnubApi/EventEngine/Presence/States/InactiveState.cs +++ b/src/Api/PubnubApi/EventEngine/Presence/States/InactiveState.cs @@ -1,4 +1,5 @@ using PubnubApi.EventEngine.Presence.Invocations; +using PubnubApi.EventEngine.Presence.Common; using PubnubApi.EventEngine.Core; using System.Collections.Generic; using System; @@ -9,7 +10,7 @@ public class InactiveState : APresenceState { public InactiveState() { - Input = null; + Input = new PresenceInput(); } // TODO: Dummy Invocation until we have real ones diff --git a/src/UnitTests/PubnubApi.Tests/EventEngine/Presence/CooldownState.cs b/src/UnitTests/PubnubApi.Tests/EventEngine/Presence/CooldownState.cs index 08fc2de17..05eee4dda 100644 --- a/src/UnitTests/PubnubApi.Tests/EventEngine/Presence/CooldownState.cs +++ b/src/UnitTests/PubnubApi.Tests/EventEngine/Presence/CooldownState.cs @@ -4,6 +4,9 @@ using PubnubApi.EventEngine.Presence.Events; using PubnubApi.EventEngine.Presence.States; using PubnubApi.EventEngine.Presence.Invocations; +using System.Linq; +using System.Security.Policy; +using System.Collections.Generic; namespace PubnubApi.Tests.EventEngine.Presence { @@ -61,7 +64,7 @@ internal class CooldownTransitions new CooldownState(), new DisconnectEvent(), new StoppedState(), - new IEffectInvocation[] { new LeaveInvocation() { Input = new PresenceInput() { Channels = new string[] { } } } } + new IEffectInvocation[] { new LeaveInvocation() { Input = new PresenceInput() } } }, new object[] { new CooldownState(), @@ -72,15 +75,34 @@ internal class CooldownTransitions }; [TestCaseSource(nameof(testCases))] - public void TestTransition(State @sut, IEvent @ev, State @expected, IEffectInvocation[] @_) + public void TestTransition(APresenceState @sut, IEvent @ev, APresenceState @expected, IEffectInvocation[] @_) { - Assert.AreEqual(@expected.GetType(), @sut.Transition(@ev).State.GetType()); + var result = @sut.Transition(@ev); + + if (result == null && expected == null) + { + // it's expected result + return; + } + + Assert.AreEqual(@expected, result.State); } [TestCaseSource(nameof(testCases))] - public void TestReturnedInvocations(State @sut, IEvent @ev, State @_, IEffectInvocation[] @expected) + public void TestReturnedInvocations(State @sut, IEvent @ev, State @_, IEffectInvocation[] @expected) { - CollectionAssert.AreEqual(@expected, @sut.Transition(@ev).Invocations); + var result = @sut.Transition(@ev); + + if (result == null && expected == null) + { + // it's expected result + return; + } + + foreach (var item in result.Invocations) + { + Assert.True(expected.Select(i => i.GetType()).Contains(item.GetType())); + } } } } diff --git a/src/UnitTests/PubnubApi.Tests/EventEngine/Presence/FailedState.cs b/src/UnitTests/PubnubApi.Tests/EventEngine/Presence/FailedState.cs index d1d34bcf9..16ec42caf 100644 --- a/src/UnitTests/PubnubApi.Tests/EventEngine/Presence/FailedState.cs +++ b/src/UnitTests/PubnubApi.Tests/EventEngine/Presence/FailedState.cs @@ -59,7 +59,15 @@ internal class FailedStateTransitions [TestCaseSource(nameof(testCases))] public void TestTransition(State @sut, IEvent @ev, State @expected) { - Assert.AreEqual(@expected.GetType(), @sut.Transition(@ev).State.GetType()); + var result = @sut.Transition(@ev); + + if (result == null && expected == null) + { + // it's expected result + return; + } + + Assert.AreEqual(@expected.GetType(), result.State.GetType()); } } } diff --git a/src/UnitTests/PubnubApi.Tests/EventEngine/Presence/HeartbeatingState.cs b/src/UnitTests/PubnubApi.Tests/EventEngine/Presence/HeartbeatingState.cs index c85875da0..87a550386 100644 --- a/src/UnitTests/PubnubApi.Tests/EventEngine/Presence/HeartbeatingState.cs +++ b/src/UnitTests/PubnubApi.Tests/EventEngine/Presence/HeartbeatingState.cs @@ -59,7 +59,15 @@ internal class HeartbeatingStateTransitions [TestCaseSource(nameof(testCases))] public void TestTransition(State @sut, IEvent @ev, State @expected) { - Assert.AreEqual(@expected.GetType(), @sut.Transition(@ev).State.GetType()); + var result = @sut.Transition(@ev); + + if (result == null && expected == null) + { + // it's expected result + return; + } + + Assert.AreEqual(@expected.GetType(), result.State.GetType()); } } } diff --git a/src/UnitTests/PubnubApi.Tests/EventEngine/Presence/InactiveState.cs b/src/UnitTests/PubnubApi.Tests/EventEngine/Presence/InactiveState.cs index 9d19ddf8a..fdddf15be 100644 --- a/src/UnitTests/PubnubApi.Tests/EventEngine/Presence/InactiveState.cs +++ b/src/UnitTests/PubnubApi.Tests/EventEngine/Presence/InactiveState.cs @@ -54,7 +54,15 @@ internal class InactiveStateTransitions [TestCaseSource(nameof(testCases))] public void TestTransition(State @sut, IEvent @ev, State @expected) { - Assert.AreEqual(@expected.GetType(), @sut.Transition(@ev).State.GetType()); + var result = @sut.Transition(@ev); + + if (result == null && expected == null) + { + // it's expected result + return; + } + + Assert.AreEqual(@expected.GetType(), result.State.GetType()); } } } diff --git a/src/UnitTests/PubnubApi.Tests/EventEngine/Presence/ReconnectingState.cs b/src/UnitTests/PubnubApi.Tests/EventEngine/Presence/ReconnectingState.cs index 9f8549af5..8456b2381 100644 --- a/src/UnitTests/PubnubApi.Tests/EventEngine/Presence/ReconnectingState.cs +++ b/src/UnitTests/PubnubApi.Tests/EventEngine/Presence/ReconnectingState.cs @@ -64,7 +64,15 @@ internal class ReconnectingStateTransitions [TestCaseSource(nameof(testCases))] public void TestTransition(State @sut, IEvent @ev, State @expected) { - Assert.AreEqual(@expected.GetType(), @sut.Transition(@ev).State.GetType()); + var result = @sut.Transition(@ev); + + if (result == null && expected == null) + { + // it's expected result + return; + } + + Assert.AreEqual(@expected.GetType(), result.State.GetType()); } } } diff --git a/src/UnitTests/PubnubApi.Tests/EventEngine/Presence/StoppedState.cs b/src/UnitTests/PubnubApi.Tests/EventEngine/Presence/StoppedState.cs index 32c41e2a8..f94239005 100644 --- a/src/UnitTests/PubnubApi.Tests/EventEngine/Presence/StoppedState.cs +++ b/src/UnitTests/PubnubApi.Tests/EventEngine/Presence/StoppedState.cs @@ -59,7 +59,15 @@ internal class StoppedStateTransitions [TestCaseSource(nameof(testCases))] public void TestTransition(State @sut, IEvent @ev, State @expected) { - Assert.AreEqual(@expected.GetType(), @sut.Transition(@ev).State.GetType()); + var result = @sut.Transition(@ev); + + if (result == null && expected == null) + { + // it's expected result + return; + } + + Assert.AreEqual(@expected.GetType(), result.State.GetType()); } } }