Fixed the way form URL encoded request body is treated

fixes #493
This commit is contained in:
Marcin Grzejszczak
2017-12-20 15:22:42 +01:00
parent 99ad52c2dd
commit b3a8124168
3 changed files with 63 additions and 13 deletions

View File

@@ -23,8 +23,6 @@ import groovy.json.JsonOutput
import groovy.transform.PackageScope
import groovy.transform.TypeChecked
import org.apache.commons.lang3.StringEscapeUtils
import org.apache.commons.logging.Log
import org.apache.commons.logging.LogFactory
import org.springframework.cloud.contract.spec.Contract
import org.springframework.cloud.contract.spec.ContractTemplate
import org.springframework.cloud.contract.spec.internal.BodyMatcher
@@ -47,7 +45,6 @@ import org.springframework.cloud.contract.verifier.util.MapConverter
import org.springframework.util.SerializationUtils
import org.springframework.util.StringUtils
import java.lang.invoke.MethodHandles
import java.util.regex.Pattern
import static org.springframework.cloud.contract.verifier.util.ContentUtils.extractValue
@@ -64,7 +61,7 @@ import static org.springframework.cloud.contract.verifier.util.ContentUtils.extr
@PackageScope
abstract class MethodBodyBuilder {
private static final Log log = LogFactory.getLog(MethodHandles.lookup().lookupClass())
private static final Closure GET_SERVER_VALUE = { it instanceof DslProperty ? it.serverValue : it }
protected final ContractVerifierConfigProperties configProperties
protected final TemplateProcessor templateProcessor
@@ -602,9 +599,11 @@ abstract class MethodBodyBuilder {
*/
protected Object extractServerValueFromBody(bodyValue) {
if (bodyValue instanceof GString) {
bodyValue = extractValue(bodyValue, { DslProperty dslProperty -> dslProperty.serverValue })
bodyValue = extractValue(bodyValue, ContentType.from(MapConverter.getTestSideValues(this.contract.request.headers?.entries?.find {
it.name.toLowerCase() == "Content-Type".toLowerCase()
}).toString()), GET_SERVER_VALUE)
} else {
bodyValue = MapConverter.transformValues(bodyValue, { it instanceof DslProperty ? it.serverValue : it })
bodyValue = MapConverter.transformValues(bodyValue, GET_SERVER_VALUE)
}
return bodyValue
}

View File

@@ -17,7 +17,7 @@
package org.springframework.cloud.contract.verifier.util
/**
* Represents content type
* Represents content type. Used to pick the way bodies are parsed.
*
* @since 1.0.0
*/
@@ -34,4 +34,19 @@ enum ContentType {
this.mimeType = mimeType
}
static ContentType from(String header) {
try {
if (header.contains("json")) {
return JSON
} else if (header.contains("xml")) {
return XML
} else if (header.contains("text") ||
header.contains("application/x-www-form-urlencoded")) {
// we want both to be treated as text
return TEXT
}
} catch(e) {}
return UNKNOWN
}
}

View File

@@ -349,7 +349,7 @@ DocumentContext parsedJson = JsonPath.parse(json);
}
@Issue("#458")
def "should reference request from body whtn body is a string [#methodBuilderName]"() {
def "should reference request from body when body is a string [#methodBuilderName]"() {
given:
Contract contractDsl = Contract.make {
request {
@@ -367,15 +367,17 @@ DocumentContext parsedJson = JsonPath.parse(json);
when:
builder.appendTo(blockBuilder)
then:
SyntaxChecker.tryToCompileWithoutCompileStatic(methodBuilderName, blockBuilder.toString())
String test = blockBuilder.toString()
SyntaxChecker.tryToCompileWithoutCompileStatic(methodBuilderName, test)
responseAsserter(test)
and:
stubMappingIsValidWireMockStub(contractDsl)
where:
methodBuilderName | methodBuilder | responseAsserter
"MockMvcSpockMethodBuilder" | { Contract dsl -> new MockMvcSpockMethodRequestProcessingBodyBuilder(dsl, properties) } | { String string -> assert string.contains('responseBody == "My name"') }
"MockMvcJUnitMethodBuilder" | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl, properties) } | { String string -> assert string.contains('assertThat(responseBody).isEqualTo("My name");') }
"JaxRsClientSpockMethodRequestProcessingBodyBuilder" | { Contract dsl -> new JaxRsClientSpockMethodRequestProcessingBodyBuilder(dsl, properties) } | { String string -> assert string.contains('responseBody == "My name"') }
"JaxRsClientJUnitMethodBodyBuilder" | { Contract dsl -> new JaxRsClientJUnitMethodBodyBuilder(dsl, properties) } | { String string -> assert string.contains('assertThat(responseBody).isEqualTo("My name");') }
"MockMvcSpockMethodBuilder" | { Contract dsl -> new MockMvcSpockMethodRequestProcessingBodyBuilder(dsl, properties) } | { String string -> string.contains('responseBody == "My name"') }
"MockMvcJUnitMethodBuilder" | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl, properties) } | { String string -> string.contains('assertThat(responseBody).isEqualTo("My name");') }
"JaxRsClientSpockMethodRequestProcessingBodyBuilder" | { Contract dsl -> new JaxRsClientSpockMethodRequestProcessingBodyBuilder(dsl, properties) } | { String string -> string.contains('responseBody == "My name"') }
"JaxRsClientJUnitMethodBodyBuilder" | { Contract dsl -> new JaxRsClientJUnitMethodBodyBuilder(dsl, properties) } | { String string -> string.contains('assertThat(responseBody).isEqualTo("My name");') }
}
def "should use fixed delay milliseconds in the generated test [#methodBuilderName]"() {
@@ -408,4 +410,38 @@ DocumentContext parsedJson = JsonPath.parse(json);
"MockMvcJUnitMethodBuilder" | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl, properties) }
}
@Issue("#493")
def "should not escape a form URL encoded request body [#methodBuilderName]"() {
given:
Contract contractDsl = Contract.make {
request {
method 'POST'
url '/api/form-endpoint'
headers {
header("Content-Type": 'application/x-www-form-urlencoded')
}
body('a=abc&b=123')
}
response {
status 200
}
}
MethodBodyBuilder builder = methodBuilder(contractDsl)
BlockBuilder blockBuilder = new BlockBuilder(" ")
when:
builder.appendTo(blockBuilder)
then:
String test = blockBuilder.toString()
SyntaxChecker.tryToCompileWithoutCompileStatic(methodBuilderName, test)
!test.contains("a=abc&b=123")
and:
stubMappingIsValidWireMockStub(contractDsl)
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) }
}
}