Skip to content

Commit

Permalink
Added test for storeUserActivityInterval (#142)
Browse files Browse the repository at this point in the history
  • Loading branch information
marcin-cebo authored Dec 12, 2024
1 parent 3090472 commit f2848d9
Show file tree
Hide file tree
Showing 9 changed files with 44 additions and 20 deletions.
2 changes: 1 addition & 1 deletion gradle/libs.versions.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ ktlint = "12.1.0"
dokka = "1.9.20"
kotlinx_serialization = "1.7.3"
kotlinx_coroutines = "1.9.0"
pubnub = "10.2.1"
pubnub = "10.3.0"

[libraries]
pubnub-kotlin-api = { module = "com.pubnub:pubnub-kotlin-api", version.ref = "pubnub" }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@ interface ThreadChannel : Channel {
* @return [PNFuture] containing [ThreadChannel]
*/
override fun pinMessage(message: Message): PNFuture<ThreadChannel>
// TODO change parameter to ThreadMessage

/**
* Unpins the previously pinned thread message from the thread channel.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,13 @@ interface ChatConfiguration {
* to be set to true. The default value is set to 60 seconds, and that's the minimum possible value.
* If you try to set it to a lower value, you'll get the storeUserActivityInterval must be at least 60000ms error.
*/
val storeUserActivityInterval: Duration // todo do we have test for this?
val storeUserActivityInterval: Duration

/**
* Specifies if you want to track the user's global presence in your chat app. The user's activity is tracked
* through [com.pubnub.chat.User.lastActiveTimestamp].
*/
val storeUserActivityTimestamps: Boolean // todo do we have test for this?
val storeUserActivityTimestamps: Boolean

/**
* List of parameters you must set if you want to enable sending/receiving mobile push notifications for phone
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -665,10 +665,10 @@ class ChatImpl(

val event = EventImpl(
chat = this,
timetoken = pnEvent.timetoken!!, // todo can this even be null?
timetoken = pnEvent.timetoken!!,
payload = payload,
channelId = pnEvent.channel,
userId = pnEvent.publisher!! // todo can this even be null?
userId = pnEvent.publisher!!
)
callback(event)
} catch (e: Exception) {
Expand Down Expand Up @@ -804,8 +804,9 @@ class ChatImpl(
return@thenAsync emptyList<GetUnreadMessagesCounts>().asFuture()
}
val channels = memberships.map { membership -> membership.channel.id }
val channelsTimetoken =
memberships.map { membership -> membership.lastReadMessageTimetoken ?: 0 }

val channelsTimetoken = memberships.map { membership -> membership.lastReadMessageTimetoken ?: 0 }

pubNub.messageCounts(channels = channels, channelsTimetoken = channelsTimetoken)
.then { pnMessageCountResult ->
val unreadMessageCounts =
Expand Down Expand Up @@ -853,7 +854,9 @@ class ChatImpl(

val customMap: Map<String, Any?> = buildMap {
membership.custom?.let { putAll(it) }
put(METADATA_LAST_READ_MESSAGE_TIMETOKEN, relevantLastMessageTimeToken)
// toString is required because server for odd numbers larger than 9007199254740991(timetoken has 17 digits)
// returns values that differ by one
put(METADATA_LAST_READ_MESSAGE_TIMETOKEN, relevantLastMessageTimeToken.toString())
}

PNChannelMembership.Partial(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,9 @@ data class MembershipImpl(
override fun setLastReadMessageTimetoken(timetoken: Long): PNFuture<Membership> {
val newCustom = buildMap {
custom?.let { putAll(it) }
put(METADATA_LAST_READ_MESSAGE_TIMETOKEN, timetoken)
// toString is required because server for odd numbers larger than 9007199254740991(timetoken has 17 digits)
// returns values that differ by one
put(METADATA_LAST_READ_MESSAGE_TIMETOKEN, timetoken.toString())
}
return update(createCustomObject(newCustom)).alsoAsync {
val canISendSignal = AccessManager(chat).canI(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -505,7 +505,7 @@ abstract class BaseChannel<C : Channel, M : Message>(
}

// there is a discrepancy between KMP and JS. There is no unsubscribe here. This is agreed and will be changed in JS Chat
override fun leave(): PNFuture<Unit> = chat.pubNub.removeMemberships(channels = listOf(id)).then { Unit }
override fun leave(): PNFuture<Unit> = chat.pubNub.removeMemberships(channels = listOf(id), includeType = false).then { Unit }

override fun getPinnedMessage(): PNFuture<Message?> {
val pinnedMessageTimetoken = this.custom?.get(PINNED_MESSAGE_TIMETOKEN).tryLong() ?: return null.asFuture()
Expand Down Expand Up @@ -600,7 +600,8 @@ abstract class BaseChannel<C : Channel, M : Message>(
log.pnError(READ_RECEIPTS_ARE_NOT_SUPPORTED_IN_PUBLIC_CHATS)
}
val timetokensPerUser = mutableMapOf<String, Long>()
val future = getMembers().then { members -> // todo what about paging? maybe not needed in non-public chats...
// in group chats it work till 100 members
val future = getMembers().then { members ->
members.members.forEach { m ->
val lastTimetoken = m.custom?.get(METADATA_LAST_READ_MESSAGE_TIMETOKEN)?.tryLong()
if (lastTimetoken != null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,6 @@ import delayForHistory
import kotlinx.coroutines.CompletableDeferred
import kotlinx.coroutines.test.runTest
import tryLong
import kotlin.test.Ignore
import kotlin.test.Test
import kotlin.test.assertEquals
import kotlin.test.assertFailsWith
Expand All @@ -66,6 +65,16 @@ class ChatIntegrationTest : BaseChatIntegrationTest() {
assertEquals(403, exception.statusCode)
}

@Test
fun test_storeUserActivityInterval_and_storeUserActivityTimestamps() = runTest {
chat = ChatImpl(ChatConfiguration(storeUserActivityInterval = 100.seconds, storeUserActivityTimestamps = true), pubnub)
chat.initialize().await()

val user: User = chat.getUser(chat.currentUser.id).await()!!

assertTrue(user.custom?.get("lastActiveTimestamp") != null)
}

@Test
fun initializeShouldPassWhenPamEnableAndTokenProvided() = runTest {
if (PLATFORM == "iOS") {
Expand Down Expand Up @@ -187,7 +196,7 @@ class ChatIntegrationTest : BaseChatIntegrationTest() {
val channelId02 = channel02.id
val membership01: ChannelMembershipInput = PNChannelMembership.Partial(channelId01, custom)
val membership02: ChannelMembershipInput = PNChannelMembership.Partial(channelId02)
chat.pubNub.setMemberships(listOf(membership01, membership02), chat.currentUser.id).await()
chat.pubNub.setMemberships(channels = listOf(membership01, membership02), uuid = chat.currentUser.id, includeType = false).await()

// to each channel add two messages(we want to check if last message will be taken by fetchMessages with limit = 1)
channel01.sendText("message01In$channelId01").await()
Expand Down Expand Up @@ -272,7 +281,6 @@ class ChatIntegrationTest : BaseChatIntegrationTest() {
}
}

@Ignore // fails from time to time
@Test
fun can_getUnreadMessagesCount_onMembership() = runTest {
val channelId01 = channel01.id
Expand All @@ -288,7 +296,7 @@ class ChatIntegrationTest : BaseChatIntegrationTest() {

// send message
channel01.sendText("message02In$channelId01").await()
delayInMillis(150) // history calls have around 130ms of cache time
delayForHistory()

val unreadMessageCount02: Long? = membership.getUnreadMessagesCount().await()
assertEquals(1L, unreadMessageCount02)
Expand All @@ -306,7 +314,6 @@ class ChatIntegrationTest : BaseChatIntegrationTest() {
chat.pubNub.deleteMessages(listOf(channelId01)).await()
}

@Ignore // fails from time to time
@Test
fun can_getUnreadMessageCounts_global() = runTest {
val channelId01 = channel01.id
Expand Down Expand Up @@ -350,7 +357,7 @@ class ChatIntegrationTest : BaseChatIntegrationTest() {
}?.count
?: 0
assertEquals(0, unreadMessagesCountsForChannel01)
assertEquals(0, unreadMessagesCountsForChannel02) // todo when run in set sometimes fails :/
assertEquals(0, unreadMessagesCountsForChannel02)

// remove messages
chat.pubNub.deleteMessages(listOf(channelId01, channelId02))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1331,7 +1331,7 @@ class ChatTest : BaseTest() {
val mute = false
val pnMemberArrayResult = PNMemberArrayResult(
status = 200,
data = listOf(PNMember(PNUUIDMetadata(id = userId), null, "", "", null)),
data = listOf(PNMember(PNUUIDMetadata(id = userId), null, "", "", null, null)),
1,
null,
null
Expand Down Expand Up @@ -1389,7 +1389,7 @@ class ChatTest : BaseTest() {
val reason = "He rehabilitated"
val pnMemberArrayResult = PNMemberArrayResult(
status = 200,
data = listOf(PNMember(PNUUIDMetadata(id = userId), null, "", "", null)),
data = listOf(PNMember(PNUUIDMetadata(id = userId), null, "", "", null, null)),
1,
null,
null
Expand Down
12 changes: 12 additions & 0 deletions src/jvmTest/kotlin/compubnub/chat/ChatIntegrationTest.kt
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,11 @@ import com.pubnub.test.Keys
import com.pubnub.test.await
import com.pubnub.test.randomString
import kotlinx.coroutines.test.runTest
import org.junit.Assert.assertTrue
import kotlin.test.Test
import kotlin.test.assertEquals
import kotlin.test.assertFailsWith
import kotlin.time.Duration.Companion.seconds

class ChatIntegrationTest : BaseIntegrationTest() {
@Test
Expand All @@ -42,6 +44,16 @@ class ChatIntegrationTest : BaseIntegrationTest() {
}
}

@Test
fun test_storeUserActivityInterval_and_storeUserActivityTimestamps() = runTest {
val chatConfig = ChatConfiguration(storeUserActivityInterval = 100.seconds, storeUserActivityTimestamps = true)

val chat: Chat = Chat.init(chatConfig, config).await()
val user = chat.getUser(chat.currentUser.id).await()

assertTrue(user?.custom?.get("lastActiveTimestamp") != null)
}

@Test
fun shouldReceiveExceptionWhenInitializingChatWithoutValidTokenWhenPamEnabled() = runTest {
val exception: PubNubException = assertFailsWith<PubNubException> {
Expand Down

0 comments on commit f2848d9

Please sign in to comment.