[#49] Fixed missing conversion of request body

This commit is contained in:
Marcin Grzejszczak
2015-05-12 16:14:46 +02:00
parent e17110253e
commit 7e7e3ff003
6 changed files with 139 additions and 65 deletions

View File

@@ -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 }
}
}

View File

@@ -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)] : [:]
}
}

View File

@@ -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
})
}
}

View File

@@ -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
}
}
}

View File

@@ -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
}
}

View File

@@ -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}')")
}
}