Matching strategy at body and contentType issue (#1113)

* Created test for equalToXml and bodyMatchers with xml content type - Failed

* Fixed equalToXml at stub for the equalToXml body and xml content type

* Fixed equalToJson at stub for the equalToJson body and explicit json content type.
If body has matching strategy then it has be used for stub generation.
This commit is contained in:
Artem Ptushkin
2019-06-27 16:00:56 +03:00
committed by Olga Maciaszek-Sharma
parent 8de9c96abf
commit de70cd1ef6
2 changed files with 130 additions and 51 deletions

View File

@@ -16,48 +16,24 @@
package org.springframework.cloud.contract.verifier.dsl.wiremock
import java.util.regex.Pattern
import com.github.tomakehurst.wiremock.client.WireMock
import com.github.tomakehurst.wiremock.http.RequestMethod
import com.github.tomakehurst.wiremock.matching.ContentPattern
import com.github.tomakehurst.wiremock.matching.RequestPattern
import com.github.tomakehurst.wiremock.matching.RequestPatternBuilder
import com.github.tomakehurst.wiremock.matching.StringValuePattern
import com.github.tomakehurst.wiremock.matching.UrlPattern
import com.github.tomakehurst.wiremock.matching.*
import groovy.json.JsonOutput
import groovy.json.StringEscapeUtils
import groovy.transform.PackageScope
import groovy.transform.TypeChecked
import groovy.transform.TypeCheckingMode
import groovy.util.logging.Commons
import org.springframework.cloud.contract.spec.Contract
import org.springframework.cloud.contract.spec.internal.Body
import org.springframework.cloud.contract.spec.internal.BodyMatcher
import org.springframework.cloud.contract.spec.internal.DslProperty
import org.springframework.cloud.contract.spec.internal.FromFileProperty
import org.springframework.cloud.contract.spec.internal.MatchingStrategy
import org.springframework.cloud.contract.spec.internal.MatchingType
import org.springframework.cloud.contract.spec.internal.NamedProperty
import org.springframework.cloud.contract.spec.internal.OptionalProperty
import org.springframework.cloud.contract.spec.internal.PathBodyMatcher
import org.springframework.cloud.contract.spec.internal.QueryParameters
import org.springframework.cloud.contract.spec.internal.RegexPatterns
import org.springframework.cloud.contract.spec.internal.RegexProperty
import org.springframework.cloud.contract.spec.internal.Request
import org.springframework.cloud.contract.verifier.util.ContentType
import org.springframework.cloud.contract.verifier.util.ContentUtils
import org.springframework.cloud.contract.verifier.util.JsonPaths
import org.springframework.cloud.contract.verifier.util.JsonToJsonPathsConverter
import org.springframework.cloud.contract.verifier.util.MapConverter
import org.springframework.cloud.contract.spec.internal.*
import org.springframework.cloud.contract.verifier.util.*
import org.springframework.cloud.contract.verifier.util.xml.XmlToXPathsConverter
import java.util.regex.Pattern
import static org.springframework.cloud.contract.spec.internal.MatchingStrategy.Type.BINARY_EQUAL_TO
import static org.springframework.cloud.contract.spec.internal.MatchingType.COMMAND
import static org.springframework.cloud.contract.spec.internal.MatchingType.EQUALITY
import static org.springframework.cloud.contract.spec.internal.MatchingType.NULL
import static org.springframework.cloud.contract.spec.internal.MatchingType.TYPE
import static org.springframework.cloud.contract.spec.internal.MatchingType.*
import static org.springframework.cloud.contract.verifier.util.ContentType.FORM
import static org.springframework.cloud.contract.verifier.util.ContentUtils.getEqualsTypeFromContentType
import static org.springframework.cloud.contract.verifier.util.RegexpBuilders.buildGStringRegexpForStubSide
@@ -115,24 +91,29 @@ class WireMockRequestStubStrategy extends BaseWireMockStubStrategy {
if (!request.body) {
return
}
boolean bodyHasMatchingStrategy = request.body.clientValue instanceof MatchingStrategy
MatchingStrategy matchingStrategy = getMatchingStrategyFromBody(request.body)
if (contentType == ContentType.JSON) {
def originalBody = matchingStrategy?.clientValue
def body = JsonToJsonPathsConverter.
removeMatchingJsonPaths(originalBody, request.bodyMatchers)
JsonPaths values = JsonToJsonPathsConverter.
transformToJsonPathWithStubsSideValuesAndNoArraySizeCheck(body)
if ((values.empty && !request.bodyMatchers?.hasMatchers())
||
onlySizeAssertionsArePresent(values)) {
requestPattern.withRequestBody(WireMock.equalToJson(JsonOutput.toJson(
getMatchingStrategy(request.body.clientValue).clientValue),
false, false))
}
else {
values.findAll { !it.assertsSize() }.each {
requestPattern.withRequestBody(WireMock.
matchingJsonPath(it.jsonPath().replace("\\\\", "\\")))
if (bodyHasMatchingStrategy) {
requestPattern.withRequestBody(
convertToValuePattern(matchingStrategy))
} else {
def body = JsonToJsonPathsConverter.
removeMatchingJsonPaths(originalBody, request.bodyMatchers)
JsonPaths values = JsonToJsonPathsConverter.
transformToJsonPathWithStubsSideValuesAndNoArraySizeCheck(body)
if ((values.empty && !request.bodyMatchers?.hasMatchers())
||
onlySizeAssertionsArePresent(values)) {
requestPattern.withRequestBody(WireMock.equalToJson(JsonOutput.toJson(
getMatchingStrategy(request.body.clientValue).clientValue),
false, false))
} else {
values.findAll { !it.assertsSize() }.each {
requestPattern.withRequestBody(WireMock.
matchingJsonPath(it.jsonPath().replace("\\\\", "\\")))
}
}
}
request.bodyMatchers?.matchers()?.each {
@@ -144,12 +125,17 @@ class WireMockRequestStubStrategy extends BaseWireMockStubStrategy {
}
else if (contentType == ContentType.XML) {
Object originalBody = matchingStrategy?.clientValue
Object body = XmlToXPathsConverter
.removeMatchingXPaths(originalBody, request.bodyMatchers)
List<BodyMatcher> byEqualityMatchersFromXml = new XmlToXPathsConverter()
.mapToMatchers(body)
byEqualityMatchersFromXml.each {
addWireMockStubMatchingSection(it, requestPattern, originalBody)
if (bodyHasMatchingStrategy) {
requestPattern.withRequestBody(
convertToValuePattern(matchingStrategy))
} else {
Object body = XmlToXPathsConverter
.removeMatchingXPaths(originalBody, request.bodyMatchers)
List<BodyMatcher> byEqualityMatchersFromXml = new XmlToXPathsConverter()
.mapToMatchers(body)
byEqualityMatchersFromXml.each {
addWireMockStubMatchingSection(it, requestPattern, originalBody)
}
}
request.bodyMatchers?.matchers()?.each {
addWireMockStubMatchingSection(it, requestPattern, originalBody)

View File

@@ -568,6 +568,51 @@ class WireMockGroovyDslSpec extends Specification implements WireMockStubVerifie
stubMappingIsValidWireMockStub(json)
}
def 'should use equalToJson and bodyMatchers with json content type'() {
given:
org.springframework.cloud.contract.spec.Contract groovyDsl = org.springframework.cloud.contract.spec.Contract.make {
request {
method 'GET'
url "/users"
headers {
header 'Content-Type': 'application/json'
}
body equalToJson('''{"name":"Jan"}''')
bodyMatchers {
jsonPath('$.name', byRegex('[A-Z]{3}'))
}
}
response {
status OK()
}
}
when:
String json = toWireMockClientJsonStub(groovyDsl)
then:
AssertionUtil.assertThatJsonsAreEqual(('''
{
"request": {
"method": "GET",
"url": "/users",
"bodyPatterns": [
{
"equalToJson":"{\\"name\\":\\"Jan\\"}"
},
{
"matchesJsonPath" : "$[?(@.name =~ /([A-Z]{3})/)]"
}
]
},
"response": {
"status": 200,
"transformers" : [ "response-template", "foo-transformer" ]
}
}
'''), json)
and:
stubMappingIsValidWireMockStub(json)
}
def 'should use equalToXml'() {
given:
org.springframework.cloud.contract.spec.Contract groovyDsl = org.springframework.cloud.contract.spec.Contract.make {
@@ -606,6 +651,54 @@ class WireMockGroovyDslSpec extends Specification implements WireMockStubVerifie
stubMappingIsValidWireMockStub(json)
}
def 'should use equalToXml and bodyMatchers with xml content type'() {
given:
org.springframework.cloud.contract.spec.Contract groovyDsl = org.springframework.cloud.contract.spec.Contract.make {
request {
method 'GET'
url "/users"
headers {
header "Content-Type", "customtype/xml"
}
body equalToXml(
"""<foo><name>${value(consumer('Jozo'),
producer('Denis'))}</name><jobId>1234567890</jobId></foo>"""
)
bodyMatchers {
xPath('/foo/jobId/text()', byRegex('[0-9]{10}'))
}
}
response {
status OK()
}
}
when:
String json = toWireMockClientJsonStub(groovyDsl)
then:
AssertionUtil.assertThatJsonsAreEqual(('''
{
"request": {
"method": "GET",
"url": "/users",
"bodyPatterns" : [ {
"equalToXml" : "<foo><name>Jozo</name><jobId>1234567890</jobId></foo>"
}, {
"matchesXPath" : {
"expression" : "/foo/jobId/text()",
"matches" : "[0-9]{10}"
}
} ]
},
"response": {
"status": 200,
"transformers" : [ "response-template", "foo-transformer" ]
}
}
'''), json)
and:
stubMappingIsValidWireMockStub(json)
}
def 'should create stub with body from the file'() {
given:
org.springframework.cloud.contract.spec.Contract groovyDsl = org.springframework.cloud.contract.spec.Contract.make {