Skip to content

Commit

Permalink
feat: support any objects for provider state parameters #1234
Browse files Browse the repository at this point in the history
  • Loading branch information
Ronald Holshausen committed Oct 31, 2020
1 parent 5c694ae commit f05d904
Show file tree
Hide file tree
Showing 4 changed files with 106 additions and 6 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
package au.com.dius.pact.consumer.junit

import au.com.dius.pact.consumer.dsl.PactDslWithProvider
import au.com.dius.pact.core.model.RequestResponsePact
import au.com.dius.pact.core.model.annotations.Pact
import groovy.json.JsonSlurper
import org.apache.http.client.fluent.Request
import org.apache.http.entity.ContentType
import org.junit.AfterClass
import org.junit.Rule
import org.junit.Test

class ProviderStateWithComplexParametersTest {

private static final String APPLICATION_JSON = 'application/json'

@Rule
@SuppressWarnings('PublicInstanceField')
public final PactProviderRule provider = new PactProviderRule('provider_with_complex_params',
'localhost', 8113, this)

@Pact(consumer='test_consumer')
@SuppressWarnings('JUnitPublicNonTestMethod')
RequestResponsePact createFragment(PactDslWithProvider builder) {
builder
.given('test state', [
a: 1,
b: 'two',
c: [1, 2, 'three']
])
.uponReceiving('A request with double precision number')
.path('/numbertest')
.method('PUT')
.body('{"name": "harry","data": 1234.0 }', APPLICATION_JSON)
.willRespondWith()
.status(200)
.body('{"responsetest": true, "name": "harry","data": 1234.0 }', APPLICATION_JSON)
.toPact()
}

@Test
@PactVerification
void runTest() {
assert '{"data":1234.0,"name":"harry","responsetest":true}' ==
Request.Put('http://localhost:8113/numbertest')
.addHeader('Accept', APPLICATION_JSON)
.bodyString('{"name": "harry","data": 1234.0 }', ContentType.APPLICATION_JSON)
.execute().returnContent().asString()
}

@AfterClass
static void afterTest() {
def testResources = ProviderStateWithComplexParametersTest.getResource('/').file
def pacts = new File(testResources + '/../../../pacts')
def pactForThisTest = new File(pacts, 'test_consumer-provider_with_complex_params.json')
def json = new JsonSlurper().parse(pactForThisTest)
assert json.interactions[0].providerStates[0].params == ['a': 1, 'b': 'two', 'c': [1, 2, 'three']]
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package au.com.dius.pact.core.model

import au.com.dius.pact.core.support.Json
import au.com.dius.pact.core.support.Utils.jsonSafeValue
import au.com.dius.pact.core.support.json.JsonValue

/**
Expand All @@ -14,7 +15,9 @@ data class ProviderState @JvmOverloads constructor(val name: String?, val params
fun toMap(): Map<String, Any> {
val map = mutableMapOf<String, Any>("name" to name.toString())
if (params.isNotEmpty()) {
map["params"] = params
map["params"] = params.entries.associate {
it.key to jsonSafeValue(it.value)
}
}
return map
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,19 +3,29 @@ package au.com.dius.pact.core.model
import spock.lang.Specification
import spock.lang.Unroll

@SuppressWarnings('LineLength')
class ProviderStateSpec extends Specification {

@SuppressWarnings(['PublicInstanceField', 'NonFinalPublicField'])
static class Pojo {
public int v = 1
public String s = 'one'
public boolean b = false
public vals = [1, 2, 'three']
}

@Unroll
def 'generates a map of the state'() {
expect:
state.toMap() == map

where:

state | map
new ProviderState('test') | [name: 'test']
new ProviderState('test', [:]) | [name: 'test']
new ProviderState('test', [a: 'B']) | [name: 'test', params: [a: 'B']]
state | map
new ProviderState('test') | [name: 'test']
new ProviderState('test', [:]) | [name: 'test']
new ProviderState('test', [a: 'B', b: 1, c: true]) | [name: 'test', params: [a: 'B', b: 1, c: true]]
new ProviderState('test', [a: [b: ['B', 'C']]]) | [name: 'test', params: [a: [b: ['B', 'C']]]]
new ProviderState('test', [a: new Pojo()]) | [name: 'test', params: [a: [v: 1, s: 'one', b: false, vals: [1, 2, 'three']]]]
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import org.apache.commons.lang3.RandomUtils
import java.io.IOException
import java.net.ServerSocket
import kotlin.reflect.full.cast
import kotlin.reflect.full.declaredMemberProperties

object Utils {
fun extractFromMap(json: Map<String, Any>, vararg s: String): Any? {
Expand Down Expand Up @@ -76,4 +77,31 @@ object Utils {
}
return result
}

fun objectToJsonMap(obj: Any?): Map<String, Any?>? {
return if (obj != null) {
obj::class.declaredMemberProperties.associate { prop ->
val key = prop.name
val value = prop.getter.call(obj)
key to jsonSafeValue(value)
}
} else {
null
}
}

fun jsonSafeValue(value: Any?): Any? {
return if (value != null) {
when (value) {
is Boolean -> value
is String -> value
is Number -> value
is Map<*, *> -> value.entries.associate { it.key.toString() to jsonSafeValue(it.value) }
is Collection<*> -> value.map { jsonSafeValue(it) }
else -> objectToJsonMap(value)
}
} else {
null
}
}
}

0 comments on commit f05d904

Please sign in to comment.