Skip to content

Commit 4af9a98

Browse files
authored
Added missing tests (#357)
1 parent 73a798d commit 4af9a98

File tree

6 files changed

+206
-7
lines changed

6 files changed

+206
-7
lines changed

pubnub-kotlin/pubnub-kotlin-api/src/jvmMain/kotlin/com/pubnub/api/PubNub.kt

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -738,10 +738,18 @@ actual interface PubNub : StatusEmitter, EventEmitter {
738738
* The count returned is the number of messages in history with a timetoken value greater
739739
* than the passed value in the [MessageCounts.channelsTimetoken] parameter.
740740
*
741+
* **Important:** The timetoken represents an exclusive boundary. Messages with timetokens
742+
* greater than (but not equal to) the specified timetoken are counted. To count messages
743+
* from a specific message onwards, you typically need to subtract 1 from the message's
744+
* timetoken.
745+
*
741746
* @param channels Channels to fetch the message count from.
742-
* @param channelsTimetoken List of timetokens, in order of the channels list.
743-
* Specify a single timetoken to apply it to all channels.
744-
* Otherwise, the list of timetokens must be the same length as the list of channels.
747+
* @param channelsTimetoken List of timetokens representing exclusive boundaries for message counting.
748+
* Each timetoken corresponds to a channel in the same order.
749+
* - **Single timetoken**: Applied to all channels (list with one element)
750+
* - **Multiple timetokens**: Must match the number of channels exactly
751+
* - **Exclusive boundary**: Only messages with timetokens > specified value are counted
752+
* - **Common pattern**: Use `(messageTimetoken - 1)` to count from a specific message onwards
745753
*/
746754
actual fun messageCounts(
747755
channels: List<String>,

pubnub-kotlin/pubnub-kotlin-core-api/src/commonMain/kotlin/com/pubnub/api/PubNubError.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ enum class PubNubError(private val code: Int, val message: String) {
1919

2020
SECRET_KEY_MISSING(
2121
114,
22-
"ULS configuration failed. Secret Key not configured",
22+
"Secret Key not configured",
2323
),
2424

2525
JSON_ERROR(

pubnub-kotlin/pubnub-kotlin-impl/src/integrationTest/kotlin/com/pubnub/api/integration/GroupManagementIntegrationTests.kt

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -102,12 +102,23 @@ class GroupManagementIntegrationTests : BaseIntegrationTest() {
102102
channelGroup = expectedGroup,
103103
channels = listOf(expectedChannel1, expectedChannel2, expectedChannel3),
104104
).await { result ->
105-
assertFalse(result.isFailure) // TODO is this part of the result? if not then there's nothing to assert on
106-
// assertEquals(1, status.affectedChannelGroups.size)
107-
// assertEquals(3, status.affectedChannels.size)
105+
assertFalse(result.isFailure)
108106
}
109107
}
110108

109+
@Test
110+
fun testDeleteChannelGroup() {
111+
pubnub.addChannelsToChannelGroup(
112+
channelGroup = expectedGroup,
113+
channels = listOf(expectedChannel1, expectedChannel2, expectedChannel3),
114+
).sync()
115+
116+
pubnub.deleteChannelGroup(channelGroup = expectedGroup).sync()
117+
118+
val listAllChannelGroupsResult = pubnub.listAllChannelGroups().sync()
119+
assertFalse(listAllChannelGroupsResult.groups.contains(expectedGroup))
120+
}
121+
111122
private fun addChannelsToGroup() {
112123
pubnub.addChannelsToChannelGroup(
113124
channelGroup = expectedGroup,

pubnub-kotlin/pubnub-kotlin-impl/src/integrationTest/kotlin/com/pubnub/api/integration/HistoryIntegrationTest.kt

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,73 @@ import org.junit.jupiter.api.Test
2525
import java.time.Duration
2626

2727
class HistoryIntegrationTest : BaseIntegrationTest() {
28+
@Test
29+
fun canGetMessageCounts() {
30+
val channel01 = randomChannel()
31+
val channel02 = randomChannel()
32+
val firstPublishToChannel01Result = pubnub.publish(channel01, message = "FirstMessageChannel01").sync()
33+
pubnub.publish(channel01, message = "SecondMessage").sync()
34+
val firstPublishToChannel02Result = pubnub.publish(channel02, message = "FirstMessageChannel02").sync()
35+
36+
// Test with multiple timetokens (one per channel)
37+
val messagesCounts = pubnub.messageCounts(
38+
channels = listOf(channel01, channel02),
39+
channelsTimetoken = listOf(
40+
firstPublishToChannel01Result.timetoken - 1, // Count from first message onwards
41+
firstPublishToChannel02Result.timetoken - 1 // Count from first message onwards
42+
)
43+
).sync()
44+
assertEquals(2, messagesCounts.channels[channel01])
45+
assertEquals(1, messagesCounts.channels[channel02])
46+
}
47+
48+
@Test
49+
fun canGetMessageCountsWithSingleTimetoken() {
50+
val channel01 = randomChannel()
51+
val channel02 = randomChannel()
52+
val firstPublishToChannel01Result = pubnub.publish(channel01, message = "FirstMessageChannel01").sync()
53+
pubnub.publish(channel01, message = "SecondMessage").sync()
54+
val firstPublishToChannel02Result = pubnub.publish(channel02, message = "FirstMessageChannel02").sync()
55+
56+
// Test with single timetoken applied to all channels
57+
val messagesCounts = pubnub.messageCounts(
58+
channels = listOf(channel01, channel02),
59+
channelsTimetoken = listOf(firstPublishToChannel01Result.timetoken - 1) // Single timetoken for all channels
60+
).sync()
61+
assertEquals(2, messagesCounts.channels[channel01])
62+
assertEquals(1, messagesCounts.channels[channel02])
63+
}
64+
65+
@Test
66+
fun canGetMessageCountsWithMultipleTimetokens() {
67+
val channel01 = randomChannel()
68+
val channel02 = randomChannel()
69+
val channel03 = randomChannel()
70+
71+
val firstPublishToChannel01Result = pubnub.publish(channel01, message = "FirstMessageChannel01").sync()
72+
pubnub.publish(channel01, message = "SecondMessage").sync()
73+
pubnub.publish(channel01, message = "ThirdMessage").sync()
74+
75+
val firstPublishToChannel02Result = pubnub.publish(channel02, message = "FirstMessageChannel02").sync()
76+
pubnub.publish(channel02, message = "SecondMessage").sync()
77+
78+
val firstPublishToChannel03Result = pubnub.publish(channel03, message = "FirstMessageChannel03").sync()
79+
80+
// Test with multiple timetokens, each tailored to specific channels
81+
val messagesCounts = pubnub.messageCounts(
82+
channels = listOf(channel01, channel02, channel03),
83+
channelsTimetoken = listOf(
84+
firstPublishToChannel01Result.timetoken, // Should count 2 messages (second and third)
85+
firstPublishToChannel02Result.timetoken - 1, // Should count 2 messages (all)
86+
firstPublishToChannel03Result.timetoken - 1 // Should count 1 message (all)
87+
)
88+
).sync()
89+
90+
assertEquals(2, messagesCounts.channels[channel01])
91+
assertEquals(2, messagesCounts.channels[channel02])
92+
assertEquals(1, messagesCounts.channels[channel03])
93+
}
94+
2895
@Test
2996
fun historySingleScenario() {
3097
val channel = randomChannel()

pubnub-kotlin/pubnub-kotlin-impl/src/integrationTest/kotlin/com/pubnub/api/integration/PublishIntegrationTests.kt

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import com.pubnub.api.callbacks.SubscribeCallback
88
import com.pubnub.api.crypto.CryptoModule
99
import com.pubnub.api.enums.PNStatusCategory
1010
import com.pubnub.api.models.consumer.PNBoundedPage
11+
import com.pubnub.api.models.consumer.PNPublishResult
1112
import com.pubnub.api.models.consumer.PNStatus
1213
import com.pubnub.api.models.consumer.pubsub.PNMessageResult
1314
import com.pubnub.api.v2.PNConfigurationOverride
@@ -37,6 +38,7 @@ import org.json.JSONArray
3738
import org.json.JSONObject
3839
import org.junit.Assert.assertEquals
3940
import org.junit.Assert.assertFalse
41+
import org.junit.Assert.assertNotNull
4042
import org.junit.Assert.assertNull
4143
import org.junit.Assert.assertTrue
4244
import org.junit.Test
@@ -54,6 +56,15 @@ class PublishIntegrationTests : BaseIntegrationTest() {
5456
guestClient = createPubNub {}
5557
}
5658

59+
@Test
60+
fun testFireMessage() {
61+
val expectedChannel = randomChannel()
62+
val fireResult: PNPublishResult =
63+
pubnub.fire(channel = expectedChannel, message = generatePayload(), meta = null).sync()
64+
65+
assertNotNull(fireResult.timetoken)
66+
}
67+
5768
@Test
5869
fun testPublishMessage() {
5970
val expectedChannel = randomChannel()
Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
package com.pubnub.api.endpoints.access
2+
3+
import com.pubnub.api.PubNubException
4+
import com.pubnub.api.UserId
5+
import com.pubnub.internal.PubNubImpl
6+
import com.pubnub.internal.endpoints.access.RevokeTokenEndpoint
7+
import com.pubnub.internal.managers.RetrofitManager
8+
import com.pubnub.internal.models.server.access_manager.v3.RevokeTokenData
9+
import com.pubnub.internal.models.server.access_manager.v3.RevokeTokenResponse
10+
import com.pubnub.internal.services.AccessManagerService
11+
import com.pubnub.internal.v2.PNConfigurationImpl
12+
import io.mockk.MockKAnnotations
13+
import io.mockk.every
14+
import io.mockk.impl.annotations.MockK
15+
import io.mockk.mockk
16+
import io.mockk.spyk
17+
import io.mockk.verify
18+
import org.junit.jupiter.api.Assertions.assertEquals
19+
import org.junit.jupiter.api.BeforeEach
20+
import org.junit.jupiter.api.Test
21+
import org.junit.jupiter.api.assertThrows
22+
import retrofit2.Call
23+
import retrofit2.Response
24+
25+
class RevokeTokenTest {
26+
private lateinit var pubNub: PubNubImpl
27+
28+
@BeforeEach
29+
internal fun setUp() {
30+
MockKAnnotations.init(this)
31+
val pnConfiguration =
32+
PNConfigurationImpl(
33+
userId = UserId("myUserId"),
34+
subscribeKey = "something",
35+
secretKey = "secretKey"
36+
)
37+
pubNub = spyk(PubNubImpl(configuration = pnConfiguration))
38+
}
39+
40+
@MockK
41+
private lateinit var revokeTokenEndpointMock: RevokeTokenEndpoint
42+
43+
@Test
44+
fun shouldThrowExceptionWhenSecretKeyNotProvided() {
45+
val pnConfiguration =
46+
PNConfigurationImpl(
47+
userId = UserId("myUserId"),
48+
subscribeKey = "something",
49+
)
50+
pubNub = spyk(PubNubImpl(configuration = pnConfiguration))
51+
52+
val token = "test-token"
53+
val exception = assertThrows<PubNubException> {
54+
pubNub.revokeToken(token).sync()
55+
}
56+
57+
assertEquals("Secret Key not configured", exception.errorMessage)
58+
}
59+
60+
@Test
61+
fun shouldThrowExceptionWhenTokenIsBlank() {
62+
val blankToken = ""
63+
val exception = assertThrows<PubNubException> {
64+
pubNub.revokeToken(blankToken).sync()
65+
}
66+
67+
assertEquals("Token missing", exception.errorMessage)
68+
}
69+
70+
@Test
71+
fun can_callRevokeToken() {
72+
val expectedToken = "token_value"
73+
val expectedSubscribeKey = "something"
74+
75+
val retrofitManager = mockk<RetrofitManager>(relaxed = true)
76+
val accessManagerService = mockk<AccessManagerService>(relaxed = true)
77+
val call = mockk<Call<RevokeTokenResponse>>()
78+
79+
every { pubNub.retrofitManager } returns retrofitManager
80+
every { retrofitManager.accessManagerService } returns accessManagerService
81+
every { accessManagerService.revokeToken(any(), any(), any()) } returns call
82+
every { call.execute() } returns Response.success(
83+
RevokeTokenResponse(
84+
200,
85+
RevokeTokenData("message", "token"),
86+
"service"
87+
)
88+
)
89+
90+
// Act
91+
pubNub.revokeToken(expectedToken).sync()
92+
93+
// Assert: verify the call with expected arguments
94+
verify {
95+
accessManagerService.revokeToken(
96+
expectedSubscribeKey,
97+
any(),
98+
any()
99+
)
100+
}
101+
}
102+
}

0 commit comments

Comments
 (0)