From 2b173888e800282585bac4c4406b38cb36d301f7 Mon Sep 17 00:00:00 2001 From: evgeny Date: Mon, 11 Nov 2024 13:06:58 +0000 Subject: [PATCH] [ECO-5014] feat: basic sandbox setup added basic sandbox setup for simple happy-path testing --- chat-android/build.gradle.kts | 1 + .../src/test/java/com/ably/chat/Sandbox.kt | 61 +++++++++++++++++++ .../test/java/com/ably/chat/SandboxTest.kt | 26 ++++++++ gradle/libs.versions.toml | 9 ++- 4 files changed, 96 insertions(+), 1 deletion(-) create mode 100644 chat-android/src/test/java/com/ably/chat/Sandbox.kt create mode 100644 chat-android/src/test/java/com/ably/chat/SandboxTest.kt diff --git a/chat-android/build.gradle.kts b/chat-android/build.gradle.kts index 9f116f4b..26a37679 100644 --- a/chat-android/build.gradle.kts +++ b/chat-android/build.gradle.kts @@ -49,6 +49,7 @@ dependencies { testImplementation(libs.junit) testImplementation(libs.mockk) testImplementation(libs.coroutine.test) + testImplementation(libs.bundles.ktor.client) androidTestImplementation(libs.androidx.test.core) androidTestImplementation(libs.androidx.test.runner) androidTestImplementation(libs.androidx.junit) diff --git a/chat-android/src/test/java/com/ably/chat/Sandbox.kt b/chat-android/src/test/java/com/ably/chat/Sandbox.kt new file mode 100644 index 00000000..0bae074b --- /dev/null +++ b/chat-android/src/test/java/com/ably/chat/Sandbox.kt @@ -0,0 +1,61 @@ +package com.ably.chat + +import com.google.gson.JsonElement +import com.google.gson.JsonParser +import io.ably.lib.realtime.AblyRealtime +import io.ktor.client.HttpClient +import io.ktor.client.engine.cio.CIO +import io.ktor.client.plugins.HttpRequestRetry +import io.ktor.client.request.get +import io.ktor.client.request.post +import io.ktor.client.request.setBody +import io.ktor.client.statement.HttpResponse +import io.ktor.client.statement.bodyAsText +import io.ktor.http.ContentType +import io.ktor.http.contentType + +val client = HttpClient(CIO) { + install(HttpRequestRetry) { + retryOnServerErrors(maxRetries = 4) + exponentialDelay() + } +} + +class Sandbox private constructor(val appId: String, val apiKey: String) { + companion object { + suspend fun createInstance(): Sandbox { + val response: HttpResponse = client.post("https://sandbox-rest.ably.io/apps") { + contentType(ContentType.Application.Json) + setBody(loadAppCreationRequestBody().toString()) + } + val body = JsonParser.parseString(response.bodyAsText()) + + return Sandbox( + appId = body.asJsonObject["appId"].asString, + // 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" + apiKey = body.asJsonObject["keys"].asJsonArray[5].asJsonObject["keyStr"].asString, + ) + } + } +} + +internal fun Sandbox.createSandboxChatClient(): DefaultChatClient { + val realtime = createSandboxRealtime(apiKey) + return DefaultChatClient(realtime, ClientOptions()) +} + +internal fun Sandbox.createSandboxRealtime(chatClientId: String = "sandbox-client"): AblyRealtime = + AblyRealtime( + io.ably.lib.types.ClientOptions().apply { + key = apiKey + environment = "sandbox" + clientId = chatClientId + }, + ) + +private suspend fun loadAppCreationRequestBody(): JsonElement = + JsonParser.parseString( + client.get("https://raw.githubusercontent.com/ably/ably-common/refs/heads/main/test-resources/test-app-setup.json") { + contentType(ContentType.Application.Json) + }.bodyAsText(), + ).asJsonObject.get("post_apps") diff --git a/chat-android/src/test/java/com/ably/chat/SandboxTest.kt b/chat-android/src/test/java/com/ably/chat/SandboxTest.kt new file mode 100644 index 00000000..0411e58e --- /dev/null +++ b/chat-android/src/test/java/com/ably/chat/SandboxTest.kt @@ -0,0 +1,26 @@ +package com.ably.chat + +import io.ably.lib.realtime.ChannelState +import java.util.UUID +import kotlinx.coroutines.test.runTest +import org.junit.Assert.assertEquals +import org.junit.Before +import org.junit.Test + +class SandboxTest { + + private lateinit var sandbox: Sandbox + + @Before + fun setUp() = runTest { + sandbox = Sandbox.createInstance() + } + + @Test + fun basicIntegrationTest() = runTest { + val chatClient = sandbox.createSandboxChatClient() + val room = chatClient.rooms.get(UUID.randomUUID().toString()) + room.attach() + assertEquals(ChannelState.attached, room.messages.channel.state) + } +} diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 35bce2df..fec4ac7f 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -20,6 +20,7 @@ gson = "2.11.0" mockk = "1.13.12" coroutine = "1.8.1" build-config = "5.4.0" +ktor = "3.0.1" [libraries] junit = { group = "junit", name = "junit", version.ref = "junit" } @@ -50,9 +51,15 @@ mockk = { group = "io.mockk", name = "mockk", version.ref = "mockk" } coroutine-core = { group = "org.jetbrains.kotlinx", name = "kotlinx-coroutines-core", version.ref = "coroutine" } coroutine-test = { group = "org.jetbrains.kotlinx", name = "kotlinx-coroutines-test", version.ref = "coroutine" } +ktor-client-core = { module = "io.ktor:ktor-client-core", version.ref = "ktor" } +ktor-client-cio = { module = "io.ktor:ktor-client-cio", version.ref = "ktor" } + +[bundles] +ktor-client = ["ktor-client-core", "ktor-client-cio"] + [plugins] detekt = { id = "io.gitlab.arturbosch.detekt", version.ref = "detekt"} -android-kotlin = { id = "org.jetbrains.kotlin.android", version.ref = "kotlin" } +android-kotlin = { id = "org.jetbrains.kotlin.android", version = "2.0.21" } android-library = { id = "com.android.library", version.ref = "agp" } android-application = { id = "com.android.application", version.ref = "agp" } compose-compiler = { id = "org.jetbrains.kotlin.plugin.compose", version.ref = "kotlin" }