Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
cb02638
add C# SDK dependency, WIP new Chat initialization workflow
jakub-grzesiowski Jul 9, 2025
57a4025
WIP on User entity migration
jakub-grzesiowski Jul 9, 2025
83dbc0a
more WIP on User migration
jakub-grzesiowski Jul 10, 2025
12c19b5
add public channel creation and getting, fix wrong json keys in custo…
jakub-grzesiowski Jul 11, 2025
ef33723
implemented channel creation + associated required memberships logic
jakub-grzesiowski Jul 15, 2025
91cd41e
WIP message receiving
jakub-grzesiowski Jul 22, 2025
fb354f3
fully remove CPP interop logic for easier migration
jakub-grzesiowski Jul 22, 2025
7d3fac2
working basic message sending and receiving, fixed missing status and…
jakub-grzesiowski Jul 24, 2025
39a085f
implement message draft
jakub-grzesiowski Aug 19, 2025
5fd0f98
implement restrictions getting/setting, start conversion to returning…
jakub-grzesiowski Aug 20, 2025
0ccfe86
implement events (both entity update callbacks and chat events)
jakub-grzesiowski Aug 22, 2025
837ec94
update event related tests, implement minor fixes
jakub-grzesiowski Aug 22, 2025
b75341d
implement thread channel and message, adapt more tests
jakub-grzesiowski Aug 26, 2025
9c0d0e9
implement WIP threads + history functionality
jakub-grzesiowski Aug 27, 2025
d2008e3
implement message forwarding and getting current user mentions
jakub-grzesiowski Sep 2, 2025
39dbe78
removed wrappers storage in chat entity, added unread messages functi…
jakub-grzesiowski Sep 4, 2025
dd74100
implement message pinning and unpinning
jakub-grzesiowski Sep 4, 2025
1b289f9
finish implementing all methods
jakub-grzesiowski Sep 11, 2025
221dee0
add .ConfigureAwait(false) to await statements
jakub-grzesiowski Sep 11, 2025
dadee4b
XML comments updates, some missing ChatOperationResult and ConfigureA…
jakub-grzesiowski Sep 11, 2025
68eada0
add more leeway in GetMessage test
jakub-grzesiowski Sep 12, 2025
03d1fdb
Update Unity project with API source code instead of CPP DLL
jakub-grzesiowski Sep 15, 2025
b519b26
test add dependency statement
jakub-grzesiowski Sep 15, 2025
17efbf8
Test add asmdef reference
jakub-grzesiowski Sep 15, 2025
4010997
Remove misleading error logs
jakub-grzesiowski Sep 15, 2025
d312fb1
implement chat PNSDK logic
jakub-grzesiowski Sep 15, 2025
bbf7cf9
Update PNSDK generation, some codacy fixes
jakub-grzesiowski Sep 16, 2025
5ce1b98
Add first batch of code snippets
jakub-grzesiowski Sep 29, 2025
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/release/versions.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,5 +21,11 @@
"clearedPrefix": true,
"clearedSuffix": false
}
],
"unity-chat/PubnubChatUnity/Assets/PubnubChat/Runtime/UnityChatPNSDKSource.cs": [
{
"pattern": "^\\s{2,}private const string build = \"(v?(\\.?\\d+){2,}([a-zA-Z0-9-]+(\\.?\\d+)?)?)\";",
"cleared": true
}
]
}
185 changes: 122 additions & 63 deletions c-sharp-chat/PubnubChatApi/PubNubChatApi.Tests/ChannelTests.cs

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
using System.Diagnostics;
using PubnubApi;
using PubNubChatAPI.Entities;
using PubnubChatApi.Entities.Data;
using Channel = PubNubChatAPI.Entities.Channel;

namespace PubNubChatApi.Tests;

Expand All @@ -14,16 +16,13 @@ public class ChatEventTests
[SetUp]
public async Task Setup()
{
chat = await Chat.CreateInstance(new PubnubChatConfig(
PubnubTestsParameters.PublishKey,
PubnubTestsParameters.SubscribeKey,
"event_tests_user")
);
channel = await chat.CreatePublicConversation("event_tests_channel");
if (!chat.TryGetCurrentUser(out user))
chat = TestUtils.AssertOperation(await Chat.CreateInstance(new PubnubChatConfig(storeUserActivityTimestamp: true), new PNConfiguration(new UserId("event_tests_user"))
{
Assert.Fail();
}
PublishKey = PubnubTestsParameters.PublishKey,
SubscribeKey = PubnubTestsParameters.SubscribeKey
}));
channel = TestUtils.AssertOperation(await chat.CreatePublicConversation("event_tests_channel"));
user = TestUtils.AssertOperation(await chat.GetCurrentUser());
channel.Join();
await Task.Delay(3500);
}
Expand Down
121 changes: 71 additions & 50 deletions c-sharp-chat/PubnubChatApi/PubNubChatApi.Tests/ChatTests.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
using System.Diagnostics;
using PubnubApi;
using PubNubChatAPI.Entities;
using PubnubChatApi.Entities.Data;
using PubnubChatApi.Enums;
using Channel = PubNubChatAPI.Entities.Channel;

namespace PubNubChatApi.Tests;

Expand All @@ -14,15 +16,14 @@ public class ChatTests
[SetUp]
public async Task Setup()
{
chat = await Chat.CreateInstance(new PubnubChatConfig(
PubnubTestsParameters.PublishKey,
PubnubTestsParameters.SubscribeKey,
"chats_tests_user_10_no_calkiem_nowy_2"));
channel = await chat.CreatePublicConversation("chat_tests_channel_2");
if (!chat.TryGetCurrentUser(out currentUser))
chat = TestUtils.AssertOperation(await Chat.CreateInstance(new PubnubChatConfig(storeUserActivityTimestamp: true),
new PNConfiguration(new UserId("chats_tests_user_fresh_3"))
{
Assert.Fail();
}
PublishKey = PubnubTestsParameters.PublishKey,
SubscribeKey = PubnubTestsParameters.SubscribeKey
}));
channel = TestUtils.AssertOperation(await chat.CreatePublicConversation("chat_tests_channel_2"));
currentUser = TestUtils.AssertOperation(await chat.GetCurrentUser());
channel.Join();
await Task.Delay(3500);
}
Expand All @@ -42,15 +43,19 @@ public async Task TestGetCurrentUserMentions()
var messageContent = "wololo";
await channel.SendText(messageContent, new SendTextParams()
{
MentionedUsers = new Dictionary<int, User>()
MentionedUsers = new Dictionary<int, MentionedUser>()
{
{0, currentUser}
{0, new MentionedUser()
{
Id = currentUser.Id,
Name = currentUser.UserName
}}
}
});

await Task.Delay(3000);

var mentions = await chat.GetCurrentUserMentions("99999999999999999", "00000000000000000", 10);
var mentions = TestUtils.AssertOperation(await chat.GetCurrentUserMentions("99999999999999999", "00000000000000000", 10));

Assert.True(mentions != null);
Assert.True(mentions.Mentions.Any(x => x.ChannelId == channel.Id && x.Message.MessageText == messageContent));
Expand All @@ -59,18 +64,22 @@ public async Task TestGetCurrentUserMentions()
[Test]
public async Task TestGetCurrentUser()
{
Assert.True(chat.TryGetCurrentUser(out var currentUser) && currentUser.Id == this.currentUser.Id);
var fetchedCurrentUser = TestUtils.AssertOperation(await chat.GetCurrentUser());
Assert.True(fetchedCurrentUser.Id == currentUser.Id);
}

[Test]
public async Task TestGetEventHistory()
{
await chat.EmitEvent(PubnubChatEventType.Custom, channel.Id, "{\"test\":\"some_nonsense\"}");
var testChannel = TestUtils.AssertOperation(await chat.CreatePublicConversation());
await chat.EmitEvent(PubnubChatEventType.Custom, testChannel.Id, "{\"test\":\"some_nonsense\"}");

await Task.Delay(5000);

var history = await chat.GetEventsHistory(channel.Id, "99999999999999999", "00000000000000000", 50);
Assert.True(history.Events.Any(x => x.ChannelId == channel.Id));
var history = TestUtils.AssertOperation(
await chat.GetEventsHistory(testChannel.Id, "99999999999999999", "00000000000000000", 50));
Assert.True(history.Events.Any(x => x.ChannelId == testChannel.Id && x.Payload.Contains("\"test\":\"some_nonsense\"")),
"Emitted event wasn't present in events history");
}

[Test]
Expand All @@ -92,12 +101,16 @@ public async Task TestGetChannels()
public async Task TestCreateDirectConversation()
{
var convoUser = await chat.GetOrCreateUser("direct_conversation_user");
var directConversation =
await chat.CreateDirectConversation(convoUser, "direct_conversation_test");
Assert.True(directConversation.CreatedChannel is { Id: "direct_conversation_test" });
var id = Guid.NewGuid().ToString();
var directConversation = TestUtils.AssertOperation(
await chat.CreateDirectConversation(convoUser, id));
Assert.True(directConversation.CreatedChannel.Id == id);
Assert.True(directConversation.HostMembership != null && directConversation.HostMembership.UserId == currentUser.Id);
Assert.True(directConversation.InviteesMemberships != null &&
directConversation.InviteesMemberships.First().UserId == convoUser.Id);

//Cleanup
await directConversation.CreatedChannel.Delete();
}

[Test]
Expand All @@ -106,21 +119,25 @@ public async Task TestCreateGroupConversation()
var convoUser1 = await chat.GetOrCreateUser("group_conversation_user_1");
var convoUser2 = await chat.GetOrCreateUser("group_conversation_user_2");
var convoUser3 = await chat.GetOrCreateUser("group_conversation_user_3");
var groupConversation = await
chat.CreateGroupConversation([convoUser1, convoUser2, convoUser3], "group_conversation_test");
Assert.True(groupConversation.CreatedChannel is { Id: "group_conversation_test" });
var id = Guid.NewGuid().ToString();
var groupConversation = TestUtils.AssertOperation(await
chat.CreateGroupConversation([convoUser1, convoUser2, convoUser3], id));
Assert.True(groupConversation.CreatedChannel.Id == id);
Assert.True(groupConversation.HostMembership != null && groupConversation.HostMembership.UserId == currentUser.Id);
Assert.True(groupConversation.InviteesMemberships is { Count: 3 });
Assert.True(groupConversation.InviteesMemberships.Any(x =>
x.UserId == convoUser1.Id && x.ChannelId == "group_conversation_test"));
x.UserId == convoUser1.Id && x.ChannelId == id));

//Cleanup
await groupConversation.CreatedChannel.Delete();
}

[Test]
public async Task TestForwardMessage()
{
var messageForwardReceivedManualEvent = new ManualResetEvent(false);

var forwardingChannel = await chat.CreatePublicConversation("forwarding_channel");
var forwardingChannel = TestUtils.AssertOperation(await chat.CreatePublicConversation("forwarding_channel"));
forwardingChannel.OnMessageReceived += message =>
{
Assert.True(message.MessageText == "message_to_forward");
Expand All @@ -129,7 +146,7 @@ public async Task TestForwardMessage()
forwardingChannel.Join();
await Task.Delay(2500);

channel.OnMessageReceived += async message => { await chat.ForwardMessage(message, forwardingChannel); };
channel.OnMessageReceived += async message => { await message.Forward(forwardingChannel.Id); };

await channel.SendText("message_to_forward");

Expand All @@ -143,7 +160,8 @@ public async Task TestEmitEvent()
var reportManualEvent = new ManualResetEvent(false);
channel.OnCustomEvent += customEvent =>
{
Assert.True(customEvent.Payload == "{\"test\":\"some_nonsense\", \"type\": \"custom\"}");
Assert.True(customEvent.Payload.Contains("test"));
Assert.True(customEvent.Payload.Contains("some_nonsense"));
reportManualEvent.Set();
};
channel.SetListeningForCustomEvents(true);
Expand All @@ -161,40 +179,44 @@ public async Task TestGetUnreadMessagesCounts()

await Task.Delay(3000);

Assert.True((await chat.GetUnreadMessagesCounts(limit: 50)).Any(x => x.Channel.Id == channel.Id && x.Count > 0));
Assert.True(TestUtils.AssertOperation(await chat.GetUnreadMessagesCounts(limit: 50)).Any(x => x.ChannelId == channel.Id && x.Count > 0));
}

[Test]
public async Task TestMarkAllMessagesAsRead()
{
await channel.SendText("wololo");

await Task.Delay(10000);
var markTestChannel = TestUtils.AssertOperation(await chat.CreatePublicConversation());
markTestChannel.Join();

await Task.Delay(3000);

await markTestChannel.SendText("wololo", new SendTextParams(){StoreInHistory = true});

Assert.True((await chat.GetUnreadMessagesCounts()).Any(x => x.Channel.Id == channel.Id && x.Count > 0));
await Task.Delay(3000);

var res = chat.MarkAllMessagesAsRead();
Assert.True(TestUtils.AssertOperation(await chat.GetUnreadMessagesCounts()).Any(x => x.ChannelId == markTestChannel.Id && x.Count > 0));

await Task.Delay(2000);
TestUtils.AssertOperation(await chat.MarkAllMessagesAsRead());

var counts = await chat.GetUnreadMessagesCounts();
await Task.Delay(5000);

var counts = TestUtils.AssertOperation(await chat.GetUnreadMessagesCounts());

Assert.False(counts.Any(x => x.Channel.Id == channel.Id && x.Count > 0));
markTestChannel.Leave();
await markTestChannel.Delete();

Assert.False(counts.Any(x => x.ChannelId == markTestChannel.Id && x.Count > 0));
}

[Test]
public async Task TestReadReceipts()
{
var otherChat = await Chat.CreateInstance(new PubnubChatConfig(
PubnubTestsParameters.PublishKey,
PubnubTestsParameters.SubscribeKey,
"other_chat_user")
);
if (!otherChat.TryGetChannel(channel.Id, out var otherChatChannel))
var otherChat = TestUtils.AssertOperation(await Chat.CreateInstance(new PubnubChatConfig(storeUserActivityTimestamp: true), new PNConfiguration(new UserId("other_chat_user"))
{
Assert.Fail();
return;
}
PublishKey = PubnubTestsParameters.PublishKey,
SubscribeKey = PubnubTestsParameters.SubscribeKey
}));
var otherChatChannel = TestUtils.AssertOperation(await otherChat.GetChannel(channel.Id));

otherChatChannel.Join();
await Task.Delay(2500);
Expand Down Expand Up @@ -225,13 +247,12 @@ public async Task TestCanI()
{
await Task.Delay(4000);

var accessChat = await Chat.CreateInstance(
new PubnubChatConfig(
PubnubTestsParameters.PublishKey,
PubnubTestsParameters.SubscribeKey,
"can_i_test_user",
authKey: "qEF2AkF0Gma8TDFDdHRsGX0AQ3Jlc6VEY2hhbqFyY2FuX2lfdGVzdF9jaGFubmVsEUNncnCgQ3NwY6BDdXNyoER1dWlkoW9jYW5faV90ZXN0X3VzZXIY_0NwYXSlRGNoYW6gQ2dycKBDc3BjoEN1c3KgRHV1aWSgRG1ldGGgRHV1aWRvY2FuX2lfdGVzdF91c2VyQ3NpZ1ggAEijACv1wHoiwQulMhEPFRKEb1C4MYIgfS0wyYMCj3Y="
));
var accessChat = TestUtils.AssertOperation(await Chat.CreateInstance(new PubnubChatConfig(storeUserActivityTimestamp: true), new PNConfiguration(new UserId("can_i_test_user"))
{
PublishKey = PubnubTestsParameters.PublishKey,
SubscribeKey = PubnubTestsParameters.SubscribeKey,
AuthKey = "qEF2AkF0Gma8TDFDdHRsGX0AQ3Jlc6VEY2hhbqFyY2FuX2lfdGVzdF9jaGFubmVsEUNncnCgQ3NwY6BDdXNyoER1dWlkoW9jYW5faV90ZXN0X3VzZXIY_0NwYXSlRGNoYW6gQ2dycKBDc3BjoEN1c3KgRHV1aWSgRG1ldGGgRHV1aWRvY2FuX2lfdGVzdF91c2VyQ3NpZ1ggAEijACv1wHoiwQulMhEPFRKEb1C4MYIgfS0wyYMCj3Y="
}));
Assert.False(await accessChat.ChatAccessManager.CanI(PubnubAccessPermission.Write, PubnubAccessResourceType.Channels,
"can_i_test_channel"));
Assert.True(await accessChat.ChatAccessManager.CanI(PubnubAccessPermission.Read, PubnubAccessResourceType.Channels,
Expand Down
Loading