Skip to content

Commit

Permalink
chore(pact-jvm-server): Converted Complete to kotlin
Browse files Browse the repository at this point in the history
  • Loading branch information
rholshausen committed Nov 19, 2024
1 parent de37b5e commit 22ba232
Show file tree
Hide file tree
Showing 7 changed files with 287 additions and 124 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
package au.com.dius.pact.server

import au.com.dius.pact.core.model.DefaultPactWriter
import au.com.dius.pact.core.model.OptionalBody
import au.com.dius.pact.core.model.Pact
import au.com.dius.pact.core.model.PactSpecVersion
import au.com.dius.pact.core.model.PactWriter
import au.com.dius.pact.core.model.Request
import au.com.dius.pact.core.model.Response
import au.com.dius.pact.core.support.Json
import au.com.dius.pact.core.support.json.JsonParser
import io.github.oshai.kotlinlogging.KotlinLogging
import java.io.File

private val logger = KotlinLogging.logger {}

object Complete {

var pactWriter: PactWriter = DefaultPactWriter
private val CrossSiteHeaders = mapOf("Access-Control-Allow-Origin" to listOf("*"))

fun getPort(j: Any?): String? = when(j) {
is Map<*, *> -> {
if (j.contains("port")) j["port"].toString()
else null
}
else -> null
}

fun toJson(error: VerificationResult) =
OptionalBody.body(("{\"error\": \"$error\"}").toByteArray())

fun parseJsonString(json: String?) =
if (json == null || json.trim().isEmpty()) null
else Json.fromJson(JsonParser.parseString(json))

@JvmStatic
fun apply(request: Request, oldState: ServerState): Result {
fun pactWritten(response: Response, port: String) = run {
val serverState = oldState.state
val server = serverState[port]
val newState = ServerState(oldState.state.filter { it.value != server })
Result(response, newState)
}

val port = getPort(parseJsonString(request.body.valueAsString()))
if (port != null) {
val mockProvider = oldState.state[port]
if (mockProvider != null) {
val sessionResults = mockProvider.session.remainingResults()
val pact = mockProvider.pact
if (pact != null) {
mockProvider.stop()

return when (val result = writeIfMatching(pact, sessionResults, mockProvider.config.pactVersion)) {
is VerificationResult.PactVerified -> pactWritten(Response(200, CrossSiteHeaders.toMutableMap()),
mockProvider.config.port.toString())
else -> pactWritten(Response(400, mapOf("Content-Type" to listOf("application/json")).toMutableMap(),
toJson(result)), mockProvider.config.port.toString())
}
}
}
}

return Result(Response(400), oldState)
}

fun writeIfMatching(pact: Pact, results: PactSessionResults, pactVersion: PactSpecVersion): VerificationResult {
if (results.allMatched()) {
val pactFile = destinationFileForPact(pact)
pactWriter.writePact(pactFile, pact, pactVersion)
}
return VerificationResult.apply(au.com.dius.pact.core.support.Result.Ok(results))
}

fun defaultFilename(pact: Pact): String = "${pact.consumer.name}-${pact.provider.name}.json"

fun destinationFileForPact(pact: Pact): File = destinationFile(defaultFilename(pact))

fun destinationFile(filename: String) = File("${System.getProperty("pact.rootDir", "target/pacts")}/$filename")
}
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ abstract class StatefulMockProvider: MockProvider {

override val session: PactSession
get() = sessionVar
val pact: Pact?
open val pact: Pact?
get() = pactVar

abstract fun start()
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
package au.com.dius.pact.server

import au.com.dius.pact.core.support.Result

sealed class VerificationResult {
object PactVerified: VerificationResult()

data class PactMismatch(val results: PactSessionResults, val userError: Throwable? = null): VerificationResult() {
override fun toString(): String {
var s = "Pact verification failed for the following reasons:\n"
for (mismatch in results.almostMatched) {
s += mismatch.description()
}
if (results.unexpected.isNotEmpty()) {
s += "\nThe following unexpected results were received:\n"
for (unexpectedResult in results.unexpected) {
s += unexpectedResult.toString()
}
}
if (results.missing.isNotEmpty()) {
s += "\nThe following requests were not received:\n"
for (unexpectedResult in results.missing) {
s += unexpectedResult.toString()
}
}
return s
}
}

data class PactError(val error: Throwable): VerificationResult()

data class UserCodeFailed<T>(val error: T): VerificationResult()

// Temporary. Should belong somewhere else.
override fun toString(): String = when(this) {
is PactVerified -> "Pact verified."
is PactMismatch -> """
|Missing: ${results.missing.mapNotNull { it.asSynchronousRequestResponse() }.map { it.request }}\n
|AlmostMatched: ${results.almostMatched}\n
|Unexpected: ${results.unexpected}\n"""
is PactError -> "${error.javaClass.getName()} ${error.message}"
is UserCodeFailed<*> -> "${error?.javaClass?.getName()} $error"
}

companion object {
fun apply(r: Result<PactSessionResults, Exception>): VerificationResult = when (r) {
is Result.Ok -> {
if (r.value.allMatched()) PactVerified
else PactMismatch(r.value)
}
is Result.Err -> PactError(r.error)
}
}
}

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ object RequestRouter extends StrictLogging {
val urlPattern(action) = request.getPath
action match {
case "create" => Create.apply(request, oldState, config)
case "complete" => Complete(request, oldState)
case "complete" => Complete.apply(request, oldState)
case "publish" => Publish(request, oldState, config)
case "" => ListServers(oldState)
case _ => new Result(pactDispatch(request, oldState), oldState)
Expand Down

This file was deleted.

Loading

0 comments on commit 22ba232

Please sign in to comment.