Skip to content
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

[JS] Fix crash on sort parameter #150

Merged
merged 3 commits into from
Dec 19, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
4 changes: 2 additions & 2 deletions gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -40,4 +40,4 @@ ENABLE_TARGET_IOS_SIMULATOR_ARM64=true

NPM_PUBLISH_REGISTRY_NPMJS_DRY=true

kotlin.js.ir.output.granularity=whole-program
kotlin.js.ir.output.granularity=whole-program
9 changes: 8 additions & 1 deletion js-chat/.pubnub.yml
Original file line number Diff line number Diff line change
@@ -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:
Expand Down
2 changes: 1 addition & 1 deletion js-chat/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
9 changes: 7 additions & 2 deletions js-chat/tests/channel.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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(
Expand Down Expand Up @@ -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,
})
Expand Down Expand Up @@ -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)
})
})
2 changes: 1 addition & 1 deletion js-chat/tests/message-draft-v2.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
5 changes: 1 addition & 4 deletions pubnub-chat-impl/config/ktlint/baseline.xml
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<baseline version="1.0">
<file name="src/jsMain/kotlin/UserJs.kt">
<error line="46" column="53" source="standard:comment-wrapping" />
</file>
<file name="src/jsMain/kotlin/converters.kt">
<error line="137" column="14" source="standard:function-naming" />
<error line="147" column="14" source="standard:function-naming" />
</file>
</baseline>
16 changes: 8 additions & 8 deletions pubnub-chat-impl/src/jsMain/kotlin/ChatJs.kt
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ class ChatJs internal constructor(val chat: ChatInternal, val config: ChatConfig
fun getUsers(params: PubNub.GetAllMetadataParameters?): Promise<GetUsersResponseJs> {
return chat.getUsers(
params?.filter,
extractSortKeys(params),
extractSortKeys(params?.sort),
params?.limit?.toInt(),
params?.page?.toKmp()
).then { result ->
Expand Down Expand Up @@ -152,12 +152,12 @@ class ChatJs internal constructor(val chat: ChatInternal, val config: ChatConfig
fun getChannels(params: PubNub.GetAllMetadataParameters?): Promise<GetChannelsResponseJs> {
return chat.getChannels(
params?.filter,
extractSortKeys(params),
extractSortKeys(params?.sort),
params?.limit?.toInt(),
params?.page?.toKmp()
).then { result ->
createJsObject<GetChannelsResponseJs> {
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
}
Expand Down Expand Up @@ -316,12 +316,12 @@ class ChatJs internal constructor(val chat: ChatInternal, val config: ChatConfig
}.asPromise()
}

fun markAllMessagesAsRead(params: PubNub.GetMembershipsParametersv2): Promise<MarkAllMessageAsReadResponseJs> {
fun markAllMessagesAsRead(params: PubNub.GetMembershipsParametersv2?): Promise<MarkAllMessageAsReadResponseJs> {
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<MarkAllMessageAsReadResponseJs> {
this.page = MetadataPage(result.next, result.prev)
Expand Down
14 changes: 1 addition & 13 deletions pubnub-chat-impl/src/jsMain/kotlin/UserJs.kt
Original file line number Diff line number Diff line change
@@ -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

Expand Down Expand Up @@ -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<JsMap<String>>()?.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<MembershipsResponseJs> {
this.page = MetadataPage(it.next, it.prev)
Expand Down
20 changes: 15 additions & 5 deletions pubnub-chat-impl/src/jsMain/kotlin/converters.kt
Original file line number Diff line number Diff line change
Expand Up @@ -38,13 +38,23 @@ internal fun GetRestrictionsResponse.toJs() =
}

internal inline fun <reified T : SortField> extractSortKeys(sort: Any?): List<PNSortKey<T>> =
sort?.unsafeCast<JsMap<String>>()?.toMap()?.map {
sort?.unsafeCast<JsMap<String?>>()?.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<T>
} ?: listOf()
Expand Down
2 changes: 1 addition & 1 deletion pubnub-chat-impl/src/jsMain/kotlin/types.kt
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ external interface CreateDirectConversationResultJs {
}

external interface GetChannelsResponseJs {
var users: Array<ChannelJs>
var channels: Array<ChannelJs>
var page: PubNub.MetadataPage
var total: Int
}
Expand Down
Original file line number Diff line number Diff line change
@@ -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<PNSortKey<PNMembershipKey>> = 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<PNSortKey<PNMemberKey>> = 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<PNSortKey<PNKey>> = 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() }
)
}
}
Loading