Fixed backward compatibility of native WireMock helpers

This commit is contained in:
Marcin Grzejszczak
2018-08-31 12:05:22 +02:00
parent b143d16f32
commit d23684d1c4
6 changed files with 95 additions and 14 deletions

View File

@@ -53,6 +53,10 @@ class Body extends DslProperty {
super(bodyAsValue)
}
Body(String bodyAsValue) {
super(bodyAsValue, bodyAsValue)
}
Body(GString bodyAsValue) {
super(bodyAsValue, bodyAsValue)
}

View File

@@ -23,7 +23,7 @@ ext {
]
}
project.version = findProperty('verifierVersion') ?: '2.0.0.BUILD-SNAPSHOT'
project.version = findProperty('verifierVersion')
apply plugin: 'groovy'
apply from: "$rootDir/gradle/release.gradle"
apply plugin: 'eclipse'
@@ -32,8 +32,8 @@ apply plugin: 'checkstyle'
group = 'org.springframework.cloud'
sourceCompatibility = 1.7
targetCompatibility = 1.7
sourceCompatibility = 1.8
targetCompatibility = 1.8
repositories {
mavenLocal()
@@ -75,7 +75,7 @@ dependencies {
}
testCompile 'info.solidsoft.spock:spock-global-unroll:0.5.0'
testCompile gradleTestKit()
checkstyle 'org.springframework.cloud:spring-cloud-build:1.0.2.RELEASE'
checkstyle 'org.springframework.cloud:spring-cloud-build:2.0.3.RELEASE'
}

View File

@@ -367,6 +367,14 @@ abstract class MethodBodyBuilder {
private void addJsonResponseBodyCheck(BlockBuilder bb, convertedResponseBody, BodyMatchers bodyMatchers) {
appendJsonPath(bb, getResponseAsString())
DocumentContext parsedRequestBody
if (contract.request?.body) {
def testSideRequestBody = MapConverter.getTestSideValues(contract.request.body)
parsedRequestBody = JsonPath.parse(testSideRequestBody)
if (convertedResponseBody instanceof String && !textContainsJsonPathTemplate(convertedResponseBody)) {
convertedResponseBody = templateProcessor.transform(contract.request, convertedResponseBody.toString())
}
}
Object copiedBody = cloneBody(convertedResponseBody)
convertedResponseBody = JsonToJsonPathsConverter.removeMatchingJsonPaths(convertedResponseBody, bodyMatchers)
// remove quotes from fromRequest objects before picking json paths
@@ -374,11 +382,6 @@ abstract class MethodBodyBuilder {
TestSideRequestTemplateModel.from(contract.request) : null
convertedResponseBody = MapConverter.transformValues(convertedResponseBody, returnReferencedEntries(templateModel))
JsonPaths jsonPaths = new JsonToJsonPathsConverter(configProperties).transformToJsonPathWithTestsSideValues(convertedResponseBody)
DocumentContext parsedRequestBody
if (contract.request?.body) {
def requestBody = MapConverter.getTestSideValues(contract.request.body)
parsedRequestBody = JsonPath.parse(requestBody)
}
jsonPaths.each {
String method = it.method()
method = processIfTemplateIsPresent(method, parsedRequestBody)
@@ -444,8 +447,7 @@ abstract class MethodBodyBuilder {
}
protected String processIfTemplateIsPresent(String method, DocumentContext parsedRequestBody) {
if (templateProcessor.containsTemplateEntry(method) &&
templateProcessor.containsJsonPathTemplateEntry(method) && contract.request?.body) {
if (textContainsJsonPathTemplate(method) && contract.request?.body) {
// Unquoting the values of non strings
String jsonPathEntry = templateProcessor.jsonPathFromTemplateEntry(method)
Object object = parsedRequestBody.read(jsonPathEntry)
@@ -458,6 +460,11 @@ abstract class MethodBodyBuilder {
return method
}
protected boolean textContainsJsonPathTemplate(String method) {
return templateProcessor.containsTemplateEntry(method) &&
templateProcessor.containsJsonPathTemplateEntry(method)
}
protected void methodForEqualityCheck(BodyMatcher bodyMatcher, BlockBuilder bb, Object copiedBody) {
String path = quotedAndEscaped(bodyMatcher.path())
Object retrievedValue = value(copiedBody, bodyMatcher)

View File

@@ -1,6 +1,8 @@
package org.springframework.cloud.contract.verifier.builder.handlebars
import com.github.tomakehurst.wiremock.extension.responsetemplating.helpers.WireMockHelpers
import org.apache.commons.logging.Log
import org.apache.commons.logging.LogFactory
import wiremock.com.github.jknack.handlebars.Helper
import wiremock.com.github.jknack.handlebars.Options
import com.github.tomakehurst.wiremock.extension.responsetemplating.RequestTemplateModel
@@ -18,12 +20,17 @@ import org.springframework.cloud.contract.verifier.builder.TestSideRequestTempla
@CompileStatic
class HandlebarsJsonPathHelper implements Helper<Object> {
private static final Log log = LogFactory.getLog(HandlebarsJsonPathHelper)
public static final String NAME = "jsonpath"
public static final String REQUEST_MODEL_NAME = "request"
@Override
Object apply(Object context, Options options) throws IOException {
if (context instanceof Map<String, Object>) {
if (log.isTraceEnabled()) {
log.trace("Will apply the legacy [jsonpath this] handlebars function")
}
// legacy
Map<String, Object> oldContext = (Map<String, Object>) context
String jsonPath = options.param(0)
@@ -35,7 +42,10 @@ class HandlebarsJsonPathHelper implements Helper<Object> {
}
throw new IllegalArgumentException("Unsupported model")
} else if (context instanceof String) {
Object value = WireMockHelpers.jsonPath.apply(context, options)
if (log.isTraceEnabled()) {
log.trace("Will apply the native WireMock [jsonPath request.body] handlebars function")
}
Object value = WireMockHelpers.jsonPath.apply(prepareForJsonPathCheck(context), options)
if (testSideModel(options)) {
return processTestResponseValue(value)
}
@@ -59,12 +69,16 @@ class HandlebarsJsonPathHelper implements Helper<Object> {
}
private Object returnObjectForTest(TestSideRequestTemplateModel model, String jsonPath) {
String body = removeSurroundingQuotes(model.rawBody).replace('\\"', '"')
String body = prepareForJsonPathCheck(model.rawBody)
DocumentContext documentContext = JsonPath.parse(body)
Object value = documentContext.read(jsonPath)
return processTestResponseValue(value)
}
protected String prepareForJsonPathCheck(String body) {
return removeSurroundingQuotes(body).replace('\\"', '"')
}
private Object processTestResponseValue(Object value) {
if (value instanceof Long) {
return String.valueOf(value) + "L"

View File

@@ -69,6 +69,8 @@ class MapConverter {
def json = new JsonSlurper().parseText(value)
if (json instanceof Map) {
return convert(json, closure)
} else if (json instanceof List) {
return transformValues(json, closure)
}
} catch (Exception ignore) {
}

View File

@@ -447,7 +447,7 @@ class MockMvcMethodBodyBuilderSpec extends Specification implements WireMockStub
"MockMvcJUnitMethodBuilder" | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl, properties) }
}
def "should generate assertions for array inside response body element with #methodBuilderName"() {
def "should generate assertions for array inside response body element with #methodBuilderName"() {
given:
Contract contractDsl = Contract.make {
request {
@@ -2628,6 +2628,60 @@ DocumentContext parsedJson = JsonPath.parse(json);
"JaxRsClientJUnitMethodBodyBuilder" | { Contract dsl -> new JaxRsClientJUnitMethodBodyBuilder(dsl, properties) } | { String body -> body.contains('assertThat(response.getHeaderString("Authorization")).isEqualTo("foo secret bar");') }
}
@Issue("#230")
def "should manage to reference request in response via WireMock native entries [#methodBuilderName]"() {
given:
//tag::template_contract[]
Contract contractDsl = Contract.make {
request {
method 'GET'
url('/api/v1/xxxx') {
queryParameters {
parameter("foo", "bar")
parameter("foo", "bar2")
}
}
headers {
header(authorization(), "secret")
header(authorization(), "secret2")
}
body(foo: "bar", baz: 5)
}
response {
status OK()
headers {
contentType(applicationJson())
}
body('''
{
"responseFoo": "{{{ jsonPath request.body '$.foo' }}}",
"responseBaz": {{{ jsonPath request.body '$.baz' }}},
"responseBaz2": "Bla bla {{{ jsonPath request.body '$.foo' }}} bla bla"
}
'''.toString())
}
}
//end::template_contract[]
MethodBodyBuilder builder = methodBuilder(contractDsl)
BlockBuilder blockBuilder = new BlockBuilder(" ")
and:
builder.appendTo(blockBuilder)
String test = blockBuilder.toString()
when:
SyntaxChecker.tryToCompileWithoutCompileStatic(methodBuilderName, test)
then:
!test.contains('''DslProperty''')
test.contains('''assertThatJson(parsedJson).field("['responseFoo']").isEqualTo("bar")''')
test.contains('''assertThatJson(parsedJson).field("['responseBaz']").isEqualTo(5)''')
test.contains('''assertThatJson(parsedJson).field("['responseBaz2']").isEqualTo("Bla bla bar bla bla")''')
where:
methodBuilderName | methodBuilder
"MockMvcSpockMethodBuilder" | { Contract dsl -> new MockMvcSpockMethodRequestProcessingBodyBuilder(dsl, properties) }
"MockMvcJUnitMethodBuilder" | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl, properties) }
"JaxRsClientSpockMethodRequestProcessingBodyBuilder" | { Contract dsl -> new JaxRsClientSpockMethodRequestProcessingBodyBuilder(dsl, properties) }
"JaxRsClientJUnitMethodBodyBuilder" | { Contract dsl -> new JaxRsClientJUnitMethodBodyBuilder(dsl, properties) }
}
def "should generate JUnit assertions with cookies"() {
given:
MethodBodyBuilder builder = new MockMvcJUnitMethodBodyBuilder(contractDslWithCookiesValue, properties)