Skip to content

Commit

Permalink
Merge branch 'main' of github.com:znsio/specmatic
Browse files Browse the repository at this point in the history
  • Loading branch information
joelrosario committed Dec 26, 2023
2 parents 9ecf0b7 + 5700630 commit 51db9f0
Show file tree
Hide file tree
Showing 6 changed files with 299 additions and 235 deletions.
6 changes: 1 addition & 5 deletions core/src/main/kotlin/in/specmatic/core/HttpRequest.kt
Original file line number Diff line number Diff line change
Expand Up @@ -192,11 +192,7 @@ data class HttpRequest(

else -> {
when {
headers.containsKey("Content-Type") -> TextContent(
bodyString,
ContentType.parse(headers["Content-Type"] as String)
)

headers.containsKey(CONTENT_TYPE) -> TextContent(bodyString, ContentType.parse(headers[CONTENT_TYPE] as String))
else -> TextContent(bodyString, ContentType.parse(body.httpContentType))
}
}
Expand Down
61 changes: 40 additions & 21 deletions core/src/main/kotlin/in/specmatic/test/HttpClient.kt
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package `in`.specmatic.test

import `in`.specmatic.core.APPLICATION_NAME_LOWER_CASE
import `in`.specmatic.core.*
import `in`.specmatic.core.HttpRequest
import `in`.specmatic.core.HttpResponse
import `in`.specmatic.core.log.HttpLogMessage
Expand Down Expand Up @@ -32,7 +32,12 @@ import java.util.zip.GZIPInputStream
// API for non-Kotlin invokers
fun createHttpClient(baseURL: String, timeout: Int) = HttpClient(baseURL, timeout)

class HttpClient(val baseURL: String, private val timeout: Int = 60, private val log: (event: LogMessage) -> Unit = ::consoleLog, private val httpClientFactory: HttpClientFactory = RealHttpClientFactory) : TestExecutor {
class HttpClient(
val baseURL: String,
private val timeout: Int = 60,
private val log: (event: LogMessage) -> Unit = ::consoleLog,
private val httpClientFactory: HttpClientFactory = RealHttpClientFactory
) : TestExecutor {
private val serverStateURL = "/_$APPLICATION_NAME_LOWER_CASE/state"

override fun execute(request: HttpRequest): HttpResponse {
Expand All @@ -52,7 +57,7 @@ class HttpClient(val baseURL: String, private val timeout: Int = 60, private val
}

val outboundRequest: HttpRequest =
ktorHttpRequestToHttpRequest(ktorResponse.request, requestWithFileContent)
ktorHttpRequestToHttpRequestForLogging(ktorResponse.request, requestWithFileContent)
httpLogMessage.addRequest(outboundRequest)

ktorResponseToHttpResponse(ktorResponse).also {
Expand Down Expand Up @@ -122,25 +127,32 @@ class HttpClient(val baseURL: String, private val timeout: Int = 60, private val
}
}

private fun ktorHttpRequestToHttpRequest(request: io.ktor.client.request.HttpRequest, qontractRequest: HttpRequest): HttpRequest {
val(body, formFields, multiPartFormData) =
when(request.content) {
is FormDataContent -> Triple(EmptyString, qontractRequest.formFields, emptyList())
is TextContent -> Triple(qontractRequest.body, emptyMap(), emptyList())
is MultiPartFormDataContent -> Triple(EmptyString, emptyMap(), qontractRequest.multiPartFormData)
private fun ktorHttpRequestToHttpRequestForLogging(
request: io.ktor.client.request.HttpRequest,
specmaticRequest: HttpRequest
): HttpRequest {
val (body, formFields, multiPartFormData) =
when (request.content) {
is FormDataContent -> Triple(EmptyString, specmaticRequest.formFields, emptyList())
is TextContent -> Triple(specmaticRequest.body, emptyMap(), emptyList())
is MultiPartFormDataContent -> Triple(EmptyString, emptyMap(), specmaticRequest.multiPartFormData)
is EmptyContent -> Triple(EmptyString, emptyMap(), emptyList())
else -> throw ContractException("Unknown type of body content sent in the request")
}

val requestHeaders = request.headers.toMap().mapValues { it.value[0] }

return HttpRequest(method = request.method.value,
path = request.url.encodedPath,
headers = requestHeaders,
body = body,
queryParams = toParams(request.url.parameters),
formFields = formFields,
multiPartFormData = multiPartFormData)
val requestHeaders: Map<String, String> = request.headers.toMap().mapValues { it.value[0] }.plus(
CONTENT_TYPE to request.content.contentType.toString()
)

return HttpRequest(
method = request.method.value,
path = request.url.encodedPath,
headers = requestHeaders,
body = body,
queryParams = toParams(request.url.parameters),
formFields = formFields,
multiPartFormData = multiPartFormData
)
}

suspend fun ktorResponseToHttpResponse(ktorResponse: io.ktor.client.statement.HttpResponse): HttpResponse {
Expand All @@ -159,13 +171,20 @@ suspend fun decodeBody(ktorResponse: io.ktor.client.statement.HttpResponse): Pai
}
}

fun decodeBody(bytes: ByteArray, encoding: String?, receivedCharset: Charset?, headers: Map<String, String>): Pair<Map<String, String>, String> =
when(encoding) {
fun decodeBody(
bytes: ByteArray,
encoding: String?,
receivedCharset: Charset?,
headers: Map<String, String>
): Pair<Map<String, String>, String> =
when (encoding) {
"gzip" -> {
Pair(
headers.minus("Content-Encoding"),
unzip(bytes, receivedCharset))
unzip(bytes, receivedCharset)
)
}

else -> Pair(headers, String(bytes))
}

Expand Down
Binary file modified gradle/wrapper/gradle-wrapper.jar
Binary file not shown.
3 changes: 2 additions & 1 deletion gradle/wrapper/gradle-wrapper.properties
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-7.6.1-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-8.5-bin.zip
networkTimeout=10000
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
Loading

0 comments on commit 51db9f0

Please sign in to comment.