From 4e986625656f3430531207a2df08bff18e225128 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kevin=20Gr=C3=BCneberg?= Date: Wed, 3 Feb 2021 22:42:40 +0100 Subject: [PATCH] Tests for query builder, fix count --- build.gradle | 2 +- .../postgrest/builder/PostgrestBuilder.kt | 12 ++ .../builder/PostgrestQueryBuilder.kt | 28 +-- .../builder/PostgrestQueryBuilderTest.kt | 176 ++++++++++++++++++ 4 files changed, 205 insertions(+), 13 deletions(-) create mode 100644 src/test/kotlin/io/supabase/postgrest/builder/PostgrestQueryBuilderTest.kt diff --git a/build.gradle b/build.gradle index 6a0065d..1d69803 100644 --- a/build.gradle +++ b/build.gradle @@ -12,7 +12,7 @@ plugins { id "com.jfrog.bintray" version "1.8.5" } -String currentVersion = '0.1.0' +String currentVersion = '0.2.0' group = 'io.supabase' version = currentVersion diff --git a/src/main/kotlin/io/supabase/postgrest/builder/PostgrestBuilder.kt b/src/main/kotlin/io/supabase/postgrest/builder/PostgrestBuilder.kt index f6115aa..05a00b2 100644 --- a/src/main/kotlin/io/supabase/postgrest/builder/PostgrestBuilder.kt +++ b/src/main/kotlin/io/supabase/postgrest/builder/PostgrestBuilder.kt @@ -61,6 +61,18 @@ open class PostgrestBuilder { return searchParams } + fun getBody(): Any? { + return this.body + } + + fun getHeaders(): Map { + return this.headers + } + + fun getMethod(): Method? { + return this.method + } + fun execute(): PostgrestHttpResponse { checkNotNull(method) { "Method cannot be null" } diff --git a/src/main/kotlin/io/supabase/postgrest/builder/PostgrestQueryBuilder.kt b/src/main/kotlin/io/supabase/postgrest/builder/PostgrestQueryBuilder.kt index a32a427..a5b907e 100644 --- a/src/main/kotlin/io/supabase/postgrest/builder/PostgrestQueryBuilder.kt +++ b/src/main/kotlin/io/supabase/postgrest/builder/PostgrestQueryBuilder.kt @@ -8,6 +8,10 @@ import java.net.URI class PostgrestQueryBuilder(url: URI, postgrestHttpClient: PostgrestHttpClient, jsonConverter: PostgrestJsonConverter, defaultHeaders: Map, schema: String?) : PostgrestBuilder(url, postgrestHttpClient, jsonConverter, defaultHeaders, schema) { + companion object { + const val HEADER_PREFER = "Prefer" + } + /** * Performs vertical filtering with SELECT. * @@ -20,18 +24,18 @@ class PostgrestQueryBuilder(url: URI, postgrestHttpClient: PostgrestHtt head: Boolean = false, count: Count? = null ): PostgrestFilterBuilder { - setMethod(Method.GET) + if (head) { + setMethod(Method.HEAD) + } else { + setMethod(Method.GET) + } val cleanedColumns = cleanColumns(columns) setSearchParam("select", cleanedColumns) if (count != null) { - setHeader("Prefer", "count=${count.identifier}") - } - - if (head) { - setMethod(Method.HEAD) + setHeader(HEADER_PREFER, "count=${count.identifier}") } return PostgrestFilterBuilder(this) @@ -55,10 +59,10 @@ class PostgrestQueryBuilder(url: URI, postgrestHttpClient: PostgrestHtt setBody(values) if (count != null) { - preferHeaders.add("count=${count}") + preferHeaders.add("count=${count.identifier}") } - setHeader("Prefer", preferHeaders.joinToString(",")) + setHeader(HEADER_PREFER, preferHeaders.joinToString(",")) return PostgrestFilterBuilder(this) } @@ -88,9 +92,9 @@ class PostgrestQueryBuilder(url: URI, postgrestHttpClient: PostgrestHtt val prefersHeaders = mutableListOf("return=${returning.identifier}") if (count != null) { - prefersHeaders.add("count=${count}") + prefersHeaders.add("count=${count.identifier}") } - setHeader("Prefer", prefersHeaders.joinToString(",")) + setHeader(HEADER_PREFER, prefersHeaders.joinToString(",")) return PostgrestFilterBuilder(this) } @@ -105,9 +109,9 @@ class PostgrestQueryBuilder(url: URI, postgrestHttpClient: PostgrestHtt val prefersHeaders = mutableListOf("return=${returning.identifier}") if (count != null) { - prefersHeaders.add("count=${count}") + prefersHeaders.add("count=${count.identifier}") } - setHeader("Prefer", prefersHeaders.joinToString(",")) + setHeader(HEADER_PREFER, prefersHeaders.joinToString(",")) return PostgrestFilterBuilder(this) } diff --git a/src/test/kotlin/io/supabase/postgrest/builder/PostgrestQueryBuilderTest.kt b/src/test/kotlin/io/supabase/postgrest/builder/PostgrestQueryBuilderTest.kt new file mode 100644 index 0000000..fd84fbf --- /dev/null +++ b/src/test/kotlin/io/supabase/postgrest/builder/PostgrestQueryBuilderTest.kt @@ -0,0 +1,176 @@ +package io.supabase.postgrest.builder + +import assertk.assertThat +import assertk.assertions.isEqualTo +import io.mockk.mockk +import org.apache.hc.core5.http.Method +import org.junit.jupiter.api.BeforeEach +import org.junit.jupiter.api.Nested +import org.junit.jupiter.api.Test +import java.net.URI + +internal class PostgrestQueryBuilderTest { + + private var queryBuilder: PostgrestQueryBuilder? = null + + @BeforeEach + fun beforeEach() { + queryBuilder = PostgrestQueryBuilder(URI("123"), mockk(), mockk(), emptyMap(), null) + } + + @Nested + inner class Select { + + @Test + fun `basic select`() { + queryBuilder!!.select(columns = "*") + assertMethod(Method.GET) + assertSearchParam("select", "*") + } + + @Test + fun `select with head`() { + queryBuilder!!.select(head = true) + assertMethod(Method.HEAD) + } + + @Test + fun `select with count`() { + queryBuilder!!.select(count = Count.PLANNED) + assertHeader("Prefer", "count=planned") + } + } + + @Nested + inner class Insert { + + private val value = mapOf("foo" to "bar") + + @Test + fun `insert single`() { + queryBuilder!!.insert(value = value) + assertMethod(Method.POST) + assertBody(listOf(value)) + } + + @Test + fun `insert multiple`() { + val values = listOf(value, value) + queryBuilder!!.insert(values = values) + assertBody(values) + } + + @Test + fun `insert with count`() { + queryBuilder!!.insert(value = value, count = Count.ESTIMATED) + assertHeader("Prefer", "return=representation,count=estimated") + } + + @Test + fun `insert with different returning`() { + queryBuilder!!.insert(value = value, returning = Returning.MINIMAL) + assertHeader("Prefer", "return=minimal") + } + + @Test + fun `upsert`() { + queryBuilder!!.insert(value = value, upsert = true) + assertHeader("Prefer", "return=representation,resolution=merge-duplicates") + } + + @Test + fun `upsert with count`() { + queryBuilder!!.insert(value = value, upsert = true, count = Count.EXACT) + assertHeader("Prefer", "return=representation,resolution=merge-duplicates,count=exact") + } + + @Test + fun `upsert with onconflict`() { + queryBuilder!!.insert(value = value, upsert = true, onConflict = "foobar") + assertHeader("Prefer", "return=representation,resolution=merge-duplicates") + assertSearchParam("on_conflict", "foobar") + } + } + + @Nested + inner class Update { + + private val value = mapOf("foo" to "bar") + + @Test + fun `update`() { + queryBuilder!!.update(value = value) + assertMethod(Method.PATCH) + } + + @Test + fun `update with count`() { + queryBuilder!!.update(value = value, count = Count.EXACT) + assertHeader("Prefer", "return=representation,count=exact") + } + + @Test + fun `insert with different returning`() { + queryBuilder!!.update(value = value, returning = Returning.MINIMAL) + assertHeader("Prefer", "return=minimal") + } + } + + @Nested + inner class Delete { + + @Test + fun `delete`() { + queryBuilder!!.delete() + assertMethod(Method.DELETE) + } + + @Test + fun `delete with count`() { + queryBuilder!!.delete(count = Count.PLANNED) + assertHeader("Prefer", "return=representation,count=planned") + } + + @Test + fun `delete with different returning`() { + queryBuilder!!.delete(returning = Returning.MINIMAL) + assertHeader("Prefer", "return=minimal") + } + } + + @Nested + inner class Rpc { + + @Test + fun `rpc without body`() { + queryBuilder!!.rpc(null) + assertMethod(Method.POST) + assertBody(null) + } + + @Test + fun `rpc with body`() { + val params = mapOf("foo" to "bar") + queryBuilder!!.rpc(params) + assertBody(params) + } + } + + private fun assertHeader(name: String, value: String) { + assertThat(queryBuilder!!.getHeaders()[name]).isEqualTo(value) + } + + private fun assertMethod(method: Method) { + assertThat(queryBuilder!!.getMethod()).isEqualTo(method) + } + + private fun assertBody(body: Any?) { + assertThat(queryBuilder!!.getBody()).isEqualTo(body) + } + + private fun assertSearchParam(name: String, value: String) { + val searchParams = queryBuilder!!.getSearchParams() + assertThat(searchParams[name]).isEqualTo(value) + } + +} \ No newline at end of file