Fix using regex patterns when matching raw body value (#692)
When matching non-json or xml body with regex the expression gets
escaped. Because of that all standard patterns (number(), positiveInt())
will not work either.
E.g.
response {
status OK()
body(value(stub("1"), test(number())))
}
Will generate invalid matcher:
assertThat(responseBody).matches("-?(d*.d+|d+)");
Valid version is:
assertThat(responseBody).matches("-?(\\d*.\\d+|\\d+)");
This commit is contained in:
committed by
Marcin Grzejszczak
parent
036e3bf117
commit
6ab02d8ce8
@@ -26,12 +26,14 @@ import org.springframework.cloud.contract.spec.internal.Header
|
||||
import org.springframework.cloud.contract.spec.internal.NamedProperty
|
||||
import org.springframework.cloud.contract.spec.internal.Request
|
||||
import org.springframework.cloud.contract.verifier.config.ContractVerifierConfigProperties
|
||||
import org.springframework.cloud.contract.verifier.util.RegexpBuilders
|
||||
|
||||
import java.util.regex.Pattern
|
||||
|
||||
import static groovy.json.StringEscapeUtils.escapeJava
|
||||
import static org.springframework.cloud.contract.verifier.config.TestFramework.JUNIT
|
||||
import static org.springframework.cloud.contract.verifier.util.ContentUtils.getJavaMultipartFileParameterContent
|
||||
|
||||
/**
|
||||
* Root class for JUnit method building
|
||||
*
|
||||
@@ -78,7 +80,7 @@ abstract class JUnitMethodBodyBuilder extends RequestProcessingMethodBodyBuilder
|
||||
|
||||
@Override
|
||||
protected String getResponseBodyPropertyComparisonString(String property, Pattern value) {
|
||||
return "assertThat(responseBody${property}).${buildEscapedMatchesMethod(value)}"
|
||||
return "assertThat(responseBody${property}).${createBodyComparison(value)}"
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -183,6 +185,11 @@ abstract class JUnitMethodBodyBuilder extends RequestProcessingMethodBodyBuilder
|
||||
return buildEscapedMatchesMethod(headerValue) + ";"
|
||||
}
|
||||
|
||||
protected String createBodyComparison(Pattern bodyValue) {
|
||||
String patternAsString = bodyValue.pattern()
|
||||
return createMatchesMethod(RegexpBuilders.buildGStringRegexpForTestSide(patternAsString)) + ";"
|
||||
}
|
||||
|
||||
protected String createCookieComparison(Object cookieValue) {
|
||||
String escapedCookie = convertUnicodeEscapesIfRequired("$cookieValue")
|
||||
return "isEqualTo(\"$escapedCookie\");"
|
||||
@@ -197,8 +204,7 @@ abstract class JUnitMethodBodyBuilder extends RequestProcessingMethodBodyBuilder
|
||||
return createMatchesMethod(escapedHeader)
|
||||
}
|
||||
|
||||
protected String createMatchesMethod(String escapedHeader) {
|
||||
return "matches(\"$escapedHeader\")"
|
||||
protected String createMatchesMethod(String pattern) {
|
||||
return "matches(\"$pattern\")"
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -72,7 +72,7 @@ class RestAssuredJUnitMethodBodyBuilder extends JUnitMethodBodyBuilder {
|
||||
|
||||
@Override
|
||||
protected String getResponseBodyPropertyComparisonString(String property, Pattern value) {
|
||||
return """assertThat(responseBody).${createHeaderComparison(value)}"""
|
||||
return """assertThat(responseBody).${createBodyComparison(value)}"""
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -27,6 +27,7 @@ import org.springframework.cloud.contract.spec.internal.Request
|
||||
import org.springframework.cloud.contract.spec.internal.ExecutionProperty
|
||||
import org.springframework.cloud.contract.verifier.config.ContractVerifierConfigProperties
|
||||
import org.springframework.cloud.contract.verifier.util.ContentUtils
|
||||
import org.springframework.cloud.contract.verifier.util.RegexpBuilders
|
||||
|
||||
import java.util.regex.Pattern
|
||||
|
||||
@@ -60,7 +61,7 @@ abstract class SpockMethodRequestProcessingBodyBuilder extends RequestProcessing
|
||||
|
||||
@Override
|
||||
protected String getResponseBodyPropertyComparisonString(String property, Pattern value) {
|
||||
return "responseBody$property ${patternComparison(value)}"
|
||||
return "responseBody$property ${createBodyComparison(value)}"
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -173,6 +174,11 @@ abstract class SpockMethodRequestProcessingBodyBuilder extends RequestProcessing
|
||||
return "== '$cookieValue'"
|
||||
}
|
||||
|
||||
protected String createBodyComparison(Pattern bodyValue) {
|
||||
String patternAsString = bodyValue.pattern()
|
||||
return patternComparison(RegexpBuilders.buildGStringRegexpForTestSide(patternAsString)) + ";"
|
||||
}
|
||||
|
||||
protected String convertCookieComparison(Pattern cookieValue) {
|
||||
return patternComparison(cookieValue)
|
||||
}
|
||||
|
||||
@@ -28,7 +28,7 @@ import static ContentType.*
|
||||
import static ContentUtils.extractValue
|
||||
|
||||
/**
|
||||
* Useful utility methods to work with regular expresisons
|
||||
* Useful utility methods to work with regular expressions
|
||||
*
|
||||
* Do not change to {@code @CompileStatic} since it's using double dispatch.
|
||||
*
|
||||
|
||||
@@ -716,4 +716,34 @@ DocumentContext parsedJson = JsonPath.parse(json);
|
||||
"JaxRsClientJUnitMethodBodyBuilder" | { Contract dsl -> new JaxRsClientJUnitMethodBodyBuilder(dsl, properties) }
|
||||
}
|
||||
|
||||
def "should not escape a regex pattern when matching raw body value [#methodBuilderName]"() {
|
||||
def pattern = "\\d+\\w?"
|
||||
def escapedPattern = "\\\\d+\\\\w?"
|
||||
|
||||
given:
|
||||
Contract contractDsl = Contract.make {
|
||||
request {
|
||||
method 'GET'
|
||||
url '/api/arbitrary-url'
|
||||
}
|
||||
response {
|
||||
status OK()
|
||||
body(value(stub("1"), test(regex(pattern))))
|
||||
}
|
||||
}
|
||||
MethodBodyBuilder builder = methodBuilder(contractDsl)
|
||||
BlockBuilder blockBuilder = new BlockBuilder(" ")
|
||||
when:
|
||||
builder.appendTo(blockBuilder)
|
||||
then:
|
||||
String test = blockBuilder.toString()
|
||||
test.contains(escapedPattern)
|
||||
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) }
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user