diff --git a/gradle.properties b/gradle.properties index 8833fa59..43ca26ae 100644 --- a/gradle.properties +++ b/gradle.properties @@ -10,7 +10,7 @@ SONATYPE_HOST=DEFAULT SONATYPE_AUTOMATIC_RELEASE=false GROUP=com.pubnub POM_PACKAGING=jar -VERSION_NAME=0.9.3 +VERSION_NAME=0.9.4 POM_NAME=PubNub Chat SDK POM_DESCRIPTION=This SDK offers a set of handy methods to create your own feature-rich chat or add a chat to your existing application. @@ -40,4 +40,4 @@ ENABLE_TARGET_IOS_SIMULATOR_ARM64=true NPM_PUBLISH_REGISTRY_NPMJS_DRY=true -kotlin.js.ir.output.granularity=whole-program \ No newline at end of file +kotlin.js.ir.output.granularity=whole-program diff --git a/js-chat/.pubnub.yml b/js-chat/.pubnub.yml index 44fcecff..a23645c3 100644 --- a/js-chat/.pubnub.yml +++ b/js-chat/.pubnub.yml @@ -1,11 +1,18 @@ --- name: pubnub-js-chat -version: 0.9.2 +version: 0.9.4 scm: github.com/pubnub/js-chat schema: 1 files: - lib/dist/index.js changelog: + - date: 2024-12-19 + version: 0.9.4 + changes: + - type: bug + text: "Crash when using `sort` parameter in various methods." + - type: bug + text: "GetChannels incorrectly returning an object with `users` property instead of `channels`." - date: 2024-12-12 version: 0.9.2 changes: diff --git a/js-chat/package.json b/js-chat/package.json index abf18f69..5f8eb84a 100644 --- a/js-chat/package.json +++ b/js-chat/package.json @@ -41,7 +41,7 @@ "module": "dist/index.es.js", "types": "dist/index.d.ts", "react-native": "dist/index.es.js", - "version": "0.9.2", + "version": "0.9.4", "name": "@pubnub/chat", "dependencies": { "pubnub": "8.2.8", diff --git a/js-chat/tests/channel.test.ts b/js-chat/tests/channel.test.ts index 3f003447..37e3f51a 100644 --- a/js-chat/tests/channel.test.ts +++ b/js-chat/tests/channel.test.ts @@ -554,7 +554,7 @@ describe("Channel test", () => { expect(foundUser1AmongSuggestedUsers).toBeTruthy() // get members of the channel and verify if user that is member of channel exists in keyset - const membersResponse = await channel.getMembers() + const membersResponse = await channel.getMembers( { "sort": {"uuid.updated": "desc"} }) const members = membersResponse.members expect( onChangeResponse.users.suggestedUsers.some( @@ -1089,7 +1089,7 @@ describe("Channel test", () => { const moderationEventCallback = jest.fn() const removeModerationListener = chat.listenForEvents({ - channel: chat.currentUser.id, + channel: "PUBNUB_INTERNAL_MODERATION." + chat.currentUser.id, type: "moderation", callback: moderationEventCallback, }) @@ -1224,4 +1224,9 @@ describe("Channel test", () => { expect(updatedMembership?.eTag).toBeDefined() removeListener() }) + + test("chat.getChannels with filter returns results", async () => { + let result = await chat.getChannels({ limit: 2, filter: `type == 'public'` }) + expect(result.channels.length).toBe(2) + }) }) diff --git a/js-chat/tests/message-draft-v2.test.ts b/js-chat/tests/message-draft-v2.test.ts index bf255c7e..e2763f3c 100644 --- a/js-chat/tests/message-draft-v2.test.ts +++ b/js-chat/tests/message-draft-v2.test.ts @@ -9,7 +9,7 @@ import { } from "./utils" import { jest } from "@jest/globals" -describe("MessageDraft", function () { +describe("MessageDraft2", function () { jest.retryTimes(2) let chat: Chat let channel: Channel diff --git a/pubnub-chat-impl/config/ktlint/baseline.xml b/pubnub-chat-impl/config/ktlint/baseline.xml index 8aa069b6..43be00e4 100644 --- a/pubnub-chat-impl/config/ktlint/baseline.xml +++ b/pubnub-chat-impl/config/ktlint/baseline.xml @@ -1,9 +1,6 @@ - - - - + diff --git a/pubnub-chat-impl/src/jsMain/kotlin/ChatJs.kt b/pubnub-chat-impl/src/jsMain/kotlin/ChatJs.kt index 07ef2f8f..e477e3cb 100644 --- a/pubnub-chat-impl/src/jsMain/kotlin/ChatJs.kt +++ b/pubnub-chat-impl/src/jsMain/kotlin/ChatJs.kt @@ -122,7 +122,7 @@ class ChatJs internal constructor(val chat: ChatInternal, val config: ChatConfig fun getUsers(params: PubNub.GetAllMetadataParameters?): Promise { return chat.getUsers( params?.filter, - extractSortKeys(params), + extractSortKeys(params?.sort), params?.limit?.toInt(), params?.page?.toKmp() ).then { result -> @@ -152,12 +152,12 @@ class ChatJs internal constructor(val chat: ChatInternal, val config: ChatConfig fun getChannels(params: PubNub.GetAllMetadataParameters?): Promise { return chat.getChannels( params?.filter, - extractSortKeys(params), + extractSortKeys(params?.sort), params?.limit?.toInt(), params?.page?.toKmp() ).then { result -> createJsObject { - this.users = result.channels.map { it.asJs(this@ChatJs) }.toTypedArray() + this.channels = result.channels.map { it.asJs(this@ChatJs) }.toTypedArray() this.page = MetadataPage(result.next, result.prev) this.total = result.total } @@ -316,12 +316,12 @@ class ChatJs internal constructor(val chat: ChatInternal, val config: ChatConfig }.asPromise() } - fun markAllMessagesAsRead(params: PubNub.GetMembershipsParametersv2): Promise { + fun markAllMessagesAsRead(params: PubNub.GetMembershipsParametersv2?): Promise { return chat.markAllMessagesAsRead( - params.limit?.toInt(), - params.page?.toKmp(), - params.filter, - extractSortKeys(params.sort) + params?.limit?.toInt(), + params?.page?.toKmp(), + params?.filter, + extractSortKeys(params?.sort) ).then { result -> createJsObject { this.page = MetadataPage(result.next, result.prev) diff --git a/pubnub-chat-impl/src/jsMain/kotlin/UserJs.kt b/pubnub-chat-impl/src/jsMain/kotlin/UserJs.kt index bf125d55..a80bfd97 100644 --- a/pubnub-chat-impl/src/jsMain/kotlin/UserJs.kt +++ b/pubnub-chat-impl/src/jsMain/kotlin/UserJs.kt @@ -1,14 +1,10 @@ @file:OptIn(ExperimentalJsExport::class, ExperimentalJsStatic::class) -import com.pubnub.api.models.consumer.objects.PNMembershipKey -import com.pubnub.api.models.consumer.objects.PNSortKey import com.pubnub.chat.User import com.pubnub.chat.internal.UserImpl -import com.pubnub.kmp.JsMap import com.pubnub.kmp.createJsObject import com.pubnub.kmp.then import com.pubnub.kmp.toJsMap -import com.pubnub.kmp.toMap import kotlin.js.Promise import kotlin.js.json @@ -73,15 +69,7 @@ class UserJs internal constructor(internal val user: User, internal val chatJs: params?.limit?.toInt(), page.toKmp(), params?.filter, - params?.sort?.unsafeCast>()?.toMap()?.map { - val fieldName = it.key - val direction = it.value - if (direction == "asc") { - PNSortKey.PNAsc(PNMembershipKey.valueOf(fieldName)) - } else { - PNSortKey.PNDesc(PNMembershipKey.valueOf(fieldName)) - } - } ?: listOf() + extractSortKeys(params?.sort) ).then { createJsObject { this.page = MetadataPage(it.next, it.prev) diff --git a/pubnub-chat-impl/src/jsMain/kotlin/converters.kt b/pubnub-chat-impl/src/jsMain/kotlin/converters.kt index a2593495..aa9cd45e 100644 --- a/pubnub-chat-impl/src/jsMain/kotlin/converters.kt +++ b/pubnub-chat-impl/src/jsMain/kotlin/converters.kt @@ -38,13 +38,23 @@ internal fun GetRestrictionsResponse.toJs() = } internal inline fun extractSortKeys(sort: Any?): List> = - sort?.unsafeCast>()?.toMap()?.map { + sort?.unsafeCast>()?.toMap()?.map { val fieldName = it.key - val direction = it.value + val direction = it.value ?: "asc" when (T::class) { - PNMembershipKey::class -> getAscOrDesc(direction, PNMembershipKey.valueOf(fieldName)) - PNKey::class -> getAscOrDesc(direction, PNKey.valueOf(fieldName)) - PNMemberKey::class -> getAscOrDesc(direction, PNMemberKey.valueOf(fieldName)) + PNMembershipKey::class -> getAscOrDesc( + direction, + PNMembershipKey.entries.find { + it.fieldName == fieldName + } ?: error("Unknown sort field: $fieldName") + ) + PNKey::class -> getAscOrDesc(direction, PNKey.entries.find { it.fieldName == fieldName } ?: error("Unknown sort field: $fieldName")) + PNMemberKey::class -> getAscOrDesc( + direction, + PNMemberKey.entries.find { + it.fieldName == fieldName + } ?: error("Unknown sort field: $fieldName") + ) else -> error("Should never happen") } as PNSortKey } ?: listOf() diff --git a/pubnub-chat-impl/src/jsMain/kotlin/types.kt b/pubnub-chat-impl/src/jsMain/kotlin/types.kt index a218cfb0..11ab02e3 100644 --- a/pubnub-chat-impl/src/jsMain/kotlin/types.kt +++ b/pubnub-chat-impl/src/jsMain/kotlin/types.kt @@ -73,7 +73,7 @@ external interface CreateDirectConversationResultJs { } external interface GetChannelsResponseJs { - var users: Array + var channels: Array var page: PubNub.MetadataPage var total: Int } diff --git a/pubnub-chat-impl/src/jsTest/kotlin/com/pubnub/kmp/ConvertersTest.kt b/pubnub-chat-impl/src/jsTest/kotlin/com/pubnub/kmp/ConvertersTest.kt new file mode 100644 index 00000000..cf5c79a7 --- /dev/null +++ b/pubnub-chat-impl/src/jsTest/kotlin/com/pubnub/kmp/ConvertersTest.kt @@ -0,0 +1,67 @@ +package com.pubnub.kmp + +import com.pubnub.api.models.consumer.objects.PNKey +import com.pubnub.api.models.consumer.objects.PNMemberKey +import com.pubnub.api.models.consumer.objects.PNMembershipKey +import com.pubnub.api.models.consumer.objects.PNSortKey +import extractSortKeys +import kotlin.test.Test +import kotlin.test.assertEquals + +class ConvertersTest { + @Test + fun test_extractSortKeys() { + val sortKeys1 = + js( + """{"updated": null, "status": "asc", "type": "desc", "channel.id": null, "channel.name": "asc", "channel.updated": "desc", "channel.status": null, "channel.type": "asc"}""" + ) + val sortKeysResult1: List> = extractSortKeys(sortKeys1) + assertEquals( + listOf( + PNSortKey.PNAsc(PNMembershipKey.UPDATED), + PNSortKey.PNAsc(PNMembershipKey.STATUS), + PNSortKey.PNDesc(PNMembershipKey.TYPE), + PNSortKey.PNAsc(PNMembershipKey.CHANNEL_ID), + PNSortKey.PNAsc(PNMembershipKey.CHANNEL_NAME), + PNSortKey.PNDesc(PNMembershipKey.CHANNEL_UPDATED), + PNSortKey.PNAsc(PNMembershipKey.CHANNEL_STATUS), + PNSortKey.PNAsc(PNMembershipKey.CHANNEL_TYPE), + ).map { it.toSortParameter() }, + sortKeysResult1.map { it.toSortParameter() } + ) + + val sortKeys2 = + js( + """{"updated": null, "status": "asc", "type": "desc", "uuid.id": null, "uuid.name": "asc", "uuid.updated": "desc", "uuid.status": null, "uuid.type": "asc"}""" + ) + val sortKeysResult2: List> = extractSortKeys(sortKeys2) + + assertEquals( + listOf( + PNSortKey.PNAsc(PNMemberKey.UPDATED), + PNSortKey.PNAsc(PNMemberKey.STATUS), + PNSortKey.PNDesc(PNMemberKey.TYPE), + PNSortKey.PNAsc(PNMemberKey.UUID_ID), + PNSortKey.PNAsc(PNMemberKey.UUID_NAME), + PNSortKey.PNDesc(PNMemberKey.UUID_UPDATED), + PNSortKey.PNAsc(PNMemberKey.UUID_STATUS), + PNSortKey.PNAsc(PNMemberKey.UUID_TYPE), + ).map { it.toSortParameter() }, + sortKeysResult2.map { it.toSortParameter() } + ) + + val sortKeys3 = js("""{"updated": null, "status": "asc", "type": "desc", "id": null, "name": "asc"}""") + val sortKeysResult3: List> = extractSortKeys(sortKeys3) + + assertEquals( + listOf( + PNSortKey.PNAsc(PNKey.UPDATED), + PNSortKey.PNAsc(PNKey.STATUS), + PNSortKey.PNDesc(PNKey.TYPE), + PNSortKey.PNAsc(PNKey.ID), + PNSortKey.PNAsc(PNKey.NAME), + ).map { it.toSortParameter() }, + sortKeysResult3.map { it.toSortParameter() } + ) + } +}