Fixed the way we parse lists with regexps in responses (#224)
* Fixed the way we parse lists with regexps in responses fixes #216
This commit is contained in:
@@ -27,8 +27,12 @@ class ContentUtils {
|
||||
it instanceof DslProperty ? it.clientValue : it
|
||||
}
|
||||
|
||||
public static final Closure GET_TEST_SIDE = {
|
||||
it instanceof DslProperty ? it.serverValue : it
|
||||
}
|
||||
|
||||
private static final Pattern TEMPORARY_PATTERN_HOLDER = Pattern.compile('.*REGEXP>>(.*)<<.*')
|
||||
private static final Pattern TEMPORARY_EXECUTION_PATTERN_HOLDER = Pattern.compile('EXECUTION>>(.*)<<')
|
||||
private static final Pattern TEMPORARY_EXECUTION_PATTERN_HOLDER = Pattern.compile('["]?EXECUTION>>(.*)<<["]?')
|
||||
private static final Pattern TEMPORARY_OPTIONAL_PATTERN_HOLDER = Pattern.compile('OPTIONAL>>(.*)<<')
|
||||
private static final String JSON_VALUE_PATTERN_FOR_REGEX = 'REGEXP>>%s<<'
|
||||
private static final String JSON_VALUE_PATTERN_FOR_OPTIONAL = 'OPTIONAL>>%s<<'
|
||||
@@ -150,23 +154,23 @@ class ContentUtils {
|
||||
)
|
||||
}
|
||||
|
||||
private static String transformJSONStringValue(Object obj, Closure valueProvider) {
|
||||
return obj.toString()
|
||||
protected static Object transformJSONStringValue(Object obj, Closure valueProvider) {
|
||||
return obj
|
||||
}
|
||||
|
||||
private static String transformJSONStringValue(DslProperty dslProperty, Closure valueProvider) {
|
||||
protected static Object transformJSONStringValue(DslProperty dslProperty, Closure valueProvider) {
|
||||
return transformJSONStringValue(valueProvider(dslProperty), valueProvider)
|
||||
}
|
||||
|
||||
private static String transformJSONStringValue(Pattern pattern, Closure valueProvider) {
|
||||
protected static Object transformJSONStringValue(Pattern pattern, Closure valueProvider) {
|
||||
return String.format(JSON_VALUE_PATTERN_FOR_REGEX, pattern.pattern())
|
||||
}
|
||||
|
||||
private static String transformJSONStringValue(OptionalProperty optional, Closure valueProvider) {
|
||||
protected static Object transformJSONStringValue(OptionalProperty optional, Closure valueProvider) {
|
||||
return String.format(JSON_VALUE_PATTERN_FOR_OPTIONAL, optional.value)
|
||||
}
|
||||
|
||||
private static String transformJSONStringValue(ExecutionProperty property, Closure valueProvider) {
|
||||
protected static Object transformJSONStringValue(ExecutionProperty property, Closure valueProvider) {
|
||||
return String.format(JSON_VALUE_PATTERN_FOR_EXECUTION, property.executionCommand)
|
||||
}
|
||||
|
||||
@@ -178,6 +182,12 @@ class ContentUtils {
|
||||
return transformXMLStringValue(valueProvider(dslProperty), valueProvider)
|
||||
}
|
||||
|
||||
protected static Object convertDslPropsToTemporaryRegexPatterns(parsedJson) {
|
||||
MapConverter.transformValues(parsedJson, { Object value ->
|
||||
return transformJSONStringValue(value, GET_TEST_SIDE)
|
||||
})
|
||||
}
|
||||
|
||||
private static Object convertAllTemporaryRegexPlaceholdersBackToPatterns(parsedJson) {
|
||||
MapConverter.transformValues(parsedJson, { Object value ->
|
||||
if (value instanceof String) {
|
||||
@@ -212,7 +222,11 @@ class ContentUtils {
|
||||
* @param string to match the regexps against
|
||||
* @return object converted from temporary holders
|
||||
*/
|
||||
static Object returnParsedObject(String string) {
|
||||
static Object returnParsedObject(Object object) {
|
||||
if (!(object instanceof String)) {
|
||||
return object
|
||||
}
|
||||
String string = (String) object
|
||||
Matcher matcher = TEMPORARY_PATTERN_HOLDER.matcher(string.trim())
|
||||
if (matcher.matches()) {
|
||||
return Pattern.compile(patternFromMatchingGroup(matcher))
|
||||
|
||||
@@ -137,6 +137,7 @@ class DelegatingJsonVerifiable implements MethodBufferingJsonVerifiable {
|
||||
public MethodBufferingJsonVerifiable matches(String value) {
|
||||
DelegatingJsonVerifiable readyToCheck = new FinishedDelegatingJsonVerifiable(delegate.matches(value), methodsBuffer);
|
||||
if (delegate.isAssertingAValueInArray()) {
|
||||
readyToCheck.appendMethodWithQuotedValue("matches", escapeJava(value));
|
||||
readyToCheck.methodsBuffer.append(".value()");
|
||||
} else {
|
||||
readyToCheck.appendMethodWithQuotedValue("matches", escapeJava(value));
|
||||
|
||||
@@ -29,9 +29,10 @@ class JsonToJsonPathsConverter {
|
||||
}
|
||||
JsonPaths pathsAndValues = [] as Set
|
||||
Object convertedJson = MapConverter.getClientOrServerSideValues(json, clientSide)
|
||||
Object jsonWithPatterns = ContentUtils.convertDslPropsToTemporaryRegexPatterns(convertedJson)
|
||||
MethodBufferingJsonVerifiable methodBufferingJsonPathVerifiable =
|
||||
new DelegatingJsonVerifiable(JsonAssertion.assertThat(JsonOutput.toJson(convertedJson)).withoutThrowingException())
|
||||
traverseRecursivelyForKey(convertedJson, methodBufferingJsonPathVerifiable)
|
||||
new DelegatingJsonVerifiable(JsonAssertion.assertThat(JsonOutput.toJson(jsonWithPatterns)).withoutThrowingException())
|
||||
traverseRecursivelyForKey(jsonWithPatterns, methodBufferingJsonPathVerifiable)
|
||||
{ MethodBufferingJsonVerifiable key, Object value ->
|
||||
if (value instanceof ExecutionProperty || !(key instanceof FinishedDelegatingJsonVerifiable)) {
|
||||
return
|
||||
@@ -42,6 +43,7 @@ class JsonToJsonPathsConverter {
|
||||
}
|
||||
|
||||
protected static def traverseRecursively(Class parentType, MethodBufferingJsonVerifiable key, def value, Closure closure) {
|
||||
value = ContentUtils.returnParsedObject(value)
|
||||
if (value instanceof String && value) {
|
||||
try {
|
||||
def json = new JsonSlurper().parseText(value)
|
||||
@@ -91,7 +93,11 @@ class JsonToJsonPathsConverter {
|
||||
|
||||
private static MethodBufferingJsonVerifiable createAsserterFromListElement(MethodBufferingJsonVerifiable jsonPathVerifiable, def element) {
|
||||
if (jsonPathVerifiable.isAssertingAValueInArray()) {
|
||||
return jsonPathVerifiable.contains(element)
|
||||
def object = ContentUtils.returnParsedObject(element)
|
||||
if (object instanceof Pattern) {
|
||||
return jsonPathVerifiable.matches((object as Pattern).pattern())
|
||||
}
|
||||
return jsonPathVerifiable.contains(object)
|
||||
}
|
||||
return jsonPathVerifiable
|
||||
}
|
||||
@@ -145,13 +151,14 @@ class JsonToJsonPathsConverter {
|
||||
private static Map convertWithKey(Class parentType, MethodBufferingJsonVerifiable parentKey, Map map, Closure closureToExecute) {
|
||||
return map.collectEntries {
|
||||
Object entrykey, value ->
|
||||
def convertedValue = ContentUtils.returnParsedObject(value)
|
||||
[entrykey, traverseRecursively(parentType,
|
||||
value instanceof List ? listContainsOnlyPrimitives(value) ?
|
||||
convertedValue instanceof List ? listContainsOnlyPrimitives(convertedValue) ?
|
||||
parentKey.arrayField(entrykey) :
|
||||
parentKey.array(entrykey) :
|
||||
value instanceof Map ? parentKey.field(new ShouldTraverse(entrykey)) :
|
||||
valueToAsserter(parentKey.field(entrykey), value)
|
||||
, value, closureToExecute)]
|
||||
convertedValue instanceof Map ? parentKey.field(new ShouldTraverse(entrykey)) :
|
||||
valueToAsserter(parentKey.field(entrykey), convertedValue)
|
||||
, convertedValue, closureToExecute)]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -160,12 +167,17 @@ class JsonToJsonPathsConverter {
|
||||
}
|
||||
|
||||
protected static MethodBufferingJsonVerifiable valueToAsserter(MethodBufferingJsonVerifiable key, Object value) {
|
||||
if (key instanceof FinishedDelegatingJsonVerifiable) {
|
||||
return key
|
||||
}
|
||||
if (value instanceof Pattern) {
|
||||
return key.matches((value as Pattern).pattern())
|
||||
} else if (value instanceof OptionalProperty) {
|
||||
return key.matches((value as OptionalProperty).optionalPattern())
|
||||
} else if (value instanceof GString) {
|
||||
return key.matches(RegexpBuilders.buildGStringRegexpForTestSide(value))
|
||||
} else if (ContentUtils.returnParsedObject(value) instanceof ExecutionProperty) {
|
||||
return key
|
||||
}
|
||||
return key.isEqualTo(value)
|
||||
}
|
||||
|
||||
@@ -1,12 +1,13 @@
|
||||
package io.codearte.accurest.util
|
||||
|
||||
import groovy.json.JsonSlurper
|
||||
import io.codearte.accurest.dsl.internal.DslProperty
|
||||
|
||||
/**
|
||||
* @author Marcin Grzejszczak
|
||||
*/
|
||||
class MapConverter {
|
||||
|
||||
|
||||
public static final boolean STUB_SIDE = true
|
||||
public static final boolean TEST_SIDE = false
|
||||
|
||||
|
||||
@@ -8,7 +8,6 @@ import spock.lang.Specification
|
||||
import spock.lang.Unroll
|
||||
|
||||
import java.util.regex.Pattern
|
||||
|
||||
/**
|
||||
* @author Jakub Kubrynski
|
||||
*/
|
||||
@@ -1118,4 +1117,76 @@ World.'''"""
|
||||
"MockMvcJUnitMethodBuilder" | { GroovyDsl dsl -> new MockMvcJUnitMethodBodyBuilder(dsl) }
|
||||
}
|
||||
|
||||
@Issue('#216')
|
||||
@Unroll
|
||||
def "should parse JSON with arrays using #methodBuilderName"() {
|
||||
given:
|
||||
GroovyDsl contractDsl = GroovyDsl.make {
|
||||
request {
|
||||
method "GET"
|
||||
urlPath('/auth/oauth/check_token') {
|
||||
queryParameters {
|
||||
parameter 'token':
|
||||
value(
|
||||
client(regex('^[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}')),
|
||||
server('6973b31d-7140-402a-bca6-1cdb954e03a7')
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
response {
|
||||
status 200
|
||||
body(
|
||||
authorities: [
|
||||
value(stub('ROLE_ADMIN'), test(regex('^[a-zA-Z0-9_\\- ]+$')))
|
||||
]
|
||||
)
|
||||
}
|
||||
}
|
||||
MethodBodyBuilder builder = methodBuilder(contractDsl)
|
||||
BlockBuilder blockBuilder = new BlockBuilder(" ")
|
||||
when:
|
||||
builder.appendTo(blockBuilder)
|
||||
def test = blockBuilder.toString()
|
||||
then:
|
||||
test.contains('''assertThatJson(parsedJson).array("authorities").matches("^[a-zA-Z0-9_\\\\- ]+\\$").value()''')
|
||||
where:
|
||||
methodBuilderName | methodBuilder
|
||||
"MockMvcSpockMethodBuilder" | { GroovyDsl dsl -> new MockMvcSpockMethodBodyBuilder(dsl) }
|
||||
"MockMvcJUnitMethodBuilder" | { GroovyDsl dsl -> new MockMvcJUnitMethodBodyBuilder(dsl) }
|
||||
}
|
||||
|
||||
@Unroll
|
||||
def "should work with execution property"() {
|
||||
given:
|
||||
GroovyDsl contractDsl = GroovyDsl.make {
|
||||
request {
|
||||
method 'PUT'
|
||||
url '/fraudcheck'
|
||||
}
|
||||
response {
|
||||
status 200
|
||||
body(
|
||||
fraudCheckStatus: "OK",
|
||||
rejectionReason: $(client(null), server(execute('assertThatRejectionReasonIsNull($it)')))
|
||||
)
|
||||
}
|
||||
|
||||
}
|
||||
MethodBodyBuilder builder = methodBuilder(contractDsl)
|
||||
BlockBuilder blockBuilder = new BlockBuilder(" ")
|
||||
when:
|
||||
builder.appendTo(blockBuilder)
|
||||
def test = blockBuilder.toString()
|
||||
then:
|
||||
!test.contains('''assertThatJson(parsedJson).field("rejectionReason").isEqualTo("assertThatRejectionReasonIsNull("''')
|
||||
test.contains('''assertThatRejectionReasonIsNull(''')
|
||||
where:
|
||||
methodBuilderName | methodBuilder
|
||||
"MockMvcSpockMethodBuilder" | { GroovyDsl dsl -> new MockMvcSpockMethodBodyBuilder(dsl) }
|
||||
"MockMvcJUnitMethodBuilder" | { GroovyDsl dsl -> new MockMvcJUnitMethodBodyBuilder(dsl) }
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user