Merge pull request #61 from 4finance/issues/49-fixed-missing-body-pattern-matching
[#49] Fixed two more issues with the conversion
This commit is contained in:
@@ -18,12 +18,12 @@ class WiremockToDslConverter {
|
||||
def response = wiremockStub.response
|
||||
def bodyPatterns = request.bodyPatterns
|
||||
return """\
|
||||
request {
|
||||
${request.method ? "method \"\"\"$request.method\"\"\"" : ""}
|
||||
${request.url ? "url \"\"\"$request.url\"\"\"" : ""}
|
||||
${request.urlPattern ? "url \$(client(regex('${escapeJava(request.urlPattern)}')), server(''))" : ""}
|
||||
${request.urlPath ? "url \"\"\"$request.urlPath\"\"\"" : ""}
|
||||
${
|
||||
request {
|
||||
${request.method ? "method \"\"\"$request.method\"\"\"" : ""}
|
||||
${request.url ? "url \"\"\"$request.url\"\"\"" : ""}
|
||||
${request.urlPattern ? "url \$(client(regex('${escapeJava(request.urlPattern)}')), server(''))" : ""}
|
||||
${request.urlPath ? "url \"\"\"$request.urlPath\"\"\"" : ""}
|
||||
${
|
||||
request.headers ? """headers {
|
||||
${
|
||||
request.headers.collect {
|
||||
@@ -36,20 +36,21 @@ class WiremockToDslConverter {
|
||||
}
|
||||
""" : ""
|
||||
}
|
||||
${bodyPatterns?.equalTo ? "body('''${bodyPatterns.equalTo}''')" : '' }
|
||||
${bodyPatterns?.matches ? "body \$(client(regex('${escapeJava(bodyPatterns.matches)}')), server(''))" : ""}
|
||||
}
|
||||
response {
|
||||
${response.status ? "status $response.status" : ""}
|
||||
${response.body ? "body( ${buildBody(response.body)})" : ""}
|
||||
${
|
||||
${bodyPatterns?.equalTo?.every { it } ? "body(\"\"\"${bodyPatterns.equalTo[0]}\"\"\")" : ''}
|
||||
${bodyPatterns?.equalToJson?.every { it } ? "body(\"\"\"${bodyPatterns.equalToJson[0]}\"\"\")" : ''}
|
||||
${bodyPatterns?.matches?.every { it } ? "body \$(client(regex('${escapeJava(bodyPatterns.matches[0])}')), server(''))" : ""}
|
||||
}
|
||||
response {
|
||||
${response.status ? "status $response.status" : ""}
|
||||
${response.body ? "body( ${buildBody(response.body)})" : ""}
|
||||
${
|
||||
response.headers ? """headers {
|
||||
${response.headers.collect { "header('$it.key': '${it.value}')\n" }.join('')}
|
||||
}
|
||||
""" : ""
|
||||
${response.headers.collect { "header('$it.key': '${it.value}')\n" }.join('')}
|
||||
}
|
||||
""" : ""
|
||||
}
|
||||
}
|
||||
"""
|
||||
}
|
||||
"""
|
||||
}
|
||||
|
||||
private String buildHeader(String method, Object value) {
|
||||
@@ -158,7 +159,7 @@ class WiremockToDslConverter {
|
||||
static String wrapWithFactoryMethod(String dslFromWiremockStub) {
|
||||
return """\
|
||||
${GroovyDsl.name}.make {
|
||||
$dslFromWiremockStub
|
||||
$dslFromWiremockStub
|
||||
}
|
||||
"""
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package io.codearte.accurest.wiremock
|
||||
|
||||
import com.github.tomakehurst.wiremock.stubbing.StubMapping
|
||||
import io.codearte.accurest.dsl.GroovyDsl
|
||||
import spock.lang.Specification
|
||||
|
||||
@@ -9,27 +10,29 @@ class WiremockToDslConverterSpec extends Specification {
|
||||
given:
|
||||
String wiremockStub = '''\
|
||||
{
|
||||
"request": {
|
||||
"method": "GET",
|
||||
"url": "/path",
|
||||
"headers" : {
|
||||
"Accept": {
|
||||
"matches": "text/.*"
|
||||
},
|
||||
"X-Custom-Header": {
|
||||
"contains": "2134"
|
||||
}
|
||||
}
|
||||
},
|
||||
"response": {
|
||||
"status": 200,
|
||||
"body": "{ \\"id\\": { \\"value\\": \\"132\\" }, \\"surname\\": \\"Kowalsky\\", \\"name\\": \\"Jan\\", \\"created\\": \\"2014-02-02 12:23:43\\" }",
|
||||
"headers": {
|
||||
"Content-Type": "text/plain",
|
||||
}
|
||||
}
|
||||
"request": {
|
||||
"method": "GET",
|
||||
"url": "/path",
|
||||
"headers" : {
|
||||
"Accept": {
|
||||
"matches": "text/.*"
|
||||
},
|
||||
"X-Custom-Header": {
|
||||
"contains": "2134"
|
||||
}
|
||||
}
|
||||
},
|
||||
"response": {
|
||||
"status": 200,
|
||||
"body": "{ \\"id\\": { \\"value\\": \\"132\\" }, \\"surname\\": \\"Kowalsky\\", \\"name\\": \\"Jan\\", \\"created\\": \\"2014-02-02 12:23:43\\" }",
|
||||
"headers": {
|
||||
"Content-Type": "text/plain"
|
||||
}
|
||||
}
|
||||
}
|
||||
'''
|
||||
and:
|
||||
stubMappingIsValidWiremockStub(wiremockStub)
|
||||
and:
|
||||
GroovyDsl expectedGroovyDsl = GroovyDsl.make {
|
||||
request {
|
||||
@@ -66,8 +69,8 @@ class WiremockToDslConverterSpec extends Specification {
|
||||
then:
|
||||
new GroovyShell(this.class.classLoader).evaluate(
|
||||
""" io.codearte.accurest.dsl.GroovyDsl.make {
|
||||
$groovyDsl
|
||||
}""") == expectedGroovyDsl
|
||||
$groovyDsl
|
||||
}""") == expectedGroovyDsl
|
||||
}
|
||||
|
||||
|
||||
@@ -75,24 +78,26 @@ class WiremockToDslConverterSpec extends Specification {
|
||||
given:
|
||||
String wiremockStub = '''\
|
||||
{
|
||||
"request": {
|
||||
"method": "DELETE",
|
||||
"urlPattern": "/credit-card-verification-data/[0-9]+",
|
||||
"headers": {
|
||||
"Content-Type": {
|
||||
"equalTo": "application/vnd.mymoid-adapter.v2+json; charset=UTF-8"
|
||||
}
|
||||
}
|
||||
},
|
||||
"response": {
|
||||
"status": 200,
|
||||
"body": "{\\"status\\": \\"OK\\"}",
|
||||
"headers": {
|
||||
"Content-Type": "application/json"
|
||||
}
|
||||
}
|
||||
"request": {
|
||||
"method": "DELETE",
|
||||
"urlPattern": "/credit-card-verification-data/[0-9]+",
|
||||
"headers": {
|
||||
"Content-Type": {
|
||||
"equalTo": "application/vnd.mymoid-adapter.v2+json; charset=UTF-8"
|
||||
}
|
||||
}
|
||||
},
|
||||
"response": {
|
||||
"status": 200,
|
||||
"body": "{\\"status\\": \\"OK\\"}",
|
||||
"headers": {
|
||||
"Content-Type": "application/json"
|
||||
}
|
||||
}
|
||||
}
|
||||
'''
|
||||
and:
|
||||
stubMappingIsValidWiremockStub(wiremockStub)
|
||||
and:
|
||||
GroovyDsl expectedGroovyDsl = GroovyDsl.make {
|
||||
request {
|
||||
@@ -105,7 +110,7 @@ class WiremockToDslConverterSpec extends Specification {
|
||||
response {
|
||||
status 200
|
||||
body("""{
|
||||
"status": "OK"
|
||||
"status": "OK"
|
||||
}""")
|
||||
headers {
|
||||
header 'Content-Type': 'application/json'
|
||||
@@ -118,8 +123,8 @@ class WiremockToDslConverterSpec extends Specification {
|
||||
then:
|
||||
new GroovyShell(this.class.classLoader).evaluate(
|
||||
""" io.codearte.accurest.dsl.GroovyDsl.make {
|
||||
$groovyDsl
|
||||
}""") == expectedGroovyDsl
|
||||
$groovyDsl
|
||||
}""") == expectedGroovyDsl
|
||||
}
|
||||
|
||||
def 'should convert Wiremock stub with response body containing integer'() {
|
||||
@@ -127,23 +132,25 @@ class WiremockToDslConverterSpec extends Specification {
|
||||
String wiremockStub = '''\
|
||||
{
|
||||
"request": {
|
||||
"method": "POST",
|
||||
"url": "/charge/count",
|
||||
"headers": {
|
||||
"Content-Type": {
|
||||
"equalTo": "application/vnd.creditcard-reporter.v1+json"
|
||||
}
|
||||
}
|
||||
"method": "POST",
|
||||
"url": "/charge/count",
|
||||
"headers": {
|
||||
"Content-Type": {
|
||||
"equalTo": "application/vnd.creditcard-reporter.v1+json"
|
||||
}
|
||||
}
|
||||
},
|
||||
"response": {
|
||||
"status": 200,
|
||||
"body": 200,
|
||||
"headers": {
|
||||
"Content-Type": "application/json"
|
||||
}
|
||||
"status": 200,
|
||||
"body": 200,
|
||||
"headers": {
|
||||
"Content-Type": "application/json"
|
||||
}
|
||||
}
|
||||
}
|
||||
'''
|
||||
and:
|
||||
stubMappingIsValidWiremockStub(wiremockStub)
|
||||
and:
|
||||
GroovyDsl expectedGroovyDsl = GroovyDsl.make {
|
||||
request {
|
||||
@@ -167,8 +174,8 @@ class WiremockToDslConverterSpec extends Specification {
|
||||
then:
|
||||
new GroovyShell(this.class.classLoader).evaluate(
|
||||
""" io.codearte.accurest.dsl.GroovyDsl.make {
|
||||
$groovyDsl
|
||||
}""") == expectedGroovyDsl
|
||||
$groovyDsl
|
||||
}""") == expectedGroovyDsl
|
||||
}
|
||||
|
||||
def 'should convert Wiremock stub with response body as a list'() {
|
||||
@@ -176,23 +183,25 @@ class WiremockToDslConverterSpec extends Specification {
|
||||
String wiremockStub = '''\
|
||||
{
|
||||
"request": {
|
||||
"method": "POST",
|
||||
"url": "/charge/count",
|
||||
"headers": {
|
||||
"Content-Type": {
|
||||
"equalTo": "application/vnd.creditcard-reporter.v1+json"
|
||||
}
|
||||
}
|
||||
"method": "POST",
|
||||
"url": "/charge/count",
|
||||
"headers": {
|
||||
"Content-Type": {
|
||||
"equalTo": "application/vnd.creditcard-reporter.v1+json"
|
||||
}
|
||||
}
|
||||
},
|
||||
"response": {
|
||||
"status": 200,
|
||||
"body": "[ {\\"a\\":1, \\"c\\":\\"3\\"}, \\"b\\", \\"a\\" ]",
|
||||
"headers": {
|
||||
"Content-Type": "application/json"
|
||||
}
|
||||
"status": 200,
|
||||
"body": "[ {\\"a\\":1, \\"c\\":\\"3\\"}, \\"b\\", \\"a\\" ]",
|
||||
"headers": {
|
||||
"Content-Type": "application/json"
|
||||
}
|
||||
}
|
||||
}
|
||||
'''
|
||||
and:
|
||||
stubMappingIsValidWiremockStub(wiremockStub)
|
||||
and:
|
||||
GroovyDsl expectedGroovyDsl = GroovyDsl.make {
|
||||
request {
|
||||
@@ -219,8 +228,8 @@ class WiremockToDslConverterSpec extends Specification {
|
||||
then:
|
||||
new GroovyShell(this.class.classLoader).evaluate(
|
||||
""" io.codearte.accurest.dsl.GroovyDsl.make {
|
||||
$groovyDsl
|
||||
}""") == expectedGroovyDsl
|
||||
$groovyDsl
|
||||
}""") == expectedGroovyDsl
|
||||
}
|
||||
|
||||
|
||||
@@ -229,20 +238,22 @@ class WiremockToDslConverterSpec extends Specification {
|
||||
String wiremockStub = '''\
|
||||
{
|
||||
"request": {
|
||||
"method": "POST",
|
||||
"url": "/charge/search?pageNumber=0&size=2147483647",
|
||||
"headers": {
|
||||
"Content-Type": {
|
||||
"equalTo": "application/vnd.creditcard-reporter.v1+json"
|
||||
}
|
||||
}
|
||||
"method": "POST",
|
||||
"url": "/charge/search?pageNumber=0&size=2147483647",
|
||||
"headers": {
|
||||
"Content-Type": {
|
||||
"equalTo": "application/vnd.creditcard-reporter.v1+json"
|
||||
}
|
||||
}
|
||||
},
|
||||
"response": {
|
||||
"status": 200,
|
||||
"body":"[{\\"amount\\":1.01,\\"name\\":\\"Name\\",\\"info\\":{\\"title\\":\\"title1\\",\\"payload\\":null},\\"booleanvalue\\":true,\\"user\\":null},{\\"amount\\":2.01,\\"name\\":\\"Name2\\",\\"info\\":{\\"title\\":\\"title2\\",\\"payload\\":null},\\"booleanvalue\\":true,\\"user\\":null}]"
|
||||
}
|
||||
"status": 200,
|
||||
"body":"[{\\"amount\\":1.01,\\"name\\":\\"Name\\",\\"info\\":{\\"title\\":\\"title1\\",\\"payload\\":null},\\"booleanvalue\\":true,\\"user\\":null},{\\"amount\\":2.01,\\"name\\":\\"Name2\\",\\"info\\":{\\"title\\":\\"title2\\",\\"payload\\":null},\\"booleanvalue\\":true,\\"user\\":null}]"
|
||||
}
|
||||
}
|
||||
'''
|
||||
and:
|
||||
stubMappingIsValidWiremockStub(wiremockStub)
|
||||
and:
|
||||
GroovyDsl expectedGroovyDsl = GroovyDsl.make {
|
||||
request {
|
||||
@@ -255,26 +266,26 @@ class WiremockToDslConverterSpec extends Specification {
|
||||
response {
|
||||
status 200
|
||||
body("""[
|
||||
{
|
||||
"amount": 1.01,
|
||||
"name": "Name",
|
||||
"info": {
|
||||
"title": "title1",
|
||||
"payload": null
|
||||
},
|
||||
"booleanvalue": true,
|
||||
"user": null
|
||||
},
|
||||
{
|
||||
"amount": 2.01,
|
||||
"name": "Name2",
|
||||
"info": {
|
||||
"title": "title2",
|
||||
"payload": null
|
||||
},
|
||||
"booleanvalue": true,
|
||||
"user": null
|
||||
}
|
||||
{
|
||||
"amount": 1.01,
|
||||
"name": "Name",
|
||||
"info": {
|
||||
"title": "title1",
|
||||
"payload": null
|
||||
},
|
||||
"booleanvalue": true,
|
||||
"user": null
|
||||
},
|
||||
{
|
||||
"amount": 2.01,
|
||||
"name": "Name2",
|
||||
"info": {
|
||||
"title": "title2",
|
||||
"payload": null
|
||||
},
|
||||
"booleanvalue": true,
|
||||
"user": null
|
||||
}
|
||||
]""")
|
||||
}
|
||||
}
|
||||
@@ -283,8 +294,8 @@ class WiremockToDslConverterSpec extends Specification {
|
||||
then:
|
||||
new GroovyShell(this.class.classLoader).evaluate(
|
||||
""" io.codearte.accurest.dsl.GroovyDsl.make {
|
||||
$groovyDsl
|
||||
}""") == expectedGroovyDsl
|
||||
$groovyDsl
|
||||
}""") == expectedGroovyDsl
|
||||
}
|
||||
|
||||
def 'should convert Wiremock stub with request body checking equality to Json'() {
|
||||
@@ -292,17 +303,19 @@ class WiremockToDslConverterSpec extends Specification {
|
||||
String wiremockStub = '''\
|
||||
{
|
||||
"request": {
|
||||
"method": "POST",
|
||||
"url": "/test",
|
||||
"bodyPatterns": {
|
||||
"equalTo": "{\\"property1\\":\\"abc\\",\\"property2\\":\\"2017-01\\",\\"property3\\":\\"666\\",\\"property4\\":1428566412}"
|
||||
}
|
||||
"method": "POST",
|
||||
"url": "/test",
|
||||
"bodyPatterns": [{
|
||||
"equalTo": "{\\"property1\\":\\"abc\\",\\"property2\\":\\"2017-01\\",\\"property3\\":\\"666\\",\\"property4\\":1428566412}"
|
||||
}]
|
||||
},
|
||||
"response": {
|
||||
"status": 200
|
||||
}
|
||||
"status": 200
|
||||
}
|
||||
}
|
||||
'''
|
||||
and:
|
||||
stubMappingIsValidWiremockStub(wiremockStub)
|
||||
and:
|
||||
GroovyDsl expectedGroovyDsl = GroovyDsl.make {
|
||||
request {
|
||||
@@ -319,8 +332,8 @@ class WiremockToDslConverterSpec extends Specification {
|
||||
then:
|
||||
GroovyDsl evaluatedGroovyDsl = new GroovyShell(this.class.classLoader).evaluate(
|
||||
""" io.codearte.accurest.dsl.GroovyDsl.make {
|
||||
$groovyDsl
|
||||
}""")
|
||||
$groovyDsl
|
||||
}""")
|
||||
and:
|
||||
evaluatedGroovyDsl == expectedGroovyDsl
|
||||
}
|
||||
@@ -330,17 +343,19 @@ class WiremockToDslConverterSpec extends Specification {
|
||||
String wiremockStub = '''\
|
||||
{
|
||||
"request": {
|
||||
"method": "POST",
|
||||
"url": "/test",
|
||||
"bodyPatterns": {
|
||||
"matches": "[0-9]{5}"
|
||||
}
|
||||
"method": "POST",
|
||||
"url": "/test",
|
||||
"bodyPatterns": [{
|
||||
"matches": "[0-9]{5}"
|
||||
}]
|
||||
},
|
||||
"response": {
|
||||
"status": 200
|
||||
}
|
||||
"status": 200
|
||||
}
|
||||
}
|
||||
'''
|
||||
and:
|
||||
stubMappingIsValidWiremockStub(wiremockStub)
|
||||
and:
|
||||
GroovyDsl expectedGroovyDsl = GroovyDsl.make {
|
||||
request {
|
||||
@@ -357,10 +372,135 @@ class WiremockToDslConverterSpec extends Specification {
|
||||
then:
|
||||
GroovyDsl evaluatedGroovyDsl = new GroovyShell(this.class.classLoader).evaluate(
|
||||
""" io.codearte.accurest.dsl.GroovyDsl.make {
|
||||
$groovyDsl
|
||||
}""")
|
||||
$groovyDsl
|
||||
}""")
|
||||
and:
|
||||
evaluatedGroovyDsl == expectedGroovyDsl
|
||||
}
|
||||
|
||||
def 'should convert Wiremock stub with request body with equalToJson'() {
|
||||
given:
|
||||
String wiremockStub = '''\
|
||||
{
|
||||
"request" : {
|
||||
"url" : "/test",
|
||||
"method" : "POST",
|
||||
"bodyPatterns" : [ {
|
||||
"equalToJson" : "{\\"pan\\":\\"4855141150107894\\",\\"expirationDate\\":\\"2017-01\\",\\"dcvx\\":\\"178\\"}",
|
||||
"jsonCompareMode" : "LENIENT"
|
||||
} ]
|
||||
},
|
||||
"response" : {
|
||||
"status" : 200
|
||||
}
|
||||
}
|
||||
'''
|
||||
and:
|
||||
stubMappingIsValidWiremockStub(wiremockStub)
|
||||
and:
|
||||
GroovyDsl expectedGroovyDsl = GroovyDsl.make {
|
||||
request {
|
||||
method 'POST'
|
||||
url '/test'
|
||||
body '''{"pan":"4855141150107894","expirationDate":"2017-01","dcvx":"178"}'''
|
||||
}
|
||||
response {
|
||||
status 200
|
||||
}
|
||||
}
|
||||
when:
|
||||
String groovyDsl = WiremockToDslConverter.fromWiremockStub(wiremockStub)
|
||||
then:
|
||||
GroovyDsl evaluatedGroovyDsl = new GroovyShell(this.class.classLoader).evaluate(
|
||||
""" io.codearte.accurest.dsl.GroovyDsl.make {
|
||||
$groovyDsl
|
||||
}""")
|
||||
and:
|
||||
evaluatedGroovyDsl == expectedGroovyDsl
|
||||
}
|
||||
|
||||
def 'should convert Wiremock stub with request body with equalTo'() {
|
||||
given:
|
||||
String wiremockStub = '''\
|
||||
{
|
||||
"request" : {
|
||||
"url" : "/test",
|
||||
"method" : "POST",
|
||||
"bodyPatterns" : [ {
|
||||
"equalTo" : "{\\"pan\\":\\"4855141150107894\\",\\"expirationDate\\":\\"2017-01\\",\\"dcvx\\":\\"178\\"}"
|
||||
} ]
|
||||
},
|
||||
"response" : {
|
||||
"status" : 200
|
||||
}
|
||||
}
|
||||
'''
|
||||
and:
|
||||
stubMappingIsValidWiremockStub(wiremockStub)
|
||||
and:
|
||||
GroovyDsl expectedGroovyDsl = GroovyDsl.make {
|
||||
request {
|
||||
method 'POST'
|
||||
url '/test'
|
||||
body '''{"pan":"4855141150107894","expirationDate":"2017-01","dcvx":"178"}'''
|
||||
}
|
||||
response {
|
||||
status 200
|
||||
}
|
||||
}
|
||||
when:
|
||||
String groovyDsl = WiremockToDslConverter.fromWiremockStub(wiremockStub)
|
||||
then:
|
||||
GroovyDsl evaluatedGroovyDsl = new GroovyShell(this.class.classLoader).evaluate(
|
||||
""" io.codearte.accurest.dsl.GroovyDsl.make {
|
||||
$groovyDsl
|
||||
}""")
|
||||
and:
|
||||
evaluatedGroovyDsl == expectedGroovyDsl
|
||||
}
|
||||
|
||||
def 'should convert Wiremock stub with request body with matches'() {
|
||||
given:
|
||||
String wiremockStub = '''\
|
||||
{
|
||||
"request" : {
|
||||
"url" : "/test",
|
||||
"method" : "POST",
|
||||
"bodyPatterns" : [ {
|
||||
"matches" : "[0-9]{2}"
|
||||
} ]
|
||||
},
|
||||
"response" : {
|
||||
"status" : 200
|
||||
}
|
||||
}
|
||||
'''
|
||||
and:
|
||||
stubMappingIsValidWiremockStub(wiremockStub)
|
||||
and:
|
||||
GroovyDsl expectedGroovyDsl = GroovyDsl.make {
|
||||
request {
|
||||
method 'POST'
|
||||
url '/test'
|
||||
body $(client(~/[0-9]{2}/), server(''))
|
||||
}
|
||||
response {
|
||||
status 200
|
||||
}
|
||||
}
|
||||
when:
|
||||
String groovyDsl = WiremockToDslConverter.fromWiremockStub(wiremockStub)
|
||||
then:
|
||||
GroovyDsl evaluatedGroovyDsl = new GroovyShell(this.class.classLoader).evaluate(
|
||||
""" io.codearte.accurest.dsl.GroovyDsl.make {
|
||||
$groovyDsl
|
||||
}""")
|
||||
and:
|
||||
evaluatedGroovyDsl == expectedGroovyDsl
|
||||
}
|
||||
|
||||
void stubMappingIsValidWiremockStub(String mappingDefinition) {
|
||||
StubMapping.buildFrom(mappingDefinition)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ import groovy.transform.PackageScope
|
||||
import groovy.transform.TypeChecked
|
||||
import io.codearte.accurest.dsl.internal.ClientRequest
|
||||
import io.codearte.accurest.dsl.internal.Request
|
||||
import io.codearte.accurest.util.JsonConverter
|
||||
|
||||
import java.util.regex.Pattern
|
||||
|
||||
@@ -38,9 +39,8 @@ class WiremockRequestStubStrategy extends BaseWiremockStubStrategy {
|
||||
return [:]
|
||||
}
|
||||
if (containsRegex(body)) {
|
||||
return [bodyPatterns: [[matches: parseBody(body)]]]
|
||||
return [bodyPatterns: [[matches: parseBody(JsonConverter.transformValues(body, { it.toString() }))]]]
|
||||
}
|
||||
|
||||
return [bodyPatterns: [[equalTo: parseBody(body)]]]
|
||||
}
|
||||
|
||||
@@ -49,4 +49,8 @@ class WiremockRequestStubStrategy extends BaseWiremockStubStrategy {
|
||||
return (bodyString =~ /\^.*\$/).find()
|
||||
}
|
||||
|
||||
boolean containsRegex(Map map) {
|
||||
return map.values().any { it instanceof Pattern }
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -21,12 +21,12 @@ class WiremockResponseStubStrategy extends BaseWiremockStubStrategy {
|
||||
|
||||
private Map<String, Object> buildResponseContent(ClientResponse response) {
|
||||
return ([status : response?.status?.clientValue,
|
||||
headers: buildClientResponseHeadersSection(response.headers)
|
||||
] << appendBody(response)).findAll { it.value }
|
||||
headers: buildClientResponseHeadersSection(response.headers)
|
||||
] << appendBody(response)).findAll { it.value }
|
||||
}
|
||||
|
||||
private Map<String, Object> appendBody(ClientResponse response) {
|
||||
Object body = response?.body?.clientValue
|
||||
return body != null ? [body: parseBody(body)] : [:]
|
||||
}
|
||||
private Map<String, Object> appendBody(ClientResponse response) {
|
||||
Object body = response?.body?.clientValue
|
||||
return body != null ? [body: parseBody(body)] : [:]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,12 +3,19 @@ package io.codearte.accurest.dsl.internal
|
||||
import groovy.json.JsonSlurper
|
||||
import groovy.transform.EqualsAndHashCode
|
||||
import groovy.transform.ToString
|
||||
import io.codearte.accurest.util.JsonConverter
|
||||
import org.codehaus.groovy.runtime.GStringImpl
|
||||
|
||||
import java.util.regex.Matcher
|
||||
import java.util.regex.Pattern
|
||||
|
||||
@ToString(includePackage = false, includeFields = true, includeNames = true)
|
||||
@EqualsAndHashCode(includeFields = true)
|
||||
class Body extends DslProperty {
|
||||
|
||||
private static final Pattern TEMPORARY_PATTERN_HOLDER = Pattern.compile('REGEXP>>(.*)<<')
|
||||
private static final String JSON_VALUE_PATTERN_FOR_REGEX = 'REGEXP>>%s<<'
|
||||
|
||||
Body(Map<String, DslProperty> body) {
|
||||
super(extractValue(body, {it.clientValue}), extractValue(body, {it.serverValue}))
|
||||
}
|
||||
@@ -35,10 +42,41 @@ class Body extends DslProperty {
|
||||
super(bodyAsValue.clientValue, bodyAsValue.serverValue)
|
||||
}
|
||||
|
||||
/**
|
||||
* Due to the fact that we allow users to have a body with GString and different values inside
|
||||
* we need to be prepared that they pass regexps around both on client and server side.
|
||||
*
|
||||
* In order to preserve the original JSON structure we need to convert the passed Regex patterns
|
||||
* to a temporary string, then convert all to a legitimate JSON structure and then finally
|
||||
* convert it back from string to a pattern.
|
||||
*
|
||||
* @param bodyAsValue - GString with passed values
|
||||
* @param valueProvider - provider of values either for server or client side
|
||||
* @return JSON structure with replaced client / server side parts
|
||||
*/
|
||||
private static Object extractValue(GString bodyAsValue, Closure valueProvider) {
|
||||
GString clientGString = new GStringImpl(bodyAsValue.values.clone(), bodyAsValue.strings.clone())
|
||||
Object[] clientValues = bodyAsValue.values.collect { it instanceof DslProperty ? valueProvider(it) : it } as Object[]
|
||||
return new JsonSlurper().parseText(new GStringImpl(clientValues, clientGString.strings).toString())
|
||||
GString gString = new GStringImpl(bodyAsValue.values.clone(), bodyAsValue.strings.clone())
|
||||
Object[] values = bodyAsValue.values.collect { it instanceof DslProperty ? valueProvider(it) : it } as Object[]
|
||||
Object[] valuesWithRegexpsAsTransformedStrings = values.collect {
|
||||
it instanceof Pattern ? String.format(JSON_VALUE_PATTERN_FOR_REGEX, it.toString()) : it
|
||||
} as Object[]
|
||||
def parsedJson = new JsonSlurper().parseText(new GStringImpl(valuesWithRegexpsAsTransformedStrings, gString.strings))
|
||||
return convertAllTemporaryRegexPlaceholdersBackToPatterns(parsedJson)
|
||||
}
|
||||
|
||||
|
||||
private static Object convertAllTemporaryRegexPlaceholdersBackToPatterns(parsedJson) {
|
||||
JsonConverter.transformValues(parsedJson, { Object value ->
|
||||
if (value instanceof String) {
|
||||
String string = (String) value
|
||||
Matcher matcher = TEMPORARY_PATTERN_HOLDER.matcher(string)
|
||||
if (matcher.matches()) {
|
||||
String pattern = matcher[0][1]
|
||||
return Pattern.compile(pattern)
|
||||
}
|
||||
return value
|
||||
}
|
||||
return value
|
||||
})
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
package io.codearte.accurest.util
|
||||
|
||||
import groovy.json.JsonSlurper
|
||||
/**
|
||||
* @author Marcin Grzejszczak
|
||||
*/
|
||||
class JsonConverter {
|
||||
|
||||
private static Map convert(Map map, Closure closure) {
|
||||
return map.collectEntries {
|
||||
key, value ->
|
||||
[key, transformValues(value, closure)]
|
||||
}
|
||||
}
|
||||
|
||||
static def transformValues(def value, Closure closure) {
|
||||
if (value instanceof String && value) {
|
||||
try {
|
||||
def json = new JsonSlurper().parseText(value)
|
||||
if (json instanceof Map) {
|
||||
return convert(json, closure)
|
||||
}
|
||||
} catch (Exception ignore) {
|
||||
return closure(value)
|
||||
}
|
||||
} else if (value instanceof Map) {
|
||||
return convert(value as Map, closure)
|
||||
} else if (value instanceof List) {
|
||||
return value.collect({ transformValues(it, closure) })
|
||||
}
|
||||
try {
|
||||
return closure(value)
|
||||
} catch (Exception ignore) {
|
||||
return value
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,53 +0,0 @@
|
||||
package io.codearte.accurest.util
|
||||
|
||||
import groovy.json.JsonException
|
||||
import groovy.json.JsonSlurper
|
||||
|
||||
import java.util.regex.Pattern
|
||||
|
||||
/**
|
||||
* @author Marcin Grzejszczak
|
||||
*/
|
||||
class StubMappingConverter {
|
||||
|
||||
private static final Pattern PLACEHOLDER_PATTERN = Pattern.compile(/^\$\{(.*):(.*)\}$/)
|
||||
public static final int SERVER_SIDE_GROUP = 2
|
||||
|
||||
static Map toStubMappingOnServerSide(File stubMapping) {
|
||||
def json = new JsonSlurper().parse(stubMapping)
|
||||
return convertPlaceholders(json as Map, { String value ->
|
||||
getGroupFromMatchingPattern(value)
|
||||
})
|
||||
}
|
||||
|
||||
private static Map convertPlaceholders(Map map, Closure closure) {
|
||||
return map.collectEntries {
|
||||
key, value ->
|
||||
[key, transformValue(value, closure)]
|
||||
}
|
||||
}
|
||||
|
||||
static def transformValue(def value, Closure closure) {
|
||||
if (value instanceof String && value) {
|
||||
try {
|
||||
def json = new JsonSlurper().parseText(value)
|
||||
if (json instanceof Map) {
|
||||
return convertPlaceholders(json, closure)
|
||||
}
|
||||
} catch (JsonException ignore) {
|
||||
return closure(value)
|
||||
}
|
||||
} else if (value instanceof Map) {
|
||||
return convertPlaceholders(value as Map, closure)
|
||||
} else if (value instanceof List) {
|
||||
return value.collect({ transformValue(it, closure) })
|
||||
}
|
||||
|
||||
return value
|
||||
}
|
||||
|
||||
private static Object getGroupFromMatchingPattern(String value) {
|
||||
return value.matches(PLACEHOLDER_PATTERN) ? PLACEHOLDER_PATTERN.matcher(value)[0][SERVER_SIDE_GROUP] : value
|
||||
}
|
||||
|
||||
}
|
||||
@@ -110,4 +110,63 @@ class SpockMethodBuilderSpec extends Specification {
|
||||
blockBuilder.toString().contains("responseBody.property1 == \"a\"")
|
||||
blockBuilder.toString().contains("responseBody.property2.property3 == \"b\"")
|
||||
}
|
||||
|
||||
def "should generate regex assertions for map objects in response body"() {
|
||||
given:
|
||||
GroovyDsl contractDsl = GroovyDsl.make {
|
||||
request {
|
||||
method "GET"
|
||||
url "test"
|
||||
}
|
||||
response {
|
||||
status 200
|
||||
body(
|
||||
property1: "a",
|
||||
property2: value(
|
||||
client(''),
|
||||
server(regex('\\\\d{3}'))
|
||||
)
|
||||
)
|
||||
headers {
|
||||
header('Content-Type': 'application/json')
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
SpockMethodBodyBuilder builder = new SpockMethodBodyBuilder(contractDsl)
|
||||
BlockBuilder blockBuilder = new BlockBuilder(" ")
|
||||
when:
|
||||
builder.appendTo(blockBuilder)
|
||||
then:
|
||||
blockBuilder.toString().contains("responseBody.property1 == \"a\"")
|
||||
blockBuilder.toString().contains("responseBody.property2 ==~ java.util.regex.Pattern.compile('\\\\d{3}')")
|
||||
}
|
||||
|
||||
def "should generate regex assertions for string objects in response body"() {
|
||||
given:
|
||||
GroovyDsl contractDsl = GroovyDsl.make {
|
||||
request {
|
||||
method "GET"
|
||||
url "test"
|
||||
}
|
||||
response {
|
||||
status 200
|
||||
body( """{"property1":"a","property2":"${value(client('123'), server(regex('[0-9]{3}')))}"}""")
|
||||
headers {
|
||||
header('Content-Type': 'application/json')
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
SpockMethodBodyBuilder builder = new SpockMethodBodyBuilder(contractDsl)
|
||||
BlockBuilder blockBuilder = new BlockBuilder(" ")
|
||||
when:
|
||||
builder.appendTo(blockBuilder)
|
||||
then:
|
||||
blockBuilder.toString().contains("responseBody.property1 == \"a\"")
|
||||
blockBuilder.toString().contains("responseBody.property2 ==~ java.util.regex.Pattern.compile('[0-9]{3}')")
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -98,6 +98,7 @@ project(':accurest-converters') {
|
||||
compile project(':accurest-core')
|
||||
compile 'org.apache.commons:commons-lang3:3.3.2'
|
||||
compile 'commons-io:commons-io:[2.4,)'
|
||||
testCompile 'com.github.tomakehurst:wiremock:1.53'
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user