diff --git a/core/src/main/kotlin/io/specmatic/core/HttpRequest.kt b/core/src/main/kotlin/io/specmatic/core/HttpRequest.kt index ec781074e..ada324c97 100644 --- a/core/src/main/kotlin/io/specmatic/core/HttpRequest.kt +++ b/core/src/main/kotlin/io/specmatic/core/HttpRequest.kt @@ -11,7 +11,6 @@ import io.ktor.http.* import io.ktor.http.content.* import io.specmatic.core.utilities.Flags.Companion.SPECMATIC_PRETTY_PRINT import io.specmatic.core.utilities.Flags.Companion.getBooleanValue -import org.apache.http.HttpHeaders.AUTHORIZATION import org.apache.http.client.utils.URLEncodedUtils import org.apache.http.message.BasicNameValuePair import java.io.File @@ -130,7 +129,7 @@ data class HttpRequest( method?.let { requestMap["method"] = StringValue(it) } ?: throw ContractException("Can't serialise the request without a method.") - setIfNotEmpty(requestMap, "query", queryParams.asMap()) + setIfNotEmpty(requestMap, "query", queryParams.asJsonMap()) setIfNotEmpty(requestMap, "headers", headers) when { @@ -387,9 +386,17 @@ data class HttpRequest( } } -private fun setIfNotEmpty(dest: MutableMap, key: String, data: Map) { +private fun setIfNotEmpty(dest: MutableMap, key: String, data: Map) { if (data.isNotEmpty()) - dest[key] = JSONObjectValue(data.mapValues { StringValue(it.value) }) + dest[key] = JSONObjectValue(data.mapValues { + if (it.value is List<*>) { + JSONArrayValue((it.value as List<*>).map { listValue -> + StringValue(listValue.toString()) + }) + } else { + StringValue(it.value.toString()) + } + }) } fun nativeString(json: Map, key: String): String? { diff --git a/core/src/main/kotlin/io/specmatic/core/QueryParameters.kt b/core/src/main/kotlin/io/specmatic/core/QueryParameters.kt index ec73df843..8444ab17f 100644 --- a/core/src/main/kotlin/io/specmatic/core/QueryParameters.kt +++ b/core/src/main/kotlin/io/specmatic/core/QueryParameters.kt @@ -38,6 +38,16 @@ data class QueryParameters(val paramPairs: List> = emptyLis }.toMap() } + fun asJsonMap(): Map { + return paramPairs.groupBy { it.first }.map { (parameterName, parameterValues) -> + if (parameterValues.size > 1) { + parameterName to parameterValues.map { it.second } + } else { + parameterName to parameterValues.single().second + } + }.toMap() + } + fun getValues(key: String): List { return paramPairs.filter { it.first == key }.map { it.second } } diff --git a/core/src/test/kotlin/io/specmatic/core/HttpRequestTest.kt b/core/src/test/kotlin/io/specmatic/core/HttpRequestTest.kt index 2a16f69b6..e20de0813 100644 --- a/core/src/test/kotlin/io/specmatic/core/HttpRequestTest.kt +++ b/core/src/test/kotlin/io/specmatic/core/HttpRequestTest.kt @@ -1,5 +1,6 @@ package io.specmatic.core +import com.fasterxml.jackson.annotation.JsonValue import io.specmatic.core.HttpRequest.* import org.assertj.core.api.Assertions.assertThat import org.assertj.core.api.Assertions.assertThatThrownBy @@ -9,10 +10,6 @@ import org.junit.jupiter.params.ParameterizedTest import org.junit.jupiter.params.provider.Arguments import org.junit.jupiter.params.provider.MethodSource import io.specmatic.core.pattern.* -import io.specmatic.core.value.EmptyString -import io.specmatic.core.value.JSONObjectValue -import io.specmatic.core.value.NumberValue -import io.specmatic.core.value.StringValue import io.specmatic.mock.ScenarioStub import io.specmatic.optionalPattern import io.ktor.client.request.* @@ -21,6 +18,7 @@ import io.mockk.every import io.mockk.spyk import io.mockk.verify import io.specmatic.core.utilities.Flags +import io.specmatic.core.value.* import java.util.stream.Stream import org.junit.jupiter.api.Assertions.assertEquals @@ -42,6 +40,25 @@ internal class HttpRequestTest { assertThat(value.jsonObject.getValue("Data")).isEqualTo(StringValue("10")) } + + @Test + fun `when serialised to json, the request should contain multiple query parameters`() { + val queryParams = QueryParameters(listOf("key1" to "value1", "key1" to "value2", "key1" to "value3", "key2" to "value1")) + val json = HttpRequest("POST", "/").copy(queryParams = queryParams).toJSON() + val value = json.jsonObject.getValue("query") as JSONObjectValue + assertThat(value.jsonObject.getValue("key1")).isEqualTo( + JSONArrayValue( + listOf( + StringValue("value1"), + StringValue("value2"), + StringValue("value3") + ) + ) + ) + assertThat(value.jsonObject.getValue("key2")).isEqualTo(StringValue("value1") + ) + } + @Test fun `when serialised to log string, the log should contain form fields`() { val logString = HttpRequest("POST", "/").copy(formFields = mapOf("Data" to "10")).toLogString() diff --git a/core/src/test/kotlin/io/specmatic/core/QueryParametersTest.kt b/core/src/test/kotlin/io/specmatic/core/QueryParametersTest.kt index 55882f1b3..85f3aaab4 100644 --- a/core/src/test/kotlin/io/specmatic/core/QueryParametersTest.kt +++ b/core/src/test/kotlin/io/specmatic/core/QueryParametersTest.kt @@ -10,4 +10,14 @@ class QueryParametersTest { val queryParameters = QueryParameters(listOf("brand_ids" to "1", "brand_ids" to "2", "brand_ids" to "3", "category_id" to "10")) assertThat(queryParameters.asMap()).isEqualTo(mapOf("brand_ids" to "[1, 2, 3]", "category_id" to "10")) } + + @Test + fun `should return map with value as json array for query parameters`() { + val queryParameters = QueryParameters( + listOf("brand_ids" to "1", "brand_ids" to "2", "brand_ids" to "3", "category_id" to "10") + ) + assertThat(queryParameters.asJsonMap()).isEqualTo( + mapOf("brand_ids" to listOf("1", "2", "3"), "category_id" to "10") + ) + } } \ No newline at end of file