Skip to content

Commit

Permalink
[ECO-5063] fix: broken test after Kotlin adapter integration
Browse files Browse the repository at this point in the history
changed some test to support new kotlin RealtimeChannel and RealtimeClient objects
  • Loading branch information
ttypic committed Feb 26, 2025
1 parent d54d2bb commit e1dc694
Show file tree
Hide file tree
Showing 13 changed files with 324 additions and 280 deletions.
1 change: 1 addition & 0 deletions chat-android/src/test/java/com/ably/chat/ChatApiTest.kt
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.ably.chat

import com.ably.pubsub.RealtimeClient
import com.google.gson.JsonObject
import io.ably.lib.types.AblyException
import io.ably.lib.types.MessageAction
Expand Down
59 changes: 29 additions & 30 deletions chat-android/src/test/java/com/ably/chat/MessagesTest.kt
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
package com.ably.chat

import com.ably.chat.room.createMockChannel
import com.ably.annotations.InternalAPI
import com.ably.chat.room.createMockChatApi
import com.ably.chat.room.createMockRealtimeChannel
import com.ably.chat.room.createMockRealtimeClient
import com.ably.chat.room.createMockRoom
import com.google.gson.JsonObject
import io.ably.lib.realtime.Channel
import io.ably.lib.realtime.ChannelBase
import io.ably.lib.realtime.ChannelState
import io.ably.lib.realtime.ChannelStateListener
import io.ably.lib.realtime.buildChannelStateChange
import io.ably.lib.types.AblyException
import io.ably.lib.types.ChannelProperties
import io.ably.lib.types.MessageAction
import io.ably.lib.types.MessageExtras
import io.mockk.every
Expand All @@ -28,18 +28,17 @@ import org.junit.Test
class MessagesTest {

private val realtimeClient = createMockRealtimeClient()
private val realtimeChannel = realtimeClient.createMockChannel()

private lateinit var messages: DefaultMessages
private val channelStateListenerSlot = slot<ChannelStateListener>()

@OptIn(InternalAPI::class)
@Before
fun setUp() {
every { realtimeClient.channels.get(any(), any()) } returns realtimeChannel
every { realtimeChannel.on(capture(channelStateListenerSlot)) } answers {
println("Channel state listener registered")
}

val channel = createMockRealtimeChannel("room1::\$chat::\$chatMessages")
every { channel.javaChannel.on(capture(channelStateListenerSlot)) } returns mockk()
val channels = realtimeClient.channels
every { channels.get("room1::\$chat::\$chatMessages", any()) } returns channel
val chatApi = createMockChatApi(realtimeClient)
val room = createMockRoom("room1", realtimeClient = realtimeClient, chatApi = chatApi)

Expand Down Expand Up @@ -90,17 +89,15 @@ class MessagesTest {
fun `should be able to subscribe to incoming messages`() = runTest {
val pubSubMessageListenerSlot = slot<PubSubMessageListener>()

every { realtimeChannel.subscribe("chat.message", capture(pubSubMessageListenerSlot)) } answers {
println("Pub/Sub message listener registered")
}
every { messages.channelWrapper.subscribe("chat.message", capture(pubSubMessageListenerSlot)) } returns mockk()

val deferredValue = CompletableDeferred<MessageEvent>()

messages.subscribe {
deferredValue.complete(it)
}

verify { realtimeChannel.subscribe("chat.message", any()) }
verify { messages.channelWrapper.subscribe("chat.message", any()) }

pubSubMessageListenerSlot.captured.onMessage(
PubSubMessage().apply {
Expand Down Expand Up @@ -168,13 +165,13 @@ class MessagesTest {
*/
@Test
fun `every subscription should have own channel serial`() = runTest {
messages.channel.properties.channelSerial = "channel-serial-1"
messages.channel.state = ChannelState.attached
every { messages.channelWrapper.state } returns ChannelState.attached
every { messages.channelWrapper.properties } returns ChannelProperties().apply { channelSerial = "channel-serial-1" }

val subscription1 = (messages.subscribe {}) as DefaultMessagesSubscription
assertEquals("channel-serial-1", subscription1.fromSerialProvider().await())

messages.channel.properties.channelSerial = "channel-serial-2"
every { messages.channelWrapper.properties } returns ChannelProperties().apply { channelSerial = "channel-serial-2" }
val subscription2 = (messages.subscribe {}) as DefaultMessagesSubscription

assertEquals("channel-serial-2", subscription2.fromSerialProvider().await())
Expand All @@ -186,14 +183,16 @@ class MessagesTest {
*/
@Test
fun `subscription should update channel serial after reattach with resume = false`() = runTest {
messages.channel.properties.channelSerial = "channel-serial-1"
messages.channel.state = ChannelState.attached
every { messages.channelWrapper.state } returns ChannelState.attached
every { messages.channelWrapper.properties } returns ChannelProperties().apply { channelSerial = "channel-serial-1" }

val subscription1 = (messages.subscribe {}) as DefaultMessagesSubscription
assertEquals("channel-serial-1", subscription1.fromSerialProvider().await())

messages.channel.properties.channelSerial = "channel-serial-2"
messages.channel.properties.attachSerial = "attach-serial-2"
every { messages.channelWrapper.properties } returns ChannelProperties().apply {
channelSerial = "channel-serial-2"
attachSerial = "attach-serial-2"
}
channelStateListenerSlot.captured.onChannelStateChanged(
buildChannelStateChange(
current = ChannelState.attached,
Expand All @@ -205,8 +204,8 @@ class MessagesTest {
assertEquals("attach-serial-2", subscription1.fromSerialProvider().await())

// Check channelSerial is used at the point of subscription when state is attached
messages.channel.properties.channelSerial = "channel-serial-3"
messages.channel.state = ChannelState.attached
every { messages.channelWrapper.properties } returns ChannelProperties().apply { channelSerial = "channel-serial-3" }
every { messages.channelWrapper.state } returns ChannelState.attached

val subscription2 = (messages.subscribe {}) as DefaultMessagesSubscription
assertEquals("channel-serial-3", subscription2.fromSerialProvider().await())
Expand All @@ -217,27 +216,27 @@ class MessagesTest {
val listener1 = mockk<Messages.Listener>(relaxed = true)
val listener2 = mockk<Messages.Listener>(relaxed = true)

val pubSubMessageListenerSlot = slot<PubSubMessageListener>()

every { messages.channelWrapper.subscribe("chat.message", capture(pubSubMessageListenerSlot)) } returns mockk()

messages.subscribe(listener1)
val capturedSlots = mutableListOf(pubSubMessageListenerSlot.captured)

messages.channel.channelMulticaster.onMessage(buildDummyPubSubMessage())
capturedSlots.forEach { it.onMessage(buildDummyPubSubMessage()) }

verify(exactly = 1) { listener1.onEvent(any()) }

messages.subscribe(listener2)
capturedSlots.add(pubSubMessageListenerSlot.captured)

messages.channel.channelMulticaster.onMessage(buildDummyPubSubMessage())
capturedSlots.forEach { it.onMessage(buildDummyPubSubMessage()) }

verify(exactly = 2) { listener1.onEvent(any()) }
verify(exactly = 1) { listener2.onEvent(any()) }
}
}

private val Channel.channelMulticaster: ChannelBase.MessageListener
get() {
val eventListeners = getPrivateField<HashMap<*, *>>("eventListeners")
return eventListeners["chat.message"] as ChannelBase.MessageListener
}

private fun buildDummyPubSubMessage() = PubSubMessage().apply {
data = JsonObject().apply {
addProperty("text", "dummy text")
Expand Down
12 changes: 6 additions & 6 deletions chat-android/src/test/java/com/ably/chat/OccupancyTest.kt
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
package com.ably.chat

import com.ably.chat.room.createMockChannel
import com.ably.chat.room.createMockChatApi
import com.ably.chat.room.createMockRealtimeChannel
import com.ably.chat.room.createMockRealtimeClient
import com.ably.chat.room.createMockRoom
import com.google.gson.JsonObject
import io.mockk.every
import io.mockk.mockk
import io.mockk.slot
import kotlinx.coroutines.CompletableDeferred
import kotlinx.coroutines.test.runTest
Expand All @@ -21,11 +22,10 @@ class OccupancyTest {

@Before
fun setUp() {
val mockRealtimeChannel = realtimeClient.createMockChannel()
every { mockRealtimeChannel.subscribe(capture(pubSubMessageListenerSlot)) } returns Unit

every { realtimeClient.channels.get(any(), any()) } returns mockRealtimeChannel

val channel = createMockRealtimeChannel("room1::\$chat::\$chatMessages")
every { channel.subscribe(capture(pubSubMessageListenerSlot)) } returns mockk(relaxUnitFun = true)
val channels = realtimeClient.channels
every { channels.get("room1::\$chat::\$chatMessages", any()) } returns channel
val mockChatApi = createMockChatApi(realtimeClient)
val room = createMockRoom("room1", realtimeClient = realtimeClient, chatApi = mockChatApi)
occupancy = DefaultOccupancy(room)
Expand Down
25 changes: 12 additions & 13 deletions chat-android/src/test/java/com/ably/chat/PresenceTest.kt
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
package com.ably.chat

import com.ably.chat.room.createMockChannel
import com.ably.chat.room.DEFAULT_ROOM_ID
import com.ably.chat.room.createMockRealtimeChannel
import com.ably.chat.room.createMockRealtimeClient
import com.ably.chat.room.createMockRoom
import com.ably.pubsub.RealtimePresence
import com.google.gson.JsonObject
import com.google.gson.JsonPrimitive
import io.ably.lib.realtime.Presence.PresenceListener
import io.ably.lib.types.ChannelOptions
import io.ably.lib.types.PresenceMessage
import io.mockk.every
import io.mockk.mockk
Expand All @@ -16,21 +17,19 @@ import kotlinx.coroutines.test.runTest
import org.junit.Assert.assertEquals
import org.junit.Before
import org.junit.Test
import io.ably.lib.realtime.Presence as PubSubPresence

class PresenceTest {

private val pubSubPresence = mockk<PubSubPresence>(relaxed = true)
private val realtimeClient = createMockRealtimeClient()
private lateinit var pubSubPresence: RealtimePresence
private lateinit var presence: DefaultPresence

@Before
fun setUp() {
val realtimeClient = createMockRealtimeClient()
val mockRealtimeChannel = realtimeClient.createMockChannel("room1::\$chat::\$messages")
mockRealtimeChannel.setPrivateField("presence", pubSubPresence)

every { realtimeClient.channels.get(any<String>(), any<ChannelOptions>()) } returns mockRealtimeChannel

val channel = createMockRealtimeChannel("$DEFAULT_ROOM_ID::\$chat::\$chatMessages")
val channels = realtimeClient.channels
every { channels.get("$DEFAULT_ROOM_ID::\$chat::\$chatMessages", any()) } returns channel
pubSubPresence = channel.presence
presence = DefaultPresence(createMockRoom(realtimeClient = realtimeClient))
}

Expand All @@ -41,7 +40,7 @@ class PresenceTest {
fun `should transform PresenceMessage into Chat's PresenceEvent if there is no data`() = runTest {
val presenceListenerSlot = slot<PresenceListener>()

every { pubSubPresence.subscribe(capture(presenceListenerSlot)) } returns Unit
every { pubSubPresence.subscribe(capture(presenceListenerSlot)) } returns mockk(relaxed = true)

val deferredValue = CompletableDeferred<PresenceEvent>()

Expand Down Expand Up @@ -77,7 +76,7 @@ class PresenceTest {
fun `should transform PresenceMessage into Chat's PresenceEvent if there is no 'userCustomData'`() = runTest {
val presenceListenerSlot = slot<PresenceListener>()

every { pubSubPresence.subscribe(capture(presenceListenerSlot)) } returns Unit
every { pubSubPresence.subscribe(capture(presenceListenerSlot)) } returns mockk(relaxUnitFun = true)

val deferredValue = CompletableDeferred<PresenceEvent>()

Expand Down Expand Up @@ -114,7 +113,7 @@ class PresenceTest {
fun `should transform PresenceMessage into Chat's PresenceEvent if 'userCustomData' is primitive`() = runTest {
val presenceListenerSlot = slot<PresenceListener>()

every { pubSubPresence.subscribe(capture(presenceListenerSlot)) } returns Unit
every { pubSubPresence.subscribe(capture(presenceListenerSlot)) } returns mockk(relaxUnitFun = true)

val deferredValue = CompletableDeferred<PresenceEvent>()

Expand Down
19 changes: 3 additions & 16 deletions chat-android/src/test/java/com/ably/chat/RoomReactionsTest.kt
Original file line number Diff line number Diff line change
@@ -1,13 +1,11 @@
package com.ably.chat

import com.ably.chat.room.createMockChannel
import com.ably.chat.room.createMockRealtimeClient
import com.ably.chat.room.createMockRoom
import com.google.gson.JsonObject
import io.ably.lib.realtime.Channel
import io.ably.lib.realtime.buildRealtimeChannel
import io.ably.lib.types.MessageExtras
import io.mockk.every
import io.mockk.mockk
import io.mockk.slot
import io.mockk.verify
import kotlinx.coroutines.CompletableDeferred
Expand All @@ -17,23 +15,12 @@ import org.junit.Before
import org.junit.Test

class RoomReactionsTest {
private lateinit var realtimeChannel: Channel
private lateinit var roomReactions: DefaultRoomReactions
private lateinit var room: DefaultRoom

@Before
fun setUp() {
val realtimeClient = createMockRealtimeClient()
realtimeChannel = realtimeClient.createMockChannel("room1::\$chat::\$reactions")

every { realtimeClient.channels.get(any(), any()) } answers {
val channelName = firstArg<String>()
if (channelName == "room1::\$chat::\$reactions") {
realtimeChannel
} else {
buildRealtimeChannel(channelName)
}
}
room = createMockRoom("room1", "client1", realtimeClient = realtimeClient)
roomReactions = DefaultRoomReactions(room)
}
Expand All @@ -58,15 +45,15 @@ class RoomReactionsTest {
fun `should be able to subscribe to incoming reactions`() = runTest {
val pubSubMessageListenerSlot = slot<PubSubMessageListener>()

every { realtimeChannel.subscribe("roomReaction", capture(pubSubMessageListenerSlot)) } returns Unit
every { roomReactions.channelWrapper.subscribe("roomReaction", capture(pubSubMessageListenerSlot)) } returns mockk(relaxed = true)

val deferredValue = CompletableDeferred<Reaction>()

roomReactions.subscribe {
deferredValue.complete(it)
}

verify { realtimeChannel.subscribe("roomReaction", any()) }
verify { roomReactions.channelWrapper.subscribe("roomReaction", any()) }

pubSubMessageListenerSlot.captured.onMessage(
PubSubMessage().apply {
Expand Down
14 changes: 8 additions & 6 deletions chat-android/src/test/java/com/ably/chat/TestUtils.kt
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package com.ably.chat

import com.ably.http.HttpMethod
import com.ably.pubsub.RealtimeClient
import com.google.gson.JsonElement
import io.ably.lib.types.AsyncHttpPaginatedResponse
import io.mockk.every
Expand All @@ -21,9 +23,9 @@ fun buildAsyncHttpPaginatedResponse(items: List<JsonElement>): AsyncHttpPaginate

fun mockMessagesApiResponse(realtimeClientMock: RealtimeClient, response: List<JsonElement>, roomId: String = "roomId") {
every {
realtimeClientMock.requestAsync("GET", "/chat/v2/rooms/$roomId/messages", any(), any(), any(), any())
realtimeClientMock.requestAsync("/chat/v2/rooms/$roomId/messages", any(), HttpMethod.Get, any(), any(), any())
} answers {
val callback = lastArg<AsyncHttpPaginatedResponse.Callback>()
val callback = secondArg<AsyncHttpPaginatedResponse.Callback>()
callback.onResponse(
buildAsyncHttpPaginatedResponse(response),
)
Expand All @@ -32,9 +34,9 @@ fun mockMessagesApiResponse(realtimeClientMock: RealtimeClient, response: List<J

fun mockSendMessageApiResponse(realtimeClientMock: RealtimeClient, response: JsonElement, roomId: String = "roomId") {
every {
realtimeClientMock.requestAsync("POST", "/chat/v2/rooms/$roomId/messages", any(), any(), any(), any())
realtimeClientMock.requestAsync("/chat/v2/rooms/$roomId/messages", any(), HttpMethod.Post, any(), any(), any())
} answers {
val callback = lastArg<AsyncHttpPaginatedResponse.Callback>()
val callback = secondArg<AsyncHttpPaginatedResponse.Callback>()
callback.onResponse(
buildAsyncHttpPaginatedResponse(
listOf(response),
Expand All @@ -45,9 +47,9 @@ fun mockSendMessageApiResponse(realtimeClientMock: RealtimeClient, response: Jso

fun mockOccupancyApiResponse(realtimeClientMock: RealtimeClient, response: JsonElement, roomId: String = "roomId") {
every {
realtimeClientMock.requestAsync("GET", "/chat/v2/rooms/$roomId/occupancy", any(), any(), any(), any())
realtimeClientMock.requestAsync("/chat/v2/rooms/$roomId/occupancy", any(), HttpMethod.Get, any(), any(), any())
} answers {
val callback = lastArg<AsyncHttpPaginatedResponse.Callback>()
val callback = secondArg<AsyncHttpPaginatedResponse.Callback>()
callback.onResponse(
buildAsyncHttpPaginatedResponse(
listOf(response),
Expand Down
Loading

0 comments on commit e1dc694

Please sign in to comment.