Skip to content

Commit 094f99c

Browse files
authored
Fix event returned IStreamChannel not triggering events due to not being watched (#149)
1 parent 2772c46 commit 094f99c

5 files changed

Lines changed: 163 additions & 15 deletions

File tree

Assets/Plugins/StreamChat/Core/State/Caches/ICacheExt.cs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,14 @@ public static StreamChannel TryCreateOrUpdate(this ICache cache, ChannelResponse
2121
=> dto == null
2222
? null
2323
: cache.Channels.CreateOrUpdate<StreamChannel, ChannelResponseInternalDTO>(dto, out _);
24+
25+
public static StreamChannel TryCreateOrUpdate(this ICache cache, ChannelResponseInternalDTO dto, out bool wasCreated)
26+
{
27+
wasCreated = false;
28+
return dto == null
29+
? null
30+
: cache.Channels.CreateOrUpdate<StreamChannel, ChannelResponseInternalDTO>(dto, out wasCreated);
31+
}
2432

2533
public static StreamChannel TryCreateOrUpdate(this ICache cache, ChannelStateResponseFieldsInternalDTO dto)
2634
=> dto == null

Assets/Plugins/StreamChat/Core/StreamChatClient.cs

Lines changed: 100 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -864,45 +864,135 @@ private void OnMarkReadNotification(NotificationMarkReadEventInternalDTO eventDt
864864

865865
private void OnAddedToChannelNotification(NotificationAddedToChannelEventInternalDTO eventDto)
866866
{
867-
var channel = _cache.TryCreateOrUpdate(eventDto.Channel);
867+
var channel = _cache.TryCreateOrUpdate(eventDto.Channel, out var wasCreated);
868868
var member = _cache.TryCreateOrUpdate(eventDto.Member);
869869
_cache.TryCreateOrUpdate(eventDto.Member.User);
870+
871+
if (!wasCreated)
872+
{
873+
AddedToChannelAsMember?.Invoke(channel, member);
874+
return;
875+
}
870876

871-
AddedToChannelAsMember?.Invoke(channel, member);
877+
// Watch channel, otherwise WS events won't be received
878+
GetOrCreateChannelWithIdAsync(channel.Type, channel.Id).ContinueWith(t =>
879+
{
880+
if (t.IsFaulted)
881+
{
882+
_logs.Error($"Failed to watch channel with type: {channel.Type} & id: {channel.Id} " +
883+
$"before triggering the {nameof(AddedToChannelAsMember)} event. Inspect the following exception.");
884+
_logs.Exception(t.Exception);
885+
return;
886+
}
887+
888+
AddedToChannelAsMember?.Invoke(channel, member);
889+
});
872890
}
873891

874892
private void OnRemovedFromChannelNotification(
875893
NotificationRemovedFromChannelEventInternalDTO eventDto)
876894
{
877-
var channel = _cache.TryCreateOrUpdate(eventDto.Channel);
895+
var channel = _cache.TryCreateOrUpdate(eventDto.Channel, out var wasCreated);
878896
var member = _cache.TryCreateOrUpdate(eventDto.Member);
879897
_cache.TryCreateOrUpdate(eventDto.Member.User);
880898

881-
RemovedFromChannelAsMember?.Invoke(channel, member);
899+
if (!wasCreated)
900+
{
901+
RemovedFromChannelAsMember?.Invoke(channel, member);
902+
return;
903+
}
904+
905+
// Watch channel, otherwise WS events won't be received
906+
GetOrCreateChannelWithIdAsync(channel.Type, channel.Id).ContinueWith(t =>
907+
{
908+
if (t.IsFaulted)
909+
{
910+
_logs.Error($"Failed to watch channel with type: {channel.Type} & id: {channel.Id} " +
911+
$"before triggering the {nameof(RemovedFromChannelAsMember)} event. Inspect the following exception.");
912+
_logs.Exception(t.Exception);
913+
return;
914+
}
915+
916+
RemovedFromChannelAsMember?.Invoke(channel, member);
917+
});
882918
}
883919

884920
private void OnInvitedNotification(NotificationInvitedEventInternalDTO eventDto)
885921
{
886-
var channel = _cache.TryCreateOrUpdate(eventDto.Channel);
922+
var channel = _cache.TryCreateOrUpdate(eventDto.Channel, out var wasCreated);
887923
var user = _cache.TryCreateOrUpdate(eventDto.User);
924+
925+
if (!wasCreated)
926+
{
927+
ChannelInviteReceived?.Invoke(channel, user);
928+
return;
929+
}
930+
931+
// Watch channel, otherwise WS events won't be received
932+
GetOrCreateChannelWithIdAsync(channel.Type, channel.Id).ContinueWith(t =>
933+
{
934+
if (t.IsFaulted)
935+
{
936+
_logs.Error($"Failed to watch channel with type: {channel.Type} & id: {channel.Id} " +
937+
$"before triggering the {nameof(ChannelInviteReceived)} event. Inspect the following exception.");
938+
_logs.Exception(t.Exception);
939+
return;
940+
}
888941

889-
ChannelInviteReceived?.Invoke(channel, user);
942+
ChannelInviteReceived?.Invoke(channel, user);
943+
});
890944
}
891945

892946
private void OnInviteAcceptedNotification(NotificationInviteAcceptedEventInternalDTO eventDto)
893947
{
894-
var channel = _cache.TryCreateOrUpdate(eventDto.Channel);
948+
var channel = _cache.TryCreateOrUpdate(eventDto.Channel, out var wasCreated);
895949
var user = _cache.TryCreateOrUpdate(eventDto.User);
950+
951+
if (!wasCreated)
952+
{
953+
ChannelInviteAccepted?.Invoke(channel, user);
954+
return;
955+
}
956+
957+
// Watch channel, otherwise WS events won't be received
958+
GetOrCreateChannelWithIdAsync(channel.Type, channel.Id).ContinueWith(t =>
959+
{
960+
if (t.IsFaulted)
961+
{
962+
_logs.Error($"Failed to watch channel with type: {channel.Type} & id: {channel.Id} " +
963+
$"before triggering the {nameof(ChannelInviteAccepted)} event. Inspect the following exception.");
964+
_logs.Exception(t.Exception);
965+
return;
966+
}
896967

897-
ChannelInviteAccepted?.Invoke(channel, user);
968+
ChannelInviteAccepted?.Invoke(channel, user);
969+
});
898970
}
899971

900972
private void OnInviteRejectedNotification(NotificationInviteRejectedEventInternalDTO eventDto)
901973
{
902-
var channel = _cache.TryCreateOrUpdate(eventDto.Channel);
974+
var channel = _cache.TryCreateOrUpdate(eventDto.Channel, out var wasCreated);
903975
var user = _cache.TryCreateOrUpdate(eventDto.User);
976+
977+
if (!wasCreated)
978+
{
979+
ChannelInviteRejected?.Invoke(channel, user);
980+
return;
981+
}
982+
983+
// Watch channel, otherwise WS events won't be received
984+
GetOrCreateChannelWithIdAsync(channel.Type, channel.Id).ContinueWith(t =>
985+
{
986+
if (t.IsFaulted)
987+
{
988+
_logs.Error($"Failed to watch channel with type: {channel.Type} & id: {channel.Id} " +
989+
$"before triggering the {nameof(ChannelInviteRejected)} event. Inspect the following exception.");
990+
_logs.Exception(t.Exception);
991+
return;
992+
}
904993

905-
ChannelInviteRejected?.Invoke(channel, user);
994+
ChannelInviteRejected?.Invoke(channel, user);
995+
});
906996
}
907997

908998
private void OnReactionReceived(ReactionNewEventInternalDTO eventDto)

Assets/Plugins/StreamChat/Tests/StatefulClient/BaseStateIntegrationTests.cs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -49,11 +49,12 @@ protected static IEnumerable<AuthCredentials> OtherAdminUsersCredentials
4949
/// <summary>
5050
/// Create temp channel with random id that will be removed in [TearDown]
5151
/// </summary>
52-
protected async Task<IStreamChannel> CreateUniqueTempChannelAsync(string name = null, bool watch = true)
52+
protected async Task<IStreamChannel> CreateUniqueTempChannelAsync(string name = null, bool watch = true, StreamChatClient overrideClient = null)
5353
{
5454
var channelId = "random-channel-11111-" + Guid.NewGuid();
55+
var client = overrideClient ?? Client;
5556

56-
var channelState = await Client.InternalGetOrCreateChannelWithIdAsync(ChannelType.Messaging, channelId, name, watch: watch);
57+
var channelState = await client.InternalGetOrCreateChannelWithIdAsync(ChannelType.Messaging, channelId, name, watch: watch);
5758
_tempChannels.Add(channelState);
5859
return channelState;
5960
}
@@ -89,7 +90,7 @@ protected static IEnumerator ConnectAndExecute(Func<Task> test)
8990
yield return ConnectAndExecuteAsync(test).RunAsIEnumerator(statefulClient: Client);
9091
}
9192

92-
protected Task<IStreamChatClient> GetConnectedOtherClient()
93+
protected Task<StreamChatClient> GetConnectedOtherClient()
9394
=> StreamTestClients.Instance.ConnectOtherStateClientAsync();
9495

9596
//StreamTodo: figure out syntax to wrap call in using that will subscribe to observing an event if possible

Assets/Plugins/StreamChat/Tests/StatefulClient/ChannelMembersTests.cs

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -335,6 +335,53 @@ private async Task When_user_added_to_not_watched_channel_expect_user_receive_ad
335335
Assert.AreEqual(channel, eventChannel);
336336
Assert.AreEqual(Client.LocalUserData.User, eventMember.User);
337337
}
338+
339+
[UnityTest]
340+
public IEnumerator When_user_added_to_not_watched_channel_expect_received_channel_being_watched()
341+
=> ConnectAndExecute(
342+
When_user_added_to_not_watched_channel_expect_received_channel_being_watched_Async);
343+
344+
private async Task When_user_added_to_not_watched_channel_expect_received_channel_being_watched_Async()
345+
{
346+
var otherClient = await GetConnectedOtherClient();
347+
var otherClientChannel = await CreateUniqueTempChannelAsync(watch: false, overrideClient: otherClient);
348+
349+
var receivedEvent = false;
350+
IStreamChannelMember eventMember = null;
351+
IStreamChannel eventChannel = null;
352+
Client.AddedToChannelAsMember += (channel2, member) =>
353+
{
354+
receivedEvent = true;
355+
eventMember = member;
356+
eventChannel = channel2;
357+
};
358+
359+
await otherClientChannel.AddMembersAsync(hideHistory: default, optionalMessage: default, Client.LocalUserData.User);
360+
await WaitWhileFalseAsync(() => receivedEvent);
361+
362+
Assert.IsTrue(receivedEvent);
363+
Assert.IsNotNull(eventChannel);
364+
Assert.IsNotNull(eventMember);
365+
Assert.AreEqual(otherClientChannel.Cid, eventChannel.Cid);
366+
Assert.AreEqual(Client.LocalUserData.User, eventMember.User);
367+
368+
var receivedMessageEvent = false;
369+
var receivedMessage = string.Empty;
370+
IStreamChannel receivedMessageChannel = null;
371+
otherClientChannel.MessageReceived += (messageChannel, message) =>
372+
{
373+
receivedMessageEvent = true;
374+
receivedMessage = message.Text;
375+
receivedMessageChannel = messageChannel;
376+
};
377+
378+
await otherClientChannel.SendNewMessageAsync("Hello");
379+
await WaitWhileFalseAsync(() => receivedEvent);
380+
381+
Assert.IsTrue(receivedMessageEvent);
382+
Assert.AreEqual(otherClientChannel.Cid, receivedMessageChannel.Cid);
383+
Assert.AreEqual(receivedMessage, "Hello");
384+
}
338385

339386
[UnityTest]
340387
public IEnumerator When_user_removed_from_not_watched_channel_expect_user_removed_from_channel_event()
@@ -371,6 +418,7 @@ private async Task When_user_removed_from_not_watched_channel_expect_user_remove
371418
Assert.AreEqual(channel, eventChannel);
372419
Assert.AreEqual(Client.LocalUserData.User, eventMember.User);
373420
}
421+
374422
}
375423
}
376424
#endif

Assets/Plugins/StreamChat/Tests/StreamTestClients.cs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@ public IEnumerator ReconnectLowLevelClientClient()
9696

9797
public Task ConnectStateClientAsync() => ConnectStateClientAsync(StateClient, _stateClientCredentials);
9898

99-
public Task<IStreamChatClient> ConnectOtherStateClientAsync()
99+
public Task<StreamChatClient> ConnectOtherStateClientAsync()
100100
=> ConnectStateClientAsync(OtherStateClient, _otherUserCredentials);
101101

102102
private static StreamTestClients _instance;
@@ -132,7 +132,7 @@ private StreamTestClients()
132132
_otherUsersCredentials = adminData.Skip(3).ToList();
133133
}
134134

135-
private static async Task<IStreamChatClient> ConnectStateClientAsync(IStreamChatClient client,
135+
private static async Task<StreamChatClient> ConnectStateClientAsync(StreamChatClient client,
136136
AuthCredentials credentials)
137137
{
138138
if (client.IsConnected)
@@ -151,6 +151,7 @@ private static async Task<IStreamChatClient> ConnectStateClientAsync(IStreamChat
151151
Debug.Log($"Wait for {nameof(StatefulClient)} to connect user with ID: {credentials.UserId}");
152152
#endif
153153

154+
client.LowLevelClient.Update(0.1f);
154155
await Task.Delay(1);
155156

156157
if (timer.ElapsedMilliseconds > timeout)

0 commit comments

Comments
 (0)