diff --git a/spring-cloud-contract-verifier/src/main/groovy/org/springframework/cloud/contract/verifier/builder/MethodBodyBuilder.groovy b/spring-cloud-contract-verifier/src/main/groovy/org/springframework/cloud/contract/verifier/builder/MethodBodyBuilder.groovy index b01af2283f..fea5dc7c1f 100644 --- a/spring-cloud-contract-verifier/src/main/groovy/org/springframework/cloud/contract/verifier/builder/MethodBodyBuilder.groovy +++ b/spring-cloud-contract-verifier/src/main/groovy/org/springframework/cloud/contract/verifier/builder/MethodBodyBuilder.groovy @@ -328,6 +328,11 @@ abstract class MethodBodyBuilder { } else { Object elementFromBody = value(copiedBody, it) if (it.minTypeOccurrence() != null || it.maxTypeOccurrence() != null) { + if (it.path().contains("[*]")) { + throw new UnsupportedOperationException("Version 1.0.x doesn't support checking sizes when JSON Path contains [*]. " + + "For more information check out https://github.com/spring-cloud/spring-cloud-contract/issues/217 . " + + "Please upgrade to the latest version of Spring Cloud Contract for this feature.") + } checkType(bb, it, elementFromBody) String method = "assertThat(parsedJson.read(${quotedAndEscaped(it.path())}, java.util.Collection.class).size()).${sizeCheckMethod(it)}" bb.addLine(postProcessJsonPathCall(method)) diff --git a/spring-cloud-contract-verifier/src/test/groovy/org/springframework/cloud/contract/verifier/builder/MockMvcMethodBodyBuilderWithMatchersSpec.groovy b/spring-cloud-contract-verifier/src/test/groovy/org/springframework/cloud/contract/verifier/builder/MockMvcMethodBodyBuilderWithMatchersSpec.groovy index 800a53b98c..5b420e7506 100644 --- a/spring-cloud-contract-verifier/src/test/groovy/org/springframework/cloud/contract/verifier/builder/MockMvcMethodBodyBuilderWithMatchersSpec.groovy +++ b/spring-cloud-contract-verifier/src/test/groovy/org/springframework/cloud/contract/verifier/builder/MockMvcMethodBodyBuilderWithMatchersSpec.groovy @@ -204,13 +204,12 @@ class MockMvcMethodBodyBuilderWithMatchersSpec extends Specification implements ]) testMatchers { jsonPath('$.phoneNumbers', byType { - minOccurrence(0) // min occurrence of 1 - maxOccurrence(4) // max occurrence of 3 + minOccurrence(0) // min occurrence of 0 + maxOccurrence(4) // max occurrence of 4 }) jsonPath('$.phoneNumbers[*].number', byRegex("^[0-9]{3} [0-9]{3}-[0-9]{4}\$")) jsonPath('$..number', byRegex("^[0-9]{3} [0-9]{3}-[0-9]{4}\$")) } - headers { contentType('application/json') } @@ -238,4 +237,42 @@ class MockMvcMethodBodyBuilderWithMatchersSpec extends Specification implements "JaxRsClientJUnitMethodBodyBuilder" | { Contract dsl -> new JaxRsClientJUnitMethodBodyBuilder(dsl, properties) } | '$' } + @Issue('#217') + def "should not allow matcher with jsonpath containing [*] for [#methodBuilderName]"() { + given: + Contract contractDsl = Contract.make { + request { + method 'GET' + url 'person' + } + response { + status 200 + body([ + "phoneNumbers": [ + number: "foo" + ] + ]) + testMatchers { + jsonPath('$.phoneNumbers[*].number', byType { + minOccurrence(0) // min occurrence of 0 + maxOccurrence(4) // max occurrence of 4 + }) + } + } + } + MethodBodyBuilder builder = methodBuilder(contractDsl) + BlockBuilder blockBuilder = new BlockBuilder(" ") + when: + builder.appendTo(blockBuilder) + then: + UnsupportedOperationException e = thrown(UnsupportedOperationException) + e.message.contains("Version 1.0.x doesn't support checking sizes when JSON Path contains [*]") + where: + methodBuilderName | methodBuilder | rootElement + "MockMvcSpockMethodBuilder" | { Contract dsl -> new MockMvcSpockMethodRequestProcessingBodyBuilder(dsl, properties) } | '\\$' + "MockMvcJUnitMethodBuilder" | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl, properties) } | '$' + "JaxRsClientSpockMethodRequestProcessingBodyBuilder" | { Contract dsl -> new JaxRsClientSpockMethodRequestProcessingBodyBuilder(dsl, properties) } | '\\$' + "JaxRsClientJUnitMethodBodyBuilder" | { Contract dsl -> new JaxRsClientJUnitMethodBodyBuilder(dsl, properties) } | '$' + } + }