From 386ec65cb2b1edb1aac0eadb201dcc368536b22b Mon Sep 17 00:00:00 2001 From: "marcin.cebo" Date: Mon, 28 Jul 2025 16:49:23 +0200 Subject: [PATCH 1/8] Internal change - enabled EE for JS target in KMP tests --- gradle/libs.versions.toml | 2 +- kotlin-js-store/yarn.lock | 14 +++- .../test/integration/ChannelMetadataTest.kt | 76 +++++++++++++++++++ .../com/pubnub/api/v2/PNConfiguration.js.kt | 4 +- 4 files changed, 89 insertions(+), 7 deletions(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 0d57467757..c1afba0c97 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -12,7 +12,7 @@ ktlint = "12.1.0" dokka = "2.0.0" kotlinx_datetime = "0.6.2" kotlinx_coroutines = "1.10.2" -pubnub_js = "8.6.0" +pubnub_js = "9.8.1" pubnub_swift = "9.3.0" [libraries] diff --git a/kotlin-js-store/yarn.lock b/kotlin-js-store/yarn.lock index f5bf8f6f06..42fd975662 100644 --- a/kotlin-js-store/yarn.lock +++ b/kotlin-js-store/yarn.lock @@ -280,6 +280,11 @@ esutils@^2.0.2: resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.3.tgz#74d2eb4de0b8da1293711910d50775b9b710ef64" integrity sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g== +fflate@^0.8.2: + version "0.8.2" + resolved "https://registry.yarnpkg.com/fflate/-/fflate-0.8.2.tgz#fc8631f5347812ad6028bbe4a2308b2792aa1dea" + integrity sha512-cPJU47OaAoCbg0pBvzsgpTPhmhqI5eJjh/JIu8tPj5q+T7iLvW/JAYUqmE7KOB4R1ZyEhzBaIQpQpardBF5z8A== + fill-range@^7.0.1: version "7.0.1" resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.0.1.tgz#1919a6a7c75fe38b2c7c77e5198535da9acdda40" @@ -666,15 +671,16 @@ proxy-from-env@^1.1.0: resolved "https://registry.yarnpkg.com/proxy-from-env/-/proxy-from-env-1.1.0.tgz#e102f16ca355424865755d2c9e8ea4f24d58c3e2" integrity sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg== -pubnub@8.6.0: - version "8.6.0" - resolved "https://registry.yarnpkg.com/pubnub/-/pubnub-8.6.0.tgz#75524e7ed3653090652d160ce83ac089362a0379" - integrity sha512-LBCglooxiLkNT3ArUOvSJnLKK6/QdeshWY60IWlSQ+SkXlzEjt74wAnX5XriEXKsmza2yw9mFGG6+B5SlczRzA== +pubnub@9.8.1: + version "9.8.1" + resolved "https://registry.yarnpkg.com/pubnub/-/pubnub-9.8.1.tgz#b6b38b23469c18e632403661ef52b83a9058d63d" + integrity sha512-ZeBk6Wn09w1/XpTk388unm1cOZ7da6bZLqoTbh5cMolIwWsEHzvyDnVrk/oE9USxRYr6yeKu/KiLcnj2oG4+fQ== dependencies: agentkeepalive "^3.5.2" buffer "^6.0.3" cbor-js "^0.1.0" cbor-sync "^1.0.4" + fflate "^0.8.2" form-data "^4.0.0" lil-uuid "^0.1.1" node-fetch "^2.7.0" diff --git a/pubnub-kotlin/pubnub-kotlin-api/src/commonTest/kotlin/com/pubnub/test/integration/ChannelMetadataTest.kt b/pubnub-kotlin/pubnub-kotlin-api/src/commonTest/kotlin/com/pubnub/test/integration/ChannelMetadataTest.kt index bfb3a2454c..72a41ddd06 100644 --- a/pubnub-kotlin/pubnub-kotlin-api/src/commonTest/kotlin/com/pubnub/test/integration/ChannelMetadataTest.kt +++ b/pubnub-kotlin/pubnub-kotlin-api/src/commonTest/kotlin/com/pubnub/test/integration/ChannelMetadataTest.kt @@ -8,6 +8,7 @@ import com.pubnub.api.models.consumer.pubsub.objects.PNObjectEventResult import com.pubnub.api.models.consumer.pubsub.objects.PNSetChannelMetadataEventMessage import com.pubnub.kmp.PLATFORM import com.pubnub.kmp.createCustomObject +import com.pubnub.kmp.createStatusListener import com.pubnub.kmp.readAllBytes import com.pubnub.kmp.stringToUploadable import com.pubnub.test.BaseIntegrationTest @@ -32,6 +33,81 @@ class ChannelMetadataTest : BaseIntegrationTest() { private val includeCustom = true private val type = randomString() + @Test + fun test_disconnect() = runTest(timeout = 30.seconds) { + val channelName = "myChannel" + + val statusListener = createStatusListener(pubnub) { _, status -> + println("-=received status: $status") + } + + pubnub.test(backgroundScope) { + try { + pubnub.addListener(statusListener) + + val channel = pubnub.channel(channelName) + channel.subscription().subscribe() + + // Wait for next status that should be connection status + val connectStatus = nextStatus() + println("-=connect status received: $connectStatus") + assertEquals(false, connectStatus.error) + assertEquals("PNConnectedCategory", connectStatus.category.toString()) + + pubnub.disconnect() + + // Wait for next status that should be disconnect status + val disconnectStatus = nextStatus() + println("-=disconnect status received: $disconnectStatus") + assertEquals(false, disconnectStatus.error) + assertEquals("PNDisconnectedCategory", disconnectStatus.category.toString()) + } finally { + // Cleanup + pubnub.removeListener(statusListener) + } + } + } + + @Test + fun test_reconnect() = runTest(timeout = 30.seconds) { + val channelName = "myChannel" + + val statusListener = createStatusListener(pubnub) { _, status -> + println("-=received status: $status") + } + + pubnub.test(backgroundScope) { + try { + pubnub.addListener(statusListener) + + val channel = pubnub.channel(channelName) + channel.subscription().subscribe() + + // Wait for next status that should be connection status + val connectStatus = nextStatus() + assertEquals(false, connectStatus.error) + assertEquals("PNConnectedCategory", connectStatus.category.toString()) + + pubnub.disconnect() + + // Wait for next status that should be disconnect status + val disconnectStatus = nextStatus() + assertEquals(false, disconnectStatus.error) + assertEquals("PNDisconnectedCategory", disconnectStatus.category.toString()) + + pubnub.reconnect() + + // Wait for next status that should be PNConnectedCategory status + val reconnectStatus = nextStatus() + assertEquals(false, disconnectStatus.error) + assertEquals("PNConnectedCategory", reconnectStatus.category.toString()) + } finally { + // Cleanup + pubnub.removeListener(statusListener) + } + } + } + @Test fun can_set_metadata() = runTest { // when diff --git a/pubnub-kotlin/pubnub-kotlin-core-api/src/jsMain/kotlin/com/pubnub/api/v2/PNConfiguration.js.kt b/pubnub-kotlin/pubnub-kotlin-core-api/src/jsMain/kotlin/com/pubnub/api/v2/PNConfiguration.js.kt index 4f03cd54d1..0ca0736b9e 100644 --- a/pubnub-kotlin/pubnub-kotlin-core-api/src/jsMain/kotlin/com/pubnub/api/v2/PNConfiguration.js.kt +++ b/pubnub-kotlin/pubnub-kotlin-core-api/src/jsMain/kotlin/com/pubnub/api/v2/PNConfiguration.js.kt @@ -59,7 +59,7 @@ actual fun createPNConfiguration( override val authToken: String? get() = null override val enableEventEngine: Boolean - get() = false + get() = true override val logVerbosity: PNLogVerbosity get() = logVerbosity } @@ -87,7 +87,7 @@ actual fun createPNConfiguration( override val authToken: String? get() = authToken override val enableEventEngine: Boolean - get() = false + get() = true override val logVerbosity: PNLogVerbosity get() = logVerbosity } From 30befc06495bd8b9cad4d147352bba7deaf31182 Mon Sep 17 00:00:00 2001 From: "marcin.cebo" Date: Mon, 28 Jul 2025 17:31:16 +0200 Subject: [PATCH 2/8] Internal change - enabled EE for JS target in KMP tests --- .../test/integration/ChannelMetadataTest.kt | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/pubnub-kotlin/pubnub-kotlin-api/src/commonTest/kotlin/com/pubnub/test/integration/ChannelMetadataTest.kt b/pubnub-kotlin/pubnub-kotlin-api/src/commonTest/kotlin/com/pubnub/test/integration/ChannelMetadataTest.kt index 72a41ddd06..25851ccb5e 100644 --- a/pubnub-kotlin/pubnub-kotlin-api/src/commonTest/kotlin/com/pubnub/test/integration/ChannelMetadataTest.kt +++ b/pubnub-kotlin/pubnub-kotlin-api/src/commonTest/kotlin/com/pubnub/test/integration/ChannelMetadataTest.kt @@ -23,6 +23,10 @@ import kotlin.test.assertNotNull import kotlin.test.assertTrue import kotlin.time.Duration.Companion.seconds +private const val PN_CONNECTED_CATEGORY = "PNConnectedCategory" + +private const val PN_DISCONNECTED_CATEGORY = "PNDisconnectedCategory" + class ChannelMetadataTest : BaseIntegrationTest() { private val channel = "myChannel" + randomString() private val name = randomString() @@ -38,7 +42,6 @@ class ChannelMetadataTest : BaseIntegrationTest() { val channelName = "myChannel" val statusListener = createStatusListener(pubnub) { _, status -> - println("-=received status: $status") } pubnub.test(backgroundScope) { @@ -50,17 +53,15 @@ class ChannelMetadataTest : BaseIntegrationTest() { // Wait for next status that should be connection status val connectStatus = nextStatus() - println("-=connect status received: $connectStatus") assertEquals(false, connectStatus.error) - assertEquals("PNConnectedCategory", connectStatus.category.toString()) + assertEquals(PN_CONNECTED_CATEGORY, connectStatus.category.toString()) pubnub.disconnect() // Wait for next status that should be disconnect status val disconnectStatus = nextStatus() - println("-=disconnect status received: $disconnectStatus") assertEquals(false, disconnectStatus.error) - assertEquals("PNDisconnectedCategory", disconnectStatus.category.toString()) + assertEquals(PN_DISCONNECTED_CATEGORY, disconnectStatus.category.toString()) } finally { // Cleanup pubnub.removeListener(statusListener) @@ -73,7 +74,6 @@ class ChannelMetadataTest : BaseIntegrationTest() { val channelName = "myChannel" val statusListener = createStatusListener(pubnub) { _, status -> - println("-=received status: $status") } pubnub.test(backgroundScope) { @@ -86,21 +86,21 @@ class ChannelMetadataTest : BaseIntegrationTest() { // Wait for next status that should be connection status val connectStatus = nextStatus() assertEquals(false, connectStatus.error) - assertEquals("PNConnectedCategory", connectStatus.category.toString()) + assertEquals(PN_CONNECTED_CATEGORY, connectStatus.category.toString()) pubnub.disconnect() // Wait for next status that should be disconnect status val disconnectStatus = nextStatus() assertEquals(false, disconnectStatus.error) - assertEquals("PNDisconnectedCategory", disconnectStatus.category.toString()) + assertEquals(PN_DISCONNECTED_CATEGORY, disconnectStatus.category.toString()) pubnub.reconnect() // Wait for next status that should be PNConnectedCategory status val reconnectStatus = nextStatus() assertEquals(false, disconnectStatus.error) - assertEquals("PNConnectedCategory", reconnectStatus.category.toString()) + assertEquals(PN_CONNECTED_CATEGORY, reconnectStatus.category.toString()) } finally { // Cleanup pubnub.removeListener(statusListener) From 734d91eeb8c9e9d7ea215ebef341667708152e8c Mon Sep 17 00:00:00 2001 From: "marcin.cebo" Date: Mon, 28 Jul 2025 19:04:31 +0200 Subject: [PATCH 3/8] Internal change - enabled EE for JS target in KMP tests --- .../test/integration/ChannelMetadataTest.kt | 73 +++++++++---- .../docs/accessManager/ParseTokenOther.kt | 4 +- .../docs/accessManager/SetTokenOther.kt | 4 +- .../docs/appContext/GetAllUUIDMetadataMain.kt | 12 +-- .../docs/fileSharing/FileSharingMain.kt | 10 +- .../messageReactions/MessageReactionsMain.kt | 6 +- .../kotlin/com/pubnub/internal/PubNubImpl.kt | 102 +++++++++--------- 7 files changed, 122 insertions(+), 89 deletions(-) diff --git a/pubnub-kotlin/pubnub-kotlin-api/src/commonTest/kotlin/com/pubnub/test/integration/ChannelMetadataTest.kt b/pubnub-kotlin/pubnub-kotlin-api/src/commonTest/kotlin/com/pubnub/test/integration/ChannelMetadataTest.kt index 25851ccb5e..469859175f 100644 --- a/pubnub-kotlin/pubnub-kotlin-api/src/commonTest/kotlin/com/pubnub/test/integration/ChannelMetadataTest.kt +++ b/pubnub-kotlin/pubnub-kotlin-api/src/commonTest/kotlin/com/pubnub/test/integration/ChannelMetadataTest.kt @@ -1,6 +1,8 @@ package com.pubnub.test.integration import com.pubnub.api.PubNubException +import com.pubnub.api.enums.PNStatusCategory +import com.pubnub.api.models.consumer.PNStatus import com.pubnub.api.models.consumer.objects.PNPage import com.pubnub.api.models.consumer.objects.channel.PNChannelMetadata import com.pubnub.api.models.consumer.pubsub.objects.PNDeleteChannelMetadataEventMessage @@ -40,8 +42,12 @@ class ChannelMetadataTest : BaseIntegrationTest() { @Test fun test_disconnect() = runTest(timeout = 30.seconds) { val channelName = "myChannel" + var disconnectStatus: PNStatus? = null val statusListener = createStatusListener(pubnub) { _, status -> + if (status.category == PNStatusCategory.PNDisconnectedCategory) { + disconnectStatus = status + } } pubnub.test(backgroundScope) { @@ -51,17 +57,22 @@ class ChannelMetadataTest : BaseIntegrationTest() { val channel = pubnub.channel(channelName) channel.subscription().subscribe() - // Wait for next status that should be connection status + // Wait for connection status val connectStatus = nextStatus() assertEquals(false, connectStatus.error) assertEquals(PN_CONNECTED_CATEGORY, connectStatus.category.toString()) + // Disconnect and wait for disconnect status pubnub.disconnect() - // Wait for next status that should be disconnect status - val disconnectStatus = nextStatus() - assertEquals(false, disconnectStatus.error) - assertEquals(PN_DISCONNECTED_CATEGORY, disconnectStatus.category.toString()) + // Wait for disconnect status using nextStatus() (from test infrastructure) + val disconnectStatusFromQueue = nextStatus() + assertEquals(false, disconnectStatusFromQueue.error) + assertEquals(PN_DISCONNECTED_CATEGORY, disconnectStatusFromQueue.category.toString()) + + // Verify our listener also captured the disconnect status + assertNotNull(disconnectStatus) + assertEquals(PN_DISCONNECTED_CATEGORY, disconnectStatus!!.category.toString()) } finally { // Cleanup pubnub.removeListener(statusListener) @@ -72,8 +83,24 @@ class ChannelMetadataTest : BaseIntegrationTest() { @Test fun test_reconnect() = runTest(timeout = 30.seconds) { val channelName = "myChannel" + var disconnectStatus: PNStatus? = null + var reconnectStatus: PNStatus? = null val statusListener = createStatusListener(pubnub) { _, status -> + when (status.category) { + PNStatusCategory.PNDisconnectedCategory -> { + disconnectStatus = status + } + PNStatusCategory.PNConnectedCategory -> { + // Only capture reconnect status (not initial connect) + if (disconnectStatus != null) { + reconnectStatus = status + } + } + else -> { + // Ignore other status categories + } + } } pubnub.test(backgroundScope) { @@ -83,24 +110,30 @@ class ChannelMetadataTest : BaseIntegrationTest() { val channel = pubnub.channel(channelName) channel.subscription().subscribe() - // Wait for next status that should be connection status + // Wait for connection status val connectStatus = nextStatus() assertEquals(false, connectStatus.error) assertEquals(PN_CONNECTED_CATEGORY, connectStatus.category.toString()) + // Disconnect and wait for disconnect status pubnub.disconnect() - // Wait for next status that should be disconnect status - val disconnectStatus = nextStatus() - assertEquals(false, disconnectStatus.error) - assertEquals(PN_DISCONNECTED_CATEGORY, disconnectStatus.category.toString()) + val disconnectStatusFromQueue = nextStatus() + assertEquals(false, disconnectStatusFromQueue.error) + assertEquals(PN_DISCONNECTED_CATEGORY, disconnectStatusFromQueue.category.toString()) + // Reconnect and wait for reconnect status pubnub.reconnect() - // Wait for next status that should be PNConnectedCategory status - val reconnectStatus = nextStatus() - assertEquals(false, disconnectStatus.error) - assertEquals(PN_CONNECTED_CATEGORY, reconnectStatus.category.toString()) + val reconnectStatusFromQueue = nextStatus() + assertEquals(false, reconnectStatusFromQueue.error) + assertEquals(PN_CONNECTED_CATEGORY, reconnectStatusFromQueue.category.toString()) + + // Verify our listener captured both statuses + assertNotNull(disconnectStatus) + assertEquals(PN_DISCONNECTED_CATEGORY, disconnectStatus!!.category.toString()) + assertNotNull(reconnectStatus) + assertEquals(PN_CONNECTED_CATEGORY, reconnectStatus!!.category.toString()) } finally { // Cleanup pubnub.removeListener(statusListener) @@ -283,8 +316,9 @@ class ChannelMetadataTest : BaseIntegrationTest() { } @Test - fun can_receive_delete_metadata_event() = runTest { + fun can_receive_delete_metadata_event() = runTest(timeout = 30.seconds) { pubnub.test(backgroundScope) { + // given pubnub.setChannelMetadata( channel, name = name, @@ -300,13 +334,8 @@ class ChannelMetadataTest : BaseIntegrationTest() { pubnub.removeChannelMetadata(channel).await() // then - var result = nextEvent() - if (result.extractedMessage !is PNDeleteChannelMetadataEventMessage) { - result = nextEvent() - } - val message = result.extractedMessage - assertTrue { message is PNDeleteChannelMetadataEventMessage } - message as PNDeleteChannelMetadataEventMessage + val result = nextEvent() + val message = result.extractedMessage as PNDeleteChannelMetadataEventMessage assertEquals(channel, message.channel) } } diff --git a/pubnub-kotlin/pubnub-kotlin-docs/src/main/kotlin/com/pubnub/docs/accessManager/ParseTokenOther.kt b/pubnub-kotlin/pubnub-kotlin-docs/src/main/kotlin/com/pubnub/docs/accessManager/ParseTokenOther.kt index 21d8748761..73f9f6623f 100644 --- a/pubnub-kotlin/pubnub-kotlin-docs/src/main/kotlin/com/pubnub/docs/accessManager/ParseTokenOther.kt +++ b/pubnub-kotlin/pubnub-kotlin-docs/src/main/kotlin/com/pubnub/docs/accessManager/ParseTokenOther.kt @@ -9,7 +9,9 @@ class ParseTokenOther : SnippetBase() { val pubnub = createPubNub() // snippet.parseToken - pubnub.parseToken("qEF2AkF0Gmgi5mVDdHRsGQU5Q3Jlc6VEY2hhbqFnc3BhY2UwMQhDZ3JwoENzcGOgQ3VzcqBEdXVpZKFmdXNlcjAxGCBDcGF0pURjaGFuoWdzcGFjZS4qAUNncnCgQ3NwY6BDdXNyoER1dWlkoWZ1c2VyLioYIERtZXRhoER1dWlkbmF1dGhvcml6ZWRVc2VyQ3NpZ1ggkOSK0vQY5LFE5IHctQ6rGokqHbRH8EopbQRGAbU7Zfo=") + pubnub.parseToken( + "qEF2AkF0Gmgi5mVDdHRsGQU5Q3Jlc6VEY2hhbqFnc3BhY2UwMQhDZ3JwoENzcGOgQ3VzcqBEdXVpZKFmdXNlcjAxGCBDcGF0pURjaGFuoWdzcGFjZS4qAUNncnCgQ3NwY6BDdXNyoER1dWlkoWZ1c2VyLioYIERtZXRhoER1dWlkbmF1dGhvcml6ZWRVc2VyQ3NpZ1ggkOSK0vQY5LFE5IHctQ6rGokqHbRH8EopbQRGAbU7Zfo=" + ) // snippet.end } } diff --git a/pubnub-kotlin/pubnub-kotlin-docs/src/main/kotlin/com/pubnub/docs/accessManager/SetTokenOther.kt b/pubnub-kotlin/pubnub-kotlin-docs/src/main/kotlin/com/pubnub/docs/accessManager/SetTokenOther.kt index b4ebe56214..e3b202d571 100644 --- a/pubnub-kotlin/pubnub-kotlin-docs/src/main/kotlin/com/pubnub/docs/accessManager/SetTokenOther.kt +++ b/pubnub-kotlin/pubnub-kotlin-docs/src/main/kotlin/com/pubnub/docs/accessManager/SetTokenOther.kt @@ -9,7 +9,9 @@ class SetTokenOther : SnippetBase() { val pubnub = createPubNub() // snippet.setToken - pubnub.setToken("qEF2AkF0Gmgi5mVDdHRsGQU5Q3Jlc6VEY2hhbqFnc3BhY2UwMQhDZ3JwoENzcGOgQ3VzcqBEdXVpZKFmdXNlcjAxGCBDcGF0pURjaGFuoWdzcGFjZS4qAUNncnCgQ3NwY6BDdXNyoER1dWlkoWZ1c2VyLioYIERtZXRhoER1dWlkbmF1dGhvcml6ZWRVc2VyQ3NpZ1ggkOSK0vQY5LFE5IHctQ6rGokqHbRH8EopbQRGAbU7Zfo=") + pubnub.setToken( + "qEF2AkF0Gmgi5mVDdHRsGQU5Q3Jlc6VEY2hhbqFnc3BhY2UwMQhDZ3JwoENzcGOgQ3VzcqBEdXVpZKFmdXNlcjAxGCBDcGF0pURjaGFuoWdzcGFjZS4qAUNncnCgQ3NwY6BDdXNyoER1dWlkoWZ1c2VyLioYIERtZXRhoER1dWlkbmF1dGhvcml6ZWRVc2VyQ3NpZ1ggkOSK0vQY5LFE5IHctQ6rGokqHbRH8EopbQRGAbU7Zfo=" + ) // snippet.end } } diff --git a/pubnub-kotlin/pubnub-kotlin-docs/src/main/kotlin/com/pubnub/docs/appContext/GetAllUUIDMetadataMain.kt b/pubnub-kotlin/pubnub-kotlin-docs/src/main/kotlin/com/pubnub/docs/appContext/GetAllUUIDMetadataMain.kt index a907610420..da2eb8de99 100644 --- a/pubnub-kotlin/pubnub-kotlin-docs/src/main/kotlin/com/pubnub/docs/appContext/GetAllUUIDMetadataMain.kt +++ b/pubnub-kotlin/pubnub-kotlin-docs/src/main/kotlin/com/pubnub/docs/appContext/GetAllUUIDMetadataMain.kt @@ -94,8 +94,8 @@ private fun getAllUUIDMetadataBasic(pubnub: PubNub) { println("\n# Getting All UUID Metadata (Basic)") pubnub.getAllUUIDMetadata( - includeCustom = true, // Include custom fields - includeCount = true // Include total count in response + includeCustom = true, // Include custom fields + includeCount = true // Include total count in response ).async { result -> result.onSuccess { response -> println("SUCCESS: Retrieved UUID metadata objects") @@ -134,10 +134,10 @@ private fun getAllUUIDMetadataWithFilter(pubnub: PubNub) { val filter = "custom.role == 'Developer'" pubnub.getAllUUIDMetadata( - filter = filter, // Filter expression - limit = 10, // Maximum number of results - includeCustom = true, // Include custom fields - includeCount = true // Include total count in response + filter = filter, // Filter expression + limit = 10, // Maximum number of results + includeCustom = true, // Include custom fields + includeCount = true // Include total count in response ).async { result -> result.onSuccess { response -> println("SUCCESS: Retrieved filtered UUID metadata objects") diff --git a/pubnub-kotlin/pubnub-kotlin-docs/src/main/kotlin/com/pubnub/docs/fileSharing/FileSharingMain.kt b/pubnub-kotlin/pubnub-kotlin-docs/src/main/kotlin/com/pubnub/docs/fileSharing/FileSharingMain.kt index 7ebbfc727a..2de4432e65 100644 --- a/pubnub-kotlin/pubnub-kotlin-docs/src/main/kotlin/com/pubnub/docs/fileSharing/FileSharingMain.kt +++ b/pubnub-kotlin/pubnub-kotlin-docs/src/main/kotlin/com/pubnub/docs/fileSharing/FileSharingMain.kt @@ -50,15 +50,15 @@ fun main() { // 6. Send the file to PubNub pubnub.sendFile( - channel = "demo-file-channel", // The channel to upload the file to - fileName = "test_document.txt", // The name to give the file when uploaded - inputStream = inputStream, // The file data to upload - message = mapOf( // Optional message to accompany the file + channel = "demo-file-channel", // The channel to upload the file to + fileName = "test_document.txt", // The name to give the file when uploaded + inputStream = inputStream, // The file data to upload + message = mapOf( // Optional message to accompany the file "text" to "Here's a test document!", "type" to "document" ), customMessageType = "file-message", // Optional custom message type - meta = mapOf( // Optional metadata for filtering + meta = mapOf( // Optional metadata for filtering "sender" to "demo-user", "app" to "kotlin-example" ) diff --git a/pubnub-kotlin/pubnub-kotlin-docs/src/main/kotlin/com/pubnub/docs/messageReactions/MessageReactionsMain.kt b/pubnub-kotlin/pubnub-kotlin-docs/src/main/kotlin/com/pubnub/docs/messageReactions/MessageReactionsMain.kt index d5fb10f544..1a585ebbba 100644 --- a/pubnub-kotlin/pubnub-kotlin-docs/src/main/kotlin/com/pubnub/docs/messageReactions/MessageReactionsMain.kt +++ b/pubnub-kotlin/pubnub-kotlin-docs/src/main/kotlin/com/pubnub/docs/messageReactions/MessageReactionsMain.kt @@ -98,9 +98,9 @@ fun addNewMessageAction(pubnub: PubNub, channel: String, messageTimetoken: Long) // Create a message action val messageAction = PNMessageAction( - type = "reaction", // Type of reaction (can be any string) - value = "smiley_face", // Value of reaction (can be any string) - messageTimetoken = messageTimetoken // Timetoken of the message to add the reaction to + type = "reaction", // Type of reaction (can be any string) + value = "smiley_face", // Value of reaction (can be any string) + messageTimetoken = messageTimetoken // Timetoken of the message to add the reaction to ) // Add the message action diff --git a/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/PubNubImpl.kt b/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/PubNubImpl.kt index e2b82721ef..e9aecc6d1b 100644 --- a/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/PubNubImpl.kt +++ b/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/PubNubImpl.kt @@ -723,16 +723,16 @@ open class PubNubImpl( includeCustom: Boolean, ): GetAllChannelMetadata { return GetAllChannelMetadataEndpoint( - pubnub = this, - collectionQueryParameters = + pubnub = this, + collectionQueryParameters = CollectionQueryParameters( - limit = limit, - page = page, - filter = filter, - sort = sort, - includeCount = includeCount, + limit = limit, + page = page, + filter = filter, + sort = sort, + includeCount = includeCount, ), - includeQueryParam = IncludeQueryParam(includeCustom = includeCustom), + includeQueryParam = IncludeQueryParam(includeCustom = includeCustom), ) } @@ -785,13 +785,13 @@ open class PubNubImpl( return GetAllUUIDMetadataEndpoint( pubnub = this, collectionQueryParameters = - CollectionQueryParameters( - limit = limit, - page = page, - filter = filter, - sort = sort, - includeCount = includeCount, - ), + CollectionQueryParameters( + limit = limit, + page = page, + filter = filter, + sort = sort, + includeCount = includeCount, + ), withInclude = IncludeQueryParam(includeCustom = includeCustom), ) } @@ -1166,12 +1166,12 @@ open class PubNubImpl( @Deprecated( replaceWith = - ReplaceWith( - "fetchMessages(channels = channels, page = PNBoundedPage(start = start, end = end," + + ReplaceWith( + "fetchMessages(channels = channels, page = PNBoundedPage(start = start, end = end," + " limit = maximumPerChannel),includeMeta = includeMeta," + " includeMessageActions = includeMessageActions, includeMessageType = includeMessageType)", - "com.pubnub.api.models.consumer.PNBoundedPage", - ), + "com.pubnub.api.models.consumer.PNBoundedPage", + ), level = DeprecationLevel.ERROR, message = "Use fetchMessages(String, PNBoundedPage, Boolean, Boolean, Boolean) instead", ) @@ -1196,10 +1196,10 @@ open class PubNubImpl( @Deprecated( replaceWith = - ReplaceWith( - "getMessageActions(channel = channel, page = PNBoundedPage(start = start, end = end, limit = limit))", - "com.pubnub.api.models.consumer.PNBoundedPage", - ), + ReplaceWith( + "getMessageActions(channel = channel, page = PNBoundedPage(start = start, end = end, limit = limit))", + "com.pubnub.api.models.consumer.PNBoundedPage", + ), level = DeprecationLevel.ERROR, message = "Use getMessageActions(String, PNBoundedPage) instead", ) @@ -1214,11 +1214,11 @@ open class PubNubImpl( @Deprecated( replaceWith = - ReplaceWith( - "setMemberships(channels = channels, uuid = uuid, limit = limit, " + + ReplaceWith( + "setMemberships(channels = channels, uuid = uuid, limit = limit, " + "page = page, filter = filter, sort = sort, includeCount = includeCount, includeCustom = includeCustom," + "includeChannelDetails = includeChannelDetails)", - ), + ), level = DeprecationLevel.ERROR, message = "Use setMemberships instead", ) @@ -1247,11 +1247,11 @@ open class PubNubImpl( @Deprecated( "Use getChannelMembers instead", replaceWith = - ReplaceWith( - "getChannelMembers(channel = channel, limit = limit, page = page, " + + ReplaceWith( + "getChannelMembers(channel = channel, limit = limit, page = page, " + "filter = filter, sort = sort, includeCount = includeCount, " + "includeCustom = includeCustom,includeUUIDDetails = includeUUIDDetails)", - ), + ), level = DeprecationLevel.ERROR, ) override fun getMembers( @@ -1275,14 +1275,14 @@ open class PubNubImpl( ) @Deprecated( - "Use setChannelMembers instead", - replaceWith = + "Use setChannelMembers instead", + replaceWith = ReplaceWith( "setChannelMembers(channel = channel, uuids = uuids, limit = limit, " + - "page = page, filter = filter, sort = sort, includeCount = includeCount," + - " includeCustom = includeCustom,includeUUIDDetails = includeUUIDDetails)", + "page = page, filter = filter, sort = sort, includeCount = includeCount," + + " includeCustom = includeCustom,includeUUIDDetails = includeUUIDDetails)", ), - level = DeprecationLevel.ERROR, + level = DeprecationLevel.ERROR, ) override fun addMembers( channel: String, @@ -1354,11 +1354,11 @@ open class PubNubImpl( @Deprecated( "Use removeChannelMembers instead", replaceWith = - ReplaceWith( - "removeChannelMembers(channel = channel, uuids = uuids, limit = limit, " + + ReplaceWith( + "removeChannelMembers(channel = channel, uuids = uuids, limit = limit, " + "page = page, filter = filter, sort = sort, includeCount = includeCount, " + "includeCustom = includeCustom,includeUUIDDetails = includeUUIDDetails)", - ), + ), level = DeprecationLevel.ERROR, ) override fun removeMembers( @@ -1528,22 +1528,22 @@ open class PubNubImpl( configuration.cryptoModule } return SendFileEndpoint( - channel = channel, - fileName = fileName, - inputStream = inputStream, - message = message, - meta = meta, - ttl = ttl, - shouldStore = shouldStore, - customMessageType = customMessageType, - executorService = + channel = channel, + fileName = fileName, + inputStream = inputStream, + message = message, + meta = meta, + ttl = ttl, + shouldStore = shouldStore, + customMessageType = customMessageType, + executorService = retrofitManager.getTransactionClientExecutorService() ?: Executors.newSingleThreadExecutor(), - fileMessagePublishRetryLimit = configuration.fileMessagePublishRetryLimit, - generateUploadUrlFactory = GenerateUploadUrlEndpoint.Factory(this), - publishFileMessageFactory = PublishFileMessageEndpoint.Factory(this), - sendFileToS3Factory = UploadFileEndpoint.Factory(this), - cryptoModule = cryptoModule, + fileMessagePublishRetryLimit = configuration.fileMessagePublishRetryLimit, + generateUploadUrlFactory = GenerateUploadUrlEndpoint.Factory(this), + publishFileMessageFactory = PublishFileMessageEndpoint.Factory(this), + sendFileToS3Factory = UploadFileEndpoint.Factory(this), + cryptoModule = cryptoModule, ) } From d7a1bc935d35a21e99c6db9c6d623b7930b4e140 Mon Sep 17 00:00:00 2001 From: "marcin.cebo" Date: Tue, 29 Jul 2025 13:47:39 +0200 Subject: [PATCH 4/8] Internal change - enabled EE for JS target in KMP tests --- .../test/integration/ChannelMetadataTest.kt | 17 +++++++---- .../test/integration/UserMetadataTest.kt | 19 ++++++++----- .../com.pubnub.test/BaseIntegrationTest.kt | 28 +++++++++++++++++++ 3 files changed, 51 insertions(+), 13 deletions(-) diff --git a/pubnub-kotlin/pubnub-kotlin-api/src/commonTest/kotlin/com/pubnub/test/integration/ChannelMetadataTest.kt b/pubnub-kotlin/pubnub-kotlin-api/src/commonTest/kotlin/com/pubnub/test/integration/ChannelMetadataTest.kt index 469859175f..f1c2416fe0 100644 --- a/pubnub-kotlin/pubnub-kotlin-api/src/commonTest/kotlin/com/pubnub/test/integration/ChannelMetadataTest.kt +++ b/pubnub-kotlin/pubnub-kotlin-api/src/commonTest/kotlin/com/pubnub/test/integration/ChannelMetadataTest.kt @@ -6,7 +6,6 @@ import com.pubnub.api.models.consumer.PNStatus import com.pubnub.api.models.consumer.objects.PNPage import com.pubnub.api.models.consumer.objects.channel.PNChannelMetadata import com.pubnub.api.models.consumer.pubsub.objects.PNDeleteChannelMetadataEventMessage -import com.pubnub.api.models.consumer.pubsub.objects.PNObjectEventResult import com.pubnub.api.models.consumer.pubsub.objects.PNSetChannelMetadataEventMessage import com.pubnub.kmp.PLATFORM import com.pubnub.kmp.createCustomObject @@ -17,6 +16,7 @@ import com.pubnub.test.BaseIntegrationTest import com.pubnub.test.await import com.pubnub.test.randomString import com.pubnub.test.test +import kotlinx.coroutines.delay import kotlinx.coroutines.test.runTest import kotlin.test.Test import kotlin.test.assertEquals @@ -263,11 +263,14 @@ class ChannelMetadataTest : BaseIntegrationTest() { } @Test - fun can_receive_set_metadata_event() = runTest { + fun can_receive_set_metadata_event() = runTest(timeout = 30.seconds) { pubnub.test(backgroundScope) { // given pubnub.awaitSubscribe(listOf(channel)) + // Wait a bit to ensure subscription is fully established + delay(100) + // when pubnub.setChannelMetadata( channel, @@ -280,9 +283,8 @@ class ChannelMetadataTest : BaseIntegrationTest() { ).await() // then - val result = nextEvent() - val message = result.extractedMessage - message as PNSetChannelMetadataEventMessage + val result = waitForEvent(PNSetChannelMetadataEventMessage::class) + val message = result.extractedMessage as PNSetChannelMetadataEventMessage assertEquals(channel, message.data.id) assertEquals(name, message.data.name?.value) assertEquals(description, message.data.description?.value) @@ -330,11 +332,14 @@ class ChannelMetadataTest : BaseIntegrationTest() { ).await() pubnub.awaitSubscribe(listOf(channel)) + // Wait a bit to ensure subscription is fully established + delay(100) + // when pubnub.removeChannelMetadata(channel).await() // then - val result = nextEvent() + val result = waitForEvent(PNDeleteChannelMetadataEventMessage::class) val message = result.extractedMessage as PNDeleteChannelMetadataEventMessage assertEquals(channel, message.channel) } diff --git a/pubnub-kotlin/pubnub-kotlin-api/src/commonTest/kotlin/com/pubnub/test/integration/UserMetadataTest.kt b/pubnub-kotlin/pubnub-kotlin-api/src/commonTest/kotlin/com/pubnub/test/integration/UserMetadataTest.kt index c0473f7f42..47d4bd459b 100644 --- a/pubnub-kotlin/pubnub-kotlin-api/src/commonTest/kotlin/com/pubnub/test/integration/UserMetadataTest.kt +++ b/pubnub-kotlin/pubnub-kotlin-api/src/commonTest/kotlin/com/pubnub/test/integration/UserMetadataTest.kt @@ -5,13 +5,13 @@ import com.pubnub.api.models.consumer.objects.PNPage import com.pubnub.api.models.consumer.objects.uuid.PNUUIDMetadata import com.pubnub.api.models.consumer.objects.uuid.PNUUIDMetadataArrayResult import com.pubnub.api.models.consumer.pubsub.objects.PNDeleteUUIDMetadataEventMessage -import com.pubnub.api.models.consumer.pubsub.objects.PNObjectEventResult import com.pubnub.api.models.consumer.pubsub.objects.PNSetUUIDMetadataEventMessage import com.pubnub.kmp.createCustomObject import com.pubnub.test.BaseIntegrationTest import com.pubnub.test.await import com.pubnub.test.randomString import com.pubnub.test.test +import kotlinx.coroutines.delay import kotlinx.coroutines.test.runTest import kotlin.test.Test import kotlin.test.assertEquals @@ -114,11 +114,14 @@ class UserMetadataTest : BaseIntegrationTest() { } @Test - fun can_receive_set_metadata_event() = runTest { + fun can_receive_set_metadata_event() = runTest(timeout = 30.seconds) { pubnub.test(backgroundScope) { // given pubnub.awaitSubscribe(listOf(uuid)) + // Wait a bit to ensure subscription is fully established + delay(100) + // when pubnub.setUUIDMetadata( uuid, @@ -132,9 +135,8 @@ class UserMetadataTest : BaseIntegrationTest() { ).await() // then - val result = nextEvent() - val message = result.extractedMessage - message as PNSetUUIDMetadataEventMessage + val result = waitForEvent(PNSetUUIDMetadataEventMessage::class) + val message = result.extractedMessage as PNSetUUIDMetadataEventMessage assertEquals(uuid, message.data.id) assertNull(message.data.name?.value) assertEquals(externalId, message.data.externalId?.value) @@ -171,7 +173,7 @@ class UserMetadataTest : BaseIntegrationTest() { } @Test - fun can_receive_delete_metadata_event() = runTest { + fun can_receive_delete_metadata_event() = runTest(timeout = 30.seconds) { pubnub.test(backgroundScope) { // given pubnub.setUUIDMetadata( @@ -187,11 +189,14 @@ class UserMetadataTest : BaseIntegrationTest() { ).await() pubnub.awaitSubscribe(listOf(uuid)) + // Wait a bit to ensure subscription is fully established + delay(100) + // when pubnub.removeUUIDMetadata(uuid).await() // then - val result = nextEvent() + val result = waitForEvent(PNDeleteUUIDMetadataEventMessage::class) val message = result.extractedMessage as PNDeleteUUIDMetadataEventMessage assertEquals(uuid, message.uuid) } diff --git a/pubnub-kotlin/pubnub-kotlin-test/src/commonMain/kotlin/com.pubnub.test/BaseIntegrationTest.kt b/pubnub-kotlin/pubnub-kotlin-test/src/commonMain/kotlin/com.pubnub.test/BaseIntegrationTest.kt index 0c72d0b035..8dcdb96f02 100644 --- a/pubnub-kotlin/pubnub-kotlin-test/src/commonMain/kotlin/com.pubnub.test/BaseIntegrationTest.kt +++ b/pubnub-kotlin/pubnub-kotlin-test/src/commonMain/kotlin/com.pubnub.test/BaseIntegrationTest.kt @@ -7,6 +7,7 @@ import com.pubnub.api.enums.PNStatusCategory import com.pubnub.api.models.consumer.PNStatus import com.pubnub.api.models.consumer.pubsub.PNEvent import com.pubnub.api.models.consumer.pubsub.PNMessageResult +import com.pubnub.api.models.consumer.pubsub.objects.PNObjectEventResult import com.pubnub.api.v2.PNConfiguration import com.pubnub.api.v2.createPNConfiguration import com.pubnub.api.v2.subscriptions.EmptyOptions @@ -26,6 +27,7 @@ import kotlinx.coroutines.suspendCancellableCoroutine import kotlinx.coroutines.withContext import kotlin.coroutines.resume import kotlin.coroutines.resumeWithException +import kotlin.reflect.KClass import kotlin.test.AfterTest import kotlin.test.BeforeTest import kotlin.test.assertTrue @@ -284,6 +286,32 @@ class PubNubTest( } } + /** + * Waits for a specific event type with retries, handling spurious events that might arrive first + */ + suspend fun PubNubTest.waitForEvent( + expectedMessageType: KClass<*>, + maxRetries: Int = 3 + ): PNObjectEventResult { + repeat(maxRetries) { attempt -> + try { + val result = nextEvent() + if (expectedMessageType.isInstance(result.extractedMessage)) { + return result + } + // Log that we got an unexpected event type (for debugging) + // Continue to next attempt + } catch (e: Exception) { + if (attempt == maxRetries - 1) { + throw e // Re-throw on final attempt + } + // Wait a bit before retrying + delay(50) + } + } + throw RuntimeException("Failed to receive expected event type ${expectedMessageType.simpleName} after $maxRetries attempts") + } + fun close() { pubNub.unsubscribeAll() pubNub.destroy() From c79b7aa3b3cce9cd2e56797963c039572c781f6e Mon Sep 17 00:00:00 2001 From: "marcin.cebo" Date: Tue, 29 Jul 2025 15:50:18 +0200 Subject: [PATCH 5/8] Internal change - enabled EE for JS target in KMP tests --- .../test/integration/ChannelMetadataTest.kt | 4 +- .../pubnub/test/integration/PublishTest.kt | 42 ++++++++++++++++--- .../test/integration/UserMetadataTest.kt | 4 +- 3 files changed, 40 insertions(+), 10 deletions(-) diff --git a/pubnub-kotlin/pubnub-kotlin-api/src/commonTest/kotlin/com/pubnub/test/integration/ChannelMetadataTest.kt b/pubnub-kotlin/pubnub-kotlin-api/src/commonTest/kotlin/com/pubnub/test/integration/ChannelMetadataTest.kt index f1c2416fe0..9f5e067c98 100644 --- a/pubnub-kotlin/pubnub-kotlin-api/src/commonTest/kotlin/com/pubnub/test/integration/ChannelMetadataTest.kt +++ b/pubnub-kotlin/pubnub-kotlin-api/src/commonTest/kotlin/com/pubnub/test/integration/ChannelMetadataTest.kt @@ -269,7 +269,7 @@ class ChannelMetadataTest : BaseIntegrationTest() { pubnub.awaitSubscribe(listOf(channel)) // Wait a bit to ensure subscription is fully established - delay(100) + delay(200) // when pubnub.setChannelMetadata( @@ -333,7 +333,7 @@ class ChannelMetadataTest : BaseIntegrationTest() { pubnub.awaitSubscribe(listOf(channel)) // Wait a bit to ensure subscription is fully established - delay(100) + delay(200) // when pubnub.removeChannelMetadata(channel).await() diff --git a/pubnub-kotlin/pubnub-kotlin-api/src/commonTest/kotlin/com/pubnub/test/integration/PublishTest.kt b/pubnub-kotlin/pubnub-kotlin-api/src/commonTest/kotlin/com/pubnub/test/integration/PublishTest.kt index 61358f449b..cc57a70fac 100644 --- a/pubnub-kotlin/pubnub-kotlin-api/src/commonTest/kotlin/com/pubnub/test/integration/PublishTest.kt +++ b/pubnub-kotlin/pubnub-kotlin-api/src/commonTest/kotlin/com/pubnub/test/integration/PublishTest.kt @@ -13,12 +13,14 @@ import com.pubnub.test.BaseIntegrationTest import com.pubnub.test.await import com.pubnub.test.randomString import com.pubnub.test.test +import kotlinx.coroutines.delay import kotlinx.coroutines.test.runTest import kotlin.js.JsExport import kotlin.test.Ignore import kotlin.test.Test import kotlin.test.assertEquals import kotlin.test.assertTrue +import kotlin.time.Duration.Companion.seconds @JsExport data class ABC( @@ -67,9 +69,13 @@ class PublishTest : BaseIntegrationTest() { } @Test - fun can_receive_message_with_map_metadata() = runTest { + fun can_receive_message_with_map_metadata() = runTest(timeout = 30.seconds) { pubnub.test(backgroundScope) { pubnub.awaitSubscribe(listOf(channel)) + + // Wait a bit to ensure subscription is fully established + delay(200) + val mapData = mapOf( "stringValue" to "bbb", "mapValue" to mapOf("innerKey" to false), @@ -88,11 +94,19 @@ class PublishTest : BaseIntegrationTest() { } private fun isIOS() = PLATFORM == "iOS" + private fun isJS() = PLATFORM == "JS" @Test - fun can_receive_message_with_primitive_payload() = runTest { + fun can_receive_message_with_primitive_payload() = runTest(timeout = 30.seconds) { + if(isJS()){ + return@runTest + } pubnub.test(backgroundScope) { pubnub.awaitSubscribe(listOf(channel)) + + // Wait a bit to ensure subscription is fully established + delay(200) + pubnub.publish( channel, 111, @@ -110,9 +124,13 @@ class PublishTest : BaseIntegrationTest() { } @Test - fun can_receive_message_with_map_payload() = runTest { + fun can_receive_message_with_map_payload() = runTest(timeout = 30.seconds) { pubnub.test(backgroundScope) { pubnub.awaitSubscribe(listOf(channel)) + + // Wait a bit to ensure subscription is fully established + delay(200) + val mapData = mapOf( "stringValue" to "bbb", "mapValue" to mapOf("innerKey" to false), @@ -131,9 +149,13 @@ class PublishTest : BaseIntegrationTest() { } @Test - fun can_receive_signal_with_map_payload() = runTest { + fun can_receive_signal_with_map_payload() = runTest(timeout = 30.seconds) { pubnub.test(backgroundScope) { pubnub.awaitSubscribe(listOf(channel)) + + // Wait a bit to ensure subscription is fully established + delay(200) + val mapData = mapOf( "stringValue" to "bbb", "mapValue" to mapOf("innerKey" to false) @@ -148,9 +170,13 @@ class PublishTest : BaseIntegrationTest() { } @Test - fun can_receive_message_with_payload_with_floats() = runTest { + fun can_receive_message_with_payload_with_floats() = runTest(timeout = 30.seconds) { pubnub.test(backgroundScope) { pubnub.awaitSubscribe(listOf(channel)) + + // Wait a bit to ensure subscription is fully established + delay(200) + val mapData = mapOf( "floatValue" to 1.23f, "doubleValue" to 1.23, @@ -187,10 +213,14 @@ class PublishTest : BaseIntegrationTest() { } @Test - fun publish_with_custom_message_type() = runTest { + fun publish_with_custom_message_type() = runTest(timeout = 30.seconds) { val customMessageType = randomString() pubnub.test(backgroundScope) { pubnub.awaitSubscribe(listOf(channel)) + + // Wait a bit to ensure subscription is fully established + delay(500) + pubnub.publish(channel, "some message", customMessageType = customMessageType).await() val result = nextMessage() assertEquals("some message", result.message.asString()) diff --git a/pubnub-kotlin/pubnub-kotlin-api/src/commonTest/kotlin/com/pubnub/test/integration/UserMetadataTest.kt b/pubnub-kotlin/pubnub-kotlin-api/src/commonTest/kotlin/com/pubnub/test/integration/UserMetadataTest.kt index 47d4bd459b..52ac776505 100644 --- a/pubnub-kotlin/pubnub-kotlin-api/src/commonTest/kotlin/com/pubnub/test/integration/UserMetadataTest.kt +++ b/pubnub-kotlin/pubnub-kotlin-api/src/commonTest/kotlin/com/pubnub/test/integration/UserMetadataTest.kt @@ -120,7 +120,7 @@ class UserMetadataTest : BaseIntegrationTest() { pubnub.awaitSubscribe(listOf(uuid)) // Wait a bit to ensure subscription is fully established - delay(100) + delay(200) // when pubnub.setUUIDMetadata( @@ -190,7 +190,7 @@ class UserMetadataTest : BaseIntegrationTest() { pubnub.awaitSubscribe(listOf(uuid)) // Wait a bit to ensure subscription is fully established - delay(100) + delay(200) // when pubnub.removeUUIDMetadata(uuid).await() From 007df6c56c303d6ebb4f65df42ac7722e6fd28c0 Mon Sep 17 00:00:00 2001 From: "marcin.cebo" Date: Tue, 29 Jul 2025 16:06:04 +0200 Subject: [PATCH 6/8] Internal change - enabled EE for JS target in KMP tests --- .../kotlin/com/pubnub/test/integration/PublishTest.kt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pubnub-kotlin/pubnub-kotlin-api/src/commonTest/kotlin/com/pubnub/test/integration/PublishTest.kt b/pubnub-kotlin/pubnub-kotlin-api/src/commonTest/kotlin/com/pubnub/test/integration/PublishTest.kt index cc57a70fac..f3527245d9 100644 --- a/pubnub-kotlin/pubnub-kotlin-api/src/commonTest/kotlin/com/pubnub/test/integration/PublishTest.kt +++ b/pubnub-kotlin/pubnub-kotlin-api/src/commonTest/kotlin/com/pubnub/test/integration/PublishTest.kt @@ -94,11 +94,12 @@ class PublishTest : BaseIntegrationTest() { } private fun isIOS() = PLATFORM == "iOS" + private fun isJS() = PLATFORM == "JS" @Test fun can_receive_message_with_primitive_payload() = runTest(timeout = 30.seconds) { - if(isJS()){ + if (isJS()) { return@runTest } pubnub.test(backgroundScope) { From b6d3b4d1204d5deee2567acbb2950ace7e1d2a61 Mon Sep 17 00:00:00 2001 From: "marcin.cebo" Date: Wed, 30 Jul 2025 17:29:51 +0200 Subject: [PATCH 7/8] Internal change - enabled EE for JS target in KMP tests --- .../test/integration/ChannelMetadataTest.kt | 27 ++++--- .../pubnub/test/integration/PublishTest.kt | 49 ++++--------- .../test/integration/UserMetadataTest.kt | 19 ++--- .../kotlin/com.pubnub.test/platform.kt | 3 + .../com.pubnub.test/BaseIntegrationTest.kt | 72 +++++++------------ .../jsMain/kotlin/com.pubnub.test/platform.kt | 3 + .../kotlin/com.pubnub.test/platform.kt | 3 + 7 files changed, 70 insertions(+), 106 deletions(-) create mode 100644 pubnub-kotlin/pubnub-kotlin-test/src/appleMain/kotlin/com.pubnub.test/platform.kt create mode 100644 pubnub-kotlin/pubnub-kotlin-test/src/jsMain/kotlin/com.pubnub.test/platform.kt create mode 100644 pubnub-kotlin/pubnub-kotlin-test/src/jvmMain/kotlin/com.pubnub.test/platform.kt diff --git a/pubnub-kotlin/pubnub-kotlin-api/src/commonTest/kotlin/com/pubnub/test/integration/ChannelMetadataTest.kt b/pubnub-kotlin/pubnub-kotlin-api/src/commonTest/kotlin/com/pubnub/test/integration/ChannelMetadataTest.kt index 9f5e067c98..f607fce4ad 100644 --- a/pubnub-kotlin/pubnub-kotlin-api/src/commonTest/kotlin/com/pubnub/test/integration/ChannelMetadataTest.kt +++ b/pubnub-kotlin/pubnub-kotlin-api/src/commonTest/kotlin/com/pubnub/test/integration/ChannelMetadataTest.kt @@ -6,6 +6,7 @@ import com.pubnub.api.models.consumer.PNStatus import com.pubnub.api.models.consumer.objects.PNPage import com.pubnub.api.models.consumer.objects.channel.PNChannelMetadata import com.pubnub.api.models.consumer.pubsub.objects.PNDeleteChannelMetadataEventMessage +import com.pubnub.api.models.consumer.pubsub.objects.PNObjectEventResult import com.pubnub.api.models.consumer.pubsub.objects.PNSetChannelMetadataEventMessage import com.pubnub.kmp.PLATFORM import com.pubnub.kmp.createCustomObject @@ -16,7 +17,6 @@ import com.pubnub.test.BaseIntegrationTest import com.pubnub.test.await import com.pubnub.test.randomString import com.pubnub.test.test -import kotlinx.coroutines.delay import kotlinx.coroutines.test.runTest import kotlin.test.Test import kotlin.test.assertEquals @@ -263,14 +263,11 @@ class ChannelMetadataTest : BaseIntegrationTest() { } @Test - fun can_receive_set_metadata_event() = runTest(timeout = 30.seconds) { + fun can_receive_set_metadata_event() = runTest { pubnub.test(backgroundScope) { // given pubnub.awaitSubscribe(listOf(channel)) - // Wait a bit to ensure subscription is fully established - delay(200) - // when pubnub.setChannelMetadata( channel, @@ -283,8 +280,9 @@ class ChannelMetadataTest : BaseIntegrationTest() { ).await() // then - val result = waitForEvent(PNSetChannelMetadataEventMessage::class) - val message = result.extractedMessage as PNSetChannelMetadataEventMessage + val result = nextEvent() + val message = result.extractedMessage + message as PNSetChannelMetadataEventMessage assertEquals(channel, message.data.id) assertEquals(name, message.data.name?.value) assertEquals(description, message.data.description?.value) @@ -318,9 +316,8 @@ class ChannelMetadataTest : BaseIntegrationTest() { } @Test - fun can_receive_delete_metadata_event() = runTest(timeout = 30.seconds) { + fun can_receive_delete_metadata_event() = runTest { pubnub.test(backgroundScope) { - // given pubnub.setChannelMetadata( channel, name = name, @@ -332,15 +329,17 @@ class ChannelMetadataTest : BaseIntegrationTest() { ).await() pubnub.awaitSubscribe(listOf(channel)) - // Wait a bit to ensure subscription is fully established - delay(200) - // when pubnub.removeChannelMetadata(channel).await() // then - val result = waitForEvent(PNDeleteChannelMetadataEventMessage::class) - val message = result.extractedMessage as PNDeleteChannelMetadataEventMessage + var result = nextEvent() + if (result.extractedMessage !is PNDeleteChannelMetadataEventMessage) { + result = nextEvent() + } + val message = result.extractedMessage + assertTrue { message is PNDeleteChannelMetadataEventMessage } + message as PNDeleteChannelMetadataEventMessage assertEquals(channel, message.channel) } } diff --git a/pubnub-kotlin/pubnub-kotlin-api/src/commonTest/kotlin/com/pubnub/test/integration/PublishTest.kt b/pubnub-kotlin/pubnub-kotlin-api/src/commonTest/kotlin/com/pubnub/test/integration/PublishTest.kt index f3527245d9..2e8258c665 100644 --- a/pubnub-kotlin/pubnub-kotlin-api/src/commonTest/kotlin/com/pubnub/test/integration/PublishTest.kt +++ b/pubnub-kotlin/pubnub-kotlin-api/src/commonTest/kotlin/com/pubnub/test/integration/PublishTest.kt @@ -13,14 +13,12 @@ import com.pubnub.test.BaseIntegrationTest import com.pubnub.test.await import com.pubnub.test.randomString import com.pubnub.test.test -import kotlinx.coroutines.delay import kotlinx.coroutines.test.runTest import kotlin.js.JsExport import kotlin.test.Ignore import kotlin.test.Test import kotlin.test.assertEquals import kotlin.test.assertTrue -import kotlin.time.Duration.Companion.seconds @JsExport data class ABC( @@ -35,28 +33,32 @@ class PublishTest : BaseIntegrationTest() { @Test fun can_publish_message_string() = runTest { - val result = pubnub.publish(channel = channel, message = "some message", customMessageType = "myCustomType").await() + val result = + pubnub.publish(channel = channel, message = "some message", customMessageType = "myCustomType").await() assertTrue { result.timetoken > 0 } } @Test fun can_signal() = runTest { - val result = pubnub.signal(channel = channel, message = "some message", customMessageType = "myCustomType").await() + val result = + pubnub.signal(channel = channel, message = "some message", customMessageType = "myCustomType").await() assertTrue { result.timetoken > 0 } } @Test fun can_publish_message_map() = runTest { - val result = pubnub.publish(channel, mapOf("platform" to PLATFORM, "otherKey" to 123, "another" to true)).await() + val result = + pubnub.publish(channel, mapOf("platform" to PLATFORM, "otherKey" to 123, "another" to true)).await() assertTrue { result.timetoken > 0 } } @Test fun can_signal_map() = runTest { - val result = pubnub.signal(channel, mapOf("platform" to PLATFORM, "otherKey" to 123, "another" to true)).await() + val result = + pubnub.signal(channel, mapOf("platform" to PLATFORM, "otherKey" to 123, "another" to true)).await() assertTrue { result.timetoken > 0 } } @@ -69,13 +71,10 @@ class PublishTest : BaseIntegrationTest() { } @Test - fun can_receive_message_with_map_metadata() = runTest(timeout = 30.seconds) { + fun can_receive_message_with_map_metadata() = runTest { pubnub.test(backgroundScope) { pubnub.awaitSubscribe(listOf(channel)) - // Wait a bit to ensure subscription is fully established - delay(200) - val mapData = mapOf( "stringValue" to "bbb", "mapValue" to mapOf("innerKey" to false), @@ -98,16 +97,9 @@ class PublishTest : BaseIntegrationTest() { private fun isJS() = PLATFORM == "JS" @Test - fun can_receive_message_with_primitive_payload() = runTest(timeout = 30.seconds) { - if (isJS()) { - return@runTest - } + fun can_receive_message_with_primitive_payload() = runTest { pubnub.test(backgroundScope) { pubnub.awaitSubscribe(listOf(channel)) - - // Wait a bit to ensure subscription is fully established - delay(200) - pubnub.publish( channel, 111, @@ -125,13 +117,10 @@ class PublishTest : BaseIntegrationTest() { } @Test - fun can_receive_message_with_map_payload() = runTest(timeout = 30.seconds) { + fun can_receive_message_with_map_payload() = runTest { pubnub.test(backgroundScope) { pubnub.awaitSubscribe(listOf(channel)) - // Wait a bit to ensure subscription is fully established - delay(200) - val mapData = mapOf( "stringValue" to "bbb", "mapValue" to mapOf("innerKey" to false), @@ -150,13 +139,10 @@ class PublishTest : BaseIntegrationTest() { } @Test - fun can_receive_signal_with_map_payload() = runTest(timeout = 30.seconds) { + fun can_receive_signal_with_map_payload() = runTest { pubnub.test(backgroundScope) { pubnub.awaitSubscribe(listOf(channel)) - // Wait a bit to ensure subscription is fully established - delay(200) - val mapData = mapOf( "stringValue" to "bbb", "mapValue" to mapOf("innerKey" to false) @@ -171,13 +157,10 @@ class PublishTest : BaseIntegrationTest() { } @Test - fun can_receive_message_with_payload_with_floats() = runTest(timeout = 30.seconds) { + fun can_receive_message_with_payload_with_floats() = runTest { pubnub.test(backgroundScope) { pubnub.awaitSubscribe(listOf(channel)) - // Wait a bit to ensure subscription is fully established - delay(200) - val mapData = mapOf( "floatValue" to 1.23f, "doubleValue" to 1.23, @@ -214,14 +197,10 @@ class PublishTest : BaseIntegrationTest() { } @Test - fun publish_with_custom_message_type() = runTest(timeout = 30.seconds) { + fun publish_with_custom_message_type() = runTest { val customMessageType = randomString() pubnub.test(backgroundScope) { pubnub.awaitSubscribe(listOf(channel)) - - // Wait a bit to ensure subscription is fully established - delay(500) - pubnub.publish(channel, "some message", customMessageType = customMessageType).await() val result = nextMessage() assertEquals("some message", result.message.asString()) diff --git a/pubnub-kotlin/pubnub-kotlin-api/src/commonTest/kotlin/com/pubnub/test/integration/UserMetadataTest.kt b/pubnub-kotlin/pubnub-kotlin-api/src/commonTest/kotlin/com/pubnub/test/integration/UserMetadataTest.kt index 52ac776505..c0473f7f42 100644 --- a/pubnub-kotlin/pubnub-kotlin-api/src/commonTest/kotlin/com/pubnub/test/integration/UserMetadataTest.kt +++ b/pubnub-kotlin/pubnub-kotlin-api/src/commonTest/kotlin/com/pubnub/test/integration/UserMetadataTest.kt @@ -5,13 +5,13 @@ import com.pubnub.api.models.consumer.objects.PNPage import com.pubnub.api.models.consumer.objects.uuid.PNUUIDMetadata import com.pubnub.api.models.consumer.objects.uuid.PNUUIDMetadataArrayResult import com.pubnub.api.models.consumer.pubsub.objects.PNDeleteUUIDMetadataEventMessage +import com.pubnub.api.models.consumer.pubsub.objects.PNObjectEventResult import com.pubnub.api.models.consumer.pubsub.objects.PNSetUUIDMetadataEventMessage import com.pubnub.kmp.createCustomObject import com.pubnub.test.BaseIntegrationTest import com.pubnub.test.await import com.pubnub.test.randomString import com.pubnub.test.test -import kotlinx.coroutines.delay import kotlinx.coroutines.test.runTest import kotlin.test.Test import kotlin.test.assertEquals @@ -114,14 +114,11 @@ class UserMetadataTest : BaseIntegrationTest() { } @Test - fun can_receive_set_metadata_event() = runTest(timeout = 30.seconds) { + fun can_receive_set_metadata_event() = runTest { pubnub.test(backgroundScope) { // given pubnub.awaitSubscribe(listOf(uuid)) - // Wait a bit to ensure subscription is fully established - delay(200) - // when pubnub.setUUIDMetadata( uuid, @@ -135,8 +132,9 @@ class UserMetadataTest : BaseIntegrationTest() { ).await() // then - val result = waitForEvent(PNSetUUIDMetadataEventMessage::class) - val message = result.extractedMessage as PNSetUUIDMetadataEventMessage + val result = nextEvent() + val message = result.extractedMessage + message as PNSetUUIDMetadataEventMessage assertEquals(uuid, message.data.id) assertNull(message.data.name?.value) assertEquals(externalId, message.data.externalId?.value) @@ -173,7 +171,7 @@ class UserMetadataTest : BaseIntegrationTest() { } @Test - fun can_receive_delete_metadata_event() = runTest(timeout = 30.seconds) { + fun can_receive_delete_metadata_event() = runTest { pubnub.test(backgroundScope) { // given pubnub.setUUIDMetadata( @@ -189,14 +187,11 @@ class UserMetadataTest : BaseIntegrationTest() { ).await() pubnub.awaitSubscribe(listOf(uuid)) - // Wait a bit to ensure subscription is fully established - delay(200) - // when pubnub.removeUUIDMetadata(uuid).await() // then - val result = waitForEvent(PNDeleteUUIDMetadataEventMessage::class) + val result = nextEvent() val message = result.extractedMessage as PNDeleteUUIDMetadataEventMessage assertEquals(uuid, message.uuid) } diff --git a/pubnub-kotlin/pubnub-kotlin-test/src/appleMain/kotlin/com.pubnub.test/platform.kt b/pubnub-kotlin/pubnub-kotlin-test/src/appleMain/kotlin/com.pubnub.test/platform.kt new file mode 100644 index 0000000000..bc5cd12f0d --- /dev/null +++ b/pubnub-kotlin/pubnub-kotlin-test/src/appleMain/kotlin/com.pubnub.test/platform.kt @@ -0,0 +1,3 @@ +package com.pubnub.test + +internal actual val PLATFORM: String = "iOS" diff --git a/pubnub-kotlin/pubnub-kotlin-test/src/commonMain/kotlin/com.pubnub.test/BaseIntegrationTest.kt b/pubnub-kotlin/pubnub-kotlin-test/src/commonMain/kotlin/com.pubnub.test/BaseIntegrationTest.kt index 8dcdb96f02..8a76fd0a69 100644 --- a/pubnub-kotlin/pubnub-kotlin-test/src/commonMain/kotlin/com.pubnub.test/BaseIntegrationTest.kt +++ b/pubnub-kotlin/pubnub-kotlin-test/src/commonMain/kotlin/com.pubnub.test/BaseIntegrationTest.kt @@ -7,7 +7,6 @@ import com.pubnub.api.enums.PNStatusCategory import com.pubnub.api.models.consumer.PNStatus import com.pubnub.api.models.consumer.pubsub.PNEvent import com.pubnub.api.models.consumer.pubsub.PNMessageResult -import com.pubnub.api.models.consumer.pubsub.objects.PNObjectEventResult import com.pubnub.api.v2.PNConfiguration import com.pubnub.api.v2.createPNConfiguration import com.pubnub.api.v2.subscriptions.EmptyOptions @@ -27,12 +26,13 @@ import kotlinx.coroutines.suspendCancellableCoroutine import kotlinx.coroutines.withContext import kotlin.coroutines.resume import kotlin.coroutines.resumeWithException -import kotlin.reflect.KClass import kotlin.test.AfterTest import kotlin.test.BeforeTest import kotlin.test.assertTrue import kotlin.time.Duration.Companion.milliseconds +internal expect val PLATFORM: String + abstract class BaseIntegrationTest { lateinit var config: PNConfiguration lateinit var config02: PNConfiguration @@ -187,29 +187,37 @@ class PubNubTest( customSubscriptionBlock: () -> Unit = { subscribe(channels.toList(), channelGroups.toList(), withPresence) } - ) = suspendCancellableCoroutine { cont -> - val statusListener = createStatusListener(pubNub) { _, pnStatus -> - if ((pnStatus.category == PNStatusCategory.PNConnectedCategory || pnStatus.category == PNStatusCategory.PNSubscriptionChanged) && - pnStatus.affectedChannels.containsAll(channels) && pnStatus.affectedChannelGroups.containsAll( - channelGroups - ) || ( - getSubscribedChannels().containsAll(channels) && getSubscribedChannelGroups().containsAll( + ) { + suspendCancellableCoroutine { cont -> + val statusListener = createStatusListener(pubNub) { _, pnStatus -> + if ((pnStatus.category == PNStatusCategory.PNConnectedCategory || pnStatus.category == PNStatusCategory.PNSubscriptionChanged) && + pnStatus.affectedChannels.containsAll(channels) && pnStatus.affectedChannelGroups.containsAll( channelGroups + ) || ( + getSubscribedChannels().containsAll(channels) && getSubscribedChannelGroups().containsAll( + channelGroups + ) ) - ) - ) { - if (!cont.isCompleted) { - cont.resume(Unit) + ) { + if (!cont.isCompleted) { + cont.resume(Unit) + } + } else if (pnStatus.category == PNStatusCategory.PNUnexpectedDisconnectCategory || pnStatus.category == PNStatusCategory.PNConnectionError) { + cont.resumeWithException(pnStatus.exception ?: RuntimeException(pnStatus.category.toString())) } - } else if (pnStatus.category == PNStatusCategory.PNUnexpectedDisconnectCategory || pnStatus.category == PNStatusCategory.PNConnectionError) { - cont.resumeWithException(pnStatus.exception ?: RuntimeException(pnStatus.category.toString())) } + pubNub.addListener(statusListener) + cont.invokeOnCancellation { + pubNub.removeListener(statusListener) + } + customSubscriptionBlock() } - pubNub.addListener(statusListener) - cont.invokeOnCancellation { - pubNub.removeListener(statusListener) + if (PLATFORM == "JS") { + withContext(Dispatchers.Default) { + // this is needed for JS test to work properly + delay(200) + } } - customSubscriptionBlock() } suspend fun PubNub.awaitUnsubscribe( @@ -286,32 +294,6 @@ class PubNubTest( } } - /** - * Waits for a specific event type with retries, handling spurious events that might arrive first - */ - suspend fun PubNubTest.waitForEvent( - expectedMessageType: KClass<*>, - maxRetries: Int = 3 - ): PNObjectEventResult { - repeat(maxRetries) { attempt -> - try { - val result = nextEvent() - if (expectedMessageType.isInstance(result.extractedMessage)) { - return result - } - // Log that we got an unexpected event type (for debugging) - // Continue to next attempt - } catch (e: Exception) { - if (attempt == maxRetries - 1) { - throw e // Re-throw on final attempt - } - // Wait a bit before retrying - delay(50) - } - } - throw RuntimeException("Failed to receive expected event type ${expectedMessageType.simpleName} after $maxRetries attempts") - } - fun close() { pubNub.unsubscribeAll() pubNub.destroy() diff --git a/pubnub-kotlin/pubnub-kotlin-test/src/jsMain/kotlin/com.pubnub.test/platform.kt b/pubnub-kotlin/pubnub-kotlin-test/src/jsMain/kotlin/com.pubnub.test/platform.kt new file mode 100644 index 0000000000..ffaa6b90f9 --- /dev/null +++ b/pubnub-kotlin/pubnub-kotlin-test/src/jsMain/kotlin/com.pubnub.test/platform.kt @@ -0,0 +1,3 @@ +package com.pubnub.test + +internal actual val PLATFORM: String = "JS" diff --git a/pubnub-kotlin/pubnub-kotlin-test/src/jvmMain/kotlin/com.pubnub.test/platform.kt b/pubnub-kotlin/pubnub-kotlin-test/src/jvmMain/kotlin/com.pubnub.test/platform.kt new file mode 100644 index 0000000000..f58cd6aaad --- /dev/null +++ b/pubnub-kotlin/pubnub-kotlin-test/src/jvmMain/kotlin/com.pubnub.test/platform.kt @@ -0,0 +1,3 @@ +package com.pubnub.test + +internal actual val PLATFORM: String = "JVM" From 43ea1952dd8ecdf24329ac66670e4e2d690f9d76 Mon Sep 17 00:00:00 2001 From: PubNub Release Bot <120067856+pubnub-release-bot@users.noreply.github.com> Date: Thu, 31 Jul 2025 09:04:05 +0200 Subject: [PATCH 8/8] PubNub SDK v10.5.6 release. --- .pubnub.yml | 13 +++++++++---- CHANGELOG.md | 6 ++++++ README.md | 2 +- gradle.properties | 2 +- .../kotlin/com/pubnub/api/legacy/PubNubImplTest.kt | 2 +- 5 files changed, 18 insertions(+), 7 deletions(-) diff --git a/.pubnub.yml b/.pubnub.yml index 1c148c8a66..b49930a1f2 100644 --- a/.pubnub.yml +++ b/.pubnub.yml @@ -1,9 +1,9 @@ name: kotlin -version: 10.5.5 +version: 10.5.6 schema: 1 scm: github.com/pubnub/kotlin files: - - build/libs/pubnub-kotlin-10.5.5-all.jar + - build/libs/pubnub-kotlin-10.5.6-all.jar sdks: - type: library @@ -23,8 +23,8 @@ sdks: - distribution-type: library distribution-repository: maven - package-name: pubnub-kotlin-10.5.5 - location: https://repo.maven.apache.org/maven2/com/pubnub/pubnub-kotlin/10.5.5/pubnub-kotlin-10.5.5.jar + package-name: pubnub-kotlin-10.5.6 + location: https://repo.maven.apache.org/maven2/com/pubnub/pubnub-kotlin/10.5.6/pubnub-kotlin-10.5.6.jar supported-platforms: supported-operating-systems: Android: @@ -121,6 +121,11 @@ sdks: license-url: https://www.apache.org/licenses/LICENSE-2.0.txt is-required: Required changelog: + - date: 2025-07-31 + version: v10.5.6 + changes: + - type: bug + text: "Internal change - enabled EE for JS target in KMP tests." - date: 2025-07-30 version: v10.5.5 changes: diff --git a/CHANGELOG.md b/CHANGELOG.md index 4212be4c82..79fefb4a4d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,9 @@ +## v10.5.6 +July 31 2025 + +#### Fixed +- Internal change - enabled EE for JS target in KMP tests. + ## v10.5.5 July 30 2025 diff --git a/README.md b/README.md index 2c823755e2..9840d60fe8 100644 --- a/README.md +++ b/README.md @@ -20,7 +20,7 @@ You will need the publish and subscribe keys to authenticate your app. Get your com.pubnub pubnub-kotlin - 10.5.5 + 10.5.6 ``` diff --git a/gradle.properties b/gradle.properties index 6c8cf64365..7d1715d8a5 100644 --- a/gradle.properties +++ b/gradle.properties @@ -18,7 +18,7 @@ RELEASE_SIGNING_ENABLED=true SONATYPE_HOST=DEFAULT SONATYPE_AUTOMATIC_RELEASE=false GROUP=com.pubnub -VERSION_NAME=10.5.5 +VERSION_NAME=10.5.6 POM_PACKAGING=jar POM_NAME=PubNub SDK diff --git a/pubnub-kotlin/pubnub-kotlin-impl/src/test/kotlin/com/pubnub/api/legacy/PubNubImplTest.kt b/pubnub-kotlin/pubnub-kotlin-impl/src/test/kotlin/com/pubnub/api/legacy/PubNubImplTest.kt index 08cb8e965d..fdfab7b2cb 100644 --- a/pubnub-kotlin/pubnub-kotlin-impl/src/test/kotlin/com/pubnub/api/legacy/PubNubImplTest.kt +++ b/pubnub-kotlin/pubnub-kotlin-impl/src/test/kotlin/com/pubnub/api/legacy/PubNubImplTest.kt @@ -56,7 +56,7 @@ class PubNubImplTest : BaseTest() { fun getVersionAndTimeStamp() { val version = PubNubImpl.SDK_VERSION val timeStamp = PubNubImpl.timestamp() - assertEquals("10.5.5", version) + assertEquals("10.5.6", version) assertTrue(timeStamp > 0) }