Skip to content

Commit 2b17388

Browse files
committed
[ECO-5014] feat: basic sandbox setup
added basic sandbox setup for simple happy-path testing
1 parent 4861812 commit 2b17388

File tree

4 files changed

+96
-1
lines changed

4 files changed

+96
-1
lines changed

chat-android/build.gradle.kts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ dependencies {
4949
testImplementation(libs.junit)
5050
testImplementation(libs.mockk)
5151
testImplementation(libs.coroutine.test)
52+
testImplementation(libs.bundles.ktor.client)
5253
androidTestImplementation(libs.androidx.test.core)
5354
androidTestImplementation(libs.androidx.test.runner)
5455
androidTestImplementation(libs.androidx.junit)
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
package com.ably.chat
2+
3+
import com.google.gson.JsonElement
4+
import com.google.gson.JsonParser
5+
import io.ably.lib.realtime.AblyRealtime
6+
import io.ktor.client.HttpClient
7+
import io.ktor.client.engine.cio.CIO
8+
import io.ktor.client.plugins.HttpRequestRetry
9+
import io.ktor.client.request.get
10+
import io.ktor.client.request.post
11+
import io.ktor.client.request.setBody
12+
import io.ktor.client.statement.HttpResponse
13+
import io.ktor.client.statement.bodyAsText
14+
import io.ktor.http.ContentType
15+
import io.ktor.http.contentType
16+
17+
val client = HttpClient(CIO) {
18+
install(HttpRequestRetry) {
19+
retryOnServerErrors(maxRetries = 4)
20+
exponentialDelay()
21+
}
22+
}
23+
24+
class Sandbox private constructor(val appId: String, val apiKey: String) {
25+
companion object {
26+
suspend fun createInstance(): Sandbox {
27+
val response: HttpResponse = client.post("https://sandbox-rest.ably.io/apps") {
28+
contentType(ContentType.Application.Json)
29+
setBody(loadAppCreationRequestBody().toString())
30+
}
31+
val body = JsonParser.parseString(response.bodyAsText())
32+
33+
return Sandbox(
34+
appId = body.asJsonObject["appId"].asString,
35+
// From JS chat repo at 7985ab7 — "The key we need to use is the one at index 5, which gives enough permissions to interact with Chat and Channels"
36+
apiKey = body.asJsonObject["keys"].asJsonArray[5].asJsonObject["keyStr"].asString,
37+
)
38+
}
39+
}
40+
}
41+
42+
internal fun Sandbox.createSandboxChatClient(): DefaultChatClient {
43+
val realtime = createSandboxRealtime(apiKey)
44+
return DefaultChatClient(realtime, ClientOptions())
45+
}
46+
47+
internal fun Sandbox.createSandboxRealtime(chatClientId: String = "sandbox-client"): AblyRealtime =
48+
AblyRealtime(
49+
io.ably.lib.types.ClientOptions().apply {
50+
key = apiKey
51+
environment = "sandbox"
52+
clientId = chatClientId
53+
},
54+
)
55+
56+
private suspend fun loadAppCreationRequestBody(): JsonElement =
57+
JsonParser.parseString(
58+
client.get("https://raw.githubusercontent.com/ably/ably-common/refs/heads/main/test-resources/test-app-setup.json") {
59+
contentType(ContentType.Application.Json)
60+
}.bodyAsText(),
61+
).asJsonObject.get("post_apps")
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
package com.ably.chat
2+
3+
import io.ably.lib.realtime.ChannelState
4+
import java.util.UUID
5+
import kotlinx.coroutines.test.runTest
6+
import org.junit.Assert.assertEquals
7+
import org.junit.Before
8+
import org.junit.Test
9+
10+
class SandboxTest {
11+
12+
private lateinit var sandbox: Sandbox
13+
14+
@Before
15+
fun setUp() = runTest {
16+
sandbox = Sandbox.createInstance()
17+
}
18+
19+
@Test
20+
fun basicIntegrationTest() = runTest {
21+
val chatClient = sandbox.createSandboxChatClient()
22+
val room = chatClient.rooms.get(UUID.randomUUID().toString())
23+
room.attach()
24+
assertEquals(ChannelState.attached, room.messages.channel.state)
25+
}
26+
}

gradle/libs.versions.toml

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ gson = "2.11.0"
2020
mockk = "1.13.12"
2121
coroutine = "1.8.1"
2222
build-config = "5.4.0"
23+
ktor = "3.0.1"
2324

2425
[libraries]
2526
junit = { group = "junit", name = "junit", version.ref = "junit" }
@@ -50,9 +51,15 @@ mockk = { group = "io.mockk", name = "mockk", version.ref = "mockk" }
5051
coroutine-core = { group = "org.jetbrains.kotlinx", name = "kotlinx-coroutines-core", version.ref = "coroutine" }
5152
coroutine-test = { group = "org.jetbrains.kotlinx", name = "kotlinx-coroutines-test", version.ref = "coroutine" }
5253

54+
ktor-client-core = { module = "io.ktor:ktor-client-core", version.ref = "ktor" }
55+
ktor-client-cio = { module = "io.ktor:ktor-client-cio", version.ref = "ktor" }
56+
57+
[bundles]
58+
ktor-client = ["ktor-client-core", "ktor-client-cio"]
59+
5360
[plugins]
5461
detekt = { id = "io.gitlab.arturbosch.detekt", version.ref = "detekt"}
55-
android-kotlin = { id = "org.jetbrains.kotlin.android", version.ref = "kotlin" }
62+
android-kotlin = { id = "org.jetbrains.kotlin.android", version = "2.0.21" }
5663
android-library = { id = "com.android.library", version.ref = "agp" }
5764
android-application = { id = "com.android.application", version.ref = "agp" }
5865
compose-compiler = { id = "org.jetbrains.kotlin.plugin.compose", version.ref = "kotlin" }

0 commit comments

Comments
 (0)