Merge pull request #133 from Codearte/issues/123-cleaner-assertions-squashed
[#121] Introduced full JSONPath support
This commit is contained in:
@@ -1,9 +1,15 @@
|
||||
language: java
|
||||
sudo: false
|
||||
|
||||
jdk:
|
||||
- oraclejdk7
|
||||
- openjdk7
|
||||
- oraclejdk8
|
||||
|
||||
cache:
|
||||
directories:
|
||||
- $HOME/.gradle
|
||||
- $HOME/.m2
|
||||
|
||||
install: ./gradlew assemble
|
||||
script: ./gradlew check --stacktrace --info --continue
|
||||
@@ -1,6 +1,6 @@
|
||||
package io.codearte.accurest.wiremock
|
||||
|
||||
import groovy.json.JsonSlurper
|
||||
import org.skyscreamer.jsonassert.JSONAssert
|
||||
import spock.lang.Specification
|
||||
|
||||
class DslToWireMockClientConverterSpec extends Specification {
|
||||
@@ -23,8 +23,9 @@ class DslToWireMockClientConverterSpec extends Specification {
|
||||
when:
|
||||
String json = converter.convertContent(dslBody)
|
||||
then:
|
||||
new JsonSlurper().parseText(json) == new JsonSlurper().parseText("""
|
||||
{"request":{"method":"PUT","urlPattern":"/[0-9]{2}"},"response":{"status":200}}""")
|
||||
JSONAssert.assertEquals('''
|
||||
{"request":{"method":"PUT","urlPattern":"/[0-9]{2}"},"response":{"status":200}}
|
||||
''', json, false)
|
||||
}
|
||||
|
||||
|
||||
@@ -80,22 +81,62 @@ class DslToWireMockClientConverterSpec extends Specification {
|
||||
when:
|
||||
String json = converter.convertContent(dslBody)
|
||||
then:
|
||||
new JsonSlurper().parseText(json) == new JsonSlurper().parseText("""{
|
||||
"request":{
|
||||
"method":"PUT",
|
||||
"url":"/api/12",
|
||||
"bodyPatterns": [
|
||||
{ "equalToJson": "[{\\"created_at\\":\\"Sat Jul 26 09:38:57 +0000 2014\\",\\"id\\":492967299297845248,\\"id_str\\":\\"492967299297845248\\",\\"place\\":{\\"attributes\\":{},\\"bounding_box\\":{\\"coordinates\\":[[[-77.119759,38.791645],[-76.909393,38.791645],[-76.909393,38.995548],[-77.119759,38.995548]]],\\"type\\":\\"Polygon\\"},\\"country\\":\\"United States\\",\\"country_code\\":\\"US\\",\\"full_name\\":\\"Washington, DC\\",\\"id\\":\\"01fbe706f872cb32\\",\\"name\\":\\"Washington\\",\\"place_type\\":\\"city\\",\\"url\\":\\"http://api.twitter.com/1/geo/id/01fbe706f872cb32.json\\"},\\"text\\":\\"Gonna see you at Warsaw\\"}]" }
|
||||
],
|
||||
"headers": {
|
||||
"Content-Type": {
|
||||
"equalTo": "application/vnd.com.ofg.twitter-places-analyzer.v1+json"
|
||||
}
|
||||
}
|
||||
},
|
||||
"response":{
|
||||
"status":200}
|
||||
}
|
||||
""")
|
||||
JSONAssert.assertEquals('''
|
||||
{
|
||||
"request" : {
|
||||
"url" : "/api/12",
|
||||
"method" : "PUT",
|
||||
"bodyPatterns" : [ {
|
||||
"matchesJsonPath" : "$[*].place.bounding_box.coordinates[*][*][?(@ == 38.995548)]"
|
||||
}, {
|
||||
"matchesJsonPath" : "$[*].place[?(@.country == 'United States')]"
|
||||
}, {
|
||||
"matchesJsonPath" : "$[*].place.bounding_box.coordinates[*][*][?(@ == -77.119759)]"
|
||||
}, {
|
||||
"matchesJsonPath" : "$[*].place[?(@.name == 'Washington')]"
|
||||
}, {
|
||||
"matchesJsonPath" : "$[*].place.bounding_box[?(@.type == 'Polygon')]"
|
||||
}, {
|
||||
"matchesJsonPath" : "$[*][?(@.id_str == '492967299297845248')]"
|
||||
}, {
|
||||
"matchesJsonPath" : "$[*].place[?(@.country_code == 'US')]"
|
||||
}, {
|
||||
"matchesJsonPath" : "$[*][?(@.id == 492967299297845248)]"
|
||||
}, {
|
||||
"matchesJsonPath" : "$[*].place.bounding_box.coordinates[*][*][?(@ == -76.909393)]"
|
||||
}, {
|
||||
"matchesJsonPath" : "$[*].place.bounding_box.coordinates[*][*][?(@ == 38.791645)]"
|
||||
}, {
|
||||
"matchesJsonPath" : "$[*].place[?(@.id == '01fbe706f872cb32')]"
|
||||
}, {
|
||||
"matchesJsonPath" : "$[*].place[?(@.url == 'http://api.twitter.com/1/geo/id/01fbe706f872cb32.json')]"
|
||||
}, {
|
||||
"matchesJsonPath" : "$[*].place.bounding_box.coordinates[*][*][?(@ == -77.119759)]"
|
||||
}, {
|
||||
"matchesJsonPath" : "$[*].place.bounding_box.coordinates[*][*][?(@ == -76.909393)]"
|
||||
}, {
|
||||
"matchesJsonPath" : "$[*].place.bounding_box.coordinates[*][*][?(@ == 38.995548)]"
|
||||
}, {
|
||||
"matchesJsonPath" : "$[*][?(@.text == 'Gonna see you at Warsaw')]"
|
||||
}, {
|
||||
"matchesJsonPath" : "$[*].place[?(@.place_type == 'city')]"
|
||||
}, {
|
||||
"matchesJsonPath" : "$[*][?(@.created_at == 'Sat Jul 26 09:38:57 +0000 2014')]"
|
||||
}, {
|
||||
"matchesJsonPath" : "$[*].place[?(@.full_name == 'Washington, DC')]"
|
||||
}, {
|
||||
"matchesJsonPath" : "$[*].place.bounding_box.coordinates[*][*][?(@ == 38.791645)]"
|
||||
} ],
|
||||
"headers" : {
|
||||
"Content-Type" : {
|
||||
"equalTo" : "application/vnd.com.ofg.twitter-places-analyzer.v1+json"
|
||||
}
|
||||
}
|
||||
},
|
||||
"response" : {
|
||||
"status" : 200
|
||||
}
|
||||
}
|
||||
''', json, false)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -50,14 +50,23 @@ class SingleTestGenerator {
|
||||
}
|
||||
|
||||
if (configProperties.ruleClassForTests) {
|
||||
|
||||
clazz.addImport('org.junit.Rule')
|
||||
.addRule(configProperties.ruleClassForTests)
|
||||
.addRule(configProperties.ruleClassForTests)
|
||||
}
|
||||
|
||||
addJsonPathRelatedImports(clazz)
|
||||
|
||||
listOfFiles.each {
|
||||
clazz.addMethod(createTestMethod(it, configProperties))
|
||||
}
|
||||
return clazz.build()
|
||||
}
|
||||
|
||||
private ClassBuilder addJsonPathRelatedImports(ClassBuilder clazz) {
|
||||
clazz.addImport(['com.jayway.jsonpath.DocumentContext',
|
||||
'com.jayway.jsonpath.JsonPath',
|
||||
'net.minidev.json.JSONArray'])
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -43,6 +43,11 @@ class ClassBuilder {
|
||||
return this
|
||||
}
|
||||
|
||||
ClassBuilder addImport(List<String> importsToAdd) {
|
||||
imports.addAll(importsToAdd)
|
||||
return this
|
||||
}
|
||||
|
||||
ClassBuilder addStaticImport(String importToAdd) {
|
||||
staticImports << importToAdd
|
||||
return this
|
||||
|
||||
@@ -3,21 +3,13 @@ import groovy.json.JsonOutput
|
||||
import groovy.transform.PackageScope
|
||||
import groovy.transform.TypeChecked
|
||||
import io.codearte.accurest.dsl.GroovyDsl
|
||||
import io.codearte.accurest.dsl.internal.DslProperty
|
||||
import io.codearte.accurest.dsl.internal.ExecutionProperty
|
||||
import io.codearte.accurest.dsl.internal.MatchingStrategy
|
||||
import io.codearte.accurest.dsl.internal.QueryParameter
|
||||
import io.codearte.accurest.dsl.internal.Request
|
||||
import io.codearte.accurest.dsl.internal.Response
|
||||
import io.codearte.accurest.dsl.internal.*
|
||||
import io.codearte.accurest.util.ContentType
|
||||
import io.codearte.accurest.util.JsonConverter
|
||||
|
||||
import java.util.regex.Pattern
|
||||
|
||||
import static io.codearte.accurest.util.ContentUtils.extractValue
|
||||
import static io.codearte.accurest.util.ContentUtils.recognizeContentTypeFromContent
|
||||
import static io.codearte.accurest.util.ContentUtils.recognizeContentTypeFromHeader
|
||||
import io.codearte.accurest.util.MapConverter
|
||||
import io.codearte.accurest.util.JsonPathJsonConverter
|
||||
import io.codearte.accurest.util.JsonPaths
|
||||
|
||||
import static io.codearte.accurest.util.ContentUtils.*
|
||||
/**
|
||||
* @author Jakub Kubrynski
|
||||
*/
|
||||
@@ -93,17 +85,34 @@ abstract class SpockMethodBodyBuilder {
|
||||
responseBody = extractValue(responseBody, contentType, { DslProperty dslProperty -> dslProperty.serverValue })
|
||||
}
|
||||
if (contentType == ContentType.JSON) {
|
||||
bb.addLine("def responseBody = new JsonSlurper().parseText($responseAsString)")
|
||||
appendJsonPath(bb, responseAsString)
|
||||
JsonPaths jsonPaths = JsonPathJsonConverter.transformToJsonPathWithTestsSideValues(responseBody)
|
||||
jsonPaths.each {
|
||||
it.buildJsonPathComparison('parsedJson').each {
|
||||
bb.addLine(it)
|
||||
}
|
||||
}
|
||||
processBodyElement(bb, "", responseBody)
|
||||
} else if (contentType == ContentType.XML) {
|
||||
bb.addLine("def responseBody = new XmlSlurper().parseText($responseAsString)")
|
||||
// TODO xml validation
|
||||
} else {
|
||||
bb.addLine("def responseBody = ($responseAsString)")
|
||||
processBodyElement(bb, "", responseBody)
|
||||
processText(bb, "", responseBody as String)
|
||||
}
|
||||
}
|
||||
|
||||
protected void processText(BlockBuilder blockBuilder, String property, String value) {
|
||||
if (value.startsWith('$')) {
|
||||
value = value.substring(1).replaceAll('\\$value', "responseBody$property")
|
||||
blockBuilder.addLine(value)
|
||||
} else {
|
||||
blockBuilder.addLine("responseBody$property == \"${value}\"")
|
||||
}
|
||||
}
|
||||
|
||||
protected String
|
||||
|
||||
protected String getBodyAsString() {
|
||||
Object bodyValue = extractServerValueFromBody(request.body.serverValue)
|
||||
return trimRepeatedQuotes(new JsonOutput().toJson(bodyValue))
|
||||
@@ -117,7 +126,7 @@ abstract class SpockMethodBodyBuilder {
|
||||
if (bodyValue instanceof GString) {
|
||||
bodyValue = extractValue(bodyValue, { DslProperty dslProperty -> dslProperty.serverValue })
|
||||
} else {
|
||||
bodyValue = JsonConverter.transformValues(bodyValue, { it instanceof DslProperty ? it.serverValue : it })
|
||||
bodyValue = MapConverter.transformValues(bodyValue, { it instanceof DslProperty ? it.serverValue : it })
|
||||
}
|
||||
return bodyValue
|
||||
}
|
||||
@@ -147,28 +156,15 @@ abstract class SpockMethodBodyBuilder {
|
||||
}
|
||||
|
||||
protected void processBodyElement(BlockBuilder blockBuilder, String property, Object value) {
|
||||
blockBuilder.addLine("responseBody$property == ${value}")
|
||||
|
||||
}
|
||||
|
||||
protected void processBodyElement(BlockBuilder blockBuilder, String property, String value) {
|
||||
if (value.startsWith('$')) {
|
||||
value = value.substring(1).replaceAll('\\$value', "responseBody$property")
|
||||
blockBuilder.addLine(value)
|
||||
} else {
|
||||
blockBuilder.addLine("responseBody$property == '''${value}'''")
|
||||
}
|
||||
}
|
||||
|
||||
protected void processBodyElement(BlockBuilder blockBuilder, String property, Pattern pattern) {
|
||||
blockBuilder.addLine("responseBody$property ==~ java.util.regex.Pattern.compile('${pattern.pattern()}')")
|
||||
}
|
||||
|
||||
protected void processBodyElement(BlockBuilder blockBuilder, String property, DslProperty dslProperty) {
|
||||
processBodyElement(blockBuilder, property, dslProperty.serverValue)
|
||||
protected void appendJsonPath(BlockBuilder blockBuilder, String json) {
|
||||
blockBuilder.addLine("DocumentContext parsedJson = JsonPath.parse($json)")
|
||||
}
|
||||
|
||||
protected void processBodyElement(BlockBuilder blockBuilder, String property, ExecutionProperty exec) {
|
||||
blockBuilder.addLine("${exec.insertValue("responseBody$property")}")
|
||||
blockBuilder.addLine("${exec.insertValue("parsedJson.read('\\\$$property')")}")
|
||||
}
|
||||
|
||||
protected void processBodyElement(BlockBuilder blockBuilder, String property, Map.Entry entry) {
|
||||
|
||||
@@ -10,7 +10,7 @@ import io.codearte.accurest.util.ContentType
|
||||
import java.util.regex.Pattern
|
||||
|
||||
import static io.codearte.accurest.util.ContentUtils.extractValue
|
||||
import static io.codearte.accurest.util.JsonConverter.transformValues
|
||||
import static io.codearte.accurest.util.MapConverter.transformValues
|
||||
|
||||
@TypeChecked
|
||||
abstract class BaseWireMockStubStrategy {
|
||||
|
||||
@@ -1,21 +1,21 @@
|
||||
package io.codearte.accurest.dsl
|
||||
import com.github.tomakehurst.wiremock.http.RequestMethod
|
||||
import com.github.tomakehurst.wiremock.matching.RequestPattern
|
||||
import com.github.tomakehurst.wiremock.matching.ValuePattern
|
||||
import groovy.json.JsonOutput
|
||||
import groovy.transform.PackageScope
|
||||
import groovy.transform.TypeChecked
|
||||
import io.codearte.accurest.dsl.internal.Body
|
||||
import io.codearte.accurest.dsl.internal.ClientRequest
|
||||
import io.codearte.accurest.dsl.internal.DslProperty
|
||||
import io.codearte.accurest.dsl.internal.MatchingStrategy
|
||||
import io.codearte.accurest.dsl.internal.QueryParameter
|
||||
import io.codearte.accurest.dsl.internal.QueryParameters
|
||||
import io.codearte.accurest.dsl.internal.Request
|
||||
import groovy.transform.TypeCheckingMode
|
||||
import io.codearte.accurest.dsl.internal.*
|
||||
import io.codearte.accurest.util.ContentType
|
||||
import io.codearte.accurest.util.ContentUtils
|
||||
import io.codearte.accurest.util.JsonPathJsonConverter
|
||||
import io.codearte.accurest.util.JsonPaths
|
||||
import io.codearte.accurest.util.MapConverter
|
||||
|
||||
import java.util.regex.Pattern
|
||||
|
||||
import static io.codearte.accurest.util.ContentUtils.getEqualsTypeFromContentType
|
||||
import static io.codearte.accurest.util.ContentUtils.recognizeContentTypeFromContent
|
||||
import static io.codearte.accurest.util.ContentUtils.recognizeContentTypeFromHeader
|
||||
import static io.codearte.accurest.util.ContentUtils.recognizeContentTypeFromMatchingStrategy
|
||||
import static io.codearte.accurest.util.ContentUtils.*
|
||||
import static io.codearte.accurest.util.RegexpBuilders.buildGStringRegexpMatch
|
||||
import static io.codearte.accurest.util.RegexpBuilders.buildJSONRegexpMatch
|
||||
|
||||
@@ -30,74 +30,144 @@ class WireMockRequestStubStrategy extends BaseWireMockStubStrategy {
|
||||
}
|
||||
|
||||
@PackageScope
|
||||
Map buildClientRequestContent() {
|
||||
return buildRequestContent(new ClientRequest(request))
|
||||
RequestPattern buildClientRequestContent() {
|
||||
RequestPattern requestPattern = new RequestPattern()
|
||||
appendMethod(requestPattern)
|
||||
appendHeaders(requestPattern)
|
||||
appendUrl(requestPattern)
|
||||
appendQueryParameters(requestPattern)
|
||||
appendBody(requestPattern)
|
||||
return requestPattern
|
||||
}
|
||||
|
||||
private Map<String, Object> buildRequestContent(ClientRequest request) {
|
||||
return ([method : request?.method?.clientValue,
|
||||
headers : buildClientRequestHeadersSection(request.headers)
|
||||
] << appendUrl(request) << appendQueryParameters(request) << appendBody(request)).findAll { it.value }
|
||||
private void appendMethod(RequestPattern requestPattern) {
|
||||
if(!request.method) {
|
||||
return
|
||||
}
|
||||
requestPattern.setMethod(RequestMethod.fromString(request.method.clientValue?.toString()))
|
||||
}
|
||||
|
||||
private Map<String, Object> appendUrl(ClientRequest clientRequest) {
|
||||
Object urlPath = clientRequest?.urlPath?.clientValue
|
||||
private void appendBody(RequestPattern requestPattern) {
|
||||
if (!request.body) {
|
||||
return
|
||||
}
|
||||
ContentType contentType = tryToGetContentType()
|
||||
if (contentType == ContentType.JSON) {
|
||||
JsonPaths values = JsonPathJsonConverter.transformToJsonPathWithStubsSideValues(getMatchingStrategyFromBody(request.body)?.clientValue)
|
||||
if (values.empty) {
|
||||
requestPattern.bodyPatterns = [new ValuePattern(jsonCompareMode: org.skyscreamer.jsonassert.JSONCompareMode.LENIENT,
|
||||
equalToJson: JsonOutput.toJson(getMatchingStrategy(request.body.clientValue).clientValue) ) ]
|
||||
} else {
|
||||
requestPattern.bodyPatterns = values.collect { new ValuePattern(matchesJsonPath: it.jsonPath) } ?: null
|
||||
}
|
||||
} else if (contentType == ContentType.XML) {
|
||||
requestPattern.bodyPatterns = [new ValuePattern(equalToXml: getMatchingStrategy(request.body.clientValue).clientValue.toString())]
|
||||
} else if (containsPattern(request?.body)) {
|
||||
MatchingStrategy matchingStrategy = appendBodyRegexpMatchPattern(request.body)
|
||||
requestPattern.bodyPatterns = [convertToValuePattern(matchingStrategy)]
|
||||
} else {
|
||||
requestPattern.bodyPatterns = [convertToValuePattern(getMatchingStrategy(request.body.clientValue))]
|
||||
}
|
||||
}
|
||||
|
||||
private ContentType tryToGetContentType() {
|
||||
ContentType contentType = recognizeContentTypeFromHeader(request.headers)
|
||||
if (contentType == ContentType.UNKNOWN) {
|
||||
if (!request.body.clientValue) {
|
||||
return ContentType.UNKNOWN
|
||||
}
|
||||
return ContentUtils.getClientContentType(request.body.clientValue)
|
||||
}
|
||||
return contentType
|
||||
}
|
||||
|
||||
private void appendHeaders(RequestPattern requestPattern) {
|
||||
if(!request.headers) {
|
||||
return
|
||||
}
|
||||
request.headers.entries.each {
|
||||
requestPattern.addHeader(it.name, convertToValuePattern(it.clientValue))
|
||||
}
|
||||
}
|
||||
|
||||
private void appendUrl(RequestPattern requestPattern) {
|
||||
Object urlPath = request?.urlPath?.clientValue
|
||||
if (urlPath) {
|
||||
return [urlPath: urlPath]
|
||||
requestPattern.setUrlPath(urlPath.toString())
|
||||
}
|
||||
Object url = clientRequest?.url?.clientValue
|
||||
return url instanceof Pattern ? [urlPattern: url.pattern()] : [url: url]
|
||||
}
|
||||
|
||||
private Map<String, Object> appendQueryParameters(ClientRequest clientRequest) {
|
||||
QueryParameters queryParameters = clientRequest?.urlPath?.queryParameters ?: clientRequest?.url?.queryParameters
|
||||
return queryParameters && !queryParameters.parameters.isEmpty() ?
|
||||
[queryParameters: buildUrlPathQueryParameters(queryParameters)] : [:]
|
||||
}
|
||||
|
||||
private Map<String, Object> buildUrlPathQueryParameters(QueryParameters queryParameters) {
|
||||
return queryParameters.parameters.collectEntries { QueryParameter param ->
|
||||
parseQueryParameter(param.name, param.clientValue)
|
||||
if(!request.url) {
|
||||
return
|
||||
}
|
||||
Object url = request?.url?.clientValue
|
||||
if(url instanceof Pattern) {
|
||||
requestPattern.setUrlPattern(url.pattern())
|
||||
} else {
|
||||
requestPattern.setUrl(url.toString())
|
||||
}
|
||||
}
|
||||
|
||||
protected Map<String, Object> parseQueryParameter(String name, MatchingStrategy matchingStrategy) {
|
||||
return buildQueryParameter(name, matchingStrategy.clientValue, matchingStrategy.type)
|
||||
private void appendQueryParameters(RequestPattern requestPattern) {
|
||||
QueryParameters queryParameters = request?.urlPath?.queryParameters ?: request?.url?.queryParameters
|
||||
queryParameters?.parameters?.each {
|
||||
requestPattern.addQueryParam(it.name, convertToValuePattern(it.clientValue))
|
||||
}
|
||||
}
|
||||
|
||||
protected Map<String, Object> parseQueryParameter(String name, Object value) {
|
||||
return buildQueryParameter(name, value, MatchingStrategy.Type.EQUAL_TO)
|
||||
@TypeChecked(TypeCheckingMode.SKIP)
|
||||
private static ValuePattern convertToValuePattern(Object object) {
|
||||
switch (object) {
|
||||
case Pattern:
|
||||
Pattern value = object as Pattern
|
||||
return ValuePattern.matches(value.pattern())
|
||||
case MatchingStrategy:
|
||||
MatchingStrategy value = object as MatchingStrategy
|
||||
switch (value.type) {
|
||||
case MatchingStrategy.Type.NOT_MATCHING:
|
||||
return new ValuePattern(doesNotMatch: value.clientValue)
|
||||
case MatchingStrategy.Type.ABSENT:
|
||||
return ValuePattern.absent()
|
||||
default:
|
||||
return ValuePattern."${value.type.name}"(value.clientValue)
|
||||
}
|
||||
default:
|
||||
return ValuePattern.equalTo(object.toString())
|
||||
}
|
||||
}
|
||||
|
||||
protected Map<String, Object> parseQueryParameter(String name, Pattern pattern) {
|
||||
return buildQueryParameter(name, pattern.pattern(), MatchingStrategy.Type.MATCHING)
|
||||
private MatchingStrategy getMatchingStrategyFromBody(Body body) {
|
||||
if(!body) {
|
||||
return null
|
||||
}
|
||||
return getMatchingStrategy(body.clientValue)
|
||||
}
|
||||
|
||||
private Map<String, Object> buildQueryParameter(String name, Pattern pattern, MatchingStrategy.Type type) {
|
||||
return buildQueryParameter(name, pattern.pattern(), type)
|
||||
private MatchingStrategy getMatchingStrategy(MatchingStrategy matchingStrategy) {
|
||||
return getMatchingStrategyIncludingContentType(matchingStrategy)
|
||||
}
|
||||
private MatchingStrategy getMatchingStrategy(GString gString) {
|
||||
if (!gString) {
|
||||
return new MatchingStrategy("", MatchingStrategy.Type.EQUAL_TO)
|
||||
}
|
||||
def extractedValue = ContentUtils.extractValue(gString) {
|
||||
it instanceof DslProperty ? it.clientValue : getStringFromGString(it)
|
||||
}
|
||||
def value = getStringFromGString(extractedValue)
|
||||
return getMatchingStrategy(value)
|
||||
}
|
||||
|
||||
private Map<String, Object> buildQueryParameter(String name, Object value, MatchingStrategy.Type type) {
|
||||
return [(name): [(type.name) : value]]
|
||||
private def getStringFromGString(Object object) {
|
||||
return object instanceof GString ? object.toString() : object
|
||||
}
|
||||
|
||||
private Map<String, Object> appendBody(ClientRequest clientRequest) {
|
||||
return clientRequest.body? appendBody(clientRequest.body) : [:]
|
||||
private MatchingStrategy getMatchingStrategy(Object bodyValue) {
|
||||
return tryToFindMachingStrategy(bodyValue)
|
||||
}
|
||||
|
||||
private Map<String, Object> appendBody(Body body) {
|
||||
return [bodyPatterns: (appendBodyPatterns(body.clientValue))]
|
||||
private MatchingStrategy tryToFindMachingStrategy(Object bodyValue) {
|
||||
return new MatchingStrategy(MapConverter.transformToClientValues(bodyValue), getEqualsTypeFromContentTypeHeader())
|
||||
}
|
||||
|
||||
private List<Map<String, Object>> appendBodyPatterns(MatchingStrategy matchingStrategy) {
|
||||
return [appendBodyPattern(matchingStrategy)]
|
||||
}
|
||||
|
||||
private List<Map<String, Object>> appendBodyPatterns(Object bodyValue) {
|
||||
return appendBodyPatterns(new MatchingStrategy(bodyValue, getEqualsTypeFromContentTypeHeader()))
|
||||
}
|
||||
|
||||
private Map<String, Object> appendBodyPattern(MatchingStrategy matchingStrategy) {
|
||||
private MatchingStrategy getMatchingStrategyIncludingContentType(MatchingStrategy matchingStrategy) {
|
||||
MatchingStrategy.Type type = matchingStrategy.type
|
||||
Object value = matchingStrategy.clientValue
|
||||
ContentType contentType = recognizeContentTypeFromMatchingStrategy(type)
|
||||
@@ -105,29 +175,22 @@ class WireMockRequestStubStrategy extends BaseWireMockStubStrategy {
|
||||
contentType = recognizeContentTypeFromContent(value)
|
||||
type = getEqualsTypeFromContentType(contentType)
|
||||
}
|
||||
if (containsPattern(value)) {
|
||||
return appendBodyRegexpMatchPattern(value, contentType)
|
||||
}
|
||||
return buildMatchPattern(new MatchingStrategy(parseBody(value, contentType), type))
|
||||
return new MatchingStrategy(parseBody(value, contentType), type)
|
||||
}
|
||||
|
||||
private Map<String, Object> appendBodyRegexpMatchPattern(Object value, ContentType contentType) {
|
||||
private MatchingStrategy appendBodyRegexpMatchPattern(Object value, ContentType contentType) {
|
||||
switch (contentType) {
|
||||
case ContentType.JSON:
|
||||
return buildMatchPattern(new MatchingStrategy(buildJSONRegexpMatch(value), MatchingStrategy.Type.MATCHING))
|
||||
return new MatchingStrategy(buildJSONRegexpMatch(value), MatchingStrategy.Type.MATCHING)
|
||||
case ContentType.UNKNOWN:
|
||||
return buildMatchPattern(new MatchingStrategy(buildGStringRegexpMatch(value), MatchingStrategy.Type.MATCHING))
|
||||
return new MatchingStrategy(buildGStringRegexpMatch(value), MatchingStrategy.Type.MATCHING)
|
||||
case ContentType.XML:
|
||||
throw new IllegalStateException("XML pattern matching is not implemented yet")
|
||||
}
|
||||
}
|
||||
|
||||
private Map<String, Object> buildMatchPattern(MatchingStrategy matchingStrategy) {
|
||||
Map<String, ? extends Object> result = [(matchingStrategy.type.name): matchingStrategy.clientValue.toString()]
|
||||
if (matchingStrategy.type == MatchingStrategy.Type.EQUAL_TO_JSON && matchingStrategy.jsonCompareMode) {
|
||||
return result << [jsonCompareMode : (matchingStrategy.jsonCompareMode.toString())]
|
||||
}
|
||||
return result
|
||||
private MatchingStrategy appendBodyRegexpMatchPattern(Object value) {
|
||||
return appendBodyRegexpMatchPattern(value, ContentType.UNKNOWN)
|
||||
}
|
||||
|
||||
private boolean containsPattern(GString bodyAsValue) {
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
package io.codearte.accurest.dsl
|
||||
import com.github.tomakehurst.wiremock.http.HttpHeader
|
||||
import com.github.tomakehurst.wiremock.http.HttpHeaders
|
||||
import com.github.tomakehurst.wiremock.http.ResponseDefinition
|
||||
import groovy.transform.PackageScope
|
||||
import groovy.transform.TypeChecked
|
||||
import io.codearte.accurest.dsl.internal.ClientResponse
|
||||
import io.codearte.accurest.dsl.internal.Request
|
||||
import io.codearte.accurest.dsl.internal.Response
|
||||
import io.codearte.accurest.util.ContentType
|
||||
@@ -22,23 +24,31 @@ class WireMockResponseStubStrategy extends BaseWireMockStubStrategy {
|
||||
}
|
||||
|
||||
@PackageScope
|
||||
Map buildClientResponseContent() {
|
||||
return buildResponseContent(new ClientResponse(response))
|
||||
ResponseDefinition buildClientResponseContent() {
|
||||
ResponseDefinition responseDefinition = new ResponseDefinition()
|
||||
responseDefinition.setStatus(response.status.clientValue as Integer)
|
||||
appendHeaders(responseDefinition)
|
||||
appendBody(responseDefinition)
|
||||
return responseDefinition
|
||||
}
|
||||
|
||||
private Map<String, Object> buildResponseContent(ClientResponse response) {
|
||||
return ([status : response?.status?.clientValue,
|
||||
headers: buildClientResponseHeadersSection(response.headers)
|
||||
] << appendBody(response)).findAll { it.value }
|
||||
private void appendHeaders(ResponseDefinition responseDefinition) {
|
||||
if(!(response.headers)) {
|
||||
return
|
||||
}
|
||||
responseDefinition.setHeaders(new HttpHeaders(response.headers.entries?.collect { new HttpHeader(it.name, it.clientValue.toString()) }))
|
||||
}
|
||||
|
||||
private Map<String, Object> appendBody(ClientResponse response) {
|
||||
Object body = response?.body?.clientValue
|
||||
private void appendBody(ResponseDefinition responseDefinition) {
|
||||
if (!response.body) {
|
||||
return
|
||||
}
|
||||
Object body = response.body.clientValue
|
||||
ContentType contentType = recognizeContentTypeFromHeader(response.headers)
|
||||
if (contentType == ContentType.UNKNOWN) {
|
||||
contentType = recognizeContentTypeFromContent(body)
|
||||
}
|
||||
return body != null ? [body: parseBody(body, contentType)] : [:]
|
||||
responseDefinition.setBody(parseBody(body, contentType))
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
package io.codearte.accurest.dsl
|
||||
|
||||
import groovy.json.JsonOutput
|
||||
import com.github.tomakehurst.wiremock.http.ResponseDefinition
|
||||
import com.github.tomakehurst.wiremock.matching.RequestPattern
|
||||
import com.github.tomakehurst.wiremock.stubbing.StubMapping
|
||||
import groovy.transform.CompileDynamic
|
||||
import groovy.transform.CompileStatic
|
||||
|
||||
@@ -19,11 +21,14 @@ class WireMockStubStrategy {
|
||||
|
||||
@CompileDynamic
|
||||
String toWireMockClientStub() {
|
||||
def wiremockStubDefinition = [request : wireMockRequestStubStrategy.buildClientRequestContent(),
|
||||
response: wireMockResponseStubStrategy.buildClientResponseContent()]
|
||||
StubMapping stubMapping = new StubMapping()
|
||||
RequestPattern request = wireMockRequestStubStrategy.buildClientRequestContent()
|
||||
ResponseDefinition response = wireMockResponseStubStrategy.buildClientResponseContent()
|
||||
if (priority) {
|
||||
wiremockStubDefinition.priority = priority
|
||||
stubMapping.priority = priority
|
||||
}
|
||||
return JsonOutput.prettyPrint(JsonOutput.toJson(wiremockStubDefinition))
|
||||
stubMapping.request = request
|
||||
stubMapping.response = response
|
||||
return StubMapping.buildJsonStringFor(stubMapping)
|
||||
}
|
||||
}
|
||||
@@ -2,7 +2,7 @@ package io.codearte.accurest.dsl.internal
|
||||
|
||||
import groovy.json.JsonOutput
|
||||
import groovy.transform.CompileStatic
|
||||
import io.codearte.accurest.util.JsonConverter
|
||||
import io.codearte.accurest.util.MapConverter
|
||||
|
||||
import java.util.regex.Pattern
|
||||
|
||||
@@ -17,7 +17,7 @@ class JsonStructureConverter {
|
||||
Closure<String> performAdditionalLogicOnSerializedJson,
|
||||
Closure convertSerializedJsonToSth) {
|
||||
LinkedList<Object> queue = new LinkedList<>()
|
||||
def transformedJson = JsonConverter.transformValues(parsedJson, {
|
||||
def transformedJson = MapConverter.transformValues(parsedJson, {
|
||||
if(retrievePlaceholders(it)) {
|
||||
queue.push(it)
|
||||
return TEMPORARY_PLACEHOLDER
|
||||
|
||||
@@ -34,7 +34,7 @@ class MatchingStrategy extends DslProperty {
|
||||
|
||||
enum Type {
|
||||
|
||||
EQUAL_TO("equalTo"), CONTAINS("contains"), MATCHING("matches"), NOT_MATCHING("doesNotMatch"),
|
||||
EQUAL_TO("equalTo"), CONTAINS("containing"), MATCHING("matches"), NOT_MATCHING("doesNotMatch"),
|
||||
EQUAL_TO_JSON("equalToJson"), EQUAL_TO_XML("equalToXml"), ABSENT("absent")
|
||||
|
||||
final String name
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package io.codearte.accurest.util
|
||||
import groovy.json.JsonException
|
||||
import groovy.json.JsonOutput
|
||||
import groovy.json.JsonSlurper
|
||||
import groovy.transform.TypeChecked
|
||||
import groovy.util.logging.Slf4j
|
||||
@@ -18,6 +19,10 @@ import static org.apache.commons.lang3.StringEscapeUtils.escapeXml11
|
||||
@Slf4j
|
||||
class ContentUtils {
|
||||
|
||||
public static final Closure GET_STUB_SIDE = {
|
||||
it instanceof DslProperty ? it.clientValue : it
|
||||
}
|
||||
|
||||
private static final Pattern TEMPORARY_PATTERN_HOLDER = Pattern.compile('REGEXP>>(.*)<<')
|
||||
private static final String JSON_VALUE_PATTERN_FOR_REGEX = 'REGEXP>>%s<<'
|
||||
|
||||
@@ -57,7 +62,57 @@ class ContentUtils {
|
||||
return extractValueForGString(bodyAsValue, valueProvider)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static ContentType getClientContentType(GString bodyAsValue) {
|
||||
try {
|
||||
extractValueForJSON(bodyAsValue, GET_STUB_SIDE)
|
||||
return ContentType.JSON
|
||||
} catch(JsonException e) {
|
||||
try {
|
||||
new XmlSlurper().parseText(extractValueForXML(bodyAsValue, GET_STUB_SIDE).toString())
|
||||
return ContentType.XML
|
||||
} catch (Exception exception) {
|
||||
extractValueForGString(bodyAsValue, GET_STUB_SIDE)
|
||||
return ContentType.UNKNOWN
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static ContentType getClientContentType(String bodyAsValue) {
|
||||
try {
|
||||
new JsonSlurper().parseText(bodyAsValue)
|
||||
return ContentType.JSON
|
||||
} catch(JsonException e) {
|
||||
try {
|
||||
new XmlSlurper().parseText(bodyAsValue)
|
||||
return ContentType.XML
|
||||
} catch (Exception exception) {
|
||||
return ContentType.UNKNOWN
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static ContentType getClientContentType(Object bodyAsValue) {
|
||||
return ContentType.UNKNOWN
|
||||
}
|
||||
|
||||
public static ContentType getClientContentType(Map bodyAsValue) {
|
||||
try {
|
||||
JsonOutput.toJson(bodyAsValue)
|
||||
return ContentType.JSON
|
||||
} catch (Exception ignore) {
|
||||
return ContentType.UNKNOWN
|
||||
}
|
||||
}
|
||||
|
||||
public static ContentType getClientContentType(List bodyAsValue) {
|
||||
try {
|
||||
JsonOutput.toJson(bodyAsValue)
|
||||
return ContentType.JSON
|
||||
} catch (Exception ignore) {
|
||||
return ContentType.UNKNOWN
|
||||
}
|
||||
}
|
||||
|
||||
private static GStringImpl extractValueForGString(GString bodyAsValue, Closure valueProvider) {
|
||||
@@ -108,7 +163,7 @@ class ContentUtils {
|
||||
}
|
||||
|
||||
private static Object convertAllTemporaryRegexPlaceholdersBackToPatterns(parsedJson) {
|
||||
JsonConverter.transformValues(parsedJson, { Object value ->
|
||||
MapConverter.transformValues(parsedJson, { Object value ->
|
||||
if (value instanceof String) {
|
||||
String string = (String) value
|
||||
Matcher matcher = TEMPORARY_PATTERN_HOLDER.matcher(string)
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
package io.codearte.accurest.util
|
||||
|
||||
import java.util.regex.Pattern
|
||||
|
||||
class JsonPathEntry {
|
||||
final String jsonPath
|
||||
final String optionalSuffix
|
||||
final Object value
|
||||
|
||||
JsonPathEntry(String jsonPath, String optionalSuffix, Object value) {
|
||||
this.jsonPath = jsonPath
|
||||
this.optionalSuffix = optionalSuffix
|
||||
this.value = value
|
||||
}
|
||||
|
||||
List<String> buildJsonPathComparison(String parsedJsonVariable) {
|
||||
if (optionalSuffix) {
|
||||
return ["!${parsedJsonVariable}.read('''${jsonPath}''', JSONArray).empty"]
|
||||
} else if (traversesOverCollections()) {
|
||||
return ["${parsedJsonVariable}.read('''${jsonPath}''', JSONArray).size() == 1",
|
||||
"${parsedJsonVariable}.read('''${jsonPath}''', JSONArray).get(0) ${operator()} ${potentiallyWrappedWithQuotesValue()}"]
|
||||
}
|
||||
return ["${parsedJsonVariable}.read('''${jsonPath}''') ${operator()} ${potentiallyWrappedWithQuotesValue()}"]
|
||||
}
|
||||
|
||||
private boolean traversesOverCollections() {
|
||||
return jsonPath.contains('[*]')
|
||||
}
|
||||
|
||||
String operator() {
|
||||
return value instanceof Pattern ? "==~" : "=="
|
||||
}
|
||||
|
||||
String potentiallyWrappedWithQuotesValue() {
|
||||
return value instanceof Number ? value : "'''$value'''"
|
||||
}
|
||||
|
||||
static JsonPathEntry simple(String jsonPath, Object value) {
|
||||
return new JsonPathEntry(jsonPath, "", value)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,153 @@
|
||||
package io.codearte.accurest.util
|
||||
|
||||
import groovy.json.JsonSlurper
|
||||
import io.codearte.accurest.dsl.internal.DslProperty
|
||||
import io.codearte.accurest.dsl.internal.ExecutionProperty
|
||||
|
||||
import java.util.regex.Pattern
|
||||
/**
|
||||
* @author Marcin Grzejszczak
|
||||
*/
|
||||
class JsonPathJsonConverter {
|
||||
|
||||
private static final Boolean SERVER_SIDE = false
|
||||
private static final Boolean CLIENT_SIDE = true
|
||||
|
||||
public static final String ROOT_JSON_PATH_ELEMENT = '$'
|
||||
public static final String ALL_ELEMENTS = "[*]"
|
||||
|
||||
public static JsonPaths transformToJsonPathWithTestsSideValues(def json) {
|
||||
return transformToJsonPathWithValues(json, SERVER_SIDE)
|
||||
}
|
||||
|
||||
public static JsonPaths transformToJsonPathWithStubsSideValues(def json) {
|
||||
return transformToJsonPathWithValues(json, CLIENT_SIDE)
|
||||
}
|
||||
|
||||
private static JsonPaths transformToJsonPathWithValues(def json, boolean clientSide) {
|
||||
if(!json) {
|
||||
return new JsonPaths()
|
||||
}
|
||||
JsonPaths pathsAndValues = [] as Set
|
||||
Object convertedJson = getClientOrServerSideValues(json, clientSide)
|
||||
traverseRecursivelyForKey(convertedJson, ROOT_JSON_PATH_ELEMENT) { String key, Object value ->
|
||||
if (value instanceof ExecutionProperty) {
|
||||
return
|
||||
}
|
||||
JsonPathEntry entry = getValueToInsert(key, value)
|
||||
pathsAndValues.add(entry)
|
||||
}
|
||||
return pathsAndValues
|
||||
}
|
||||
|
||||
private static Object getClientOrServerSideValues(json, boolean clientSide) {
|
||||
return MapConverter.transformValues(json) {
|
||||
boolean dslProp = it instanceof DslProperty
|
||||
if (dslProp) {
|
||||
DslProperty dslProperty = ((DslProperty) it)
|
||||
return clientSide ?
|
||||
getClientOrServerSideValues(dslProperty.clientValue, clientSide) : getClientOrServerSideValues(dslProperty.serverValue, clientSide)
|
||||
}
|
||||
return it
|
||||
}
|
||||
}
|
||||
|
||||
protected static def traverseRecursively(Class parentType, String key, def value, Closure closure) {
|
||||
if (value instanceof String && value) {
|
||||
try {
|
||||
def json = new JsonSlurper().parseText(value)
|
||||
if (json instanceof Map) {
|
||||
return convertWithKey(parentType, key, json, closure)
|
||||
}
|
||||
} catch (Exception ignore) {
|
||||
return closure(key, value)
|
||||
}
|
||||
} else if (isAnEntryWithNonCollectionLikeValue(value)) {
|
||||
return convertWithKey(List, key, value as Map, closure)
|
||||
} else if (isAnEntryWithoutNestedStructures(value)) {
|
||||
return convertWithKey(List, key, value as Map, closure)
|
||||
} else if (value instanceof Map) {
|
||||
return convertWithKey(Map, key, value as Map, closure)
|
||||
} else if (value instanceof List) {
|
||||
value.each { def element ->
|
||||
traverseRecursively(List, "$key[*]", element, closure)
|
||||
}
|
||||
return value
|
||||
}
|
||||
try {
|
||||
return closure(key, value)
|
||||
} catch (Exception ignore) {
|
||||
return value
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean isAnEntryWithNonCollectionLikeValue(def value) {
|
||||
if (!(value instanceof Map)) {
|
||||
return false
|
||||
}
|
||||
Map valueAsMap = ((Map) value)
|
||||
boolean mapHasOneEntry = valueAsMap.size() == 1
|
||||
if (!mapHasOneEntry) {
|
||||
return false
|
||||
}
|
||||
Object valueOfEntry = valueAsMap.entrySet().first().value
|
||||
return !(valueOfEntry instanceof Map || valueOfEntry instanceof List)
|
||||
}
|
||||
|
||||
private static boolean isAnEntryWithoutNestedStructures(def value) {
|
||||
if (!(value instanceof Map)) {
|
||||
return false
|
||||
}
|
||||
Map valueAsMap = ((Map) value)
|
||||
return valueAsMap.entrySet().every { Map.Entry entry ->
|
||||
[String, Number].any { entry.value.getClass().isAssignableFrom(it) }
|
||||
}
|
||||
}
|
||||
|
||||
private static Map convertWithKey(Class parentType, String parentKey, Map map, Closure closureToExecute) {
|
||||
return map.collectEntries {
|
||||
String entrykey, value ->
|
||||
[entrykey, traverseRecursively(parentType, "${parentKey}.${entrykey}", value, closureToExecute)]
|
||||
}
|
||||
}
|
||||
|
||||
private static void traverseRecursivelyForKey(def json, String rootKey, Closure closure) {
|
||||
traverseRecursively(Map, rootKey, json, closure)
|
||||
}
|
||||
|
||||
private static JsonPathEntry getValueToInsert(String key, Object value) {
|
||||
return convertToListElementFiltering(key, value)
|
||||
}
|
||||
|
||||
protected static JsonPathEntry convertToListElementFiltering(String key, Object value) {
|
||||
if (key.endsWith(ALL_ELEMENTS)) {
|
||||
int lastAllElements = key.lastIndexOf(ALL_ELEMENTS)
|
||||
String keyWithoutAllElements = key.substring(0, lastAllElements)
|
||||
return JsonPathEntry.simple("""$keyWithoutAllElements[?(@ ${compareWith(value)})]""".toString(), value)
|
||||
}
|
||||
return getKeyForTraversalOfListWithNonPrimitiveTypes(key, value)
|
||||
}
|
||||
|
||||
private static JsonPathEntry getKeyForTraversalOfListWithNonPrimitiveTypes(String key, Object value) {
|
||||
int lastDot = key.lastIndexOf('.')
|
||||
String keyWithoutLastElement = key.substring(0, lastDot)
|
||||
String lastElement = key.substring(lastDot + 1).replaceAll(~/\[\*\]/, "")
|
||||
return new JsonPathEntry(
|
||||
"""$keyWithoutLastElement[?(@.$lastElement ${compareWith(value)})]""".toString(),
|
||||
lastElement,
|
||||
value
|
||||
)
|
||||
}
|
||||
|
||||
protected static String compareWith(Object value) {
|
||||
if (value instanceof Pattern) {
|
||||
return """=~ /${(value as Pattern).pattern()}/"""
|
||||
}
|
||||
return """== ${potentiallyWrappedWithQuotesValue(value)}"""
|
||||
}
|
||||
|
||||
protected static String potentiallyWrappedWithQuotesValue(Object value) {
|
||||
return value instanceof Number ? value : "'$value'"
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
package io.codearte.accurest.util
|
||||
|
||||
class JsonPaths extends HashSet<JsonPathEntry> {
|
||||
|
||||
Object getAt(String key) {
|
||||
return find {
|
||||
it.jsonPath == key
|
||||
}?.value
|
||||
}
|
||||
|
||||
Object putAt(String key, Object value) {
|
||||
JsonPathEntry entry = find {
|
||||
it.jsonPath == key
|
||||
}
|
||||
if (!entry) {
|
||||
return null
|
||||
}
|
||||
Object oldValue = entry.value
|
||||
add(new JsonPathEntry(entry.jsonPath, entry.optionalSuffix, value))
|
||||
return oldValue
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,15 +1,16 @@
|
||||
package io.codearte.accurest.util
|
||||
|
||||
import groovy.json.JsonSlurper
|
||||
import io.codearte.accurest.dsl.internal.DslProperty
|
||||
|
||||
/**
|
||||
* @author Marcin Grzejszczak
|
||||
*/
|
||||
class JsonConverter {
|
||||
class MapConverter {
|
||||
|
||||
private static Map convert(Map map, Closure closure) {
|
||||
return map.collectEntries {
|
||||
key, value ->
|
||||
[key, transformValues(value, closure)]
|
||||
static def transformToClientValues(def value) {
|
||||
return transformValues(value) {
|
||||
it instanceof DslProperty ? it.clientValue : it
|
||||
}
|
||||
}
|
||||
|
||||
@@ -35,4 +36,11 @@ class JsonConverter {
|
||||
}
|
||||
}
|
||||
|
||||
private static Map convert(Map map, Closure closure) {
|
||||
return map.collectEntries {
|
||||
key, value ->
|
||||
[key, transformValues(value, closure)]
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -26,8 +26,8 @@ class JaxRsClientSpockMethodBuilderSpec extends Specification {
|
||||
when:
|
||||
builder.appendTo(blockBuilder)
|
||||
then:
|
||||
blockBuilder.toString().contains("responseBody.property1 == '''a'''")
|
||||
blockBuilder.toString().contains("responseBody.property2 == '''b'''")
|
||||
blockBuilder.toString().contains("\$[?(@.property1 == 'a')]")
|
||||
blockBuilder.toString().contains("\$[?(@.property2 == 'b')]")
|
||||
}
|
||||
|
||||
@Issue("#79")
|
||||
@@ -54,9 +54,9 @@ class JaxRsClientSpockMethodBuilderSpec extends Specification {
|
||||
when:
|
||||
builder.appendTo(blockBuilder)
|
||||
then:
|
||||
blockBuilder.toString().contains("responseBody.property1 == '''a'''")
|
||||
blockBuilder.toString().contains("responseBody.property2[0].a == '''sth'''")
|
||||
blockBuilder.toString().contains("responseBody.property2[1].b == '''sthElse'''")
|
||||
blockBuilder.toString().contains("\$[?(@.property1 == 'a')]")
|
||||
blockBuilder.toString().contains("\$.property2[*][?(@.a == 'sth')]")
|
||||
blockBuilder.toString().contains("\$.property2[*][?(@.b == 'sthElse')]")
|
||||
}
|
||||
|
||||
@Issue("#82")
|
||||
@@ -128,8 +128,8 @@ class JaxRsClientSpockMethodBuilderSpec extends Specification {
|
||||
when:
|
||||
builder.appendTo(blockBuilder)
|
||||
then:
|
||||
blockBuilder.toString().contains("responseBody[0].property1 == '''a'''")
|
||||
blockBuilder.toString().contains("responseBody[1].property2 == '''b'''")
|
||||
blockBuilder.toString().contains("\$[*][?(@.property1 == 'a')]")
|
||||
blockBuilder.toString().contains("\$[*][?(@.property2 == 'b')]")
|
||||
}
|
||||
|
||||
def "should generate assertions for array inside response body element"() {
|
||||
@@ -154,8 +154,8 @@ class JaxRsClientSpockMethodBuilderSpec extends Specification {
|
||||
when:
|
||||
builder.appendTo(blockBuilder)
|
||||
then:
|
||||
blockBuilder.toString().contains("responseBody.property1[0].property2 == '''test1'''")
|
||||
blockBuilder.toString().contains("responseBody.property1[1].property3 == '''test2'''")
|
||||
blockBuilder.toString().contains("\$.property1[*][?(@.property3 == 'test2')]")
|
||||
blockBuilder.toString().contains("\$.property1[*][?(@.property2 == 'test1')]")
|
||||
}
|
||||
|
||||
def "should generate assertions for nested objects in response body"() {
|
||||
@@ -180,8 +180,8 @@ class JaxRsClientSpockMethodBuilderSpec extends Specification {
|
||||
when:
|
||||
builder.appendTo(blockBuilder)
|
||||
then:
|
||||
blockBuilder.toString().contains("responseBody.property1 == '''a'''")
|
||||
blockBuilder.toString().contains("responseBody.property2.property3 == '''b'''")
|
||||
blockBuilder.toString().contains("\$.property2[?(@.property3 == 'b')]")
|
||||
blockBuilder.toString().contains("\$[?(@.property1 == 'a')]")
|
||||
}
|
||||
|
||||
def "should generate regex assertions for map objects in response body"() {
|
||||
@@ -212,8 +212,8 @@ class JaxRsClientSpockMethodBuilderSpec extends Specification {
|
||||
when:
|
||||
builder.appendTo(blockBuilder)
|
||||
then:
|
||||
blockBuilder.toString().contains("responseBody.property1 == '''a'''")
|
||||
blockBuilder.toString().contains("responseBody.property2 ==~ java.util.regex.Pattern.compile('[0-9]{3}')")
|
||||
blockBuilder.toString().contains("\$[?(@.property2 =~ /[0-9]{3}/)]")
|
||||
blockBuilder.toString().contains("\$[?(@.property1 == 'a')]")
|
||||
}
|
||||
|
||||
def "should generate regex assertions for string objects in response body"() {
|
||||
@@ -238,8 +238,8 @@ class JaxRsClientSpockMethodBuilderSpec extends Specification {
|
||||
when:
|
||||
builder.appendTo(blockBuilder)
|
||||
then:
|
||||
blockBuilder.toString().contains("responseBody.property1 == '''a'''")
|
||||
blockBuilder.toString().contains("responseBody.property2 ==~ java.util.regex.Pattern.compile('[0-9]{3}')")
|
||||
blockBuilder.toString().contains("\$[?(@.property2 =~ /[0-9]{3}/)]")
|
||||
blockBuilder.toString().contains("\$[?(@.property1 == 'a')]")
|
||||
}
|
||||
|
||||
def "should ignore 'Accept' header and use 'request' method"() {
|
||||
@@ -335,8 +335,8 @@ class JaxRsClientSpockMethodBuilderSpec extends Specification {
|
||||
spockTest.contains("queryParam('age', '99'")
|
||||
spockTest.contains("queryParam('name', 'Denis.Stepanov'")
|
||||
spockTest.contains("queryParam('email', 'bob@email.com'")
|
||||
spockTest.contains("responseBody.property1 == '''a'''")
|
||||
spockTest.contains("responseBody.property2 == '''b'''")
|
||||
spockTest.contains('$[?(@.property2 == \'b\')]')
|
||||
spockTest.contains('$[?(@.property1 == \'a\')]')
|
||||
}
|
||||
|
||||
def "should generate test for empty body"() {
|
||||
@@ -372,12 +372,14 @@ class JaxRsClientSpockMethodBuilderSpec extends Specification {
|
||||
body "test"
|
||||
}
|
||||
}
|
||||
JaxRsClientSpockMethodBodyBuilder builder = new JaxRsClientSpockMethodBodyBuilder(contractDsl)
|
||||
MockMvcSpockMethodBodyBuilder builder = new MockMvcSpockMethodBodyBuilder(contractDsl)
|
||||
BlockBuilder blockBuilder = new BlockBuilder(" ")
|
||||
when:
|
||||
builder.appendTo(blockBuilder)
|
||||
def spockTest = blockBuilder.toString()
|
||||
then:
|
||||
spockTest.contains("responseBody == '''test'''")
|
||||
spockTest.contains('def responseBody = (response.body.asString())')
|
||||
spockTest.contains('responseBody == "test"')
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -3,15 +3,13 @@ package io.codearte.accurest.builder
|
||||
import io.codearte.accurest.dsl.GroovyDsl
|
||||
import spock.lang.Issue
|
||||
import spock.lang.Specification
|
||||
import spock.lang.Unroll
|
||||
|
||||
/**
|
||||
* @author Jakub Kubrynski
|
||||
*/
|
||||
class MockMvcSpockMethodBuilderSpec extends Specification {
|
||||
|
||||
@Unroll
|
||||
def "should generate assertions for simple response body for [#spockMethodBuilder]"() {
|
||||
def "should generate assertions for simple response body"() {
|
||||
given:
|
||||
GroovyDsl contractDsl = GroovyDsl.make {
|
||||
request {
|
||||
@@ -26,13 +24,13 @@ class MockMvcSpockMethodBuilderSpec extends Specification {
|
||||
}"""
|
||||
}
|
||||
}
|
||||
SpockMethodBodyBuilder builder = new MockMvcSpockMethodBodyBuilder(contractDsl)
|
||||
MockMvcSpockMethodBodyBuilder builder = new MockMvcSpockMethodBodyBuilder(contractDsl)
|
||||
BlockBuilder blockBuilder = new BlockBuilder(" ")
|
||||
when:
|
||||
builder.appendTo(blockBuilder)
|
||||
then:
|
||||
blockBuilder.toString().contains("responseBody.property1 == '''a'''")
|
||||
blockBuilder.toString().contains("responseBody.property2 == '''b'''")
|
||||
blockBuilder.toString().contains("\$[?(@.property1 == 'a')]")
|
||||
blockBuilder.toString().contains("\$[?(@.property2 == 'b')]")
|
||||
}
|
||||
|
||||
@Issue("#79")
|
||||
@@ -54,14 +52,14 @@ class MockMvcSpockMethodBuilderSpec extends Specification {
|
||||
)
|
||||
}
|
||||
}
|
||||
SpockMethodBodyBuilder builder = new MockMvcSpockMethodBodyBuilder(contractDsl)
|
||||
MockMvcSpockMethodBodyBuilder builder = new MockMvcSpockMethodBodyBuilder(contractDsl)
|
||||
BlockBuilder blockBuilder = new BlockBuilder(" ")
|
||||
when:
|
||||
builder.appendTo(blockBuilder)
|
||||
then:
|
||||
blockBuilder.toString().contains("responseBody.property1 == '''a'''")
|
||||
blockBuilder.toString().contains("responseBody.property2[0].a == '''sth'''")
|
||||
blockBuilder.toString().contains("responseBody.property2[1].b == '''sthElse'''")
|
||||
blockBuilder.toString().contains("\$[?(@.property1 == 'a')]")
|
||||
blockBuilder.toString().contains("\$.property2[*][?(@.a == 'sth')]")
|
||||
blockBuilder.toString().contains("\$.property2[*][?(@.b == 'sthElse')]")
|
||||
}
|
||||
|
||||
@Issue("#82")
|
||||
@@ -79,7 +77,7 @@ class MockMvcSpockMethodBuilderSpec extends Specification {
|
||||
status 200
|
||||
}
|
||||
}
|
||||
SpockMethodBodyBuilder builder = new MockMvcSpockMethodBodyBuilder(contractDsl)
|
||||
MockMvcSpockMethodBodyBuilder builder = new MockMvcSpockMethodBodyBuilder(contractDsl)
|
||||
BlockBuilder blockBuilder = new BlockBuilder(" ")
|
||||
when:
|
||||
builder.appendTo(blockBuilder)
|
||||
@@ -102,7 +100,7 @@ class MockMvcSpockMethodBuilderSpec extends Specification {
|
||||
status 200
|
||||
}
|
||||
}
|
||||
SpockMethodBodyBuilder builder = new MockMvcSpockMethodBodyBuilder(contractDsl)
|
||||
MockMvcSpockMethodBodyBuilder builder = new MockMvcSpockMethodBodyBuilder(contractDsl)
|
||||
BlockBuilder blockBuilder = new BlockBuilder(" ")
|
||||
when:
|
||||
builder.appendTo(blockBuilder)
|
||||
@@ -128,13 +126,13 @@ class MockMvcSpockMethodBuilderSpec extends Specification {
|
||||
}]"""
|
||||
}
|
||||
}
|
||||
SpockMethodBodyBuilder builder = new MockMvcSpockMethodBodyBuilder(contractDsl)
|
||||
MockMvcSpockMethodBodyBuilder builder = new MockMvcSpockMethodBodyBuilder(contractDsl)
|
||||
BlockBuilder blockBuilder = new BlockBuilder(" ")
|
||||
when:
|
||||
builder.appendTo(blockBuilder)
|
||||
then:
|
||||
blockBuilder.toString().contains("responseBody[0].property1 == '''a'''")
|
||||
blockBuilder.toString().contains("responseBody[1].property2 == '''b'''")
|
||||
blockBuilder.toString().contains("\$[*][?(@.property1 == 'a')]")
|
||||
blockBuilder.toString().contains("\$[*][?(@.property2 == 'b')]")
|
||||
}
|
||||
|
||||
def "should generate assertions for array inside response body element"() {
|
||||
@@ -154,13 +152,13 @@ class MockMvcSpockMethodBuilderSpec extends Specification {
|
||||
}"""
|
||||
}
|
||||
}
|
||||
SpockMethodBodyBuilder builder = new MockMvcSpockMethodBodyBuilder(contractDsl)
|
||||
MockMvcSpockMethodBodyBuilder builder = new MockMvcSpockMethodBodyBuilder(contractDsl)
|
||||
BlockBuilder blockBuilder = new BlockBuilder(" ")
|
||||
when:
|
||||
builder.appendTo(blockBuilder)
|
||||
then:
|
||||
blockBuilder.toString().contains("responseBody.property1[0].property2 == '''test1'''")
|
||||
blockBuilder.toString().contains("responseBody.property1[1].property3 == '''test2'''")
|
||||
blockBuilder.toString().contains("\$.property1[*][?(@.property3 == 'test2')]")
|
||||
blockBuilder.toString().contains("\$.property1[*][?(@.property2 == 'test1')]")
|
||||
}
|
||||
|
||||
def "should generate assertions for nested objects in response body"() {
|
||||
@@ -180,13 +178,13 @@ class MockMvcSpockMethodBuilderSpec extends Specification {
|
||||
'''
|
||||
}
|
||||
}
|
||||
SpockMethodBodyBuilder builder = new MockMvcSpockMethodBodyBuilder(contractDsl)
|
||||
MockMvcSpockMethodBodyBuilder builder = new MockMvcSpockMethodBodyBuilder(contractDsl)
|
||||
BlockBuilder blockBuilder = new BlockBuilder(" ")
|
||||
when:
|
||||
builder.appendTo(blockBuilder)
|
||||
then:
|
||||
blockBuilder.toString().contains("responseBody.property1 == '''a'''")
|
||||
blockBuilder.toString().contains("responseBody.property2.property3 == '''b'''")
|
||||
blockBuilder.toString().contains("\$.property2[?(@.property3 == 'b')]")
|
||||
blockBuilder.toString().contains("\$[?(@.property1 == 'a')]")
|
||||
}
|
||||
|
||||
def "should generate regex assertions for map objects in response body"() {
|
||||
@@ -212,13 +210,13 @@ class MockMvcSpockMethodBuilderSpec extends Specification {
|
||||
|
||||
}
|
||||
}
|
||||
SpockMethodBodyBuilder builder = new MockMvcSpockMethodBodyBuilder(contractDsl)
|
||||
MockMvcSpockMethodBodyBuilder builder = new MockMvcSpockMethodBodyBuilder(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}')")
|
||||
blockBuilder.toString().contains("\$[?(@.property2 =~ /[0-9]{3}/)]")
|
||||
blockBuilder.toString().contains("\$[?(@.property1 == 'a')]")
|
||||
}
|
||||
|
||||
def "should generate regex assertions for string objects in response body"() {
|
||||
@@ -238,14 +236,13 @@ class MockMvcSpockMethodBuilderSpec extends Specification {
|
||||
|
||||
}
|
||||
}
|
||||
SpockMethodBodyBuilder builder = new MockMvcSpockMethodBodyBuilder(contractDsl)
|
||||
MockMvcSpockMethodBodyBuilder builder = new MockMvcSpockMethodBodyBuilder(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}')")
|
||||
|
||||
blockBuilder.toString().contains("\$[?(@.property2 =~ /[0-9]{3}/)]")
|
||||
blockBuilder.toString().contains("\$[?(@.property1 == 'a')]")
|
||||
}
|
||||
|
||||
def "should generate a call with an url path and query parameters"() {
|
||||
@@ -278,15 +275,15 @@ class MockMvcSpockMethodBuilderSpec extends Specification {
|
||||
"""
|
||||
}
|
||||
}
|
||||
SpockMethodBodyBuilder builder = new MockMvcSpockMethodBodyBuilder(contractDsl)
|
||||
MockMvcSpockMethodBodyBuilder builder = new MockMvcSpockMethodBodyBuilder(contractDsl)
|
||||
BlockBuilder blockBuilder = new BlockBuilder(" ")
|
||||
when:
|
||||
builder.appendTo(blockBuilder)
|
||||
def spockTest = blockBuilder.toString()
|
||||
then:
|
||||
spockTest.contains('get("/users?limit=10&offset=20&filter=email&sort=name&search=55&age=99&name=Denis.Stepanov&email=bob@email.com")')
|
||||
spockTest.contains("responseBody.property1 == '''a'''")
|
||||
spockTest.contains("responseBody.property2 == '''b'''")
|
||||
spockTest.contains('$[?(@.property2 == \'b\')]')
|
||||
spockTest.contains('$[?(@.property1 == \'a\')]')
|
||||
}
|
||||
|
||||
def "should generate test for empty body"() {
|
||||
@@ -301,7 +298,7 @@ class MockMvcSpockMethodBuilderSpec extends Specification {
|
||||
status 406
|
||||
}
|
||||
}
|
||||
SpockMethodBodyBuilder builder = new MockMvcSpockMethodBodyBuilder(contractDsl)
|
||||
MockMvcSpockMethodBodyBuilder builder = new MockMvcSpockMethodBodyBuilder(contractDsl)
|
||||
BlockBuilder blockBuilder = new BlockBuilder(" ")
|
||||
when:
|
||||
builder.appendTo(blockBuilder)
|
||||
@@ -322,45 +319,14 @@ class MockMvcSpockMethodBuilderSpec extends Specification {
|
||||
body "test"
|
||||
}
|
||||
}
|
||||
SpockMethodBodyBuilder builder = new MockMvcSpockMethodBodyBuilder(contractDsl)
|
||||
MockMvcSpockMethodBodyBuilder builder = new MockMvcSpockMethodBodyBuilder(contractDsl)
|
||||
BlockBuilder blockBuilder = new BlockBuilder(" ")
|
||||
when:
|
||||
builder.appendTo(blockBuilder)
|
||||
def spockTest = blockBuilder.toString()
|
||||
then:
|
||||
spockTest.contains('def responseBody = (response.body.asString())')
|
||||
spockTest.contains("responseBody == '''test'''")
|
||||
}
|
||||
|
||||
@Issue("#127")
|
||||
def 'should use "stub" as an alias for "client"'() {
|
||||
given:
|
||||
GroovyDsl contractDsl = GroovyDsl.make {
|
||||
request {
|
||||
method "GET"
|
||||
url "test"
|
||||
}
|
||||
response {
|
||||
status 200
|
||||
body(
|
||||
property: value(
|
||||
stub(123),
|
||||
test(123)
|
||||
)
|
||||
)
|
||||
headers {
|
||||
header('Content-Type': 'application/json')
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
MockMvcSpockMethodBodyBuilder builder = new MockMvcSpockMethodBodyBuilder(contractDsl)
|
||||
BlockBuilder blockBuilder = new BlockBuilder(" ")
|
||||
when:
|
||||
builder.appendTo(blockBuilder)
|
||||
then:
|
||||
blockBuilder.toString().contains("responseBody.property == 123")
|
||||
spockTest.contains('responseBody == "test"')
|
||||
}
|
||||
|
||||
@Issue('113')
|
||||
@@ -387,7 +353,7 @@ class MockMvcSpockMethodBuilderSpec extends Specification {
|
||||
}
|
||||
}
|
||||
}
|
||||
SpockMethodBodyBuilder builder = new MockMvcSpockMethodBodyBuilder(contractDsl)
|
||||
MockMvcSpockMethodBodyBuilder builder = new MockMvcSpockMethodBodyBuilder(contractDsl)
|
||||
BlockBuilder blockBuilder = new BlockBuilder(" ")
|
||||
when:
|
||||
builder.appendTo(blockBuilder)
|
||||
@@ -420,7 +386,7 @@ class MockMvcSpockMethodBuilderSpec extends Specification {
|
||||
}
|
||||
}
|
||||
}
|
||||
SpockMethodBodyBuilder builder = new MockMvcSpockMethodBodyBuilder(contractDsl)
|
||||
MockMvcSpockMethodBodyBuilder builder = new MockMvcSpockMethodBodyBuilder(contractDsl)
|
||||
BlockBuilder blockBuilder = new BlockBuilder(" ")
|
||||
when:
|
||||
builder.appendTo(blockBuilder)
|
||||
@@ -429,31 +395,38 @@ class MockMvcSpockMethodBuilderSpec extends Specification {
|
||||
spockTest.contains('''response.header('Location') ==~ java.util.regex.Pattern.compile('^((http[s]?|ftp):\\/)\\/?([^:\\/\\s]+)(:[0-9]{1,5})?/partners/[0-9]+/users/[0-9]+')''')
|
||||
}
|
||||
|
||||
@Issue('124')
|
||||
def "should create proper response body matching for multiline strings"() {
|
||||
def "should work with more complex stuff and jsonpaths"() {
|
||||
given:
|
||||
GroovyDsl contractDsl = GroovyDsl.make {
|
||||
|
||||
priority 10
|
||||
request {
|
||||
method 'POST'
|
||||
url '/invitations'
|
||||
url '/validation/client'
|
||||
headers {
|
||||
header 'Content-Type': 'application/json'
|
||||
}
|
||||
body(
|
||||
bank_account_number: '0014282912345698765432161182',
|
||||
email: 'foo@bar.com',
|
||||
phone_number: '100299300',
|
||||
personal_id: 'ABC123456'
|
||||
)
|
||||
}
|
||||
|
||||
response {
|
||||
status 422
|
||||
body(
|
||||
message: "First line\n" +
|
||||
" Second line"
|
||||
)
|
||||
status 200
|
||||
body(errors: [
|
||||
[property: "bank_account_number", message: "incorrect_format"]
|
||||
])
|
||||
}
|
||||
}
|
||||
SpockMethodBodyBuilder builder = new MockMvcSpockMethodBodyBuilder(contractDsl)
|
||||
MockMvcSpockMethodBodyBuilder builder = new MockMvcSpockMethodBodyBuilder(contractDsl)
|
||||
BlockBuilder blockBuilder = new BlockBuilder(" ")
|
||||
when:
|
||||
builder.appendTo(blockBuilder)
|
||||
def spockTest = blockBuilder.toString()
|
||||
then:
|
||||
spockTest.contains("""responseBody.message == '''First line
|
||||
Second line'''""")
|
||||
spockTest.contains('''$.errors[*][?(@.property == 'bank_account_number')]''')
|
||||
spockTest.contains('''$.errors[*][?(@.message == 'incorrect_format')]''')
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,52 +0,0 @@
|
||||
package io.codearte.accurest.dsl
|
||||
|
||||
import groovy.json.JsonSlurper
|
||||
import spock.lang.Specification
|
||||
|
||||
class WireMockGroovyDslResponseSpec extends Specification {
|
||||
|
||||
def 'should generate response without body for client side'() {
|
||||
given:
|
||||
GroovyDsl dsl = GroovyDsl.make {
|
||||
response {
|
||||
status 200
|
||||
}
|
||||
}
|
||||
expect:
|
||||
new WireMockResponseStubStrategy(dsl).buildClientResponseContent() == new JsonSlurper().parseText(expectedStub)
|
||||
where:
|
||||
expectedStub << ['''
|
||||
{
|
||||
"status": 200
|
||||
}
|
||||
''',
|
||||
|
||||
'''
|
||||
{
|
||||
"status": 200
|
||||
}
|
||||
''']
|
||||
}
|
||||
|
||||
def 'should generate headers for response for client side'() {
|
||||
given:
|
||||
GroovyDsl dsl = GroovyDsl.make {
|
||||
response {
|
||||
headers {
|
||||
header 'Content-Type', $(client('text/xml'), server('text/*'))
|
||||
}
|
||||
status 200
|
||||
}
|
||||
}
|
||||
expect:
|
||||
new WireMockResponseStubStrategy(dsl).buildClientResponseContent() == new JsonSlurper().parseText('''
|
||||
{
|
||||
"headers": {
|
||||
"Content-Type": "text/xml"
|
||||
},
|
||||
"status": 200
|
||||
}
|
||||
''')
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
package io.codearte.accurest.dsl
|
||||
|
||||
import groovy.json.JsonBuilder
|
||||
import groovy.json.JsonSlurper
|
||||
import org.skyscreamer.jsonassert.JSONAssert
|
||||
import spock.lang.Issue
|
||||
|
||||
class WireMockGroovyDslSpec extends WireMockSpec {
|
||||
@@ -35,21 +35,21 @@ class WireMockGroovyDslSpec extends WireMockSpec {
|
||||
when:
|
||||
String wireMockStub = new WireMockStubStrategy(groovyDsl).toWireMockClientStub()
|
||||
then:
|
||||
new JsonSlurper().parseText(wireMockStub) == new JsonSlurper().parseText('''
|
||||
{
|
||||
"request": {
|
||||
"method": "GET",
|
||||
"urlPattern": "/[0-9]{2}"
|
||||
},
|
||||
"response": {
|
||||
"status": 200,
|
||||
"body": "{\\"id\\":\\"123\\",\\"surname\\":\\"Kowalsky\\",\\"name\\":\\"Jan\\",\\"created\\":\\"2014-02-02 12:23:43\\"}",
|
||||
"headers": {
|
||||
"Content-Type": "text/plain"
|
||||
}
|
||||
}
|
||||
}
|
||||
''')
|
||||
JSONAssert.assertEquals('''
|
||||
{
|
||||
"request" : {
|
||||
"urlPattern" : "/[0-9]{2}",
|
||||
"method" : "GET"
|
||||
},
|
||||
"response" : {
|
||||
"status" : 200,
|
||||
"body" : "{\\"id\\":\\"123\\",\\"surname\\":\\"Kowalsky\\",\\"name\\":\\"Jan\\",\\"created\\":\\"2014-02-02 12:23:43\\"}",
|
||||
"headers" : {
|
||||
"Content-Type" : "text/plain"
|
||||
}
|
||||
}
|
||||
}
|
||||
''', wireMockStub, false)
|
||||
and:
|
||||
stubMappingIsValidWireMockStub(wireMockStub)
|
||||
}
|
||||
@@ -80,23 +80,23 @@ class WireMockGroovyDslSpec extends WireMockSpec {
|
||||
when:
|
||||
String wireMockStub = new WireMockStubStrategy(groovyDsl).toWireMockClientStub()
|
||||
then:
|
||||
new JsonSlurper().parseText(wireMockStub) == new JsonSlurper().parseText('''
|
||||
JSONAssert.assertEquals('''
|
||||
{
|
||||
"request": {
|
||||
"method": "GET",
|
||||
"headers": {
|
||||
"Content-Type": {
|
||||
"equalTo": "application/vnd.pl.devoxx.aggregatr.v1+json"
|
||||
}
|
||||
},
|
||||
"url": "/ingredients"
|
||||
},
|
||||
"response": {
|
||||
"status": 200,
|
||||
"body": "{\\"ingredients\\":[{\\"type\\":\\"MALT\\",\\"quantity\\":100},{\\"type\\":\\"WATER\\",\\"quantity\\":200},{\\"type\\":\\"HOP\\",\\"quantity\\":300},{\\"type\\":\\"YIEST\\",\\"quantity\\":400}]}"
|
||||
"request" : {
|
||||
"url" : "/ingredients",
|
||||
"method" : "GET",
|
||||
"headers" : {
|
||||
"Content-Type" : {
|
||||
"equalTo" : "application/vnd.pl.devoxx.aggregatr.v1+json"
|
||||
}
|
||||
}
|
||||
},
|
||||
"response" : {
|
||||
"status" : 200,
|
||||
"body" : "{\\"ingredients\\":[{\\"type\\":\\"MALT\\",\\"quantity\\":100},{\\"type\\":\\"WATER\\",\\"quantity\\":200},{\\"type\\":\\"HOP\\",\\"quantity\\":300},{\\"type\\":\\"YIEST\\",\\"quantity\\":400}]}"
|
||||
}
|
||||
}
|
||||
''')
|
||||
''', wireMockStub, false)
|
||||
and:
|
||||
stubMappingIsValidWireMockStub(wireMockStub)
|
||||
}
|
||||
@@ -128,7 +128,7 @@ class WireMockGroovyDslSpec extends WireMockSpec {
|
||||
when:
|
||||
String wireMockStub = new WireMockStubStrategy(groovyDsl).toWireMockClientStub()
|
||||
then:
|
||||
new JsonSlurper().parseText(wireMockStub) == new JsonSlurper().parseText('''
|
||||
JSONAssert.assertEquals('''
|
||||
{
|
||||
"request": {
|
||||
"method": "POST",
|
||||
@@ -149,7 +149,7 @@ class WireMockGroovyDslSpec extends WireMockSpec {
|
||||
"body": "{\\"paymentId\\":\\"4\\",\\"foundExistingPayment\\":false}"
|
||||
}
|
||||
}
|
||||
''')
|
||||
''', wireMockStub, false)
|
||||
and:
|
||||
stubMappingIsValidWireMockStub(wireMockStub)
|
||||
}
|
||||
@@ -180,21 +180,21 @@ class WireMockGroovyDslSpec extends WireMockSpec {
|
||||
when:
|
||||
String wireMockStub = new WireMockStubStrategy(groovyDsl).toWireMockClientStub()
|
||||
then:
|
||||
new JsonSlurper().parseText(wireMockStub) == new JsonSlurper().parseText('''
|
||||
JSONAssert.assertEquals(('''
|
||||
{
|
||||
"request": {
|
||||
"method": "GET",
|
||||
"urlPattern": "/[0-9]{2}"
|
||||
},
|
||||
"response": {
|
||||
"status": 200,
|
||||
"body": "{\\"created\\":\\"2014-02-02 12:23:43\\",\\"id\\":\\"123\\",\\"name\\":\\"Jan\\",\\"surname\\":\\"Kowalsky\\"}",
|
||||
"headers": {
|
||||
"Content-Type": "text/plain"
|
||||
}
|
||||
"request" : {
|
||||
"urlPattern" : "/[0-9]{2}",
|
||||
"method" : "GET"
|
||||
},
|
||||
"response" : {
|
||||
"status" : 200,
|
||||
"body" : "{\\"created\\":\\"2014-02-02 12:23:43\\",\\"id\\":\\"123\\",\\"name\\":\\"Jan\\",\\"surname\\":\\"Kowalsky\\"}",
|
||||
"headers" : {
|
||||
"Content-Type" : "text/plain"
|
||||
}
|
||||
}
|
||||
}
|
||||
''')
|
||||
'''), wireMockStub, false)
|
||||
and:
|
||||
stubMappingIsValidWireMockStub(wireMockStub)
|
||||
}
|
||||
@@ -227,26 +227,24 @@ class WireMockGroovyDslSpec extends WireMockSpec {
|
||||
when:
|
||||
String wireMockStub = new WireMockStubStrategy(groovyDsl).toWireMockClientStub()
|
||||
then:
|
||||
new JsonSlurper().parseText(wireMockStub) == new JsonSlurper().parseText('''
|
||||
JSONAssert.assertEquals('''
|
||||
{
|
||||
"request": {
|
||||
"method": "GET",
|
||||
"urlPattern": "/[0-9]{2}",
|
||||
"bodyPatterns": [
|
||||
{
|
||||
"equalToJson":"{\\"name\\":\\"Jan\\"}"
|
||||
}
|
||||
]
|
||||
},
|
||||
"response": {
|
||||
"status": 200,
|
||||
"body": "{\\"name\\":\\"Jan\\"}",
|
||||
"headers": {
|
||||
"Content-Type": "text/plain"
|
||||
}
|
||||
"request" : {
|
||||
"urlPattern" : "/[0-9]{2}",
|
||||
"method" : "GET",
|
||||
"bodyPatterns" : [ {
|
||||
"matchesJsonPath" : "$[?(@.name == 'Jan')]"
|
||||
} ]
|
||||
},
|
||||
"response" : {
|
||||
"status" : 200,
|
||||
"body" : "{\\"name\\":\\"Jan\\"}",
|
||||
"headers" : {
|
||||
"Content-Type" : "text/plain"
|
||||
}
|
||||
}
|
||||
}
|
||||
''')
|
||||
''', wireMockStub, false)
|
||||
and:
|
||||
stubMappingIsValidWireMockStub(wireMockStub)
|
||||
}
|
||||
@@ -277,22 +275,26 @@ class WireMockGroovyDslSpec extends WireMockSpec {
|
||||
when:
|
||||
String wireMockStub = new WireMockStubStrategy(groovyDsl).toWireMockClientStub()
|
||||
then:
|
||||
new JsonSlurper().parseText(wireMockStub) == new JsonSlurper().parseText('''
|
||||
{
|
||||
"request": {
|
||||
"method": "GET",
|
||||
"urlPattern": "/[0-9]{2}",
|
||||
"bodyPatterns": [
|
||||
{
|
||||
"equalToJson": "{\\"id\\":\\"123\\",\\"surname\\":\\"Kowalsky\\",\\"name\\":\\"Jan\\",\\"created\\":\\"2014-02-02 12:23:43\\"}"
|
||||
}
|
||||
]
|
||||
},
|
||||
"response": {
|
||||
"status": 200,
|
||||
}
|
||||
}
|
||||
''')
|
||||
JSONAssert.assertEquals(('''
|
||||
{
|
||||
"request" : {
|
||||
"urlPattern" : "/[0-9]{2}",
|
||||
"method" : "GET",
|
||||
"bodyPatterns" : [ {
|
||||
"matchesJsonPath" : "$[?(@.created == '2014-02-02 12:23:43')]"
|
||||
}, {
|
||||
"matchesJsonPath" : "$[?(@.surname == 'Kowalsky')]"
|
||||
}, {
|
||||
"matchesJsonPath" : "$[?(@.name == 'Jan')]"
|
||||
}, {
|
||||
"matchesJsonPath" : "$[?(@.id == '123')]"
|
||||
} ]
|
||||
},
|
||||
"response" : {
|
||||
"status" : 200
|
||||
}
|
||||
}
|
||||
'''), wireMockStub, false)
|
||||
and:
|
||||
stubMappingIsValidWireMockStub(wireMockStub)
|
||||
}
|
||||
@@ -319,27 +321,25 @@ class WireMockGroovyDslSpec extends WireMockSpec {
|
||||
when:
|
||||
String json = toWireMockClientJsonStub(groovyDsl)
|
||||
then:
|
||||
parseJson(json) == parseJson('''
|
||||
{
|
||||
"request": {
|
||||
"method": "GET",
|
||||
"url": "/users",
|
||||
"headers": {
|
||||
"Content-Type": {
|
||||
"equalTo": "customtype/json"
|
||||
}
|
||||
},
|
||||
"bodyPatterns": [
|
||||
{
|
||||
"equalToJson":"{\\"name\\":\\"Jan\\"}"
|
||||
}
|
||||
]
|
||||
},
|
||||
"response": {
|
||||
"status": 200
|
||||
}
|
||||
}
|
||||
''')
|
||||
JSONAssert.assertEquals(('''
|
||||
{
|
||||
"request" : {
|
||||
"url" : "/users",
|
||||
"method" : "GET",
|
||||
"bodyPatterns" : [ {
|
||||
"matchesJsonPath" : "$[?(@.name == 'Jan')]"
|
||||
} ],
|
||||
"headers" : {
|
||||
"Content-Type" : {
|
||||
"equalTo" : "customtype/json"
|
||||
}
|
||||
}
|
||||
},
|
||||
"response" : {
|
||||
"status" : 200
|
||||
}
|
||||
}
|
||||
'''), json, false)
|
||||
and:
|
||||
stubMappingIsValidWireMockStub(json)
|
||||
}
|
||||
@@ -364,7 +364,7 @@ class WireMockGroovyDslSpec extends WireMockSpec {
|
||||
when:
|
||||
String json = toWireMockClientJsonStub(groovyDsl)
|
||||
then:
|
||||
parseJson(json) == parseJson('''
|
||||
JSONAssert.assertEquals(('''
|
||||
{
|
||||
"request": {
|
||||
"method": "GET",
|
||||
@@ -384,7 +384,7 @@ class WireMockGroovyDslSpec extends WireMockSpec {
|
||||
"status": 200
|
||||
}
|
||||
}
|
||||
''')
|
||||
'''), json, false)
|
||||
and:
|
||||
stubMappingIsValidWireMockStub(json)
|
||||
}
|
||||
@@ -406,7 +406,7 @@ class WireMockGroovyDslSpec extends WireMockSpec {
|
||||
when:
|
||||
String json = toWireMockClientJsonStub(groovyDsl)
|
||||
then:
|
||||
parseJson(json) == parseJson('''
|
||||
JSONAssert.assertEquals(('''
|
||||
{
|
||||
"request": {
|
||||
"method": "GET",
|
||||
@@ -421,7 +421,7 @@ class WireMockGroovyDslSpec extends WireMockSpec {
|
||||
"status": 200
|
||||
}
|
||||
}
|
||||
''')
|
||||
'''), json, false)
|
||||
and:
|
||||
stubMappingIsValidWireMockStub(json)
|
||||
}
|
||||
@@ -443,7 +443,7 @@ class WireMockGroovyDslSpec extends WireMockSpec {
|
||||
when:
|
||||
String json = toWireMockClientJsonStub(groovyDsl)
|
||||
then:
|
||||
parseJson(json) == parseJson('''
|
||||
JSONAssert.assertEquals(('''
|
||||
{
|
||||
"request": {
|
||||
"method": "GET",
|
||||
@@ -454,7 +454,7 @@ class WireMockGroovyDslSpec extends WireMockSpec {
|
||||
"body":"<user><name>Jozo</name><jobId><test></jobId></user>"
|
||||
}
|
||||
}
|
||||
''')
|
||||
'''), json, false)
|
||||
and:
|
||||
stubMappingIsValidWireMockStub(json)
|
||||
}
|
||||
@@ -474,7 +474,7 @@ class WireMockGroovyDslSpec extends WireMockSpec {
|
||||
when:
|
||||
String json = toWireMockClientJsonStub(groovyDsl)
|
||||
then:
|
||||
parseJson(json) == parseJson('''
|
||||
JSONAssert.assertEquals(('''
|
||||
{
|
||||
"request": {
|
||||
"method": "GET",
|
||||
@@ -489,7 +489,7 @@ class WireMockGroovyDslSpec extends WireMockSpec {
|
||||
"status": 200
|
||||
}
|
||||
}
|
||||
''')
|
||||
'''), json, false)
|
||||
and:
|
||||
stubMappingIsValidWireMockStub(json)
|
||||
}
|
||||
@@ -511,7 +511,7 @@ class WireMockGroovyDslSpec extends WireMockSpec {
|
||||
when:
|
||||
String json = toWireMockClientJsonStub(groovyDsl)
|
||||
then:
|
||||
parseJson(json) == parseJson('''
|
||||
JSONAssert.assertEquals(('''
|
||||
{
|
||||
"request": {
|
||||
"method": "GET",
|
||||
@@ -526,7 +526,7 @@ class WireMockGroovyDslSpec extends WireMockSpec {
|
||||
"status": 200
|
||||
}
|
||||
}
|
||||
''')
|
||||
'''), json, false)
|
||||
and:
|
||||
stubMappingIsValidWireMockStub(json)
|
||||
}
|
||||
@@ -559,24 +559,24 @@ class WireMockGroovyDslSpec extends WireMockSpec {
|
||||
when:
|
||||
String wireMockStub = new WireMockStubStrategy(groovyDsl).toWireMockClientStub()
|
||||
then:
|
||||
new JsonSlurper().parseText(wireMockStub) == new JsonSlurper().parseText('''
|
||||
JSONAssert.assertEquals(('''
|
||||
{
|
||||
"request": {
|
||||
"method": "GET",
|
||||
"urlPattern": "/[0-9]{2}",
|
||||
"bodyPatterns": [
|
||||
{"matches": "\\\\s*\\\\{\\\\s*\\\"personalId\\\"\\\\s*:\\\\s*\\\"?^[0-9]{11}$\\\"?\\\\s*\\\\}\\\\s*"}
|
||||
]
|
||||
},
|
||||
"response": {
|
||||
"status": 200,
|
||||
"body": "{\\"name\\":\\"Jan\\"}",
|
||||
"headers": {
|
||||
"Content-Type": "text/plain"
|
||||
}
|
||||
"request" : {
|
||||
"urlPattern" : "/[0-9]{2}",
|
||||
"method" : "GET",
|
||||
"bodyPatterns" : [ {
|
||||
"matchesJsonPath" : "$[?(@.personalId =~ /^[0-9]{11}$/)]"
|
||||
} ]
|
||||
},
|
||||
"response" : {
|
||||
"status" : 200,
|
||||
"body" : "{\\"name\\":\\"Jan\\"}",
|
||||
"headers" : {
|
||||
"Content-Type" : "text/plain"
|
||||
}
|
||||
}
|
||||
}
|
||||
''')
|
||||
'''), wireMockStub, false)
|
||||
and:
|
||||
stubMappingIsValidWireMockStub(wireMockStub)
|
||||
}
|
||||
@@ -614,84 +614,35 @@ class WireMockGroovyDslSpec extends WireMockSpec {
|
||||
when:
|
||||
String wireMockStub = new WireMockStubStrategy(groovyDsl).toWireMockClientStub()
|
||||
then:
|
||||
new JsonSlurper().parseText(wireMockStub) == new JsonSlurper().parseText('''
|
||||
JSONAssert.assertEquals(('''
|
||||
{
|
||||
"request": {
|
||||
"method": "PUT",
|
||||
"headers": {
|
||||
"Content-Type": {
|
||||
"equalTo": "application/vnd.fraud.v1+json"
|
||||
}
|
||||
},
|
||||
"url": "/fraudcheck",
|
||||
"bodyPatterns": [
|
||||
{"matches": "\\\\s*\\\\{\\\\s*\\"clientPesel\\"\\\\s*:\\\\s*\\"?[0-9]{10}\\"?\\\\s*,\\\\s*\\"loanAmount\\"\\\\s*:\\\\s*\\"?123.123\\"?\\\\s*\\\\}\\\\s*"}
|
||||
]
|
||||
},
|
||||
"response": {
|
||||
"status": 200,
|
||||
"headers": {
|
||||
"Content-Type": "application/vnd.fraud.v1+json"
|
||||
},
|
||||
"body": "{\\"fraudCheckStatus\\":\\"OK\\",\\"rejectionReason\\":null}"
|
||||
"request" : {
|
||||
"url" : "/fraudcheck",
|
||||
"method" : "PUT",
|
||||
"bodyPatterns" : [ {
|
||||
"matchesJsonPath" : "$[?(@.loanAmount == 123.123)]"
|
||||
}, {
|
||||
"matchesJsonPath" : "$[?(@.clientPesel =~ /[0-9]{10}/)]"
|
||||
} ],
|
||||
"headers" : {
|
||||
"Content-Type" : {
|
||||
"equalTo" : "application/vnd.fraud.v1+json"
|
||||
}
|
||||
}
|
||||
},
|
||||
"response" : {
|
||||
"status" : 200,
|
||||
"body" : "{\\"fraudCheckStatus\\":\\"OK\\",\\"rejectionReason\\":null}",
|
||||
"headers" : {
|
||||
"Content-Type" : "application/vnd.fraud.v1+json"
|
||||
}
|
||||
}
|
||||
}
|
||||
''')
|
||||
'''), wireMockStub, false)
|
||||
and:
|
||||
stubMappingIsValidWireMockStub(wireMockStub)
|
||||
}
|
||||
|
||||
|
||||
def "should generate stub with GET"() {
|
||||
given:
|
||||
GroovyDsl groovyDsl = GroovyDsl.make {
|
||||
request {
|
||||
method("GET")
|
||||
}
|
||||
}
|
||||
expect:
|
||||
new WireMockRequestStubStrategy(groovyDsl).buildClientRequestContent() == new JsonSlurper().parseText('''
|
||||
{
|
||||
"method":"GET"
|
||||
}
|
||||
''')
|
||||
}
|
||||
|
||||
def "should generate request when two elements are provided "() {
|
||||
given:
|
||||
GroovyDsl groovyDsl = GroovyDsl.make {
|
||||
request {
|
||||
method("GET")
|
||||
url("/sth")
|
||||
}
|
||||
}
|
||||
expect:
|
||||
new WireMockRequestStubStrategy(groovyDsl).buildClientRequestContent() == new JsonSlurper().parseText('''
|
||||
{
|
||||
"method":"GET",
|
||||
"url":"/sth"
|
||||
}
|
||||
''')
|
||||
}
|
||||
|
||||
def "should generate request with urlPattern for client side"() {
|
||||
given:
|
||||
GroovyDsl groovyDsl = GroovyDsl.make {
|
||||
request {
|
||||
url $(
|
||||
client(~/^\/[0-9]{2}$/),
|
||||
server('/12')
|
||||
)
|
||||
}
|
||||
}
|
||||
expect:
|
||||
new WireMockRequestStubStrategy(groovyDsl).buildClientRequestContent() == new JsonSlurper().parseText('''
|
||||
{
|
||||
"urlPattern":"^/[0-9]{2}$"
|
||||
}
|
||||
''')
|
||||
}
|
||||
|
||||
def "should generate request with urlPath and queryParameters for client side"() {
|
||||
given:
|
||||
GroovyDsl groovyDsl = GroovyDsl.make {
|
||||
@@ -717,7 +668,7 @@ class WireMockGroovyDslSpec extends WireMockSpec {
|
||||
when:
|
||||
def json = toWireMockClientJsonStub(groovyDsl)
|
||||
then:
|
||||
parseJson(json) == parseJson('''
|
||||
JSONAssert.assertEquals(('''
|
||||
{
|
||||
"request": {
|
||||
"method": "GET",
|
||||
@@ -753,7 +704,7 @@ class WireMockGroovyDslSpec extends WireMockSpec {
|
||||
"status": 200,
|
||||
}
|
||||
}
|
||||
''')
|
||||
'''), json, false)
|
||||
and:
|
||||
stubMappingIsValidWireMockStub(json)
|
||||
}
|
||||
@@ -772,7 +723,7 @@ class WireMockGroovyDslSpec extends WireMockSpec {
|
||||
when:
|
||||
def json = toWireMockClientJsonStub(groovyDsl)
|
||||
then:
|
||||
parseJson(json) == parseJson('''
|
||||
JSONAssert.assertEquals(('''
|
||||
{
|
||||
"request": {
|
||||
"method": "GET",
|
||||
@@ -782,7 +733,7 @@ class WireMockGroovyDslSpec extends WireMockSpec {
|
||||
"status": 200,
|
||||
}
|
||||
}
|
||||
''')
|
||||
'''), json, false)
|
||||
and:
|
||||
stubMappingIsValidWireMockStub(json)
|
||||
}
|
||||
@@ -801,7 +752,7 @@ class WireMockGroovyDslSpec extends WireMockSpec {
|
||||
when:
|
||||
def json = toWireMockClientJsonStub(groovyDsl)
|
||||
then:
|
||||
parseJson(json) == parseJson('''
|
||||
JSONAssert.assertEquals(('''
|
||||
{
|
||||
"request": {
|
||||
"method": "GET",
|
||||
@@ -811,7 +762,7 @@ class WireMockGroovyDslSpec extends WireMockSpec {
|
||||
"status": 200,
|
||||
}
|
||||
}
|
||||
''')
|
||||
'''), json, false)
|
||||
and:
|
||||
stubMappingIsValidWireMockStub(json)
|
||||
}
|
||||
@@ -947,7 +898,7 @@ class WireMockGroovyDslSpec extends WireMockSpec {
|
||||
when:
|
||||
def json = toWireMockClientJsonStub(groovyDsl)
|
||||
then:
|
||||
parseJson(json) == parseJson('''
|
||||
JSONAssert.assertEquals(('''
|
||||
{
|
||||
"request": {
|
||||
"method": "GET",
|
||||
@@ -965,46 +916,11 @@ class WireMockGroovyDslSpec extends WireMockSpec {
|
||||
"status": 200,
|
||||
}
|
||||
}
|
||||
''')
|
||||
'''), json, false)
|
||||
and:
|
||||
stubMappingIsValidWireMockStub(json)
|
||||
}
|
||||
|
||||
def "should generate stub with some headers section for client side"() {
|
||||
given:
|
||||
GroovyDsl groovyDsl = GroovyDsl.make {
|
||||
request {
|
||||
headers {
|
||||
header('Content-Type': 'text/xml')
|
||||
header('Accept': $(
|
||||
client(regex('text/.*')),
|
||||
server('text/plain')
|
||||
))
|
||||
header('X-Custom-Header': $(
|
||||
client(regex('^.*2134.*$')),
|
||||
server('121345')
|
||||
))
|
||||
}
|
||||
}
|
||||
}
|
||||
expect:
|
||||
new WireMockRequestStubStrategy(groovyDsl).buildClientRequestContent() == new JsonSlurper().parseText('''
|
||||
{
|
||||
"headers": {
|
||||
"Content-Type": {
|
||||
"equalTo": "text/xml"
|
||||
},
|
||||
"Accept": {
|
||||
"matches": "text/.*"
|
||||
},
|
||||
"X-Custom-Header": {
|
||||
"matches": "^.*2134.*$"
|
||||
}
|
||||
}
|
||||
}
|
||||
''')
|
||||
}
|
||||
|
||||
def 'should convert groovy dsl stub with rich tree Body as String to wireMock stub for the client side'() {
|
||||
given:
|
||||
GroovyDsl groovyDsl = GroovyDsl.make {
|
||||
@@ -1046,25 +962,38 @@ class WireMockGroovyDslSpec extends WireMockSpec {
|
||||
when:
|
||||
String wireMockStub = new WireMockStubStrategy(groovyDsl).toWireMockClientStub()
|
||||
then:
|
||||
new JsonSlurper().parseText(wireMockStub) == new JsonSlurper().parseText('''
|
||||
{
|
||||
"request": {
|
||||
"method": "GET",
|
||||
"urlPattern": "/[0-9]{2}",
|
||||
"bodyPatterns": [
|
||||
{
|
||||
"matches": "\\\\s*\\\\{\\\\s*\\"birthDate\\"\\\\s*:\\\\s*\\"?[0-9]{4}-[0-9]{2}-[0-9]{2}\\"?\\\\s*,\\\\s*\\"errors\\"\\\\s*:\\\\s*\\\\[\\\\s*\\\\{\\\\s*\\"propertyName\\"\\\\s*:\\\\s*\\"?[0-9]{2}\\"?\\\\s*,\\\\s*\\"providerValue\\"\\\\s*:\\\\s*\\"?Test\\"?\\\\s*\\\\}\\\\s*,\\\\s*\\\\{\\\\s*\\"propertyName\\"\\\\s*:\\\\s*\\"?[0-9]{2}\\"?\\\\s*,\\\\s*\\"providerValue\\"\\\\s*:\\\\s*\\"?Test\\"?\\\\s*\\\\}\\\\s*\\\\]\\\\s*,\\\\s*\\"firstName\\"\\\\s*:\\\\s*\\"?.*\\"?\\\\s*,\\\\s*\\"lastName\\"\\\\s*:\\\\s*\\"?.*\\"?\\\\s*,\\\\s*\\"personalId\\"\\\\s*:\\\\s*\\"?[0-9]{11}\\"?\\\\s*\\\\}\\\\s*"
|
||||
}
|
||||
] },
|
||||
"response": {
|
||||
"status": 200,
|
||||
"body": "{\\"name\\":\\"Jan\\"}",
|
||||
"headers": {
|
||||
"Content-Type": "text/plain"
|
||||
}
|
||||
}
|
||||
}
|
||||
''')
|
||||
JSONAssert.assertEquals(('''
|
||||
{
|
||||
"request" : {
|
||||
"urlPattern" : "/[0-9]{2}",
|
||||
"method" : "GET",
|
||||
"bodyPatterns" : [ {
|
||||
"matchesJsonPath" : "$.errors[*][?(@.propertyName =~ /[0-9]{2}/)]"
|
||||
}, {
|
||||
"matchesJsonPath" : "$.errors[*][?(@.providerValue == 'Test')]"
|
||||
}, {
|
||||
"matchesJsonPath" : "$.errors[*][?(@.providerValue == 'Test')]"
|
||||
}, {
|
||||
"matchesJsonPath" : "$[?(@.lastName =~ /.*/)]"
|
||||
}, {
|
||||
"matchesJsonPath" : "$.errors[*][?(@.propertyName =~ /[0-9]{2}/)]"
|
||||
}, {
|
||||
"matchesJsonPath" : "$[?(@.birthDate =~ /[0-9]{4}-[0-9]{2}-[0-9]{2}/)]"
|
||||
}, {
|
||||
"matchesJsonPath" : "$[?(@.personalId =~ /[0-9]{11}/)]"
|
||||
}, {
|
||||
"matchesJsonPath" : "$[?(@.firstName =~ /.*/)]"
|
||||
} ]
|
||||
},
|
||||
"response" : {
|
||||
"status" : 200,
|
||||
"body" : "{\\"name\\":\\"Jan\\"}",
|
||||
"headers" : {
|
||||
"Content-Type" : "text/plain"
|
||||
}
|
||||
}
|
||||
}
|
||||
'''), wireMockStub, false)
|
||||
}
|
||||
|
||||
def 'should use regexp matches when request body match is defined using a map with a pattern'() {
|
||||
@@ -1097,26 +1026,34 @@ class WireMockGroovyDslSpec extends WireMockSpec {
|
||||
when:
|
||||
def json = toWireMockClientJsonStub(groovyDsl)
|
||||
then:
|
||||
parseJson(json) == parseJson('''
|
||||
{
|
||||
"request": {
|
||||
"method": "POST",
|
||||
"url": "/reissue-payment-order",
|
||||
"bodyPatterns": [
|
||||
{
|
||||
"matches": "\\\\s*\\\\{\\\\s*\\"loanNumber\\"\\\\s*:\\\\s*\\"?999997001\\"?\\\\s*,\\\\s*\\"amount\\"\\\\s*:\\\\s*\\"?[0-9.]+\\"?\\\\s*,\\\\s*\\"currency\\"\\\\s*:\\\\s*\\"?DKK\\"?\\\\s*,\\\\s*\\"applicationName\\"\\\\s*:\\\\s*\\"?.*\\"?\\\\s*,\\\\s*\\"username\\"\\\\s*:\\\\s*\\"?.*\\"?\\\\s*,\\\\s*\\"cardId\\"\\\\s*:\\\\s*\\"?1\\"?\\\\s*\\\\}\\\\s*"
|
||||
}
|
||||
]
|
||||
},
|
||||
"response": {
|
||||
"status": 200,
|
||||
"body": "{\\"status\\":\\"OK\\"}",
|
||||
"headers": {
|
||||
"Content-Type": "application/json"
|
||||
}
|
||||
}
|
||||
}
|
||||
''')
|
||||
JSONAssert.assertEquals(('''
|
||||
{
|
||||
"request" : {
|
||||
"url" : "/reissue-payment-order",
|
||||
"method" : "POST",
|
||||
"bodyPatterns" : [ {
|
||||
"matchesJsonPath" : "$[?(@.loanNumber == '999997001')]"
|
||||
}, {
|
||||
"matchesJsonPath" : "$[?(@.username =~ /.*/)]"
|
||||
}, {
|
||||
"matchesJsonPath" : "$[?(@.amount =~ /[0-9.]+/)]"
|
||||
}, {
|
||||
"matchesJsonPath" : "$[?(@.cardId == 1)]"
|
||||
}, {
|
||||
"matchesJsonPath" : "$[?(@.currency == 'DKK')]"
|
||||
}, {
|
||||
"matchesJsonPath" : "$[?(@.applicationName =~ /.*/)]"
|
||||
} ]
|
||||
},
|
||||
"response" : {
|
||||
"status" : 200,
|
||||
"body" : "{\\"status\\":\\"OK\\"}",
|
||||
"headers" : {
|
||||
"Content-Type" : "application/json"
|
||||
}
|
||||
}
|
||||
}
|
||||
'''), json, false)
|
||||
}
|
||||
|
||||
def "should generate stub for empty body"() {
|
||||
@@ -1134,7 +1071,7 @@ class WireMockGroovyDslSpec extends WireMockSpec {
|
||||
when:
|
||||
def json = toWireMockClientJsonStub(groovyDsl)
|
||||
then:
|
||||
parseJson(json) == parseJson('''
|
||||
JSONAssert.assertEquals(('''
|
||||
{
|
||||
"request": {
|
||||
"method": "POST",
|
||||
@@ -1149,7 +1086,7 @@ class WireMockGroovyDslSpec extends WireMockSpec {
|
||||
"status": 406
|
||||
}
|
||||
}
|
||||
''')
|
||||
'''), json, false)
|
||||
}
|
||||
|
||||
def "should generate stub with priority"() {
|
||||
@@ -1167,7 +1104,7 @@ class WireMockGroovyDslSpec extends WireMockSpec {
|
||||
when:
|
||||
def json = toWireMockClientJsonStub(groovyDsl)
|
||||
then:
|
||||
parseJson(json) == parseJson('''
|
||||
JSONAssert.assertEquals(('''
|
||||
{
|
||||
"priority": 9,
|
||||
"request": {
|
||||
@@ -1178,7 +1115,7 @@ class WireMockGroovyDslSpec extends WireMockSpec {
|
||||
"status": 406
|
||||
}
|
||||
}
|
||||
''')
|
||||
'''), json, false)
|
||||
}
|
||||
|
||||
@Issue("#127")
|
||||
@@ -1198,21 +1135,19 @@ class WireMockGroovyDslSpec extends WireMockSpec {
|
||||
when:
|
||||
String wireMockStub = new WireMockStubStrategy(groovyDsl).toWireMockClientStub()
|
||||
then:
|
||||
new JsonSlurper().parseText(wireMockStub) == new JsonSlurper().parseText('''
|
||||
{
|
||||
"request": {
|
||||
"method": "POST",
|
||||
"bodyPatterns": [
|
||||
{
|
||||
"equalToJson": "{\\"property\\":\\"value\\"}"
|
||||
}
|
||||
]
|
||||
},
|
||||
"response": {
|
||||
"status": 200
|
||||
}
|
||||
}
|
||||
''')
|
||||
JSONAssert.assertEquals(('''
|
||||
{
|
||||
"request" : {
|
||||
"method" : "POST",
|
||||
"bodyPatterns" : [ {
|
||||
"matchesJsonPath" : "$[?(@.property == 'value')]"
|
||||
} ]
|
||||
},
|
||||
"response" : {
|
||||
"status" : 200
|
||||
}
|
||||
}
|
||||
'''), wireMockStub, false)
|
||||
and:
|
||||
stubMappingIsValidWireMockStub(wireMockStub)
|
||||
}
|
||||
@@ -1234,7 +1169,7 @@ class WireMockGroovyDslSpec extends WireMockSpec {
|
||||
when:
|
||||
String wireMockStub = new WireMockStubStrategy(groovyDsl).toWireMockClientStub()
|
||||
then:
|
||||
new JsonSlurper().parseText(wireMockStub) == new JsonSlurper().parseText('''
|
||||
JSONAssert.assertEquals(('''
|
||||
{
|
||||
"request": {
|
||||
"method": "POST",
|
||||
@@ -1248,7 +1183,7 @@ class WireMockGroovyDslSpec extends WireMockSpec {
|
||||
"status": 200
|
||||
}
|
||||
}
|
||||
''')
|
||||
'''), wireMockStub, false)
|
||||
and:
|
||||
stubMappingIsValidWireMockStub(wireMockStub)
|
||||
}
|
||||
|
||||
@@ -0,0 +1,199 @@
|
||||
package io.codearte.accurest.util
|
||||
import groovy.json.JsonOutput
|
||||
import groovy.json.JsonSlurper
|
||||
import com.jayway.jsonpath.Configuration
|
||||
import com.jayway.jsonpath.DocumentContext
|
||||
import com.jayway.jsonpath.JsonPath
|
||||
import com.jayway.jsonpath.Option
|
||||
import net.minidev.json.JSONArray
|
||||
import spock.lang.Specification
|
||||
import spock.lang.Unroll
|
||||
|
||||
import java.util.regex.Pattern
|
||||
|
||||
class JsonPathJsonConverterSpec extends Specification {
|
||||
|
||||
@Unroll
|
||||
def 'should convert a json with list as root to a map of path to value'() {
|
||||
when:
|
||||
JsonPaths pathAndValues = JsonPathJsonConverter.transformToJsonPathWithTestsSideValues(new JsonSlurper().parseText(json))
|
||||
then:
|
||||
pathAndValues['''$[*].some.nested[?(@.json == 'with value')]'''] == 'with value'
|
||||
pathAndValues['''$[*].some.nested[?(@.anothervalue == 4)]'''] == 4
|
||||
pathAndValues['''$[*].some.nested.withlist[*][?(@.name == 'name1')]'''] == 'name1'
|
||||
pathAndValues['''$[*].some.nested.withlist[*][?(@.name == 'name2')]'''] == 'name2'
|
||||
pathAndValues['''$[*].some.nested.withlist[*].anothernested[?(@.name == 'name3')]'''] == 'name3'
|
||||
and:
|
||||
assertThatJsonPathsInMapAreValid(json, pathAndValues)
|
||||
where:
|
||||
json << [
|
||||
'''
|
||||
[ {
|
||||
"some" : {
|
||||
"nested" : {
|
||||
"json" : "with value",
|
||||
"anothervalue": 4,
|
||||
"withlist" : [
|
||||
{ "name" :"name1"} , {"name": "name2"}, {"anothernested": { "name": "name3"} }
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"someother" : {
|
||||
"nested" : {
|
||||
"json" : "with value",
|
||||
"anothervalue": 4,
|
||||
"withlist" : [
|
||||
{ "name" :"name1"} , {"name": "name2"}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
''',
|
||||
'''
|
||||
[{
|
||||
"someother" : {
|
||||
"nested" : {
|
||||
"json" : "with value",
|
||||
"anothervalue": 4,
|
||||
"withlist" : [
|
||||
{ "name" :"name1"} , {"name": "name2"}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"some" : {
|
||||
"nested" : {
|
||||
"json" : "with value",
|
||||
"anothervalue": 4,
|
||||
"withlist" : [
|
||||
{"name": "name2"}, {"anothernested": { "name": "name3"} }, { "name" :"name1"}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
]''']
|
||||
}
|
||||
|
||||
def 'should convert a json with a map as root to a map of path to value'() {
|
||||
given:
|
||||
String json = '''
|
||||
{
|
||||
"some" : {
|
||||
"nested" : {
|
||||
"json" : "with value",
|
||||
"anothervalue": 4,
|
||||
"withlist" : [
|
||||
{ "name" :"name1"} , {"name": "name2"}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
'''
|
||||
when:
|
||||
JsonPaths pathAndValues = JsonPathJsonConverter.transformToJsonPathWithTestsSideValues(new JsonSlurper().parseText(json))
|
||||
then:
|
||||
pathAndValues['''$.some.nested[?(@.json == 'with value')]'''] == 'with value'
|
||||
pathAndValues['''$.some.nested[?(@.anothervalue == 4)]'''] == 4
|
||||
pathAndValues['''$.some.nested.withlist[*][?(@.name == 'name1')]'''] == 'name1'
|
||||
pathAndValues['''$.some.nested.withlist[*][?(@.name == 'name2')]'''] == 'name2'
|
||||
and:
|
||||
assertThatJsonPathsInMapAreValid(json, pathAndValues)
|
||||
}
|
||||
|
||||
def 'should convert a json with a list'() {
|
||||
given:
|
||||
String json = '''
|
||||
{
|
||||
"items" : ["HOP"]
|
||||
}
|
||||
'''
|
||||
when:
|
||||
JsonPaths pathAndValues = JsonPathJsonConverter.transformToJsonPathWithTestsSideValues(new JsonSlurper().parseText(json))
|
||||
then:
|
||||
pathAndValues['''$.items[?(@ == 'HOP')]'''] == 'HOP'
|
||||
and:
|
||||
assertThatJsonPathsInMapAreValid(json, pathAndValues)
|
||||
}
|
||||
|
||||
|
||||
def 'should convert a json with a list of errors'() {
|
||||
given:
|
||||
String json = '''
|
||||
{
|
||||
"errors" : [
|
||||
{ "property" : "email", "message" : "inconsistent value" },
|
||||
{ "property" : "email", "message" : "inconsistent value2" }
|
||||
]
|
||||
}
|
||||
'''
|
||||
when:
|
||||
JsonPaths pathAndValues = JsonPathJsonConverter.transformToJsonPathWithTestsSideValues(new JsonSlurper().parseText(json))
|
||||
then:
|
||||
pathAndValues['''$.errors[*][?(@.property == 'email')]'''] == 'email'
|
||||
pathAndValues['''$.errors[*][?(@.message == 'inconsistent value')]'''] == 'inconsistent value'
|
||||
pathAndValues['''$.errors[*][?(@.message == 'inconsistent value2')]'''] == 'inconsistent value2'
|
||||
pathAndValues['''$.errors[*][?(@.property == 'email')]'''] == 'email'
|
||||
and:
|
||||
assertThatJsonPathsInMapAreValid(json, pathAndValues)
|
||||
}
|
||||
|
||||
|
||||
def 'should convert a map json with a regex pattern'() {
|
||||
given:
|
||||
List json = [
|
||||
[some:
|
||||
[nested: [
|
||||
json: "with value",
|
||||
anothervalue: 4,
|
||||
withlist:
|
||||
[
|
||||
[name: "name2"],
|
||||
[name: "name1"],
|
||||
[anothernested:
|
||||
[name: Pattern.compile('[a-zA-Z]+')]
|
||||
],
|
||||
[age: "123456789"]
|
||||
]
|
||||
]
|
||||
]
|
||||
],
|
||||
[someother:
|
||||
[nested: [
|
||||
json: "with value",
|
||||
anothervalue: 4,
|
||||
withlist:
|
||||
[
|
||||
[name: "name2"],
|
||||
[name: "name1"]
|
||||
]
|
||||
]
|
||||
]
|
||||
]
|
||||
]
|
||||
when:
|
||||
JsonPaths pathAndValues = JsonPathJsonConverter.transformToJsonPathWithTestsSideValues(json)
|
||||
then:
|
||||
pathAndValues['''$[*].some.nested[?(@.json == 'with value')]'''] == 'with value'
|
||||
pathAndValues['''$[*].some.nested[?(@.anothervalue == 4)]'''] == 4
|
||||
pathAndValues['''$[*].some.nested.withlist[*][?(@.name == 'name1')]'''] == 'name1'
|
||||
pathAndValues['''$[*].some.nested.withlist[*][?(@.name == 'name2')]''']
|
||||
(pathAndValues['''$[*].some.nested.withlist[*].anothernested[?(@.name =~ /[a-zA-Z]+/)]'''] as Pattern).pattern() == '[a-zA-Z]+'
|
||||
when:
|
||||
pathAndValues['''$[*].some.nested.withlist[*].anothernested[?(@.name =~ /[a-zA-Z]+/)]'''] = "Kowalski"
|
||||
json.some.nested.withlist[0][2].anothernested.name = "Kowalski"
|
||||
then:
|
||||
assertThatJsonPathsInMapAreValid(JsonOutput.prettyPrint(JsonOutput.toJson(json)), pathAndValues)
|
||||
}
|
||||
|
||||
private void assertThatJsonPathsInMapAreValid(String json, JsonPaths pathAndValues) {
|
||||
DocumentContext parsedJson = JsonPath.using(Configuration.builder().options(Option.ALWAYS_RETURN_LIST).build()).parse(json);
|
||||
pathAndValues.each {
|
||||
assert parsedJson.read(it.jsonPath, JSONArray).getAt(it.optionalSuffix ?: 0) == it.optionalSuffix ? [it.value] : it.value
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -4,6 +4,7 @@ import io.codearte.accurest.config.AccurestConfigProperties
|
||||
import org.gradle.api.Plugin
|
||||
import org.gradle.api.Project
|
||||
import org.gradle.api.Task
|
||||
import org.gradle.api.artifacts.DependencyResolveDetails
|
||||
|
||||
/**
|
||||
* @author Jakub Kubrynski
|
||||
@@ -29,6 +30,21 @@ class AccurestGradlePlugin implements Plugin<Project> {
|
||||
createGenerateTestsTask(extension)
|
||||
createAndConfigureGenerateWireMockClientStubsFromDslTask(extension)
|
||||
deprecatedCreateAndConfigureGenerateWiremockClientStubsFromDslTask()
|
||||
project.dependencies.add("testCompile", "io.codearte.accurest:accurest-core:+")
|
||||
project.dependencies.add("testCompile", "com.blogspot.toomuchcoding:wiremock:0.0.1")
|
||||
project.repositories { jcenter() }
|
||||
project.configurations {
|
||||
all {
|
||||
resolutionStrategy {
|
||||
eachDependency { DependencyResolveDetails details ->
|
||||
if (details.requested.group == 'com.github.tomakehurst' && details.requested.name == "wiremock") {
|
||||
details.useTarget("com.blogspot.toomuchcoding:wiremock:0.0.1")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
project.afterEvaluate {
|
||||
def hasIdea = project.plugins.findPlugin(IDEA_PLUGIN_CLASS)
|
||||
|
||||
@@ -18,7 +18,6 @@ ext {
|
||||
subprojects {
|
||||
apply plugin: 'groovy'
|
||||
|
||||
|
||||
repositories {
|
||||
mavenCentral()
|
||||
mavenLocal()
|
||||
|
||||
11
build.gradle
11
build.gradle
@@ -48,6 +48,7 @@ subprojects {
|
||||
repositories {
|
||||
mavenLocal()
|
||||
mavenCentral()
|
||||
jcenter()
|
||||
}
|
||||
|
||||
//Dependencies in all subprojects - http://solidsoft.wordpress.com/2014/11/13/gradle-tricks-display-dependencies-for-all-subprojects-in-multi-project-build/
|
||||
@@ -84,15 +85,21 @@ subprojects {
|
||||
}
|
||||
|
||||
project(':accurest-core') {
|
||||
|
||||
dependencies {
|
||||
compile 'org.slf4j:slf4j-api:[1.6.0,)'
|
||||
compile 'org.codehaus.plexus:plexus-utils:[3.0.0,)'
|
||||
compile 'commons-io:commons-io:[2.0,)'
|
||||
compile 'org.apache.commons:commons-lang3:[3.3,)'
|
||||
compile 'com.google.code.gson:gson:2.3.1'
|
||||
compile 'com.fasterxml.jackson.core:jackson-databind:2.4.5'
|
||||
compile 'asm:asm:3.3.1'
|
||||
compile 'com.blogspot.toomuchcoding:wiremock:0.0.1'
|
||||
testCompile 'cglib:cglib-nodep:2.2'
|
||||
testCompile 'org.objenesis:objenesis:2.1'
|
||||
testCompile 'com.github.tomakehurst:wiremock:1.57'
|
||||
testCompile 'org.skyscreamer:jsonassert:1.2.3'
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
project(':accurest-converters') {
|
||||
@@ -101,7 +108,7 @@ project(':accurest-converters') {
|
||||
compile 'org.apache.commons:commons-lang3:[3.0,)'
|
||||
compile 'commons-io:commons-io:[2.0,)'
|
||||
compile 'dk.brics.automaton:automaton:1.11-8' // needed for Xeger
|
||||
testCompile 'com.github.tomakehurst:wiremock:1.57'
|
||||
testCompile 'com.blogspot.toomuchcoding:wiremock:0.0.1'
|
||||
testCompile 'org.hamcrest:hamcrest-all:1.3'
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,7 +12,7 @@ task sourcesJar(type: Jar) {
|
||||
}
|
||||
|
||||
artifacts {
|
||||
archives javadocJar, sourcesJar
|
||||
archives javadocJar, sourcesJar, repackagedJar
|
||||
}
|
||||
|
||||
signing {
|
||||
|
||||
Reference in New Issue
Block a user