From 4a025a0d3bb319cec8fe522663e120d344733018 Mon Sep 17 00:00:00 2001
From: Owen Nelson <onelson@svix.com>
Date: Tue, 15 Oct 2024 20:13:01 -0700
Subject: [PATCH] Libs(Kotlin): add kitchen sink test

This test, like the rest of the kitchen sinks added to libs along the
way, verifies that the nullable collections like Endpoint's filterTypes
and channels are serialized properly so they don't result in a 422
status when left unset.
---
 kotlin/build.gradle                           |  9 ++-
 .../lib/src/test/com/svix/kotlin/BasicTest.kt | 76 +++++++++++++++----
 2 files changed, 70 insertions(+), 15 deletions(-)

diff --git a/kotlin/build.gradle b/kotlin/build.gradle
index 88f04c0e4e..9226f3dfbb 100644
--- a/kotlin/build.gradle
+++ b/kotlin/build.gradle
@@ -22,6 +22,7 @@ buildscript {
 }
 
 apply plugin: 'kotlin'
+apply plugin: 'com.diffplug.spotless'
 
 repositories {
     maven { url "https://repo1.maven.org/maven2" }
@@ -66,4 +67,10 @@ javadoc {
     excludes = [ "com/svix/**/*" ]
 }
 
-apply from: "deploy.gradle"
\ No newline at end of file
+apply from: "deploy.gradle"
+
+test {
+    testLogging {
+        events "passed", "skipped", "failed"
+    }
+}
\ No newline at end of file
diff --git a/kotlin/lib/src/test/com/svix/kotlin/BasicTest.kt b/kotlin/lib/src/test/com/svix/kotlin/BasicTest.kt
index 093aa447dd..bc9a4518cb 100644
--- a/kotlin/lib/src/test/com/svix/kotlin/BasicTest.kt
+++ b/kotlin/lib/src/test/com/svix/kotlin/BasicTest.kt
@@ -1,15 +1,36 @@
 package com.svix.kotlin
 
+import com.svix.kotlin.exceptions.ApiException
 import com.svix.kotlin.models.ApplicationIn
+import com.svix.kotlin.models.EndpointIn
+import com.svix.kotlin.models.EndpointPatch
+import com.svix.kotlin.models.EventTypeIn
 import com.svix.kotlin.models.MessageIn
+
 import kotlinx.coroutines.runBlocking
+import java.net.URI
 import kotlin.test.Test
 import kotlin.test.assertEquals
 
 class BasicTest {
+
+    companion object {
+        private val AUTH_TOKEN: String? = System.getenv("SVIX_TOKEN")
+        private val SERVER_URL: String? = System.getenv("SVIX_SERVER_URL")
+    }
+
+    private fun getTestClient(): Svix? {
+        return if (AUTH_TOKEN == null || SERVER_URL == null) {
+            // TODO: figure out how to log a warning here to help teach about tests that skip when the env vars are unset.
+            null
+        } else {
+            Svix(AUTH_TOKEN, SvixOptions(SERVER_URL))
+        }
+    }
+
     @Test
     fun basicCrudTest() {
-        val svix = Svix(AUTH_TOKEN, SvixOptions(SERVER_URL))
+        val svix = getTestClient() ?: return
         runBlocking {
             val applicationOut = svix.application.create(ApplicationIn(name = "App1"))
             assertEquals("App1", applicationOut.name)
@@ -18,24 +39,51 @@ class BasicTest {
                 MessageIn(
                     eventType = "invoice.paid",
                     payload =
-                        mapOf<String, Any>(
-                            "id" to "invoice_WF7WtCLFFtd8ubcTgboSFNql",
-                            "status" to "paid",
-                            "attempt" to 2,
-                        ),
+                    mapOf<String, Any>(
+                        "id" to "invoice_WF7WtCLFFtd8ubcTgboSFNql",
+                        "status" to "paid",
+                        "attempt" to 2,
+                    ),
                 ),
             )
             svix.application.delete(applicationOut.id)
         }
     }
 
-    companion object {
-        // Token for org org_00000000000LibTest000000000
-        private const val AUTH_TOKEN =
-            "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9." +
-                "eyJpYXQiOjE2NTc2MzQwNjcsImV4cCI6MTk3Mjk5NDA2NywibmJmIjoxNjU3NjM0MDY3LCJpc3M" +
-                "iOiJzdml4LXNlcnZlciIsInN1YiI6Im9yZ18wMDAwMDAwMDAwMExpYlRlc3QwMDAwMDAwMDAifQ." +
-                "IAy2wrnWhbGTeGHSYygKOID2LKFITaxNW8mHO7F5jWM"
-        private const val SERVER_URL = "http://localhost:8071"
+    @Test
+    fun kitchenSinkTest() {
+        val svix = getTestClient() ?: return
+
+        runBlocking {
+            val appOut = svix.application.create(ApplicationIn(name = "App2"))
+            try {
+                svix.eventType.create(EventTypeIn(name = "event.started", description = "Something started"))
+            } catch (e: ApiException) {
+                assertEquals(409, e.statusCode, "conflicts are expected but other bad statuses are not")
+            }
+            try {
+                svix.eventType.create(EventTypeIn(name = "event.ended", description = "Something ended"))
+            } catch (e: ApiException) {
+                assertEquals(409, e.statusCode, "conflicts are expected but other bad statuses are not")
+            }
+
+            val epOut = svix.endpoint.create(
+                appOut.id,
+                EndpointIn(url = URI("https://example.svix.com"), channels = setOf("ch0", "ch1"))
+            )
+            assertEquals(setOf("ch0", "ch1"), epOut.channels, "initial ep should have 2 channels")
+            assertEquals(0, epOut.filterTypes?.size ?: 0, "initial ep should have 0 filter types")
+            val epPatched = svix.endpoint.patch(
+                appOut.id,
+                epOut.id,
+                EndpointPatch(filterTypes = setOf("event.started", "event.ended"))
+            )
+            assertEquals(setOf("ch0", "ch1"), epPatched.channels, "patched ep should have 2 channels")
+            assertEquals(
+                setOf("event.started", "event.ended"),
+                epPatched.filterTypes,
+                "patched ep should have 2 filter types"
+            )
+        }
     }
 }