Skip to content

effect invocations used in transitions #206

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 62 commits into from
Feb 19, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
62 commits
Select commit Hold shift + click to select a range
b4bcc30
add events
Xavrax Jan 23, 2024
c405b51
proper formatting
Xavrax Jan 23, 2024
135c876
all states declared
Xavrax Jan 23, 2024
0ac1aba
fields declared
Xavrax Jan 23, 2024
2ffd098
joined event
Xavrax Jan 23, 2024
f61a79a
Left event
Xavrax Jan 23, 2024
3798d8b
left all
Xavrax Jan 23, 2024
13b22a8
fix function param
Xavrax Jan 23, 2024
edc602a
hb fail + transition fix
Xavrax Jan 23, 2024
3f4ce72
give up
Xavrax Jan 23, 2024
3881560
reconnect
Xavrax Jan 23, 2024
d0a12d3
disconnect
Xavrax Jan 23, 2024
d4c7a1e
timeup
Xavrax Jan 23, 2024
384ef5d
missing enumerable
Xavrax Jan 23, 2024
e371d59
building should work
Xavrax Jan 23, 2024
c6bcba0
enumerable instead of list
Xavrax Jan 23, 2024
9cb95a5
add UT
Xavrax Jan 23, 2024
3427cbc
fix/build: missing reference links for effect handlers
mohitpubnub Jan 24, 2024
2581fa9
attempt to fix UWP project build errors
mohitpubnub Jan 24, 2024
56ebedd
fix CSC : error CS1617: error for language version
mohitpubnub Jan 24, 2024
19eb3f3
updating language version to 9 suppoerted by VS2019
mohitpubnub Jan 25, 2024
9b26375
updated LangVersion to `preview`
mohitpubnub Jan 25, 2024
dc61a26
take-4/fix language version. `default`
mohitpubnub Jan 25, 2024
abd4327
take-5: reverting LangVersion to `latest`
mohitpubnub Jan 25, 2024
491d5c9
removed `<LangVersion>` overrides
mohitpubnub Jan 28, 2024
3fff0d1
reverted 491d5c9
mohitpubnub Jan 28, 2024
c6b03c6
Update run-tests.yml
mohitpubnub Feb 1, 2024
39d45f1
take-2
mohitpubnub Feb 1, 2024
eae3301
take-3
mohitpubnub Feb 1, 2024
e03a01f
fix state switches
Xavrax Feb 5, 2024
b223349
wip for ci
Xavrax Feb 5, 2024
8db5621
leave this branch as is - new branch for testing
Xavrax Feb 5, 2024
93f1a14
comment out ee tests
Xavrax Feb 14, 2024
21d6c53
add invocations
Xavrax Feb 14, 2024
4873194
add invocation for leave event
Xavrax Feb 14, 2024
5a447e7
compiling Leave invocation
Xavrax Feb 15, 2024
669da83
left all invocations
Xavrax Feb 15, 2024
f5f56ec
disconnect transitions
Xavrax Feb 15, 2024
942a8b8
Cooldownstate UT
Xavrax Feb 15, 2024
d62df51
sus
Xavrax Feb 15, 2024
1e40309
even more sus
Xavrax Feb 15, 2024
9b4dd94
will it run tests?
Xavrax Feb 15, 2024
d7a9a4a
dotnet my only love
Xavrax Feb 15, 2024
5c0fcb2
dotnet my only love vol 2 - sequel
Xavrax Feb 15, 2024
3bc3f47
Nie przejmuj się bo wszystko będzie dobrze
Xavrax Feb 15, 2024
dce24ff
never gonna give you up
Xavrax Feb 15, 2024
5c5ceed
Electric Avenue
Xavrax Feb 15, 2024
c6c6b89
add presence tests
Xavrax Feb 16, 2024
a126225
will it help?
Xavrax Feb 16, 2024
bf830bd
revert
Xavrax Feb 16, 2024
f3b9d57
windows masterrace here
Xavrax Feb 16, 2024
7c7e2cc
PCL?
Xavrax Feb 16, 2024
d361bc3
fix tests
Xavrax Feb 16, 2024
029d115
fix tests vol 2
Xavrax Feb 16, 2024
d6bfdd2
fixes - tests passing
Xavrax Feb 19, 2024
72366fb
failed state
Xavrax Feb 19, 2024
05229fe
heartbeating works
Xavrax Feb 19, 2024
97f1e9e
inactive
Xavrax Feb 19, 2024
cb31460
reconnecting
Xavrax Feb 19, 2024
b0f11dd
stopped
Xavrax Feb 19, 2024
3d51e99
.net6 should work
Xavrax Feb 19, 2024
ae3277f
Merge branch 'ee/integration' into ee/invocations
Xavrax Feb 19, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions .github/workflows/run-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,12 @@ jobs:
env:
WORKSPACE_PATH: ${{ github.workspace }}
run: .\\.github\\workflows\\release\\build-packages.ps1
- name: Run unit tests
env:
PN_PUB_KEY: ${{ secrets.PN_PUB_KEY }}
PN_SUB_KEY: ${{ secrets.PN_SUB_KEY }}
PN_SEC_KEY: ${{ secrets.PN_SEC_KEY }}
run: dotnet test .\\src\\UnitTests\\PubnubApiPCL.Tests\\PubnubApiPCL.Tests.csproj --verbosity normal --logger trx
- name: Cancel workflow runs for commit on error
if: failure()
uses: ./.github/.release/actions/actions/utils/fast-jobs-failure
Expand Down
22 changes: 16 additions & 6 deletions src/Api/PubnubApi/EventEngine/Presence/Common/PresenceInput.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,24 +5,24 @@ namespace PubnubApi.EventEngine.Presence.Common
{
public class PresenceInput
{
public IEnumerable<string> Channels { get; set; }
public IEnumerable<string> ChannelGroups { get; set; }
public IEnumerable<string> Channels { get; set; } = Enumerable.Empty<string>();
public IEnumerable<string> ChannelGroups { get; set; } = Enumerable.Empty<string>();

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(),
};
}

public static PresenceInput operator -(PresenceInput a, PresenceInput b)
{
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(),
};
}

Expand All @@ -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);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
using PubnubApi.EventEngine.Core;

namespace PubnubApi.EventEngine.Presence.Invocations
{
public class CancelDelayedHeartbeatInvocation : Core.IEffectInvocation {}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
using PubnubApi.EventEngine.Core;

namespace PubnubApi.EventEngine.Presence.Invocations
{
public class CancelWaitInvocation : Core.IEffectInvocation {}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
using PubnubApi.EventEngine.Presence.Common;
using PubnubApi.EventEngine.Core;

namespace PubnubApi.EventEngine.Presence.Invocations
{
public class DelayedHeartbeatInvocation : Core.IEffectInvocation
{
public PresenceInput Input { get; set; }
public int Attempts { get; set; }
public PNStatus Reason { get; set; }
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
using PubnubApi.EventEngine.Presence.Common;
using PubnubApi.EventEngine.Core;

namespace PubnubApi.EventEngine.Presence.Invocations
{
public class HeartbeatInvocation : Core.IEffectInvocation
{
public PresenceInput Input { get; set; }
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
using PubnubApi.EventEngine.Presence.Common;
using PubnubApi.EventEngine.Core;

namespace PubnubApi.EventEngine.Presence.Invocations
{
public class LeaveInvocation : Core.IEffectInvocation
{
public PresenceInput Input { get; set; }
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
using PubnubApi.EventEngine.Core;

namespace PubnubApi.EventEngine.Presence.Invocations
{
public class TerminateEventEngineInvocation : Core.IEffectInvocation {}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
using PubnubApi.EventEngine.Presence.Common;
using PubnubApi.EventEngine.Core;

namespace PubnubApi.EventEngine.Presence.Invocations
{
public class WaitInvocation : Core.IEffectInvocation
{
public PresenceInput Input { get; set; }
}
}
19 changes: 15 additions & 4 deletions src/Api/PubnubApi/EventEngine/Presence/States/APresenceState.cs
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
using PubnubApi.EventEngine.Core;
using PubnubApi.EventEngine.Presence.Common;
using PubnubApi.EventEngine.Presence.Invocations;

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()
{
Expand All @@ -16,12 +17,22 @@ protected TransitionResult HandleLeftEvent(Events.LeftEvent e)
{
var newInput = this.Input - e.Input;

return newInput.IsEmpty()
? (TransitionResult)new InactiveState()
: (TransitionResult)new HeartbeatingState()
State state = newInput.IsEmpty()
? new InactiveState()
: new HeartbeatingState()
{
Input = newInput,
};

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);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,12 @@ public override TransitionResult Transition(IEvent ev)
Input = e.Input != this.Input ? this.Input + e.Input : this.Input,
},
Events.LeftEvent e => HandleLeftEvent(e),
Events.LeftAllEvent e => new InactiveState(),
Events.LeftAllEvent e => new InactiveState()
.With(new LeaveInvocation(){ Input = this.Input }),
Events.DisconnectEvent e => new StoppedState()
{
Input = this.Input,
},
}.With(new LeaveInvocation(){ Input = this.Input }),
Events.TimesUpEvent e => new HeartbeatingState()
{
Input = this.Input,
Expand Down
5 changes: 3 additions & 2 deletions src/Api/PubnubApi/EventEngine/Presence/States/FailedState.cs
Original file line number Diff line number Diff line change
Expand Up @@ -23,15 +23,16 @@ public override TransitionResult Transition(IEvent ev)
Input = e.Input != this.Input ? this.Input + e.Input : this.Input,
},
Events.LeftEvent e => HandleLeftEvent(e),
Events.LeftAllEvent e => new InactiveState(),
Events.LeftAllEvent e => new InactiveState()
.With(new LeaveInvocation(){ Input = this.Input }),
Events.ReconnectEvent e => new HeartbeatingState()
{
Input = this.Input,
},
Events.DisconnectEvent e => new StoppedState()
{
Input = this.Input,
},
}.With(new LeaveInvocation() { Input = this.Input }),
_ => null,
};
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,8 @@ public override TransitionResult Transition(IEvent ev)
Input = e.Input != this.Input ? this.Input + e.Input : this.Input,
},
Events.LeftEvent e => HandleLeftEvent(e),
Events.LeftAllEvent e => new InactiveState(),
Events.LeftAllEvent e => new InactiveState()
.With(new LeaveInvocation(){ Input = this.Input }),
Events.HeartbeatSuccessEvent e => new CooldownState()
{
Input = this.Input,
Expand All @@ -30,7 +31,7 @@ public override TransitionResult Transition(IEvent ev)
Events.DisconnectEvent e => new StoppedState()
{
Input = this.Input,
},
}.With(new LeaveInvocation(){ Input = this.Input }),
_ => null,
};
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using PubnubApi.EventEngine.Presence.Invocations;
using PubnubApi.EventEngine.Presence.Common;
using PubnubApi.EventEngine.Core;
using System.Collections.Generic;
using System;
Expand All @@ -9,7 +10,7 @@ public class InactiveState : APresenceState
{
public InactiveState()
{
Input = null;
Input = new PresenceInput();
}

// TODO: Dummy Invocation until we have real ones
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,8 @@ public override TransitionResult Transition(IEvent ev)
Input = e.Input != this.Input ? this.Input + e.Input : this.Input,
},
Events.LeftEvent e => HandleLeftEvent(e),
Events.LeftAllEvent e => new InactiveState(),
Events.LeftAllEvent e => new InactiveState()
.With(new LeaveInvocation(){ Input = this.Input }),
Events.HeartbeatSuccessEvent e => new CooldownState()
{
Input = this.Input,
Expand All @@ -38,7 +39,7 @@ public override TransitionResult Transition(IEvent ev)
Events.DisconnectEvent e => new StoppedState()
{
Input = this.Input,
},
}.With(new LeaveInvocation(){ Input = this.Input }),
_ => null,
};
}
Expand Down
17 changes: 17 additions & 0 deletions src/Api/PubnubApiPCL/PubnubApiPCL.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -249,6 +249,23 @@
<Compile Include="..\PubnubApi\EventEngine\Subscribe\States\UnsubscribedState.cs" Link="EventEngine\Subscribe\States\UnsubscribedState.cs" />
<Compile Include="..\PubnubApi\EventEngine\Subscribe\SubscribeEventEngine.cs" Link="EventEngine\Subscribe\SubscribeEventEngine.cs" />
<Compile Include="..\PubnubApi\EventEngine\Subscribe\SubscribeEventEngineFactory.cs" Link="EventEngine\Subscribe\SubscribeEventEngineFactory.cs" />
<Compile Include="..\PubnubApi\EventEngine\Presence\Common\PresenceInput.cs" Link="EventEngine\Presence\Common\PresenceInput.cs" />
<Compile Include="..\PubnubApi\EventEngine\Presence\Events\PresenceEvents.cs" Link="EventEngine\Presence\Events\PresenceEvents.cs" />
<Compile Include="..\PubnubApi\EventEngine\Presence\Invocations\CancelDelayedHeartbeatInvocation.cs" Link="EventEngine\Presence\Invocations\CancelDelayedHeartbeatInvocation.cs" />
<Compile Include="..\PubnubApi\EventEngine\Presence\Invocations\CancelWaitInvocation.cs" Link="EventEngine\Presence\Invocations\CancelWaitInvocation.cs" />
<Compile Include="..\PubnubApi\EventEngine\Presence\Invocations\DelayedHeartbeatInvocation.cs" Link="EventEngine\Presence\Invocations\DelayedHeartbeatInvocation.cs" />
<Compile Include="..\PubnubApi\EventEngine\Presence\Invocations\Dummy.cs" Link="EventEngine\Presence\Invocations\Dummy.cs" />
<Compile Include="..\PubnubApi\EventEngine\Presence\Invocations\HearbeatInvocation.cs" Link="EventEngine\Presence\Invocations\HearbeatInvocation.cs" />
<Compile Include="..\PubnubApi\EventEngine\Presence\Invocations\LeaveInvocation.cs" Link="EventEngine\Presence\Invocations\LeaveInvocation.cs" />
<Compile Include="..\PubnubApi\EventEngine\Presence\Invocations\TerminateEventEngineInvocation.cs" Link="EventEngine\Presence\Invocations\TerminateEventEngineInvocation.cs" />
<Compile Include="..\PubnubApi\EventEngine\Presence\Invocations\WaitInvocation.cs" Link="EventEngine\Presence\Invocations\WaitInvocation.cs" />
<Compile Include="..\PubnubApi\EventEngine\Presence\States\APresenceState.cs" Link="EventEngine\Presence\States\APresenceState.cs" />
<Compile Include="..\PubnubApi\EventEngine\Presence\States\CooldownState.cs" Link="EventEngine\Presence\States\CooldownState.cs" />
<Compile Include="..\PubnubApi\EventEngine\Presence\States\FailedState.cs" Link="EventEngine\Presence\States\FailedState.cs" />
<Compile Include="..\PubnubApi\EventEngine\Presence\States\HeartBeatingState.cs" Link="EventEngine\Presence\States\HeartBeatingState.cs" />
<Compile Include="..\PubnubApi\EventEngine\Presence\States\InactiveState.cs" Link="EventEngine\Presence\States\InactiveState.cs" />
<Compile Include="..\PubnubApi\EventEngine\Presence\States\ReconnectingState.cs" Link="EventEngine\Presence\States\ReconnectingState.cs" />
<Compile Include="..\PubnubApi\EventEngine\Presence\States\StoppedState.cs" Link="EventEngine\Presence\States\StoppedState.cs" />
<Compile Include="..\PubnubApi\Helper\MobilePushHelper.cs" Link="Helper\MobilePushHelper.cs" />
<Compile Include="..\PubnubApi\HttpUtility\HttpUtility.cs">
<Link>HttpUtility\HttpUtility.cs</Link>
Expand Down
2 changes: 1 addition & 1 deletion src/UnitTests/PubnubApi.Tests/EncryptionTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -821,4 +821,4 @@ public static string DecodeEncodedNonAsciiCharacters(string value)
});
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,68 +3,104 @@
using PubnubApi.EventEngine.Presence.Common;
using PubnubApi.EventEngine.Presence.Events;
using PubnubApi.EventEngine.Presence.States;
using PubnubApi.EventEngine.Presence.Invocations;
using System.Linq;

namespace PubnubApi.Tests.EventEngine.Presence
{
internal class CooldownTransitions
{
// Test case:
// - Current state
// - Event
// - Expected next state
// - Invocations
private static readonly object[] testCases = {
new object[] {
new CooldownState(),
new JoinedEvent() { Input = new PresenceInput() { Channels = new [] { "a" } } },
new HeartbeatingState() { Input = new PresenceInput() { Channels = new [] { "a" } } },
null
},
new object[] {
new CooldownState() { Input = new PresenceInput() { Channels = new [] { "a", "b" } } },
new LeftEvent() { Input = new PresenceInput() { Channels = new [] { "b" } } },
new HeartbeatingState() { Input = new PresenceInput() { Channels = new [] { "a" } } },
new IEffectInvocation[] { new LeaveInvocation() { Input = new PresenceInput() { Channels = new [] { "b" } } } }
},
new object[] {
new CooldownState() { Input = new PresenceInput() { Channels = new [] { "a" } } },
new LeftEvent() { Input = new PresenceInput() { Channels = new [] { "a" } } },
new InactiveState(),
new IEffectInvocation[] { new LeaveInvocation() { Input = new PresenceInput() { Channels = new [] { "a" } } } }
},
new object[] {
new CooldownState(),
new LeftAllEvent(),
new InactiveState(),
new IEffectInvocation[] { new LeaveInvocation() { Input = new PresenceInput() { Channels = new string[] { } } } }
},
new object[] {
new CooldownState(),
new HeartbeatSuccessEvent(),
null,
null
},
new object[] {
new CooldownState(),
new HeartbeatFailureEvent() { Status = new PNStatus() },
null,
},
new object[] {
new CooldownState(),
new HeartbeatGiveUpEvent() { Status = new PNStatus() { Category = PNStatusCategory.PNCancelledCategory } },
null,
null
},
new object[] {
new CooldownState(),
new ReconnectEvent(),
null,
null
},
new object[] {
new CooldownState(),
new DisconnectEvent(),
new StoppedState(),
new IEffectInvocation[] { new LeaveInvocation() { Input = new PresenceInput() } }
},
new object[] {
new CooldownState(),
new TimesUpEvent(),
new HeartbeatingState(),
null
},
};

[TestCasesSource(nameof(testCases))]
public void TestTransition(State @sut, IEvent @ev, State @expected)
[TestCaseSource(nameof(testCases))]
public void TestTransition(APresenceState @sut, IEvent @ev, APresenceState @expected, IEffectInvocation[] @_)
{
Assert.AreEqual(expected, sut.Transition(ev));
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)
{
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()));
}
}
}
}
Loading