[#49] Fixed missing conversion of request body
This commit is contained in:
@@ -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}))
|
||||
}
|
||||
@@ -36,9 +43,28 @@ class Body extends DslProperty {
|
||||
}
|
||||
|
||||
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}')")
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user