diff --git a/docs/src/main/asciidoc/spring-cloud-wiremock.adoc b/docs/src/main/asciidoc/spring-cloud-wiremock.adoc index ba88b8f67c..3dc28dac17 100644 --- a/docs/src/main/asciidoc/spring-cloud-wiremock.adoc +++ b/docs/src/main/asciidoc/spring-cloud-wiremock.adoc @@ -180,8 +180,7 @@ include::{wiremock_tests}/src/test/java/org/springframework/cloud/contract/wirem https://projects.spring.io/spring-restdocs[Spring REST Docs] can be used to generate documentation (for example in Asciidoctor format) for an HTTP API with Spring MockMvc -or `WebTestClient` or -Rest Assured. At the same time that you generate documentation for your API, you can also +or `WebTestClient` or Rest Assured. At the same time that you generate documentation for your API, you can also generate WireMock stubs by using Spring Cloud Contract WireMock. To do so, write your normal REST Docs test cases and use `@AutoConfigureRestDocs` to have stubs be automatically generated in the REST Docs output directory. The following code shows an diff --git a/docs/src/main/asciidoc/verifier_introduction.adoc b/docs/src/main/asciidoc/verifier_introduction.adoc index 30302124b3..69f97a0f2a 100644 --- a/docs/src/main/asciidoc/verifier_introduction.adoc +++ b/docs/src/main/asciidoc/verifier_introduction.adoc @@ -363,10 +363,38 @@ public void validate_shouldMarkClientAsFraud() throws Exception { ---- The preceding example uses Spring's `MockMvc` to run the tests. This is the default test -mode for HTTP contracts. However, JAX-RX client and explicit HTTP invocations can also be +mode for HTTP contracts. However, JAX-RS client and explicit HTTP invocations can also be used. (To do so, change the `testMode` property of the plugin to `JAX-RS` or `EXPLICIT`, respectively.) +Since 2.1.0, it is also possible to use `RestAssuredWebTestClient`with Spring's reactive `WebTestClient` +run under the hood. This is particularly recommended while working with Reactive, `Web-Flux`-based applications. +In order to use `WebTestClient` set `testMode` to `WEBTESTCLIENT`. + +Here is an example of a test generated in `WEBTESTCLIENT` test mode: + + [source,java,indent=0] +---- +@Test + public void validate_shouldRejectABeerIfTooYoung() throws Exception { + // given: + WebTestClientRequestSpecification request = given() + .header("Content-Type", "application/json") + .body("{\"age\":10}"); + + // when: + WebTestClientResponse response = given().spec(request) + .post("/check"); + + // then: + assertThat(response.statusCode()).isEqualTo(200); + assertThat(response.header("Content-Type")).matches("application/json.*"); + // and: + DocumentContext parsedJson = JsonPath.parse(response.getBody().asString()); + assertThatJson(parsedJson).field("['status']").isEqualTo("NOT_OK"); + } +---- + Apart from the default JUnit 4, you can instead use JUnit 5 or Spock tests, by setting the plugin `testFramework` property to either `JUNIT5` or `Spock`. diff --git a/docs/src/main/asciidoc/verifier_setup.adoc b/docs/src/main/asciidoc/verifier_setup.adoc index ef7f7ce63d..b88a36a30f 100644 --- a/docs/src/main/asciidoc/verifier_setup.adoc +++ b/docs/src/main/asciidoc/verifier_setup.adoc @@ -217,7 +217,7 @@ contracts { ==== Configuration Options * *testMode*: Defines the mode for acceptance tests. By default, the mode is MockMvc, -which is based on Spring's MockMvc. It can also be changed to *JaxRsClient* or to +which is based on Spring's MockMvc. It can also be changed to *WebTestClient*, *JaxRsClient* or to *Explicit* for real HTTP calls. * *imports*: Creates an array with imports that should be included in generated tests (for example ['org.myorg.Matchers']). By default, it creates an empty array. @@ -569,7 +569,7 @@ definition or the `execution` definition, as shown here: ==== Configuration Options * *testMode*: Defines the mode for acceptance tests. By default, the mode is MockMvc, -which is based on Spring's MockMvc. It can also be changed to *JaxRsClient* or to +which is based on Spring's MockMvc. It can also be changed to *WebTestClient*, *JaxRsClient* or to *Explicit* for real HTTP calls. * *basePackageForTests*: Specifies the base package for all generated tests. If not set, the value is picked from `baseClassForTests`'s package and from `packageWithBaseClasses`. diff --git a/spring-cloud-contract-dependencies/pom.xml b/spring-cloud-contract-dependencies/pom.xml index 2b67e2b8af..12314a7c67 100644 --- a/spring-cloud-contract-dependencies/pom.xml +++ b/spring-cloud-contract-dependencies/pom.xml @@ -17,7 +17,7 @@ 2.19.0 0.4.13 1.0.2.v20150114 - 3.0.7 + 3.2.0 @@ -115,6 +115,21 @@ + + io.rest-assured + spring-web-test-client + ${rest-assured.version} + + + spring-context + org.springframework + + + spring-webflux + org.springframework + + + io.rest-assured rest-assured diff --git a/spring-cloud-contract-verifier/pom.xml b/spring-cloud-contract-verifier/pom.xml index 87fb766bdd..2773b5f414 100644 --- a/spring-cloud-contract-verifier/pom.xml +++ b/spring-cloud-contract-verifier/pom.xml @@ -133,6 +133,16 @@ spring-mock-mvc test + + io.rest-assured + spring-web-test-client + test + + + org.springframework + spring-webflux + test + org.junit.jupiter junit-jupiter-api diff --git a/spring-cloud-contract-verifier/src/main/groovy/org/springframework/cloud/contract/verifier/builder/MockMvcSpockMethodRequestProcessingBodyBuilder.groovy b/spring-cloud-contract-verifier/src/main/groovy/org/springframework/cloud/contract/verifier/builder/HttpSpockMethodRequestProcessingBodyBuilder.groovy similarity index 95% rename from spring-cloud-contract-verifier/src/main/groovy/org/springframework/cloud/contract/verifier/builder/MockMvcSpockMethodRequestProcessingBodyBuilder.groovy rename to spring-cloud-contract-verifier/src/main/groovy/org/springframework/cloud/contract/verifier/builder/HttpSpockMethodRequestProcessingBodyBuilder.groovy index 45f475d49e..ef7709e928 100644 --- a/spring-cloud-contract-verifier/src/main/groovy/org/springframework/cloud/contract/verifier/builder/MockMvcSpockMethodRequestProcessingBodyBuilder.groovy +++ b/spring-cloud-contract-verifier/src/main/groovy/org/springframework/cloud/contract/verifier/builder/HttpSpockMethodRequestProcessingBodyBuilder.groovy @@ -34,9 +34,9 @@ import java.util.regex.Pattern */ @PackageScope @TypeChecked -class MockMvcSpockMethodRequestProcessingBodyBuilder extends SpockMethodRequestProcessingBodyBuilder { +class HttpSpockMethodRequestProcessingBodyBuilder extends SpockMethodRequestProcessingBodyBuilder { - MockMvcSpockMethodRequestProcessingBodyBuilder(Contract stubDefinition, ContractVerifierConfigProperties configProperties) { + HttpSpockMethodRequestProcessingBodyBuilder(Contract stubDefinition, ContractVerifierConfigProperties configProperties) { super(stubDefinition, configProperties) } diff --git a/spring-cloud-contract-verifier/src/main/groovy/org/springframework/cloud/contract/verifier/builder/JavaTestGenerator.groovy b/spring-cloud-contract-verifier/src/main/groovy/org/springframework/cloud/contract/verifier/builder/JavaTestGenerator.groovy index b6c09026c6..cee3ab8c52 100644 --- a/spring-cloud-contract-verifier/src/main/groovy/org/springframework/cloud/contract/verifier/builder/JavaTestGenerator.groovy +++ b/spring-cloud-contract-verifier/src/main/groovy/org/springframework/cloud/contract/verifier/builder/JavaTestGenerator.groovy @@ -117,6 +117,7 @@ class JavaTestGenerator implements SingleTestGenerator { clazz.addStaticImports(httpImportProvider.getStaticImports(configProperties.targetFramework, configProperties.testMode)) } + // TODO for 2.2: leave only RestAssured 3 private String getRestAssuredPackage() { boolean restAssured2Present = this.checker.isClassPresent(REST_ASSURED_2_0_CLASS) String restAssuredPackage = restAssured2Present ? 'com.jayway.restassured' : 'io.restassured' diff --git a/spring-cloud-contract-verifier/src/main/groovy/org/springframework/cloud/contract/verifier/builder/MethodBuilder.groovy b/spring-cloud-contract-verifier/src/main/groovy/org/springframework/cloud/contract/verifier/builder/MethodBuilder.groovy index 3f01da3c32..267076832b 100644 --- a/spring-cloud-contract-verifier/src/main/groovy/org/springframework/cloud/contract/verifier/builder/MethodBuilder.groovy +++ b/spring-cloud-contract-verifier/src/main/groovy/org/springframework/cloud/contract/verifier/builder/MethodBuilder.groovy @@ -19,7 +19,6 @@ package org.springframework.cloud.contract.verifier.builder import groovy.transform.CompileStatic import groovy.transform.PackageScope import groovy.util.logging.Commons - import org.springframework.cloud.contract.spec.Contract import org.springframework.cloud.contract.verifier.config.ContractVerifierConfigProperties import org.springframework.cloud.contract.verifier.config.TestMode @@ -118,14 +117,19 @@ class MethodBuilder { return new JaxRsClientJUnitMethodBodyBuilder(stubContent, configProperties) } return new JaxRsClientSpockMethodRequestProcessingBodyBuilder(stubContent, configProperties) + } else if (configProperties.testMode == TestMode.WEBTESTCLIENT) { + if (isJUnitType()) { + return new WebTestClientJUnitMethodBodyBuilder(stubContent, configProperties) + } + return new HttpSpockMethodRequestProcessingBodyBuilder(stubContent, configProperties) } else if (configProperties.testMode == TestMode.EXPLICIT) { if (isJUnitType()) { return new ExplicitJUnitMethodBodyBuilder(stubContent, configProperties) } // in Groovy we're using def so we don't have to update the imports - return new MockMvcSpockMethodRequestProcessingBodyBuilder(stubContent, configProperties) + return new HttpSpockMethodRequestProcessingBodyBuilder(stubContent, configProperties) } else if (configProperties.targetFramework == SPOCK) { - return new MockMvcSpockMethodRequestProcessingBodyBuilder(stubContent, configProperties) + return new HttpSpockMethodRequestProcessingBodyBuilder(stubContent, configProperties) } return new MockMvcJUnitMethodBodyBuilder(stubContent, configProperties) } diff --git a/spring-cloud-contract-verifier/src/main/groovy/org/springframework/cloud/contract/verifier/builder/MockMvcJUnitMethodBodyBuilder.groovy b/spring-cloud-contract-verifier/src/main/groovy/org/springframework/cloud/contract/verifier/builder/MockMvcJUnitMethodBodyBuilder.groovy index fc015a92ef..63d631fe61 100644 --- a/spring-cloud-contract-verifier/src/main/groovy/org/springframework/cloud/contract/verifier/builder/MockMvcJUnitMethodBodyBuilder.groovy +++ b/spring-cloud-contract-verifier/src/main/groovy/org/springframework/cloud/contract/verifier/builder/MockMvcJUnitMethodBodyBuilder.groovy @@ -16,8 +16,8 @@ package org.springframework.cloud.contract.verifier.builder +import groovy.transform.CompileStatic import groovy.transform.PackageScope -import groovy.transform.TypeChecked import org.springframework.cloud.contract.spec.Contract import org.springframework.cloud.contract.verifier.config.ContractVerifierConfigProperties @@ -28,7 +28,7 @@ import org.springframework.cloud.contract.verifier.config.ContractVerifierConfig * * @since 1.0.0 */ -@TypeChecked +@CompileStatic @PackageScope class MockMvcJUnitMethodBodyBuilder extends RestAssuredJUnitMethodBodyBuilder { @@ -38,12 +38,12 @@ class MockMvcJUnitMethodBodyBuilder extends RestAssuredJUnitMethodBodyBuilder { @Override protected String returnedResponseType() { - return "ResponseOptions" + return 'ResponseOptions' } @Override protected String returnedRequestType() { - return "MockMvcRequestSpecification" + return 'MockMvcRequestSpecification' } } diff --git a/spring-cloud-contract-verifier/src/main/groovy/org/springframework/cloud/contract/verifier/builder/WebTestClientJUnitMethodBodyBuilder.groovy b/spring-cloud-contract-verifier/src/main/groovy/org/springframework/cloud/contract/verifier/builder/WebTestClientJUnitMethodBodyBuilder.groovy new file mode 100644 index 0000000000..ff2e714ced --- /dev/null +++ b/spring-cloud-contract-verifier/src/main/groovy/org/springframework/cloud/contract/verifier/builder/WebTestClientJUnitMethodBodyBuilder.groovy @@ -0,0 +1,45 @@ +package org.springframework.cloud.contract.verifier.builder + +import groovy.transform.CompileStatic +import groovy.transform.PackageScope +import org.springframework.cloud.contract.spec.Contract +import org.springframework.cloud.contract.spec.internal.Url +import org.springframework.cloud.contract.verifier.config.ContractVerifierConfigProperties + +/** + * A {@link JUnitMethodBodyBuilder} implementation that uses WebTestClient to send requests. + * + * @author Olga Maciaszek-Sharma + * + * @since 2.1.0 + */ +@CompileStatic +@PackageScope +class WebTestClientJUnitMethodBodyBuilder extends RestAssuredJUnitMethodBodyBuilder { + + WebTestClientJUnitMethodBodyBuilder(Contract stubDefinition, ContractVerifierConfigProperties configProperties) { + super(stubDefinition, configProperties) + } + + @Override + protected String returnedResponseType() { + return 'WebTestClientResponse' + } + + @Override + protected String returnedRequestType() { + return 'WebTestClientRequestSpecification' + } + + @Override + protected void when(BlockBuilder bb) { + bb.addLine(getInputString(request)) + bb.indent() + + Url url = getUrl(request) + addQueryParameters(url, bb) + addUrl(url, bb) + addColonIfRequired(bb) + bb.unindent() + } +} diff --git a/spring-cloud-contract-verifier/src/main/groovy/org/springframework/cloud/contract/verifier/builder/imports/HttpImportProvider.groovy b/spring-cloud-contract-verifier/src/main/groovy/org/springframework/cloud/contract/verifier/builder/imports/HttpImportProvider.groovy index 879f204303..2a5002e592 100644 --- a/spring-cloud-contract-verifier/src/main/groovy/org/springframework/cloud/contract/verifier/builder/imports/HttpImportProvider.groovy +++ b/spring-cloud-contract-verifier/src/main/groovy/org/springframework/cloud/contract/verifier/builder/imports/HttpImportProvider.groovy @@ -10,6 +10,7 @@ import static org.springframework.cloud.contract.verifier.config.TestFramework.S import static org.springframework.cloud.contract.verifier.config.TestMode.EXPLICIT import static org.springframework.cloud.contract.verifier.config.TestMode.JAXRSCLIENT import static org.springframework.cloud.contract.verifier.config.TestMode.MOCKMVC +import static org.springframework.cloud.contract.verifier.config.TestMode.WEBTESTCLIENT /** * Provides imports based on test framework and test mode. @@ -21,29 +22,38 @@ import static org.springframework.cloud.contract.verifier.config.TestMode.MOCKMV class HttpImportProvider { private final Map TEST_MODE_SPECIFIC_IMPORTS = [ - (JAXRSCLIENT): new ImportDefinitions([], ['javax.ws.rs.client.Entity.*']), - (MOCKMVC) : new ImportDefinitions([], ["${restAssuredPackage}.module.mockmvc.RestAssuredMockMvc.*"]), - (EXPLICIT) : new ImportDefinitions([], ["${restAssuredPackage}.RestAssured.*"])] + (JAXRSCLIENT) : new ImportDefinitions([], ['javax.ws.rs.client.Entity.*']), + (MOCKMVC) : new ImportDefinitions([], ["${restAssuredPackage}.module.mockmvc.RestAssuredMockMvc.*"]), + (EXPLICIT) : new ImportDefinitions([], ["${restAssuredPackage}.RestAssured.*"]), + (WEBTESTCLIENT): new ImportDefinitions([], ['io.restassured.module.webtestclient.RestAssuredWebTestClient.*'])] private final Map, ImportDefinitions> FRAMEWORK_AND_TEST_MODE_SPECIFIC_IMPORTS = [ - (new Tuple2(JUNIT, JAXRSCLIENT)) : new ImportDefinitions(['javax.ws.rs.core.Response']), - (new Tuple2(JUNIT5, JAXRSCLIENT)): new ImportDefinitions(['javax.ws.rs.core.Response']), - (new Tuple2(JUNIT, MOCKMVC)) : new ImportDefinitions([ + (new Tuple2(JUNIT, JAXRSCLIENT)) : new ImportDefinitions(['javax.ws.rs.core.Response']), + (new Tuple2(JUNIT5, JAXRSCLIENT)) : new ImportDefinitions(['javax.ws.rs.core.Response']), + (new Tuple2(JUNIT, MOCKMVC)) : new ImportDefinitions([ "${restAssuredPackage}.module.mockmvc.specification.MockMvcRequestSpecification", "${restAssuredPackage}.response.ResponseOptions"]), - (new Tuple2(JUNIT5, MOCKMVC)) : new ImportDefinitions([ + (new Tuple2(JUNIT, WEBTESTCLIENT)) : new ImportDefinitions([ + 'io.restassured.module.webtestclient.specification.WebTestClientRequestSpecification', + 'io.restassured.module.webtestclient.response.WebTestClientResponse']), + (new Tuple2(JUNIT5, MOCKMVC)) : new ImportDefinitions([ "${restAssuredPackage}.module.mockmvc.specification.MockMvcRequestSpecification", "${restAssuredPackage}.response.ResponseOptions"]), - (new Tuple2(JUNIT, EXPLICIT)) : new ImportDefinitions(["${restAssuredPackage}.specification.RequestSpecification", + (new Tuple2(JUNIT5, WEBTESTCLIENT)): new ImportDefinitions([ + 'io.restassured.module.webtestclient.specification.WebTestClientRequestSpecification', + 'io.restassured.module.webtestclient.response.WebTestClientResponse']), + (new Tuple2(JUNIT, EXPLICIT)) : new ImportDefinitions(["${restAssuredPackage}.specification.RequestSpecification", "${restAssuredPackage}.response.Response"]), - (new Tuple2(JUNIT5, EXPLICIT)) : new ImportDefinitions(["${restAssuredPackage}.specification.RequestSpecification", - "${restAssuredPackage}.response.Response"]), - (new Tuple2(SPOCK, JAXRSCLIENT)) : new ImportDefinitions([]), - (new Tuple2(CUSTOM, JAXRSCLIENT)): new ImportDefinitions([]), - (new Tuple2(SPOCK, MOCKMVC)) : new ImportDefinitions([]), - (new Tuple2(CUSTOM, MOCKMVC)) : new ImportDefinitions([]), - (new Tuple2(SPOCK, EXPLICIT)) : new ImportDefinitions([]), - (new Tuple2(CUSTOM, EXPLICIT)) : new ImportDefinitions([]) + (new Tuple2(JUNIT5, EXPLICIT)) : new ImportDefinitions(["${restAssuredPackage}.specification.RequestSpecification", + "${restAssuredPackage}.response.Response"]), + (new Tuple2(SPOCK, JAXRSCLIENT)) : new ImportDefinitions([]), + (new Tuple2(CUSTOM, JAXRSCLIENT)) : new ImportDefinitions([]), + (new Tuple2(SPOCK, MOCKMVC)) : new ImportDefinitions([]), + (new Tuple2(CUSTOM, MOCKMVC)) : new ImportDefinitions([]), + (new Tuple2(SPOCK, EXPLICIT)) : new ImportDefinitions([]), + (new Tuple2(CUSTOM, EXPLICIT)) : new ImportDefinitions([]), + (new Tuple2(SPOCK, WEBTESTCLIENT)) : new ImportDefinitions([]), + (new Tuple2(CUSTOM, WEBTESTCLIENT)): new ImportDefinitions([]) ] private final String restAssuredPackage diff --git a/spring-cloud-contract-verifier/src/main/groovy/org/springframework/cloud/contract/verifier/config/TestMode.groovy b/spring-cloud-contract-verifier/src/main/groovy/org/springframework/cloud/contract/verifier/config/TestMode.groovy index ab303b95f4..861a98432a 100644 --- a/spring-cloud-contract-verifier/src/main/groovy/org/springframework/cloud/contract/verifier/config/TestMode.groovy +++ b/spring-cloud-contract-verifier/src/main/groovy/org/springframework/cloud/contract/verifier/config/TestMode.groovy @@ -37,5 +37,10 @@ enum TestMode { /** * Uses JAX-RS client */ - JAXRSCLIENT + JAXRSCLIENT, + + /** + * Uses Spring's reactive WebTestClient + */ + WEBTESTCLIENT } \ No newline at end of file diff --git a/spring-cloud-contract-verifier/src/test/groovy/org/springframework/cloud/contract/verifier/builder/ContractHttpDocsSpec.groovy b/spring-cloud-contract-verifier/src/test/groovy/org/springframework/cloud/contract/verifier/builder/ContractHttpDocsSpec.groovy index ff54143e7b..004b51333a 100644 --- a/spring-cloud-contract-verifier/src/test/groovy/org/springframework/cloud/contract/verifier/builder/ContractHttpDocsSpec.groovy +++ b/spring-cloud-contract-verifier/src/test/groovy/org/springframework/cloud/contract/verifier/builder/ContractHttpDocsSpec.groovy @@ -282,7 +282,7 @@ class ContractHttpDocsSpec extends Specification { def 'should convert dsl with optionals to proper Spock test'() { given: BlockBuilder blockBuilder = new BlockBuilder(" ") - new MockMvcSpockMethodRequestProcessingBodyBuilder(optionals, properties).appendTo(blockBuilder) + new HttpSpockMethodRequestProcessingBodyBuilder(optionals, properties).appendTo(blockBuilder) expect: String expectedTest = // tag::optionals_test[] diff --git a/spring-cloud-contract-verifier/src/test/groovy/org/springframework/cloud/contract/verifier/builder/JaxRsClientMethodBuilderSpec.groovy b/spring-cloud-contract-verifier/src/test/groovy/org/springframework/cloud/contract/verifier/builder/JaxRsClientMethodBuilderSpec.groovy index b94301dcca..30e57fa29a 100644 --- a/spring-cloud-contract-verifier/src/test/groovy/org/springframework/cloud/contract/verifier/builder/JaxRsClientMethodBuilderSpec.groovy +++ b/spring-cloud-contract-verifier/src/test/groovy/org/springframework/cloud/contract/verifier/builder/JaxRsClientMethodBuilderSpec.groovy @@ -845,7 +845,7 @@ class JaxRsClientMethodBuilderSpec extends Specification implements WireMockStub and: stubMappingIsValidWireMockStub(contractDsl) and: - SyntaxChecker.tryToCompileJava(blockBuilder.toString()) + SyntaxChecker.tryToCompileJava(JaxRsClientJUnitMethodBodyBuilder.simpleName, blockBuilder.toString()) } @Issue('#85') @@ -974,7 +974,7 @@ class JaxRsClientMethodBuilderSpec extends Specification implements WireMockStub then: test.contains("assertThat(responseBody).matches(\".*\");") and: - SyntaxChecker.tryToCompileJava(blockBuilder.toString()) + SyntaxChecker.tryToCompileJava(JaxRsClientJUnitMethodBodyBuilder.simpleName, blockBuilder.toString()) } @Issue('#150') @@ -999,7 +999,7 @@ class JaxRsClientMethodBuilderSpec extends Specification implements WireMockStub then: test.contains("responseBody ==~ java.util.regex.Pattern.compile('.*')") and: - SyntaxChecker.tryToCompileGroovy(blockBuilder.toString()) + SyntaxChecker.tryToCompileGroovy(JaxRsClientJUnitMethodBodyBuilder.simpleName, blockBuilder.toString()) } @Issue('#150') @@ -1048,7 +1048,7 @@ class JaxRsClientMethodBuilderSpec extends Specification implements WireMockStub test.contains("foo(responseBody)") and: // no static compilation due to bug in Groovy https://issues.apache.org/jira/browse/GROOVY-8055 - SyntaxChecker.tryToCompileGroovy(blockBuilder.toString(), false) + SyntaxChecker.tryToCompileGroovy(JaxRsClientJUnitMethodBodyBuilder.simpleName, blockBuilder.toString(), false) } def "should allow c/p version of consumer producer"() { diff --git a/spring-cloud-contract-verifier/src/test/groovy/org/springframework/cloud/contract/verifier/builder/MethodBodyBuilderSpec.groovy b/spring-cloud-contract-verifier/src/test/groovy/org/springframework/cloud/contract/verifier/builder/MethodBodyBuilderSpec.groovy index 525e3d9746..fd2b37d0bd 100644 --- a/spring-cloud-contract-verifier/src/test/groovy/org/springframework/cloud/contract/verifier/builder/MethodBodyBuilderSpec.groovy +++ b/spring-cloud-contract-verifier/src/test/groovy/org/springframework/cloud/contract/verifier/builder/MethodBodyBuilderSpec.groovy @@ -30,524 +30,538 @@ import java.lang.reflect.InvocationTargetException class MethodBodyBuilderSpec extends Specification implements WireMockStubVerifier { - @Rule OutputCapture capture = new OutputCapture() + @Rule + OutputCapture capture = new OutputCapture() - @Shared ContractVerifierConfigProperties properties = new ContractVerifierConfigProperties( - assertJsonSize: true - ) + @Shared + ContractVerifierConfigProperties properties = new ContractVerifierConfigProperties( + assertJsonSize: true + ) - @Issue('#251') - def "should work with execute and arrays [#methodBuilderName]"() { - given: - Contract contractDsl = Contract.make { - request { - method 'GET' - urlPath '/foo' - headers { - accept(applicationJson()) - contentType(applicationJson()) - } - } - response { - status OK() - body ([ - myArray:[ - [ - notABugGeneratedHere: $(c("foo"), p(execute('assertThat((String)$it).isEqualTo("foo")'))), - anotherArrayNeededForBug:[ - [ - optionalNotEmpty: $(c("foo"), p(execute('assertThat((String)$it).isEqualTo("12")'))) - ] - ], - yetAnotherArrayNeededForBug:[ - [ - optionalNotEmpty: $(c("foo"), p(execute('assertThat((String)$it).isEqualTo("22")'))) - ] - ] - ], - [ - anotherArrayNeededForBug2:[ - [ - optionalNotEmpty: $(c("foo"), p(execute('assertThat((String)$it).isEqualTo("122")'))) - ] - ] - ], - ] - ]) - headers { - contentType(applicationJson()) - } - } - } - MethodBodyBuilder builder = methodBuilder(contractDsl) - BlockBuilder blockBuilder = new BlockBuilder(" ") - when: - builder.appendTo(blockBuilder) - def test = blockBuilder.toString() - then: - test.contains('$.myArray.[0].anotherArrayNeededForBug.[0].optionalNotEmpty') - !test.contains('cursor') - !test.contains('REGEXP>>') - and: - SyntaxChecker.tryToCompile(methodBuilderName, blockBuilder.toString()) - and: - String jsonSample = '''\ + @Issue('#251') + def 'should work with execute and arrays [#methodBuilderName]'() { + given: + Contract contractDsl = Contract.make { + request { + method 'GET' + urlPath '/foo' + headers { + accept(applicationJson()) + contentType(applicationJson()) + } + } + response { + status OK() + body([ + myArray: [ + [ + notABugGeneratedHere : $(c('foo'), p(execute('assertThat((String)$it).isEqualTo("foo")'))), + anotherArrayNeededForBug : [ + [ + optionalNotEmpty: $(c('foo'), p(execute('assertThat((String)$it).isEqualTo("12")'))) + ] + ], + yetAnotherArrayNeededForBug: [ + [ + optionalNotEmpty: $(c('foo'), p(execute('assertThat((String)$it).isEqualTo("22")'))) + ] + ] + ], + [ + anotherArrayNeededForBug2: [ + [ + optionalNotEmpty: $(c('foo'), p(execute('assertThat((String)$it).isEqualTo("122")'))) + ] + ] + ], + ] + ]) + headers { + contentType(applicationJson()) + } + } + } + MethodBodyBuilder builder = methodBuilder(contractDsl) + BlockBuilder blockBuilder = new BlockBuilder(" ") + when: + builder.appendTo(blockBuilder) + def test = blockBuilder.toString() + then: + test.contains('$.myArray.[0].anotherArrayNeededForBug.[0].optionalNotEmpty') + !test.contains('cursor') + !test.contains('REGEXP>>') + and: + SyntaxChecker.tryToCompile(methodBuilderName, blockBuilder.toString()) + and: + String jsonSample = '''\ String json = "{\\"myArray\\":[{\\"notABugGeneratedHere\\":\\"foo\\",\\"anotherArrayNeededForBug\\":[{\\"optionalNotEmpty\\":\\"12\\"}],\\"yetAnotherArrayNeededForBug\\":[{\\"optionalNotEmpty\\":\\"22\\"}]},{\\"anotherArrayNeededForBug2\\":[{\\"optionalNotEmpty\\":\\"122\\"}]}]}"; DocumentContext parsedJson = JsonPath.parse(json); ''' - and: - LinkedList lines = [] as LinkedList - test.eachLine { if (it.contains("assertThatJson") || it.contains("assertThat((String")) lines << it else it } - lines.addFirst(jsonSample) - SyntaxChecker.tryToRun(methodBuilderName, lines.join("\n")) - where: - methodBuilderName | methodBuilder - "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) } - } + and: + LinkedList lines = [] as LinkedList + test.eachLine { if (it.contains("assertThatJson") || it.contains("assertThat((String")) lines << it else it } + lines.addFirst(jsonSample) + SyntaxChecker.tryToRun(methodBuilderName, lines.join("\n")) + where: + methodBuilderName | methodBuilder + HttpSpockMethodRequestProcessingBodyBuilder.simpleName | { Contract dsl -> new HttpSpockMethodRequestProcessingBodyBuilder(dsl, properties) } + MockMvcJUnitMethodBodyBuilder.simpleName | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl, properties) } + JaxRsClientSpockMethodRequestProcessingBodyBuilder.simpleName | { Contract dsl -> new JaxRsClientSpockMethodRequestProcessingBodyBuilder(dsl, properties) } + JaxRsClientJUnitMethodBodyBuilder.simpleName | { Contract dsl -> new JaxRsClientJUnitMethodBodyBuilder(dsl, properties) } + WebTestClientJUnitMethodBodyBuilder.simpleName | { Contract dsl -> new WebTestClientJUnitMethodBodyBuilder(dsl, properties) } + } - @Issue('#588') - def "should work patterns in GString [#methodBuilderName]"() { - given: - Contract contractDsl = Contract.make { - request { - method GET() - url("/${regex('\\d+')}") - } - response { - status 200 - body([ - ok: true - ]) - } - } - MethodBodyBuilder builder = methodBuilder(contractDsl) - BlockBuilder blockBuilder = new BlockBuilder(" ") - when: - builder.appendTo(blockBuilder) - def test = blockBuilder.toString() - then: - !test.contains('d+') - !test.contains('REGEXP>>') - and: - SyntaxChecker.tryToCompile(methodBuilderName, blockBuilder.toString()) - where: - methodBuilderName | methodBuilder - "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) } - } + @Issue('#588') + def 'should work patterns in GString [#methodBuilderName]'() { + given: + Contract contractDsl = Contract.make { + request { + method GET() + url("/${regex('\\d+')}") + } + response { + status 200 + body([ + ok: true + ]) + } + } + MethodBodyBuilder builder = methodBuilder(contractDsl) + BlockBuilder blockBuilder = new BlockBuilder(' ') + when: + builder.appendTo(blockBuilder) + def test = blockBuilder.toString() + then: + !test.contains('d+') + !test.contains('REGEXP>>') + and: + SyntaxChecker.tryToCompile(methodBuilderName, blockBuilder.toString()) + where: + methodBuilderName | methodBuilder + HttpSpockMethodRequestProcessingBodyBuilder.simpleName | { Contract dsl -> new HttpSpockMethodRequestProcessingBodyBuilder(dsl, properties) } + MockMvcJUnitMethodBodyBuilder.simpleName | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl, properties) } + JaxRsClientSpockMethodRequestProcessingBodyBuilder.simpleName | { Contract dsl -> new JaxRsClientSpockMethodRequestProcessingBodyBuilder(dsl, properties) } + JaxRsClientJUnitMethodBodyBuilder.simpleName | { Contract dsl -> new JaxRsClientJUnitMethodBodyBuilder(dsl, properties) } + WebTestClientJUnitMethodBodyBuilder.simpleName | { Contract dsl -> new WebTestClientJUnitMethodBodyBuilder(dsl, properties) } + } - @Issue('#521') - def "should always escape generated chars [#methodBuilderName]"() { - expect: - [1..200].each { - Contract contractDsl = Contract.make { - request { - method GET() - urlPath('/v1/users') { - queryParameters { - parameter 'userId': value(regex(nonBlank())) - } - } - } - response { - status 200 - body([ - ok: value(regex(nonBlank())) - ]) - } - } - MethodBodyBuilder builder = methodBuilder(contractDsl) - BlockBuilder blockBuilder = new BlockBuilder(" ") + @Issue('#521') + def 'should always escape generated chars [#methodBuilderName]'() { + expect: + [1..200].each { + Contract contractDsl = Contract.make { + request { + method GET() + urlPath('/v1/users') { + queryParameters { + parameter 'userId': value(regex(nonBlank())) + } + } + } + response { + status 200 + body([ + ok: value(regex(nonBlank())) + ]) + } + } + MethodBodyBuilder builder = methodBuilder(contractDsl) + BlockBuilder blockBuilder = new BlockBuilder(" ") - builder.appendTo(blockBuilder) - def test = blockBuilder.toString() + builder.appendTo(blockBuilder) + def test = blockBuilder.toString() - assert !test.contains('REGEXP>>') - SyntaxChecker.tryToCompile(methodBuilderName, blockBuilder.toString()) - } - where: - methodBuilderName | methodBuilder - "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) } - } + assert !test.contains('REGEXP>>') + SyntaxChecker.tryToCompile(methodBuilderName, blockBuilder.toString()) + } + where: + methodBuilderName | methodBuilder + HttpSpockMethodRequestProcessingBodyBuilder.simpleName | { Contract dsl -> new HttpSpockMethodRequestProcessingBodyBuilder(dsl, properties) } + MockMvcJUnitMethodBodyBuilder.simpleName | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl, properties) } + JaxRsClientSpockMethodRequestProcessingBodyBuilder.simpleName | { Contract dsl -> new JaxRsClientSpockMethodRequestProcessingBodyBuilder(dsl, properties) } + JaxRsClientJUnitMethodBodyBuilder.simpleName | { Contract dsl -> new JaxRsClientJUnitMethodBodyBuilder(dsl, properties) } + WebTestClientJUnitMethodBodyBuilder.simpleName | { Contract dsl -> new WebTestClientJUnitMethodBodyBuilder(dsl, properties) } + } - @Issue('#269') - def "should work with execute and keys with dots [#methodBuilderName]"() { - given: - Contract contractDsl = Contract.make { - request { - method 'GET' - urlPath '/foo' - } - response { - status OK() - body ( - foo: ["my.dotted.response" : $(c('foo'), p(execute('"foo".equals($it)')))] - ) - headers { - contentType(applicationJson()) - } - } - } - MethodBodyBuilder builder = methodBuilder(contractDsl) - BlockBuilder blockBuilder = new BlockBuilder(" ") - when: - builder.appendTo(blockBuilder) - def test = blockBuilder.toString() - then: - test.contains('''$.foo.['my.dotted.response']''') - !test.contains('cursor') - !test.contains('REGEXP>>') - and: - SyntaxChecker.tryToCompile(methodBuilderName, blockBuilder.toString()) - and: - String jsonSample = '''\ + @Issue('#269') + def 'should work with execute and keys with dots [#methodBuilderName]'() { + given: + Contract contractDsl = Contract.make { + request { + method 'GET' + urlPath '/foo' + } + response { + status OK() + body( + foo: ["my.dotted.response": $(c('foo'), p(execute('"foo".equals($it)')))] + ) + headers { + contentType(applicationJson()) + } + } + } + MethodBodyBuilder builder = methodBuilder(contractDsl) + BlockBuilder blockBuilder = new BlockBuilder(" ") + when: + builder.appendTo(blockBuilder) + def test = blockBuilder.toString() + then: + test.contains('''$.foo.['my.dotted.response']''') + !test.contains('cursor') + !test.contains('REGEXP>>') + and: + SyntaxChecker.tryToCompile(methodBuilderName, blockBuilder.toString()) + and: + String jsonSample = '''\ String json = "{\\"foo\\":{\\"my.dotted.response\\":\\"foo\\"}}"; DocumentContext parsedJson = JsonPath.parse(json); ''' - and: - LinkedList lines = [] as LinkedList - test.eachLine { if (it.contains('"foo".equals')) lines << it else it } - lines.addFirst(jsonSample) - SyntaxChecker.tryToRun(methodBuilderName, lines.join("\n")) - where: - methodBuilderName | methodBuilder - "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) } - } + and: + LinkedList lines = [] as LinkedList + test.eachLine { if (it.contains('"foo".equals')) lines << it else it } + lines.addFirst(jsonSample) + SyntaxChecker.tryToRun(methodBuilderName, lines.join("\n")) + where: + methodBuilderName | methodBuilder + HttpSpockMethodRequestProcessingBodyBuilder.simpleName | { Contract dsl -> new HttpSpockMethodRequestProcessingBodyBuilder(dsl, properties) } + MockMvcJUnitMethodBodyBuilder.simpleName | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl, properties) } + JaxRsClientSpockMethodRequestProcessingBodyBuilder.simpleName | { Contract dsl -> new JaxRsClientSpockMethodRequestProcessingBodyBuilder(dsl, properties) } + JaxRsClientJUnitMethodBodyBuilder.simpleName | { Contract dsl -> new JaxRsClientJUnitMethodBodyBuilder(dsl, properties) } + WebTestClientJUnitMethodBodyBuilder.simpleName | { Contract dsl -> new WebTestClientJUnitMethodBodyBuilder(dsl, properties) } + } - @Issue('#289') - def "should fail on nonexistent field [#methodBuilderName]"() { - given: - Contract contractDsl = Contract.make { - request { - method 'GET' - url '/something' - headers { - contentType(applicationJson()) - } - } - response { - status OK() - headers { - contentType(applicationJson()) - } - body([ - doesNotExist: $(p(anyAlphaUnicode()), c("123")) - ]) - } - } - MethodBodyBuilder builder = methodBuilder(contractDsl) - BlockBuilder blockBuilder = new BlockBuilder(" ") - when: - builder.appendTo(blockBuilder) - def test = blockBuilder.toString() - then: - SyntaxChecker.tryToCompile(methodBuilderName, blockBuilder.toString()) - and: - String jsonSample = '''\ + @Issue('#289') + def 'should fail on nonexistent field [#methodBuilderName]'() { + given: + Contract contractDsl = Contract.make { + request { + method 'GET' + url '/something' + headers { + contentType(applicationJson()) + } + } + response { + status OK() + headers { + contentType(applicationJson()) + } + body([ + doesNotExist: $(p(anyAlphaUnicode()), c("123")) + ]) + } + } + MethodBodyBuilder builder = methodBuilder(contractDsl) + BlockBuilder blockBuilder = new BlockBuilder(" ") + when: + builder.appendTo(blockBuilder) + def test = blockBuilder.toString() + then: + SyntaxChecker.tryToCompile(methodBuilderName, blockBuilder.toString()) + and: + String jsonSample = '''\ String json = "{}"; DocumentContext parsedJson = JsonPath.parse(json); ''' - and: - LinkedList lines = [] as LinkedList - test.eachLine { if (it.contains('assertThatJson')) lines << it else it } - lines.addFirst(jsonSample) - try { - SyntaxChecker.tryToRun(methodBuilderName, lines.join("\n")) - } catch (IllegalStateException e) { - assert e.message.contains("Parsed JSON [{}] doesn't match the JSON path") - } catch (InvocationTargetException e1) { - assert e1.cause.message.contains("Parsed JSON [{}] doesn't match the JSON path") - } - where: - methodBuilderName | methodBuilder - "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) } - } + and: + LinkedList lines = [] as LinkedList + test.eachLine { if (it.contains('assertThatJson')) lines << it else it } + lines.addFirst(jsonSample) + try { + SyntaxChecker.tryToRun(methodBuilderName, lines.join("\n")) + } catch (IllegalStateException e) { + assert e.message.contains("Parsed JSON [{}] doesn't match the JSON path") + } catch (InvocationTargetException e1) { + assert e1.cause.message.contains("Parsed JSON [{}] doesn't match the JSON path") + } + where: + methodBuilderName | methodBuilder + HttpSpockMethodRequestProcessingBodyBuilder.simpleName | { Contract dsl -> new HttpSpockMethodRequestProcessingBodyBuilder(dsl, properties) } + MockMvcJUnitMethodBodyBuilder.simpleName | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl, properties) } + JaxRsClientSpockMethodRequestProcessingBodyBuilder.simpleName | { Contract dsl -> new JaxRsClientSpockMethodRequestProcessingBodyBuilder(dsl, properties) } + JaxRsClientJUnitMethodBodyBuilder.simpleName | { Contract dsl -> new JaxRsClientJUnitMethodBodyBuilder(dsl, properties) } + WebTestClientJUnitMethodBodyBuilder.simpleName | { Contract dsl -> new WebTestClientJUnitMethodBodyBuilder(dsl, properties) } + } - @Issue('#313') - def "should allow to use execute in request body [#methodBuilderName]"() { - given: - //tag::body_execute[] - Contract contractDsl = Contract.make { - request { - method 'GET' - url '/something' - body( - $(c("foo"), p(execute("hashCode()"))) - ) - } - response { - status OK() - } - } - //end::body_execute[] - MethodBodyBuilder builder = methodBuilder(contractDsl) - BlockBuilder blockBuilder = new BlockBuilder(" ") - when: - builder.appendTo(blockBuilder) - def test = blockBuilder.toString() - then: - SyntaxChecker.tryToCompile(methodBuilderName, blockBuilder.toString()) - !test.contains("executionCommand") - where: - methodBuilderName | methodBuilder - "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) } - } + @Issue('#313') + def 'should allow to use execute in request body [#methodBuilderName]'() { + given: + //tag::body_execute[] + Contract contractDsl = Contract.make { + request { + method 'GET' + url '/something' + body( + $(c('foo'), p(execute('hashCode()'))) + ) + } + response { + status OK() + } + } + //end::body_execute[] + MethodBodyBuilder builder = methodBuilder(contractDsl) + BlockBuilder blockBuilder = new BlockBuilder(" ") + when: + builder.appendTo(blockBuilder) + def test = blockBuilder.toString() + then: + SyntaxChecker.tryToCompile(methodBuilderName, blockBuilder.toString()) + !test.contains("executionCommand") + where: + methodBuilderName | methodBuilder + HttpSpockMethodRequestProcessingBodyBuilder.simpleName | { Contract dsl -> new HttpSpockMethodRequestProcessingBodyBuilder(dsl, properties) } + MockMvcJUnitMethodBodyBuilder.simpleName | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl, properties) } + JaxRsClientSpockMethodRequestProcessingBodyBuilder.simpleName | { Contract dsl -> new JaxRsClientSpockMethodRequestProcessingBodyBuilder(dsl, properties) } + JaxRsClientJUnitMethodBodyBuilder.simpleName | { Contract dsl -> new JaxRsClientJUnitMethodBodyBuilder(dsl, properties) } + WebTestClientJUnitMethodBodyBuilder.simpleName | { Contract dsl -> new WebTestClientJUnitMethodBodyBuilder(dsl, properties) } + } - @Issue('#318') - def "should assert the response headers properly [#methodBuilderName]"() { - given: - def contractDsl = org.springframework.cloud.contract.spec.Contract.make { - request { - method 'POST' - urlPath '/documents/app_statement_v1' - headers { - contentType(applicationPdf()) - } - body([ - PESEL: "77100604360", - CLIENT_NAME: "STANISLAW STASZIC", - STATEMENT_NUMBER: "00200001/C4/2017/1" - ]) - } - response { - status OK() - headers { - contentType(applicationPdf()) - header('Content-Length': 4) - } + @Issue('#318') + def 'should assert the response headers properly [#methodBuilderName]'() { + given: + def contractDsl = org.springframework.cloud.contract.spec.Contract.make { + request { + method 'POST' + urlPath '/documents/app_statement_v1' + headers { + contentType(applicationPdf()) + } + body([ + PESEL : '77100604360', + CLIENT_NAME : 'STANISLAW STASZIC', + STATEMENT_NUMBER: '00200001/C4/2017/1' + ]) + } + response { + status OK() + headers { + contentType(applicationPdf()) + header('Content-Length': 4) + } - } - } - MethodBodyBuilder builder = methodBuilder(contractDsl) - BlockBuilder blockBuilder = new BlockBuilder(" ") - when: - builder.appendTo(blockBuilder) - def test = blockBuilder.toString() - then: - SyntaxChecker.tryToCompile(methodBuilderName, test) - asserter(test) - where: - methodBuilderName | methodBuilder | asserter - "MockMvcSpockMethodBuilder" | { Contract dsl -> new MockMvcSpockMethodRequestProcessingBodyBuilder(dsl, properties) } | { String testBody -> testBody.contains("response.header('Content-Length') == 4") && testBody.contains("response.header('Content-Type') ==~ java.util.regex.Pattern.compile('application/pdf.*')") } - "MockMvcJUnitMethodBuilder" | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl, properties) } | { String testBody -> testBody.contains('assertThat(response.header("Content-Length")).isEqualTo(4);') && testBody.contains('assertThat(response.header("Content-Type")).matches("application/pdf.*");') } - "JaxRsClientSpockMethodRequestProcessingBodyBuilder" | { Contract dsl -> new JaxRsClientSpockMethodRequestProcessingBodyBuilder(dsl, properties) } | { String testBody -> testBody.contains("response.getHeaderString('Content-Length') == 4") && testBody.contains(" response.getHeaderString('Content-Type') ==~ java.util.regex.Pattern.compile('application/pdf.*')") } - "JaxRsClientJUnitMethodBodyBuilder" | { Contract dsl -> new JaxRsClientJUnitMethodBodyBuilder(dsl, properties) } | { String testBody -> testBody.contains('assertThat(response.getHeaderString("Content-Length")).isEqualTo(4);') && testBody.contains('assertThat(response.getHeaderString("Content-Type")).matches("application/pdf.*");') } - } + } + } + MethodBodyBuilder builder = methodBuilder(contractDsl) + BlockBuilder blockBuilder = new BlockBuilder(" ") + when: + builder.appendTo(blockBuilder) + def test = blockBuilder.toString() + then: + SyntaxChecker.tryToCompile(methodBuilderName, test) + asserter(test) + where: + methodBuilderName | methodBuilder | asserter + HttpSpockMethodRequestProcessingBodyBuilder.simpleName | { Contract dsl -> new HttpSpockMethodRequestProcessingBodyBuilder(dsl, properties) } | { String testBody -> testBody.contains("response.header('Content-Length') == 4") && testBody.contains("response.header('Content-Type') ==~ java.util.regex.Pattern.compile('application/pdf.*')") } + MockMvcJUnitMethodBodyBuilder.simpleName | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl, properties) } | { String testBody -> testBody.contains('assertThat(response.header("Content-Length")).isEqualTo(4);') && testBody.contains('assertThat(response.header("Content-Type")).matches("application/pdf.*");') } + JaxRsClientSpockMethodRequestProcessingBodyBuilder.simpleName | { Contract dsl -> new JaxRsClientSpockMethodRequestProcessingBodyBuilder(dsl, properties) } | { String testBody -> testBody.contains("response.getHeaderString('Content-Length') == 4") && testBody.contains(" response.getHeaderString('Content-Type') ==~ java.util.regex.Pattern.compile('application/pdf.*')") } + JaxRsClientJUnitMethodBodyBuilder.simpleName | { Contract dsl -> new JaxRsClientJUnitMethodBodyBuilder(dsl, properties) } | { String testBody -> testBody.contains('assertThat(response.getHeaderString("Content-Length")).isEqualTo(4);') && testBody.contains('assertThat(response.getHeaderString("Content-Type")).matches("application/pdf.*");') } + WebTestClientJUnitMethodBodyBuilder.simpleName | { Contract dsl -> new WebTestClientJUnitMethodBodyBuilder(dsl, properties) } | { String testBody -> testBody.contains('assertThat(response.header("Content-Length")).isEqualTo(4);') && testBody.contains('assertThat(response.header("Content-Type")).matches("application/pdf.*");') } + } - def "should put L on long values [#methodBuilderName]"() { - given: - Contract contractDsl = Contract.make { - request { - method GET() - url "test" - } - response { - status OK() - body( - "createdAt": 1502766000000, - "updatedAt": 1499476115000 - ) - } - } - MethodBodyBuilder builder = methodBuilder(contractDsl) - BlockBuilder blockBuilder = new BlockBuilder(" ") - when: - builder.appendTo(blockBuilder) - then: - blockBuilder.toString().contains("""assertThatJson(parsedJson).field("['createdAt']").isEqualTo(1502766000000L)""") - blockBuilder.toString().contains("""assertThatJson(parsedJson).field("['updatedAt']").isEqualTo(1499476115000L)""") - and: - SyntaxChecker.tryToCompileWithoutCompileStatic(methodBuilderName, blockBuilder.toString()) - and: - stubMappingIsValidWireMockStub(contractDsl) - where: - methodBuilderName | methodBuilder - "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) } - } + def 'should put L on long values [#methodBuilderName]'() { + given: + Contract contractDsl = Contract.make { + request { + method GET() + url 'test' + } + response { + status OK() + body( + 'createdAt': 1502766000000, + 'updatedAt': 1499476115000 + ) + } + } + MethodBodyBuilder builder = methodBuilder(contractDsl) + BlockBuilder blockBuilder = new BlockBuilder(" ") + when: + builder.appendTo(blockBuilder) + then: + blockBuilder.toString().contains("""assertThatJson(parsedJson).field("['createdAt']").isEqualTo(1502766000000L)""") + blockBuilder.toString().contains("""assertThatJson(parsedJson).field("['updatedAt']").isEqualTo(1499476115000L)""") + and: + SyntaxChecker.tryToCompileWithoutCompileStatic(methodBuilderName, blockBuilder.toString()) + and: + stubMappingIsValidWireMockStub(contractDsl) + where: + methodBuilderName | methodBuilder + HttpSpockMethodRequestProcessingBodyBuilder.simpleName | { Contract dsl -> new HttpSpockMethodRequestProcessingBodyBuilder(dsl, properties) } + MockMvcJUnitMethodBodyBuilder.simpleName | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl, properties) } + JaxRsClientSpockMethodRequestProcessingBodyBuilder.simpleName | { Contract dsl -> new JaxRsClientSpockMethodRequestProcessingBodyBuilder(dsl, properties) } + JaxRsClientJUnitMethodBodyBuilder.simpleName | { Contract dsl -> new JaxRsClientJUnitMethodBodyBuilder(dsl, properties) } + WebTestClientJUnitMethodBodyBuilder.simpleName | { Contract dsl -> new WebTestClientJUnitMethodBodyBuilder(dsl, properties) } + } - @Issue("#424") - def "should not put an absent header to the request [#methodBuilderName]"() { - given: - Contract contractDsl = Contract.make { - request { - method 'GET' - url '/mytest' - headers { - header('myheader', absent()) - } - } - response { - status OK() - } - } - MethodBodyBuilder builder = methodBuilder(contractDsl) - BlockBuilder blockBuilder = new BlockBuilder(" ") - when: - builder.appendTo(blockBuilder) - then: - !blockBuilder.toString().contains("myheader") - and: - SyntaxChecker.tryToCompileWithoutCompileStatic(methodBuilderName, blockBuilder.toString()) - and: - stubMappingIsValidWireMockStub(contractDsl) - where: - methodBuilderName | methodBuilder - "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) } - } + @Issue('#424') + def 'should not put an absent header to the request [#methodBuilderName]'() { + given: + Contract contractDsl = Contract.make { + request { + method 'GET' + url '/mytest' + headers { + header('myheader', absent()) + } + } + response { + status OK() + } + } + MethodBodyBuilder builder = methodBuilder(contractDsl) + BlockBuilder blockBuilder = new BlockBuilder(' ') + when: + builder.appendTo(blockBuilder) + then: + !blockBuilder.toString().contains('myheader') + and: + SyntaxChecker.tryToCompileWithoutCompileStatic(methodBuilderName, blockBuilder.toString()) + and: + stubMappingIsValidWireMockStub(contractDsl) + where: + methodBuilderName | methodBuilder + HttpSpockMethodRequestProcessingBodyBuilder.simpleName | { Contract dsl -> new HttpSpockMethodRequestProcessingBodyBuilder(dsl, properties) } + MockMvcJUnitMethodBodyBuilder.simpleName | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl, properties) } + JaxRsClientSpockMethodRequestProcessingBodyBuilder.simpleName | { Contract dsl -> new JaxRsClientSpockMethodRequestProcessingBodyBuilder(dsl, properties) } + JaxRsClientJUnitMethodBodyBuilder.simpleName | { Contract dsl -> new JaxRsClientJUnitMethodBodyBuilder(dsl, properties) } + WebTestClientJUnitMethodBodyBuilder.simpleName | { Contract dsl -> new WebTestClientJUnitMethodBodyBuilder(dsl, properties) } + } - @Issue("#458") - def "should reference request from body when body is a string [#methodBuilderName]"() { - given: - Contract contractDsl = Contract.make { - request { - method 'GET' - url '/mytest' - body("""{ "name": "My name" }""") - } - response { - status OK() - body fromRequest().body('$.name') - } - } - MethodBodyBuilder builder = methodBuilder(contractDsl) - BlockBuilder blockBuilder = new BlockBuilder(" ") - when: - builder.appendTo(blockBuilder) - then: - String test = blockBuilder.toString() - SyntaxChecker.tryToCompileWithoutCompileStatic(methodBuilderName, test) - responseAsserter(test) - and: - stubMappingIsValidWireMockStub(contractDsl) - where: - methodBuilderName | methodBuilder | responseAsserter - "MockMvcSpockMethodBuilder" | { Contract dsl -> new MockMvcSpockMethodRequestProcessingBodyBuilder(dsl, properties) } | { String string -> string.contains('responseBody == "My name"') } - "MockMvcJUnitMethodBuilder" | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl, properties) } | { String string -> string.contains('assertThat(responseBody).isEqualTo("My name");') } - "JaxRsClientSpockMethodRequestProcessingBodyBuilder" | { Contract dsl -> new JaxRsClientSpockMethodRequestProcessingBodyBuilder(dsl, properties) } | { String string -> string.contains('responseBody == "My name"') } - "JaxRsClientJUnitMethodBodyBuilder" | { Contract dsl -> new JaxRsClientJUnitMethodBodyBuilder(dsl, properties) } | { String string -> string.contains('assertThat(responseBody).isEqualTo("My name");') } - } + @Issue('#458') + def 'should reference request from body when body is a string [#methodBuilderName]'() { + given: + Contract contractDsl = Contract.make { + request { + method 'GET' + url '/mytest' + body("""{ "name": "My name" }""") + } + response { + status OK() + body fromRequest().body('$.name') + } + } + MethodBodyBuilder builder = methodBuilder(contractDsl) + BlockBuilder blockBuilder = new BlockBuilder(' ') + when: + builder.appendTo(blockBuilder) + then: + String test = blockBuilder.toString() + SyntaxChecker.tryToCompileWithoutCompileStatic(methodBuilderName, test) + responseAsserter(test) + and: + stubMappingIsValidWireMockStub(contractDsl) + where: + methodBuilderName | methodBuilder | responseAsserter + HttpSpockMethodRequestProcessingBodyBuilder.simpleName | { Contract dsl -> new HttpSpockMethodRequestProcessingBodyBuilder(dsl, properties) } | { String string -> string.contains('responseBody == "My name"') } + MockMvcJUnitMethodBodyBuilder.simpleName | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl, properties) } | { String string -> string.contains('assertThat(responseBody).isEqualTo("My name");') } + JaxRsClientSpockMethodRequestProcessingBodyBuilder.simpleName | { Contract dsl -> new JaxRsClientSpockMethodRequestProcessingBodyBuilder(dsl, properties) } | { String string -> string.contains('responseBody == "My name"') } + JaxRsClientJUnitMethodBodyBuilder.simpleName | { Contract dsl -> new JaxRsClientJUnitMethodBodyBuilder(dsl, properties) } | { String string -> string.contains('assertThat(responseBody).isEqualTo("My name");') } + WebTestClientJUnitMethodBodyBuilder.simpleName | { Contract dsl -> new WebTestClientJUnitMethodBodyBuilder(dsl, properties) } | { String string -> string.contains('assertThat(responseBody).isEqualTo("My name");') } + } - @Issue("#559") - def "should reference request from body without escaping of non-string [#methodBuilderName]"() { - given: - Contract contractDsl = Contract.make { - request { - method 'GET' - url( '/mytest') { - queryParameters { - parameter("foo", "bar") - parameter("number", 1) - } - } - body("""{ "name": "My name" }""") - } - response { - status OK() - body ( - foo: fromRequest().query("foo"), - number: fromRequest().query("number") - ) - } - } - MethodBodyBuilder builder = methodBuilder(contractDsl) - BlockBuilder blockBuilder = new BlockBuilder(" ") - when: - builder.appendTo(blockBuilder) - then: - String test = blockBuilder.toString() - SyntaxChecker.tryToCompileWithoutCompileStatic(methodBuilderName, test) - test.contains('''assertThatJson(parsedJson).field("['foo']").isEqualTo("bar")''') - test.contains('''assertThatJson(parsedJson).field("['number']").isEqualTo(1)''') - and: - stubMappingIsValidWireMockStub(contractDsl) - where: - methodBuilderName | methodBuilder - "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) } - } + @Issue('#559') + def 'should reference request from body without escaping of non-string [#methodBuilderName]'() { + given: + Contract contractDsl = Contract.make { + request { + method 'GET' + url('/mytest') { + queryParameters { + parameter('foo', 'bar') + parameter('number', 1) + } + } + body("""{ "name": "My name" }""") + } + response { + status OK() + body( + foo: fromRequest().query('foo'), + number: fromRequest().query('number') + ) + } + } + MethodBodyBuilder builder = methodBuilder(contractDsl) + BlockBuilder blockBuilder = new BlockBuilder(" ") + when: + builder.appendTo(blockBuilder) + then: + String test = blockBuilder.toString() + SyntaxChecker.tryToCompileWithoutCompileStatic(methodBuilderName, test) + test.contains('''assertThatJson(parsedJson).field("['foo']").isEqualTo("bar")''') + test.contains('''assertThatJson(parsedJson).field("['number']").isEqualTo(1)''') + and: + stubMappingIsValidWireMockStub(contractDsl) + where: + methodBuilderName | methodBuilder + HttpSpockMethodRequestProcessingBodyBuilder.simpleName | { Contract dsl -> new HttpSpockMethodRequestProcessingBodyBuilder(dsl, properties) } + MockMvcJUnitMethodBodyBuilder.simpleName | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl, properties) } + JaxRsClientSpockMethodRequestProcessingBodyBuilder.simpleName | { Contract dsl -> new JaxRsClientSpockMethodRequestProcessingBodyBuilder(dsl, properties) } + JaxRsClientJUnitMethodBodyBuilder.simpleName | { Contract dsl -> new JaxRsClientJUnitMethodBodyBuilder(dsl, properties) } + WebTestClientJUnitMethodBodyBuilder.simpleName | { Contract dsl -> new WebTestClientJUnitMethodBodyBuilder(dsl, properties) } + } - @Issue("#702") - def "should generate proper type for large numbers [#methodBuilderName]"() { - given: - Contract contractDsl = Contract.make { - request { - method 'PUT' - urlPath '/example/create' - headers { - contentType applicationJson() - } - body( - [ - "name" : $(consumer(~/.+/), producer("string-1")), - "updatedTs" : $(consumer(~/\d{13}/), producer(1531916906000L)), - "isDisabled": $(consumer(regex(anyBoolean())), producer(true)) - ] - ) - } + @Issue('#702') + def 'should generate proper type for large numbers [#methodBuilderName]'() { + given: + Contract contractDsl = Contract.make { + request { + method 'PUT' + urlPath '/example/create' + headers { + contentType applicationJson() + } + body( + [ + "name" : $(consumer(~/.+/), producer('string-1')), + "updatedTs" : $(consumer(~/\d{13}/), producer(1531916906000L)), + "isDisabled": $(consumer(regex(anyBoolean())), producer(true)) + ] + ) + } - response { - status 200 - headers { - contentType applicationJsonUtf8() - } - body( - [ - "id" : $(consumer(2222L), producer(~/\d+/)), - "name" : fromRequest().body("name"), - "updatedTs" : fromRequest().body("updatedTs"), - "isDisabled": fromRequest().body("isDisabled") - ] - ) - } - } - MethodBodyBuilder builder = methodBuilder(contractDsl) - BlockBuilder blockBuilder = new BlockBuilder(" ") - when: - builder.appendTo(blockBuilder) - then: - String test = blockBuilder.toString() - SyntaxChecker.tryToCompileWithoutCompileStatic(methodBuilderName, test) - test.contains('''assertThatJson(parsedJson).field("['updatedTs']").isEqualTo(1531916906000L)''') - and: - stubMappingIsValidWireMockStub(contractDsl) - where: - methodBuilderName | methodBuilder - "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) } - } + response { + status 200 + headers { + contentType applicationJsonUtf8() + } + body( + [ + "id" : $(consumer(2222L), producer(~/\d+/)), + "name" : fromRequest().body('name'), + "updatedTs" : fromRequest().body('updatedTs'), + "isDisabled": fromRequest().body('isDisabled') + ] + ) + } + } + MethodBodyBuilder builder = methodBuilder(contractDsl) + BlockBuilder blockBuilder = new BlockBuilder(" ") + when: + builder.appendTo(blockBuilder) + then: + String test = blockBuilder.toString() + SyntaxChecker.tryToCompileWithoutCompileStatic(methodBuilderName, test) + test.contains('''assertThatJson(parsedJson).field("['updatedTs']").isEqualTo(1531916906000L)''') + and: + stubMappingIsValidWireMockStub(contractDsl) + where: + methodBuilderName | methodBuilder + HttpSpockMethodRequestProcessingBodyBuilder.simpleName | { Contract dsl -> new HttpSpockMethodRequestProcessingBodyBuilder(dsl, properties) } + MockMvcJUnitMethodBodyBuilder.simpleName | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl, properties) } + JaxRsClientSpockMethodRequestProcessingBodyBuilder.simpleName | { Contract dsl -> new JaxRsClientSpockMethodRequestProcessingBodyBuilder(dsl, properties) } + JaxRsClientJUnitMethodBodyBuilder.simpleName | { Contract dsl -> new JaxRsClientJUnitMethodBodyBuilder(dsl, properties) } + WebTestClientJUnitMethodBodyBuilder.simpleName | { Contract dsl -> new WebTestClientJUnitMethodBodyBuilder(dsl, properties) } + } - @Issue("#465") - def "should work for '/' url for [#methodBuilderName]"() { - given: - Contract contractDsl = Contract.make { - description(""" + @Issue('#465') + def "should work for '/' url for [#methodBuilderName]"() { + given: + Contract contractDsl = Contract.make { + description(""" Represents a request to the shouldReturnName service given: @@ -557,296 +571,305 @@ DocumentContext parsedJson = JsonPath.parse(json); then: return Ryan """) - request { - method 'GET' - url '/' - } - response { - status OK() - body("Ryan") - headers { - contentType(textHtml()) - } - } - } - MethodBodyBuilder builder = methodBuilder(contractDsl) - BlockBuilder blockBuilder = new BlockBuilder(" ") - when: - builder.appendTo(blockBuilder) - String test = blockBuilder.toString() - then: - SyntaxChecker.tryToCompileWithoutCompileStatic(methodBuilderName, test) - and: - stubMappingIsValidWireMockStub(contractDsl) - where: - methodBuilderName | methodBuilder - "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) } - } + request { + method 'GET' + url '/' + } + response { + status OK() + body('Ryan') + headers { + contentType(textHtml()) + } + } + } + MethodBodyBuilder builder = methodBuilder(contractDsl) + BlockBuilder blockBuilder = new BlockBuilder(" ") + when: + builder.appendTo(blockBuilder) + String test = blockBuilder.toString() + then: + SyntaxChecker.tryToCompileWithoutCompileStatic(methodBuilderName, test) + and: + stubMappingIsValidWireMockStub(contractDsl) + where: + methodBuilderName | methodBuilder + HttpSpockMethodRequestProcessingBodyBuilder.simpleName | { Contract dsl -> new HttpSpockMethodRequestProcessingBodyBuilder(dsl, properties) } + MockMvcJUnitMethodBodyBuilder.simpleName | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl, properties) } + JaxRsClientSpockMethodRequestProcessingBodyBuilder.simpleName | { Contract dsl -> new JaxRsClientSpockMethodRequestProcessingBodyBuilder(dsl, properties) } + JaxRsClientJUnitMethodBodyBuilder.simpleName | { Contract dsl -> new JaxRsClientJUnitMethodBodyBuilder(dsl, properties) } + WebTestClientJUnitMethodBodyBuilder.simpleName | { Contract dsl -> new WebTestClientJUnitMethodBodyBuilder(dsl, properties) } + } - def "should use fixed delay milliseconds in the generated test [#methodBuilderName]"() { - given: - Contract contractDsl = Contract.make { - request { - method GET() - url "test" - } - response { - status OK() - async() - fixedDelayMilliseconds(10000) - body(a: 'foo') - } - } - MethodBodyBuilder builder = methodBuilder(contractDsl) - BlockBuilder blockBuilder = new BlockBuilder(" ") - when: - builder.appendTo(blockBuilder) - then: - blockBuilder.toString().contains(""".timeout(10000)""") - and: - SyntaxChecker.tryToCompile(methodBuilderName, blockBuilder.toString()) - and: - stubMappingIsValidWireMockStub(contractDsl) - where: - methodBuilderName | methodBuilder - "MockMvcSpockMethodBuilder" | { Contract dsl -> new MockMvcSpockMethodRequestProcessingBodyBuilder(dsl, properties) } - "MockMvcJUnitMethodBuilder" | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl, properties) } - } + def 'should use fixed delay milliseconds in the generated test [#methodBuilderName]'() { + given: + Contract contractDsl = Contract.make { + request { + method GET() + url 'test' + } + response { + status OK() + async() + fixedDelayMilliseconds(10000) + body(a: 'foo') + } + } + MethodBodyBuilder builder = methodBuilder(contractDsl) + BlockBuilder blockBuilder = new BlockBuilder(" ") + when: + builder.appendTo(blockBuilder) + then: + blockBuilder.toString().contains(""".timeout(10000)""") + and: + SyntaxChecker.tryToCompile(methodBuilderName, blockBuilder.toString()) + and: + stubMappingIsValidWireMockStub(contractDsl) + where: + methodBuilderName | methodBuilder + HttpSpockMethodRequestProcessingBodyBuilder.simpleName | { Contract dsl -> new HttpSpockMethodRequestProcessingBodyBuilder(dsl, properties) } + MockMvcJUnitMethodBodyBuilder.simpleName | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl, properties) } + } - @Issue("#493") - def "should not escape a form URL encoded request body [#methodBuilderName]"() { - given: - Contract contractDsl = Contract.make { - request { - method 'POST' - url '/api/form-endpoint' - headers { - header("Content-Type": 'application/x-www-form-urlencoded') - } - body('a=abc&b=123') - } - response { - status OK() - } - } - MethodBodyBuilder builder = methodBuilder(contractDsl) - BlockBuilder blockBuilder = new BlockBuilder(" ") - when: - builder.appendTo(blockBuilder) - then: - String test = blockBuilder.toString() - SyntaxChecker.tryToCompileWithoutCompileStatic(methodBuilderName, test) - !test.contains("a=abc&b=123") - and: - stubMappingIsValidWireMockStub(contractDsl) - where: - methodBuilderName | methodBuilder - "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) } - } + @Issue('#493') + def 'should not escape a form URL encoded request body [#methodBuilderName]'() { + given: + Contract contractDsl = Contract.make { + request { + method 'POST' + url '/api/form-endpoint' + headers { + header("Content-Type": 'application/x-www-form-urlencoded') + } + body('a=abc&b=123') + } + response { + status OK() + } + } + MethodBodyBuilder builder = methodBuilder(contractDsl) + BlockBuilder blockBuilder = new BlockBuilder(' ') + when: + builder.appendTo(blockBuilder) + then: + String test = blockBuilder.toString() + SyntaxChecker.tryToCompileWithoutCompileStatic(methodBuilderName, test) + !test.contains('a=abc&b=123') + and: + stubMappingIsValidWireMockStub(contractDsl) + where: + methodBuilderName | methodBuilder + HttpSpockMethodRequestProcessingBodyBuilder.simpleName | { Contract dsl -> new HttpSpockMethodRequestProcessingBodyBuilder(dsl, properties) } + MockMvcJUnitMethodBodyBuilder.simpleName | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl, properties) } + JaxRsClientSpockMethodRequestProcessingBodyBuilder.simpleName | { Contract dsl -> new JaxRsClientSpockMethodRequestProcessingBodyBuilder(dsl, properties) } + JaxRsClientJUnitMethodBodyBuilder.simpleName | { Contract dsl -> new JaxRsClientJUnitMethodBodyBuilder(dsl, properties) } + WebTestClientJUnitMethodBodyBuilder.simpleName | { Contract dsl -> new WebTestClientJUnitMethodBodyBuilder(dsl, properties) } + } - @Issue("#578") - def "should work for form parameters [#methodBuilderName]"() { - given: - Contract contractDsl = Contract.make { - request { - method POST() - urlPath('/oauth/token') - headers { - header(authorization(), anyNonBlankString()) - header(contentType(), applicationFormUrlencoded()) - header(accept(), applicationJson()) - } - body([ - username : 'user', - password : 'password', - grant_type: 'password' - ]) - } - response { - status 200 - headers { - header(contentType(), applicationJson()) - } - body([ - refresh_token: 'RANDOM_REFRESH_TOKEN', - access_token : 'RANDOM_ACCESS_TOKEN', - token_type : 'bearer', - expires_in : 3600, - scope : ['task'], - user : [ - id : 1, - username: 'user', - name : 'User' - ] - ]) - } - } - MethodBodyBuilder builder = methodBuilder(contractDsl) - BlockBuilder blockBuilder = new BlockBuilder(" ") - when: - builder.appendTo(blockBuilder) - then: - String test = blockBuilder.toString() - SyntaxChecker.tryToCompileWithoutCompileStatic(methodBuilderName, test) - test.contains("username=user&password=password&grant_type=password") - and: - stubMappingIsValidWireMockStub(contractDsl) - where: - methodBuilderName | methodBuilder - "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) } - } + @Issue('#578') + def 'should work for form parameters [#methodBuilderName]'() { + given: + Contract contractDsl = Contract.make { + request { + method POST() + urlPath('/oauth/token') + headers { + header(authorization(), anyNonBlankString()) + header(contentType(), applicationFormUrlencoded()) + header(accept(), applicationJson()) + } + body([ + username : 'user', + password : 'password', + grant_type: 'password' + ]) + } + response { + status 200 + headers { + header(contentType(), applicationJson()) + } + body([ + refresh_token: 'RANDOM_REFRESH_TOKEN', + access_token : 'RANDOM_ACCESS_TOKEN', + token_type : 'bearer', + expires_in : 3600, + scope : ['task'], + user : [ + id : 1, + username: 'user', + name : 'User' + ] + ]) + } + } + MethodBodyBuilder builder = methodBuilder(contractDsl) + BlockBuilder blockBuilder = new BlockBuilder(" ") + when: + builder.appendTo(blockBuilder) + then: + String test = blockBuilder.toString() + SyntaxChecker.tryToCompileWithoutCompileStatic(methodBuilderName, test) + test.contains('username=user&password=password&grant_type=password') + and: + stubMappingIsValidWireMockStub(contractDsl) + where: + methodBuilderName | methodBuilder + HttpSpockMethodRequestProcessingBodyBuilder.simpleName | { Contract dsl -> new HttpSpockMethodRequestProcessingBodyBuilder(dsl, properties) } + MockMvcJUnitMethodBodyBuilder.simpleName | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl, properties) } + JaxRsClientSpockMethodRequestProcessingBodyBuilder.simpleName | { Contract dsl -> new JaxRsClientSpockMethodRequestProcessingBodyBuilder(dsl, properties) } + JaxRsClientJUnitMethodBodyBuilder.simpleName | { Contract dsl -> new JaxRsClientJUnitMethodBodyBuilder(dsl, properties) } + WebTestClientJUnitMethodBodyBuilder.simpleName | { Contract dsl -> new WebTestClientJUnitMethodBodyBuilder(dsl, properties) } + } - @Issue("#493") - def "should not escape a form URL encoded request body another try [#methodBuilderName]"() { - given: - Contract contractDsl = Contract.make { - request { - method POST() - urlPath('/oauth/token') - headers { - header(authorization(), anyNonBlankString()) - header(contentType(), 'application/x-www-form-urlencoded; charset=UTF-8') - header(accept(), anyNonBlankString()) - } - body('username=user&password=password&grant_type=password') - } - response { - status 200 - headers { - header(contentType(), applicationJsonUtf8()) - } - body([ - refresh_token: 'RANDOM_REFRESH_TOKEN', - access_token : 'RANDOM_ACCESS_TOKEN', - token_type : 'bearer', - expires_in : 3600, - scope : ['task'], - user : [ - id : 1, - username: 'user', - name : 'User' - ] - ]) - } - } - MethodBodyBuilder builder = methodBuilder(contractDsl) - BlockBuilder blockBuilder = new BlockBuilder(" ") - when: - builder.appendTo(blockBuilder) - then: - String test = blockBuilder.toString() - SyntaxChecker.tryToCompileWithoutCompileStatic(methodBuilderName, test) - !test.contains("&") - and: - stubMappingIsValidWireMockStub(contractDsl) - where: - methodBuilderName | methodBuilder - "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) } - } + @Issue('#493') + def 'should not escape a form URL encoded request body another try [#methodBuilderName]'() { + given: + Contract contractDsl = Contract.make { + request { + method POST() + urlPath('/oauth/token') + headers { + header(authorization(), anyNonBlankString()) + header(contentType(), 'application/x-www-form-urlencoded; charset=UTF-8') + header(accept(), anyNonBlankString()) + } + body('username=user&password=password&grant_type=password') + } + response { + status 200 + headers { + header(contentType(), applicationJsonUtf8()) + } + body([ + refresh_token: 'RANDOM_REFRESH_TOKEN', + access_token : 'RANDOM_ACCESS_TOKEN', + token_type : 'bearer', + expires_in : 3600, + scope : ['task'], + user : [ + id : 1, + username: 'user', + name : 'User' + ] + ]) + } + } + MethodBodyBuilder builder = methodBuilder(contractDsl) + BlockBuilder blockBuilder = new BlockBuilder(' ') + when: + builder.appendTo(blockBuilder) + then: + String test = blockBuilder.toString() + SyntaxChecker.tryToCompileWithoutCompileStatic(methodBuilderName, test) + !test.contains('&') + and: + stubMappingIsValidWireMockStub(contractDsl) + where: + methodBuilderName | methodBuilder + HttpSpockMethodRequestProcessingBodyBuilder.simpleName | { Contract dsl -> new HttpSpockMethodRequestProcessingBodyBuilder(dsl, properties) } + MockMvcJUnitMethodBodyBuilder.simpleName | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl, properties) } + JaxRsClientSpockMethodRequestProcessingBodyBuilder.simpleName | { Contract dsl -> new JaxRsClientSpockMethodRequestProcessingBodyBuilder(dsl, properties) } + JaxRsClientJUnitMethodBodyBuilder.simpleName | { Contract dsl -> new JaxRsClientJUnitMethodBodyBuilder(dsl, properties) } + WebTestClientJUnitMethodBodyBuilder.simpleName | { Contract dsl -> new WebTestClientJUnitMethodBodyBuilder(dsl, properties) } + } - @Issue("#509") - def "classToCheck() should return class of object"() { - given: - Contract contractDsl = Contract.make { - request { - method 'POST' - url '/api/users' - } - response { - status OK() - } - } - MethodBodyBuilder builder = methodBuilder(contractDsl) - when: - Map map = new LinkedHashMap<>() - Integer number = Integer.valueOf(42) - List list = new ArrayList<>() - Set set = new HashSet<>() - then: - builder.classToCheck(map) == Map.class - and: - builder.classToCheck(number) == Integer.class - and: - builder.classToCheck(list) == List.class - and: - builder.classToCheck(set) == Set.class - where: - methodBuilderName | methodBuilder - "MockMvcSpockMethodBuilder" | { Contract dsl -> new MockMvcSpockMethodRequestProcessingBodyBuilder(dsl, properties) } - } + @Issue('#509') + def 'classToCheck() should return class of object'() { + given: + Contract contractDsl = Contract.make { + request { + method 'POST' + url '/api/users' + } + response { + status OK() + } + } + MethodBodyBuilder builder = methodBuilder(contractDsl) + when: + Map map = new LinkedHashMap<>() + Integer number = Integer.valueOf(42) + List list = new ArrayList<>() + Set set = new HashSet<>() + then: + builder.classToCheck(map) == Map.class + and: + builder.classToCheck(number) == Integer.class + and: + builder.classToCheck(list) == List.class + and: + builder.classToCheck(set) == Set.class + where: + methodBuilderName | methodBuilder + HttpSpockMethodRequestProcessingBodyBuilder.simpleName | { Contract dsl -> new HttpSpockMethodRequestProcessingBodyBuilder(dsl, properties) } + MockMvcJUnitMethodBodyBuilder.simpleName | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl, properties) } + JaxRsClientSpockMethodRequestProcessingBodyBuilder.simpleName | { Contract dsl -> new JaxRsClientSpockMethodRequestProcessingBodyBuilder(dsl, properties) } + JaxRsClientJUnitMethodBodyBuilder.simpleName | { Contract dsl -> new JaxRsClientJUnitMethodBodyBuilder(dsl, properties) } + WebTestClientJUnitMethodBodyBuilder.simpleName | { Contract dsl -> new WebTestClientJUnitMethodBodyBuilder(dsl, properties) } + } - def "should assert null values without matchers [#methodBuilderName]"() { - given: - Contract contractDsl = Contract.make { - request { - method GET() - url "test" - } - response { - status OK() - body([ - nullValue: null - ]) - } - } - MethodBodyBuilder builder = methodBuilder(contractDsl) - BlockBuilder blockBuilder = new BlockBuilder(" ") - when: - builder.appendTo(blockBuilder) - then: - blockBuilder.toString().contains("""assertThatJson(parsedJson).field("['nullValue']").isNull()""") - and: - SyntaxChecker.tryToCompileWithoutCompileStatic(methodBuilderName, blockBuilder.toString()) - and: - stubMappingIsValidWireMockStub(contractDsl) - where: - methodBuilderName | methodBuilder - "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) } - } + def 'should assert null values without matchers [#methodBuilderName]'() { + given: + Contract contractDsl = Contract.make { + request { + method GET() + url 'test' + } + response { + status OK() + body([ + nullValue: null + ]) + } + } + MethodBodyBuilder builder = methodBuilder(contractDsl) + BlockBuilder blockBuilder = new BlockBuilder(" ") + when: + builder.appendTo(blockBuilder) + then: + blockBuilder.toString().contains("""assertThatJson(parsedJson).field("['nullValue']").isNull()""") + and: + SyntaxChecker.tryToCompileWithoutCompileStatic(methodBuilderName, blockBuilder.toString()) + and: + stubMappingIsValidWireMockStub(contractDsl) + where: + methodBuilderName | methodBuilder + HttpSpockMethodRequestProcessingBodyBuilder.simpleName | { Contract dsl -> new HttpSpockMethodRequestProcessingBodyBuilder(dsl, properties) } + MockMvcJUnitMethodBodyBuilder.simpleName | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl, properties) } + JaxRsClientSpockMethodRequestProcessingBodyBuilder.simpleName | { Contract dsl -> new JaxRsClientSpockMethodRequestProcessingBodyBuilder(dsl, properties) } + JaxRsClientJUnitMethodBodyBuilder.simpleName | { Contract dsl -> new JaxRsClientJUnitMethodBodyBuilder(dsl, properties) } + WebTestClientJUnitMethodBodyBuilder.simpleName | { Contract dsl -> new WebTestClientJUnitMethodBodyBuilder(dsl, properties) } + } - def "should not escape a regex pattern when matching raw body value [#methodBuilderName]"() { - def pattern = "\\d+\\w?" - def escapedPattern = "\\\\d+\\\\w?" - - given: - Contract contractDsl = Contract.make { - request { - method 'GET' - url '/api/arbitrary-url' - } - response { - status OK() - body(value(stub("1"), test(regex(pattern)))) - } - } - MethodBodyBuilder builder = methodBuilder(contractDsl) - BlockBuilder blockBuilder = new BlockBuilder(" ") - when: - builder.appendTo(blockBuilder) - then: - String test = blockBuilder.toString() - test.contains(escapedPattern) - where: - methodBuilderName | methodBuilder - "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) } - } + def 'should not escape a regex pattern when matching raw body value [#methodBuilderName]'() { + def pattern = "\\d+\\w?" + def escapedPattern = "\\\\d+\\\\w?" + given: + Contract contractDsl = Contract.make { + request { + method 'GET' + url '/api/arbitrary-url' + } + response { + status OK() + body(value(stub("1"), test(regex(pattern)))) + } + } + MethodBodyBuilder builder = methodBuilder(contractDsl) + BlockBuilder blockBuilder = new BlockBuilder(" ") + when: + builder.appendTo(blockBuilder) + then: + String test = blockBuilder.toString() + test.contains(escapedPattern) + where: + methodBuilderName | methodBuilder + HttpSpockMethodRequestProcessingBodyBuilder.simpleName | { Contract dsl -> new HttpSpockMethodRequestProcessingBodyBuilder(dsl, properties) } + MockMvcJUnitMethodBodyBuilder.simpleName | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl, properties) } + JaxRsClientSpockMethodRequestProcessingBodyBuilder.simpleName | { Contract dsl -> new JaxRsClientSpockMethodRequestProcessingBodyBuilder(dsl, properties) } + JaxRsClientJUnitMethodBodyBuilder.simpleName | { Contract dsl -> new JaxRsClientJUnitMethodBodyBuilder(dsl, properties) } + WebTestClientJUnitMethodBodyBuilder.simpleName | { Contract dsl -> new WebTestClientJUnitMethodBodyBuilder(dsl, properties) } + } } diff --git a/spring-cloud-contract-verifier/src/test/groovy/org/springframework/cloud/contract/verifier/builder/MockMvcMethodBodyBuilderSpec.groovy b/spring-cloud-contract-verifier/src/test/groovy/org/springframework/cloud/contract/verifier/builder/MockMvcMethodBodyBuilderSpec.groovy deleted file mode 100644 index 79a558a0a2..0000000000 --- a/spring-cloud-contract-verifier/src/test/groovy/org/springframework/cloud/contract/verifier/builder/MockMvcMethodBodyBuilderSpec.groovy +++ /dev/null @@ -1,2823 +0,0 @@ -/* - * Copyright 2013-2018 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.contract.verifier.builder - -import java.util.regex.Pattern - -import org.codehaus.groovy.control.MultipleCompilationErrorsException -import org.junit.Rule -import spock.lang.Issue -import spock.lang.Shared -import spock.lang.Specification -import spock.util.environment.RestoreSystemProperties - -import org.springframework.boot.test.rule.OutputCapture -import org.springframework.cloud.contract.spec.Contract -import org.springframework.cloud.contract.verifier.config.ContractVerifierConfigProperties -import org.springframework.cloud.contract.verifier.dsl.WireMockStubVerifier -import org.springframework.cloud.contract.verifier.util.SyntaxChecker -/** - * @author Jakub Kubrynski, codearte.io - * @author Tim Ysewyn - */ -class MockMvcMethodBodyBuilderSpec extends Specification implements WireMockStubVerifier { - - @Rule OutputCapture capture = new OutputCapture() - - @Shared ContractVerifierConfigProperties properties = new ContractVerifierConfigProperties( - assertJsonSize: true - ) - - @Shared - Contract contractDslWithCookiesValue = Contract.make { - request { - method "GET" - url "/foo" - headers { - header 'Accept': 'application/json' - } - cookies { - cookie 'cookie-key': 'cookie-value' - } - } - response { - status 200 - headers { - header 'Content-Type': 'application/json' - } - cookies { - cookie 'cookie-key': 'new-cookie-value' - } - body([status: 'OK']) - } - } - - @Shared - Contract contractDslWithCookiesPattern = Contract.make { - request { - method "GET" - url "/foo" - headers { - header 'Accept': 'application/json' - } - cookies { - cookie 'cookie-key': regex('[A-Za-z]+') - } - } - response { - status 200 - headers { - header 'Content-Type': 'application/json' - } - cookies { - cookie 'cookie-key': regex('[A-Za-z]+') - } - body([status: 'OK']) - } - } - - @Shared - Contract contractDslWithAbsentCookies = Contract.make { - request { - method "GET" - url "/foo" - cookies { - cookie 'cookie-key': absent() - } - } - response { - status 200 - body([status: 'OK']) - } - } - - @Shared - // tag::contract_with_regex[] - Contract dslWithOptionalsInString = Contract.make { - priority 1 - request { - method POST() - url '/users/password' - headers { - contentType(applicationJson()) - } - body( - email: $(consumer(optional(regex(email()))), producer('abc@abc.com')), - callback_url: $(consumer(regex(hostname())), producer('http://partners.com')) - ) - } - response { - status 404 - headers { - contentType(applicationJson()) - } - body( - code: value(consumer("123123"), producer(optional("123123"))), - message: "User not found by email = [${value(producer(regex(email())), consumer('not.existing@user.com'))}]" - ) - } - } - // end::contract_with_regex[] - - @Shared - Contract dslWithOptionals = Contract.make { - priority 1 - request { - method POST() - url '/users/password' - headers { - contentType(applicationJson()) - } - body( - """ { - "email" : "${ - value(consumer(optional(regex(email()))), producer('abc@abc.com')) - }", - "callback_url" : "${ - value(consumer(regex(hostname())), producer('http://partners.com')) - }" - } - """ - ) - } - response { - status 404 - headers { - contentType(applicationJson()) - } - body( - """ { - "code" : "${value(consumer(123123), producer(optional(123123)))}", - "message" : "User not found by email = [${ - value(producer(regex(email())), consumer('not.existing@user.com')) - }]" - } - """ - ) - } - } - - def "should generate assertions for simple response body with #methodBuilderName"() { - given: - Contract contractDsl = Contract.make { - request { - method GET() - url "test" - } - response { - status OK() - body """{ - "property1": "a", - "property2": "b" -}""" - } - } - MethodBodyBuilder builder = methodBuilder(contractDsl) - BlockBuilder blockBuilder = new BlockBuilder(" ") - when: - builder.appendTo(blockBuilder) - then: - blockBuilder.toString().contains("""assertThatJson(parsedJson).field("['property1']").isEqualTo("a")""") - blockBuilder.toString().contains("""assertThatJson(parsedJson).field("['property2']").isEqualTo("b")""") - and: - stubMappingIsValidWireMockStub(contractDsl) - and: - SyntaxChecker.tryToCompile(methodBuilderName, blockBuilder.toString()) - where: - methodBuilderName | methodBuilder - "MockMvcSpockMethodBuilder" | { Contract dsl -> new MockMvcSpockMethodRequestProcessingBodyBuilder(dsl, properties) } - "MockMvcJUnitMethodBuilder" | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl, properties) } - } - - @Issue("#187") - def "should generate assertions for null and boolean values with #methodBuilderName"() { - given: - Contract contractDsl = Contract.make { - request { - method GET() - url "test" - } - response { - status OK() - body """{ - "property1": "true", - "property2": null, - "property3": false -}""" - } - } - MethodBodyBuilder builder = methodBuilder(contractDsl) - BlockBuilder blockBuilder = new BlockBuilder(" ") - when: - builder.appendTo(blockBuilder) - then: - blockBuilder.toString().contains("""assertThatJson(parsedJson).field("['property1']").isEqualTo("true")""") - blockBuilder.toString().contains("""assertThatJson(parsedJson).field("['property2']").isNull()""") - blockBuilder.toString().contains("""assertThatJson(parsedJson).field("['property3']").isEqualTo(false)""") - and: - stubMappingIsValidWireMockStub(contractDsl) - and: - SyntaxChecker.tryToCompile(methodBuilderName, blockBuilder.toString()) - where: - methodBuilderName | methodBuilder - "MockMvcSpockMethodBuilder" | { Contract dsl -> new MockMvcSpockMethodRequestProcessingBodyBuilder(dsl, properties) } - "MockMvcJUnitMethodBuilder" | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl, properties) } - } - - @Issue("#79") - def "should generate assertions for simple response body constructed from map with a list with #methodBuilderName"() { - given: - Contract contractDsl = Contract.make { - request { - method "GET" - url "test" - } - response { - status OK() - body( - property1: 'a', - property2: [ - [a: 'sth'], - [b: 'sthElse'] - ] - ) - } - } - MethodBodyBuilder builder = methodBuilder(contractDsl) - BlockBuilder blockBuilder = new BlockBuilder(" ") - when: - builder.appendTo(blockBuilder) - then: - blockBuilder.toString().contains("""assertThatJson(parsedJson).field("['property1']").isEqualTo("a")""") - blockBuilder.toString().contains("""assertThatJson(parsedJson).array("['property2']").contains("['a']").isEqualTo("sth")""") - blockBuilder.toString().contains("""assertThatJson(parsedJson).array("['property2']").contains("['b']").isEqualTo("sthElse")""") - and: - stubMappingIsValidWireMockStub(contractDsl) - and: - SyntaxChecker.tryToCompile(methodBuilderName, blockBuilder.toString()) - where: - methodBuilderName | methodBuilder - "MockMvcSpockMethodBuilder" | { Contract dsl -> new MockMvcSpockMethodRequestProcessingBodyBuilder(dsl, properties) } - "MockMvcJUnitMethodBuilder" | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl, properties) } - } - - @Issue("#79") - @RestoreSystemProperties - def "should generate assertions for simple response body constructed from map with a list with #methodBuilderName with array size check"() { - given: - System.setProperty('spring.cloud.contract.verifier.assert.size', 'true') - Contract contractDsl = Contract.make { - request { - method "GET" - url "test" - } - response { - status OK() - body( - property1: 'a', - property2: [ - [a: 'sth'], - [b: 'sthElse'] - ] - ) - } - } - MethodBodyBuilder builder = methodBuilder(contractDsl) - BlockBuilder blockBuilder = new BlockBuilder(" ") - when: - builder.appendTo(blockBuilder) - then: - blockBuilder.toString().contains("""assertThatJson(parsedJson).field("['property1']").isEqualTo("a")""") - blockBuilder.toString().contains("""assertThatJson(parsedJson).array("['property2']").contains("['a']").isEqualTo("sth")""") - blockBuilder.toString().contains("""assertThatJson(parsedJson).array("['property2']").hasSize(2)""") - blockBuilder.toString().contains("""assertThatJson(parsedJson).array("['property2']").contains("['b']").isEqualTo("sthElse")""") - and: - stubMappingIsValidWireMockStub(contractDsl) - and: - SyntaxChecker.tryToCompile(methodBuilderName, blockBuilder.toString()) - where: - methodBuilderName | methodBuilder - "MockMvcSpockMethodBuilder" | { Contract dsl -> new MockMvcSpockMethodRequestProcessingBodyBuilder(dsl, properties) } - "MockMvcJUnitMethodBuilder" | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl, properties) } - } - - @Issue("#82") - def "should generate proper request when body constructed from map with a list #methodBuilderName"() { - given: - Contract contractDsl = Contract.make { - request { - method "GET" - url "test" - body( - items: ['HOP'] - ) - } - response { - status OK() - } - } - MethodBodyBuilder builder = methodBuilder(contractDsl) - BlockBuilder blockBuilder = new BlockBuilder(" ") - when: - builder.appendTo(blockBuilder) - then: - blockBuilder.toString().contains(bodyString) - and: - stubMappingIsValidWireMockStub(contractDsl) - and: - SyntaxChecker.tryToCompile(methodBuilderName, blockBuilder.toString()) - where: - methodBuilderName | methodBuilder | bodyString - "MockMvcSpockMethodBuilder" | { Contract dsl -> new MockMvcSpockMethodRequestProcessingBodyBuilder(dsl, properties) } | """.body('''{\"items\":[\"HOP\"]}''')""" - "MockMvcJUnitMethodBuilder" | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl, properties) } | '.body("{\\"items\\":[\\"HOP\\"]}")' - } - - @Issue("#88") - def "should generate proper request when body constructed from GString with #methodBuilderName"() { - given: - Contract contractDsl = Contract.make { - request { - method "GET" - url "test" - body( - "property1=VAL1" - ) - } - response { - status OK() - } - } - MethodBodyBuilder builder = methodBuilder(contractDsl) - BlockBuilder blockBuilder = new BlockBuilder(" ") - when: - builder.appendTo(blockBuilder) - then: - blockBuilder.toString().contains(bodyString) - and: - SyntaxChecker.tryToCompile(methodBuilderName, blockBuilder.toString()) - and: - stubMappingIsValidWireMockStub(contractDsl) - where: - methodBuilderName | methodBuilder | bodyString - "MockMvcSpockMethodBuilder" | { Contract dsl -> new MockMvcSpockMethodRequestProcessingBodyBuilder(dsl, properties) } | """.body('''property1=VAL1''')""" - "MockMvcJUnitMethodBuilder" | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl, properties) } | '.body("property1=VAL1")' - } - - @Issue("185") - def "should generate assertions for a response body containing map with integers as keys with #methodBuilderName"() { - given: - Contract contractDsl = Contract.make { - request { - method "GET" - url "test" - } - response { - status OK() - body( - property: [ - 14: 0.0, - 7 : 0.0 - ] - ) - } - } - MethodBodyBuilder builder = methodBuilder(contractDsl) - BlockBuilder blockBuilder = new BlockBuilder(" ") - when: - builder.appendTo(blockBuilder) - then: - blockBuilder.toString().contains("""assertThatJson(parsedJson).field("['property']").field(7).isEqualTo(0.0)""") - blockBuilder.toString().contains("""assertThatJson(parsedJson).field("['property']").field(14).isEqualTo(0.0)""") - and: - stubMappingIsValidWireMockStub(contractDsl) - and: - SyntaxChecker.tryToCompile(methodBuilderName, blockBuilder.toString()) - where: - methodBuilderName | methodBuilder - "MockMvcSpockMethodBuilder" | { Contract dsl -> new MockMvcSpockMethodRequestProcessingBodyBuilder(dsl, properties) } - "MockMvcJUnitMethodBuilder" | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl, properties) } - } - - def "should generate assertions for array in response body with #methodBuilderName"() { - given: - Contract contractDsl = Contract.make { - request { - method "GET" - url "test" - } - response { - status OK() - body """[ -{ - "property1": "a" -}, -{ - "property2": "b" -}]""" - } - } - MethodBodyBuilder builder = methodBuilder(contractDsl) - BlockBuilder blockBuilder = new BlockBuilder(" ") - when: - builder.appendTo(blockBuilder) - then: - blockBuilder.toString().contains("""assertThatJson(parsedJson).array().contains("['property2']").isEqualTo("b")""") - blockBuilder.toString().contains("""assertThatJson(parsedJson).array().contains("['property1']").isEqualTo("a")""") - and: - stubMappingIsValidWireMockStub(contractDsl) - and: - SyntaxChecker.tryToCompile(methodBuilderName, blockBuilder.toString()) - where: - methodBuilderName | methodBuilder - "MockMvcSpockMethodBuilder" | { Contract dsl -> new MockMvcSpockMethodRequestProcessingBodyBuilder(dsl, properties) } - "MockMvcJUnitMethodBuilder" | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl, properties) } - } - - def "should generate assertions for array inside response body element with #methodBuilderName"() { - given: - Contract contractDsl = Contract.make { - request { - method "GET" - url "test" - } - response { - status OK() - body """{ - "property1": [ - { "property2": "test1"}, - { "property3": "test2"} - ] -}""" - } - } - MethodBodyBuilder builder = methodBuilder(contractDsl) - BlockBuilder blockBuilder = new BlockBuilder(" ") - when: - builder.appendTo(blockBuilder) - then: - blockBuilder.toString().contains("""assertThatJson(parsedJson).array("['property1']").contains("['property2']").isEqualTo("test1")""") - blockBuilder.toString().contains("""assertThatJson(parsedJson).array("['property1']").contains("['property3']").isEqualTo("test2")""") - and: - stubMappingIsValidWireMockStub(contractDsl) - and: - SyntaxChecker.tryToCompile(methodBuilderName, blockBuilder.toString()) - where: - methodBuilderName | methodBuilder - "MockMvcSpockMethodBuilder" | { Contract dsl -> new MockMvcSpockMethodRequestProcessingBodyBuilder(dsl, properties) } - "MockMvcJUnitMethodBuilder" | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl, properties) } - } - - def "should generate assertions for nested objects in response body with #methodBuilderName"() { - given: - Contract contractDsl = Contract.make { - request { - method "GET" - url "test" - } - response { - status OK() - body '''\ -{ - "property1": "a", - "property2": {"property3": "b"} -} -''' - } - } - MethodBodyBuilder builder = methodBuilder(contractDsl) - BlockBuilder blockBuilder = new BlockBuilder(" ") - when: - builder.appendTo(blockBuilder) - then: - blockBuilder.toString().contains("""assertThatJson(parsedJson).field("['property2']").field("['property3']").isEqualTo("b")""") - blockBuilder.toString().contains("""assertThatJson(parsedJson).field("['property1']").isEqualTo("a")""") - and: - stubMappingIsValidWireMockStub(contractDsl) - and: - SyntaxChecker.tryToCompile(methodBuilderName, blockBuilder.toString()) - where: - methodBuilderName | methodBuilder - "MockMvcSpockMethodBuilder" | { Contract dsl -> new MockMvcSpockMethodRequestProcessingBodyBuilder(dsl, properties) } - "MockMvcJUnitMethodBuilder" | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl, properties) } - } - - def "should generate regex assertions for map objects in response body with #methodBuilderName"() { - given: - Contract contractDsl = Contract.make { - request { - method "GET" - url "test" - } - response { - status OK() - body( - property1: "a", - property2: value( - consumer('123'), - producer(regex('[0-9]{3}')) - ) - ) - headers { - contentType(applicationJson()) - } - } - } - MethodBodyBuilder builder = methodBuilder(contractDsl) - BlockBuilder blockBuilder = new BlockBuilder(" ") - when: - builder.appendTo(blockBuilder) - then: - blockBuilder.toString().contains("""assertThatJson(parsedJson).field("['property2']").matches("[0-9]{3}")""") - blockBuilder.toString().contains("""assertThatJson(parsedJson).field("['property1']").isEqualTo("a")""") - and: - stubMappingIsValidWireMockStub(contractDsl) - and: - SyntaxChecker.tryToCompile(methodBuilderName, blockBuilder.toString()) - where: - methodBuilderName | methodBuilder - "MockMvcSpockMethodBuilder" | { Contract dsl -> new MockMvcSpockMethodRequestProcessingBodyBuilder(dsl, properties) } - "MockMvcJUnitMethodBuilder" | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl, properties) } - } - - def "should generate regex assertions for string objects in response body with #methodBuilderName"() { - given: - Contract contractDsl = Contract.make { - request { - method "GET" - url "test" - } - response { - status OK() - body("""{"property1":"a","property2":"${ - value(consumer('123'), producer(regex('[0-9]{3}'))) - }"}""") - headers { - contentType(applicationJson()) - } - } - } - MethodBodyBuilder builder = methodBuilder(contractDsl) - BlockBuilder blockBuilder = new BlockBuilder(" ") - when: - builder.appendTo(blockBuilder) - then: - blockBuilder.toString().contains("""assertThatJson(parsedJson).field("['property2']").matches("[0-9]{3}")""") - blockBuilder.toString().contains("""assertThatJson(parsedJson).field("['property1']").isEqualTo("a")""") - and: - stubMappingIsValidWireMockStub(contractDsl) - and: - SyntaxChecker.tryToCompile(methodBuilderName, blockBuilder.toString()) - where: - methodBuilderName | methodBuilder - "MockMvcSpockMethodBuilder" | { Contract dsl -> new MockMvcSpockMethodRequestProcessingBodyBuilder(dsl, properties) } - "MockMvcJUnitMethodBuilder" | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl, properties) } - } - - @Issue(["#126", "#143"]) - def "should generate escaped regex assertions for string objects in response body with #methodBuilderName"() { - given: - Contract contractDsl = Contract.make { - request { - method "GET" - url "test" - } - response { - status OK() - body("""{"property":" ${ - value(consumer('123'), producer(regex('\\d+'))) - }"}""") - headers { - contentType(applicationJson()) - } - } - } - MethodBodyBuilder builder = methodBuilder(contractDsl) - BlockBuilder blockBuilder = new BlockBuilder(" ") - when: - builder.appendTo(blockBuilder) - then: - blockBuilder.toString().contains("""assertThatJson(parsedJson).field("['property']").matches("\\\\d+")""") - and: - stubMappingIsValidWireMockStub(contractDsl) - and: - SyntaxChecker.tryToCompile(methodBuilderName, blockBuilder.toString()) - where: - methodBuilderName | methodBuilder - "MockMvcSpockMethodBuilder" | { Contract dsl -> new MockMvcSpockMethodRequestProcessingBodyBuilder(dsl, properties) } - "MockMvcJUnitMethodBuilder" | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl, properties) } - } - - def "should generate a call with an url path and query parameters with #methodBuilderName"() { - given: - Contract contractDsl = Contract.make { - request { - method 'GET' - urlPath('/users') { - queryParameters { - parameter 'limit': $(consumer(equalTo("20")), producer(equalTo("10"))) - parameter 'offset': $(consumer(containing("20")), producer(equalTo("20"))) - parameter 'filter': "email" - parameter 'sort': equalTo("name") - parameter 'search': $(consumer(notMatching(~/^\/[0-9]{2}$/)), producer("55")) - parameter 'age': $(consumer(notMatching("^\\w*\$")), producer("99")) - parameter 'name': $(consumer(matching("Denis.*")), producer("Denis.Stepanov")) - parameter 'email': "bob@email.com" - parameter 'hello': $(consumer(matching("Denis.*")), producer(absent())) - parameter 'hello': absent() - } - } - } - response { - status OK() - body """ - { - "property1": "a", - "property2": "b" - } - """ - } - } - MethodBodyBuilder builder = methodBuilder(contractDsl) - BlockBuilder blockBuilder = new BlockBuilder(" ") - when: - builder.appendTo(blockBuilder) - def test = blockBuilder.toString() - then: - test.contains('''.queryParam("limit","10")''') - test.contains('''.queryParam("offset","20")''') - test.contains('''.queryParam("filter","email")''') - test.contains('''.queryParam("sort","name")''') - test.contains('''.queryParam("search","55")''') - test.contains('''.queryParam("age","99")''') - test.contains('''.queryParam("name","Denis.Stepanov")''') - test.contains('''.queryParam("email","bob@email.com")''') - test.contains('''.get("/users")''') - test.contains('assertThatJson(parsedJson).field("[\'property1\']").isEqualTo("a")') - test.contains('assertThatJson(parsedJson).field("[\'property2\']").isEqualTo("b")') - and: - stubMappingIsValidWireMockStub(contractDsl) - and: - SyntaxChecker.tryToCompile(methodBuilderName, blockBuilder.toString()) - where: - methodBuilderName | methodBuilder - "MockMvcSpockMethodBuilder" | { Contract dsl -> new MockMvcSpockMethodRequestProcessingBodyBuilder(dsl, properties) } - "MockMvcJUnitMethodBuilder" | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl, properties) } - } - - @Issue('#169') - def "should generate a call with an url path and query parameters with url containing a pattern with #methodBuilderName"() { - given: - Contract contractDsl = Contract.make { - request { - method 'GET' - url($(consumer(regex('/foo/[0-9]+')), producer('/foo/123456'))) { - queryParameters { - parameter 'limit': $(consumer(equalTo("20")), producer(equalTo("10"))) - parameter 'offset': $(consumer(containing("20")), producer(equalTo("20"))) - parameter 'filter': "email" - parameter 'sort': equalTo("name") - parameter 'search': $(consumer(notMatching(~/^\/[0-9]{2}$/)), producer("55")) - parameter 'age': $(consumer(notMatching("^\\w*\$")), producer("99")) - parameter 'name': $(consumer(matching("Denis.*")), producer("Denis.Stepanov")) - parameter 'email': "bob@email.com" - parameter 'hello': $(consumer(matching("Denis.*")), producer(absent())) - parameter 'hello': absent() - } - } - } - response { - status OK() - body """ - { - "property1": "a", - "property2": "b" - } - """ - } - } - MethodBodyBuilder builder = methodBuilder(contractDsl) - BlockBuilder blockBuilder = new BlockBuilder(" ") - when: - builder.appendTo(blockBuilder) - def test = blockBuilder.toString() - then: - test.contains('''.queryParam("limit","10")''') - test.contains('''.queryParam("offset","20")''') - test.contains('''.queryParam("filter","email")''') - test.contains('''.queryParam("sort","name")''') - test.contains('''.queryParam("search","55")''') - test.contains('''.queryParam("age","99")''') - test.contains('''.queryParam("name","Denis.Stepanov")''') - test.contains('''.queryParam("email","bob@email.com")''') - test.contains('''.get("/foo/123456")''') - test.contains('assertThatJson(parsedJson).field("[\'property1\']").isEqualTo("a")') - test.contains('assertThatJson(parsedJson).field("[\'property2\']").isEqualTo("b")') - and: - stubMappingIsValidWireMockStub(contractDsl) - and: - SyntaxChecker.tryToCompile(methodBuilderName, blockBuilder.toString()) - where: - methodBuilderName | methodBuilder - "MockMvcSpockMethodBuilder" | { Contract dsl -> new MockMvcSpockMethodRequestProcessingBodyBuilder(dsl, properties) } - "MockMvcJUnitMethodBuilder" | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl, properties) } - } - - def "should generate test for empty body with #methodBuilderName"() { - given: - Contract contractDsl = Contract.make { - request { - method(POST()) - url("/ws/payments") - body("") - } - response { - status 406 - } - } - MethodBodyBuilder builder = methodBuilder(contractDsl) - BlockBuilder blockBuilder = new BlockBuilder(" ") - when: - builder.appendTo(blockBuilder) - def test = blockBuilder.toString() - then: - test.contains(bodyString) - and: - stubMappingIsValidWireMockStub(contractDsl) - and: - SyntaxChecker.tryToCompile(methodBuilderName, blockBuilder.toString()) - where: - methodBuilderName | methodBuilder | bodyString - "MockMvcSpockMethodBuilder" | { Contract dsl -> new MockMvcSpockMethodRequestProcessingBodyBuilder(dsl, properties) } | ".body('''''')" - "MockMvcJUnitMethodBuilder" | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl, properties) } | '.body("")' - } - - def "should generate test for String in response body with #methodBuilderName"() { - given: - Contract contractDsl = Contract.make { - request { - method "POST" - url "test" - } - response { - status OK() - body "test" - } - } - MethodBodyBuilder builder = methodBuilder(contractDsl) - BlockBuilder blockBuilder = new BlockBuilder(" ") - when: - builder.appendTo(blockBuilder) - def test = blockBuilder.toString() - then: - test.contains(bodyDefinitionString) - test.contains(bodyEvaluationString) - and: - stubMappingIsValidWireMockStub(contractDsl) - and: - SyntaxChecker.tryToCompile(methodBuilderName, blockBuilder.toString()) - where: - methodBuilderName | methodBuilder | bodyDefinitionString | bodyEvaluationString - "MockMvcSpockMethodBuilder" | { Contract dsl -> new MockMvcSpockMethodRequestProcessingBodyBuilder(dsl, properties) } | 'def responseBody = (response.body.asString())' | 'responseBody == "test"' - "MockMvcJUnitMethodBuilder" | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl, properties) } | 'String responseBody = response.getBody().asString();' | 'assertThat(responseBody).isEqualTo("test");' - } - - @Issue('113') - def "should generate regex test for String in response header with #methodBuilderName"() { - given: - Contract contractDsl = Contract.make { - request { - method 'POST' - url $(consumer(regex('/partners/[0-9]+/users')), producer('/partners/1000/users')) - headers { contentType(applicationJson()) } - body( - first_name: 'John', - last_name: 'Smith', - personal_id: '12345678901', - phone_number: '500500500', - invitation_token: '00fec7141bb94793bfe7ae1d0f39bda0', - password: 'john' - ) - } - response { - status 201 - headers { - header 'Location': $(consumer('http://localhost/partners/1000/users/1001'), producer(regex('http://localhost/partners/[0-9]+/users/[0-9]+'))) - } - } - } - MethodBodyBuilder builder = methodBuilder(contractDsl) - BlockBuilder blockBuilder = new BlockBuilder(" ") - when: - builder.appendTo(blockBuilder) - def test = blockBuilder.toString() - then: - test.contains(headerEvaluationString) - and: - stubMappingIsValidWireMockStub(contractDsl) - and: - SyntaxChecker.tryToCompile(methodBuilderName, blockBuilder.toString()) - where: - methodBuilderName | methodBuilder | headerEvaluationString - "MockMvcSpockMethodBuilder" | { Contract dsl -> new MockMvcSpockMethodRequestProcessingBodyBuilder(dsl, properties) } | '''response.header('Location') ==~ java.util.regex.Pattern.compile('http://localhost/partners/[0-9]+/users/[0-9]+')''' - "MockMvcJUnitMethodBuilder" | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl, properties) } | 'assertThat(response.header("Location")).matches("http://localhost/partners/[0-9]+/users/[0-9]+");' - } - - @Issue('115') - def "should generate regex with helper method with #methodBuilderName"() { - given: - Contract contractDsl = Contract.make { - request { - method 'POST' - url $(consumer(regex('/partners/[0-9]+/users')), producer('/partners/1000/users')) - headers { contentType(applicationJson()) } - body( - first_name: 'John', - last_name: 'Smith', - personal_id: '12345678901', - phone_number: '500500500', - invitation_token: '00fec7141bb94793bfe7ae1d0f39bda0', - password: 'john' - ) - } - response { - status 201 - headers { - header 'Location': $(consumer('http://localhost/partners/1000/users/1001'), producer(regex("^${hostname()}/partners/[0-9]+/users/[0-9]+"))) - } - } - } - MethodBodyBuilder builder = methodBuilder(contractDsl) - BlockBuilder blockBuilder = new BlockBuilder(" ") - when: - builder.appendTo(blockBuilder) - def test = blockBuilder.toString() - then: - test.contains(headerEvaluationString) - and: - stubMappingIsValidWireMockStub(contractDsl) - and: - SyntaxChecker.tryToCompile(methodBuilderName, blockBuilder.toString()) - where: - methodBuilderName | methodBuilder | headerEvaluationString - "MockMvcSpockMethodBuilder" | { Contract dsl -> new MockMvcSpockMethodRequestProcessingBodyBuilder(dsl, properties) } | '''response.header('Location') ==~ java.util.regex.Pattern.compile('^((http[s]?|ftp):/)/?([^:/s]+)(:[0-9]{1,5})?/partners/[0-9]+/users/[0-9]+')''' - "MockMvcJUnitMethodBuilder" | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl, properties) } | 'assertThat(response.header("Location")).matches("^((http[s]?|ftp):/)/?([^:/s]+)(:[0-9]{1,5})?/partners/[0-9]+/users/[0-9]+");' - } - - def "should work with more complex stuff and jsonpaths with #methodBuilderName"() { - given: - Contract contractDsl = Contract.make { - priority 10 - request { - method 'POST' - url '/validation/client' - headers { - contentType(applicationJson()) - } - body( - bank_account_number: '0014282912345698765432161182', - email: 'foo@bar.com', - phone_number: '100299300', - personal_id: 'ABC123456' - ) - } - - response { - status OK() - body(errors: [ - [property: "bank_account_number", message: "incorrect_format"] - ]) - } - } - MethodBodyBuilder builder = methodBuilder(contractDsl) - BlockBuilder blockBuilder = new BlockBuilder(" ") - when: - builder.appendTo(blockBuilder) - def test = blockBuilder.toString() - then: - test.contains("""assertThatJson(parsedJson).array("['errors']").contains("['property']").isEqualTo("bank_account_number")""") - test.contains("""assertThatJson(parsedJson).array("['errors']").contains("['message']").isEqualTo("incorrect_format")""") - and: - stubMappingIsValidWireMockStub(contractDsl) - and: - SyntaxChecker.tryToCompile(methodBuilderName, blockBuilder.toString()) - where: - methodBuilderName | methodBuilder - "MockMvcSpockMethodBuilder" | { Contract dsl -> new MockMvcSpockMethodRequestProcessingBodyBuilder(dsl, properties) } - "MockMvcJUnitMethodBuilder" | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl, properties) } - } - - def "should work properly with GString url with #methodBuilderName"() { - given: - Contract contractDsl = Contract.make { - - request { - method PUT() - url "/partners/${value(consumer(regex('^[0-9]*$')), producer('11'))}/agents/11/customers/09665703Z" - headers { - contentType(applicationJson()) - } - body( - first_name: 'Josef', - ) - } - response { - status 422 - } - } - MethodBodyBuilder builder = methodBuilder(contractDsl) - BlockBuilder blockBuilder = new BlockBuilder(" ") - when: - builder.appendTo(blockBuilder) - def test = blockBuilder.toString() - then: - test.contains('''/partners/11/agents/11/customers/09665703Z''') - and: - stubMappingIsValidWireMockStub(contractDsl) - and: - SyntaxChecker.tryToCompile(methodBuilderName, blockBuilder.toString()) - where: - methodBuilderName | methodBuilder - "MockMvcSpockMethodBuilder" | { Contract dsl -> new MockMvcSpockMethodRequestProcessingBodyBuilder(dsl, properties) } - "MockMvcJUnitMethodBuilder" | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl, properties) } - } - - def "should resolve properties in GString with regular expression with #methodBuilderName"() { - given: - Contract contractDsl = Contract.make { - priority 1 - request { - method POST() - url '/users/password' - headers { - contentType(applicationJson()) - } - body( - email: $(consumer(regex(email())), producer('not.existing@user.com')), - callback_url: $(consumer(regex(hostname())), producer('http://partners.com')) - ) - } - response { - status 404 - headers { - contentType(applicationJson()) - } - body( - code: 4, - message: "User not found by email = [${value(producer(regex(email())), consumer('not.existing@user.com'))}]" - ) - } - } - MethodBodyBuilder builder = methodBuilder(contractDsl) - BlockBuilder blockBuilder = new BlockBuilder(" ") - when: - builder.appendTo(blockBuilder) - def test = blockBuilder.toString() - then: - test.contains("""assertThatJson(parsedJson).field("['message']").matches("User not found by email = \\\\\\\\[[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\\\\\\\.[a-zA-Z]{2,6}\\\\\\\\]")""") - and: - // no static compilation due to bug in Groovy https://issues.apache.org/jira/browse/GROOVY-8055 - SyntaxChecker.tryToCompileWithoutCompileStatic(methodBuilderName, blockBuilder.toString()) - where: - methodBuilderName | methodBuilder - "MockMvcSpockMethodBuilder" | { Contract dsl -> new MockMvcSpockMethodRequestProcessingBodyBuilder(dsl, properties) } - "MockMvcJUnitMethodBuilder" | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl, properties) } - } - - @Issue('42') - def "should not omit the optional field in the test creation with MockMvcSpockMethodBodyBuilder"() { - given: - MethodBodyBuilder builder = new MockMvcSpockMethodRequestProcessingBodyBuilder(contractDsl, properties) - BlockBuilder blockBuilder = new BlockBuilder(" ") - when: - builder.appendTo(blockBuilder) - def test = blockBuilder.toString() - then: - test.contains('''"email":"abc@abc.com"''') - test.contains("""assertThatJson(parsedJson).field("['code']").matches("(123123)?")""") - !test.contains('''REGEXP''') - !test.contains('''OPTIONAL''') - !test.contains('''OptionalProperty''') - and: - SyntaxChecker.tryToCompileGroovy(blockBuilder.toString()) - where: - contractDsl << [dslWithOptionals, dslWithOptionalsInString] - } - - @Issue('42') - def "should not omit the optional field in the test creation with MockMvcJUnitMethodBodyBuilder"() { - given: - MethodBodyBuilder builder = new MockMvcJUnitMethodBodyBuilder(contractDsl, properties) - BlockBuilder blockBuilder = new BlockBuilder(" ") - when: - builder.appendTo(blockBuilder) - def test = blockBuilder.toString() - then: - test.contains('\\"email\\":\\"abc@abc.com\\"') - test.contains('assertThatJson(parsedJson).field("[\'code\']").matches("(123123)?");') - !test.contains('''REGEXP''') - !test.contains('''OPTIONAL''') - !test.contains('''OptionalProperty''') - and: - SyntaxChecker.tryToCompileJava(blockBuilder.toString()) - where: - contractDsl << [dslWithOptionals, dslWithOptionalsInString] - } - - @Issue('72') - def "should make the execute method work with #methodBuilderName"() { - given: - Contract contractDsl = Contract.make { - request { - method """PUT""" - url """/fraudcheck""" - body(""" - { - "clientPesel":"${ - value(consumer(regex('[0-9]{10}')), producer('1234567890')) - }", - "loanAmount":123.123 - } - """ - ) - headers { - header("""Content-Type""", """application/vnd.fraud.v1+json""") - } - - } - response { - status OK() - body("""{ - "fraudCheckStatus": "OK", - "rejectionReason": ${ - value(consumer(null), producer(execute('assertThatRejectionReasonIsNull($it)'))) - } -}""") - headers { - header('Content-Type': 'application/vnd.fraud.v1+json') - header 'Location': value( - consumer(null), - producer(execute('assertThatLocationIsNull($it)')) - ) - } - } - } - MethodBodyBuilder builder = methodBuilder(contractDsl) - BlockBuilder blockBuilder = new BlockBuilder(" ") - when: - builder.appendTo(blockBuilder) - String test = blockBuilder.toString() - then: - assertionStrings.each { String assertionString -> - assert test.contains(assertionString) - } - where: - methodBuilderName | methodBuilder | assertionStrings - "MockMvcSpockMethodBuilder" | { Contract dsl -> new MockMvcSpockMethodRequestProcessingBodyBuilder(dsl, properties) } | ['''assertThatRejectionReasonIsNull(parsedJson.read(\'\'\'$.rejectionReason\'\'\'))''', '''assertThatLocationIsNull(response.header('Location'))'''] - "MockMvcJUnitMethodBuilder" | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl, properties) } | ['''assertThatRejectionReasonIsNull(parsedJson.read("$.rejectionReason"))''', '''assertThatLocationIsNull(response.header("Location"))'''] - } - - def "should support inner map and list definitions with #methodBuilderName"() { - given: - - Pattern PHONE_NUMBER = Pattern.compile(/[+\w]*/) - Pattern ANYSTRING = Pattern.compile(/.*/) - Pattern NUMBERS = Pattern.compile(/[\d\.]*/) - Pattern DATETIME = ANYSTRING - - Contract contractDsl = Contract.make { - request { - method "PUT" - url "/v1/payments/e86df6f693de4b35ae648464c5b0dc09/client_data" - headers { - contentType(applicationJson()) - } - body( - client: [ - first_name : $(consumer(regex(onlyAlphaUnicode())), producer('Denis')), - last_name : $(consumer(regex(onlyAlphaUnicode())), producer('FakeName')), - email : $(consumer(regex(email())), producer('fakemail@fakegmail.com')), - fax : $(consumer(PHONE_NUMBER), producer('+xx001213214')), - phone : $(consumer(PHONE_NUMBER), producer('2223311')), - data_of_birth: $(consumer(DATETIME), producer('2002-10-22T00:00:00Z')) - ], - client_id_card: [ - id : $(consumer(ANYSTRING), producer('ABC12345')), - date_of_issue: $(consumer(ANYSTRING), producer('2002-10-02T00:00:00Z')), - address : [ - street : $(consumer(ANYSTRING), producer('Light Street')), - city : $(consumer(ANYSTRING), producer('Fire')), - region : $(consumer(ANYSTRING), producer('Skys')), - country: $(consumer(ANYSTRING), producer('HG')), - zip : $(consumer(NUMBERS), producer('658965')) - ] - ], - incomes_and_expenses: [ - monthly_income : $(consumer(NUMBERS), producer('0.0')), - monthly_loan_repayments: $(consumer(NUMBERS), producer('100')), - monthly_living_expenses: $(consumer(NUMBERS), producer('22')) - ], - additional_info: [ - allow_to_contact: $(consumer(optional(regex(anyBoolean()))), producer('true')) - ] - ) - } - response { - status OK() - headers { - contentType(applicationJson()) - } - } - } - MethodBodyBuilder builder = methodBuilder(contractDsl) - BlockBuilder blockBuilder = new BlockBuilder(" ") - when: - builder.appendTo(blockBuilder) - def test = blockBuilder.toString() - then: - test.contains bodyString - !test.contains("clientValue") - !test.contains("cursor") - and: - SyntaxChecker.tryToCompile(methodBuilderName, blockBuilder.toString()) - where: - methodBuilderName | methodBuilder | bodyString - "MockMvcSpockMethodBuilder" | { Contract dsl -> new MockMvcSpockMethodRequestProcessingBodyBuilder(dsl, properties) } | '"street":"Light Street"' - "MockMvcJUnitMethodBuilder" | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl, properties) } | '\\"street\\":\\"Light Street\\"' - - } - - def "should work with optional fields that have null #methodBuilderName"() { - given: - Contract contractDsl = Contract.make { - request { - method "PUT" - url "/v1/payments/e86df6f693de4b35ae648464c5b0dc09/client_data" - headers { - contentType(applicationJson()) - } - } - response { - status OK() - headers { - contentType(applicationJson()) - } - body( - code: $(optional(regex("123123"))) - ) - } - } - MethodBodyBuilder builder = methodBuilder(contractDsl) - BlockBuilder blockBuilder = new BlockBuilder(" ") - when: - builder.appendTo(blockBuilder) - def test = blockBuilder.toString() - then: - SyntaxChecker.tryToCompile(methodBuilderName, blockBuilder.toString()) - and: - String jsonSample = '''\ -String json = "{\\"code\\":null}"; -DocumentContext parsedJson = JsonPath.parse(json); -''' - and: - LinkedList lines = [] as LinkedList - test.eachLine { if (it.contains("assertThatJson")) lines << it else it } - lines.addFirst(jsonSample) - SyntaxChecker.tryToRun(methodBuilderName, lines.join("\n")) - where: - methodBuilderName | methodBuilder | bodyString - "MockMvcSpockMethodBuilder" | { Contract dsl -> new MockMvcSpockMethodRequestProcessingBodyBuilder(dsl, properties) } | '"street":"Light Street"' - "MockMvcJUnitMethodBuilder" | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl, properties) } | '\\"street\\":\\"Light Street\\"' - - } - - def "shouldn't generate unicode escape characters with #methodBuilderName"() { - given: - Pattern ONLY_ALPHA_UNICODE = Pattern.compile(/[\p{L}]*/) - - Contract contractDsl = Contract.make { - request { - method "PUT" - url "/v1/payments/e86df6f693de4b35ae648464c5b0dc09/енев" - headers { - contentType(applicationJson()) - } - body( - client: [ - first_name: $(consumer(ONLY_ALPHA_UNICODE), producer('Пенева')), - last_name : $(consumer(ONLY_ALPHA_UNICODE), producer('Пенева')) - ] - ) - } - response { - status OK() - headers { - contentType(applicationJson()) - } - } - } - MethodBodyBuilder builder = methodBuilder(contractDsl) - BlockBuilder blockBuilder = new BlockBuilder(" ") - when: - builder.appendTo(blockBuilder) - def test = blockBuilder.toString() - then: - !test.contains("\\u041f") - and: - SyntaxChecker.tryToCompile(methodBuilderName, blockBuilder.toString()) - where: - methodBuilderName | methodBuilder - "MockMvcSpockMethodBuilder" | { Contract dsl -> new MockMvcSpockMethodRequestProcessingBodyBuilder(dsl, properties) } - "MockMvcJUnitMethodBuilder" | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl, properties) } - } - - @Issue('177') - def "should generate proper test code when having multiline body with #methodBuilderName"() { - given: - Contract contractDsl = Contract.make { - request { - method "PUT" - url "/multiline" - body('''hello, -World.''') - } - response { - status OK() - } - } - MethodBodyBuilder builder = methodBuilder(contractDsl) - BlockBuilder blockBuilder = new BlockBuilder(" ") - when: - builder.given(blockBuilder) - def test = blockBuilder.toString() - then: - test.contains(bodyString) - and: - SyntaxChecker.tryToCompile(methodBuilderName, blockBuilder.toString()) - where: - methodBuilderName | methodBuilder | bodyString - "MockMvcSpockMethodBuilder" | { Contract dsl -> new MockMvcSpockMethodRequestProcessingBodyBuilder(dsl, properties) } | """'''hello, -World.'''""" - "MockMvcJUnitMethodBuilder" | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl, properties) } | '"hello,\\nWorld."' - } - - @Issue('180') - def "should generate proper test code when having multipart parameters with #methodBuilderName"() { - given: - // tag::multipartdsl[] - org.springframework.cloud.contract.spec.Contract contractDsl = org.springframework.cloud.contract.spec.Contract.make { - request { - method "PUT" - url "/multipart" - headers { - contentType('multipart/form-data;boundary=AaB03x') - } - multipart( - // key (parameter name), value (parameter value) pair - formParameter: $(c(regex('".+"')), p('"formParameterValue"')), - someBooleanParameter: $(c(regex(anyBoolean())), p('true')), - // a named parameter (e.g. with `file` name) that represents file with - // `name` and `content`. You can also call `named("fileName", "fileContent")` - file: named( - // name of the file - name: $(c(regex(nonEmpty())), p('filename.csv')), - // content of the file - content: $(c(regex(nonEmpty())), p('file content')), - // content type for the part - contentType: $(c(regex(nonEmpty())), p('application/json'))) - ) - } - response { - status OK() - } - } - // end::multipartdsl[] - MethodBodyBuilder builder = methodBuilder(contractDsl) - BlockBuilder blockBuilder = new BlockBuilder(" ") - when: - builder.appendTo(blockBuilder) - def test = blockBuilder.toString() - then: - for (String requestString : requestStrings) { - assert test.contains(requestString) - } - and: - SyntaxChecker.tryToCompile(methodBuilderName, blockBuilder.toString()) - where: - methodBuilderName | methodBuilder | requestStrings - "MockMvcSpockMethodBuilder" | {Contract dsl -> new MockMvcSpockMethodRequestProcessingBodyBuilder(dsl, properties)} | ['"Content-Type", "multipart/form-data;boundary=AaB03x"', - """.param('formParameter', '"formParameterValue"'""", - """.param('someBooleanParameter', 'true')""", - """.multiPart('file', 'filename.csv', 'file content'.bytes, 'application/json')"""] - "MockMvcJUnitMethodBuilder" | {Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl, properties)} | ['"Content-Type", "multipart/form-data;boundary=AaB03x"', - '.param("formParameter", "\\"formParameterValue\\"")', - '.param("someBooleanParameter", "true")', - '.multiPart("file", "filename.csv", "file content".getBytes(), "application/json");'] - } - - @Issue('180') - def "should generate proper test code when having multipart parameters without content type with #methodBuilderName"() { - given: - org.springframework.cloud.contract.spec.Contract contractDsl = org.springframework.cloud.contract.spec.Contract.make { - request { - method "PUT" - url "/multipart" - headers { - contentType('multipart/form-data;boundary=AaB03x') - } - multipart( - // key (parameter name), value (parameter value) pair - formParameter: $(c(regex('".+"')), p('"formParameterValue"')), - someBooleanParameter: $(c(regex(anyBoolean())), p('true')), - // a named parameter (e.g. with `file` name) that represents file with - // `name` and `content`. You can also call `named("fileName", "fileContent")` - file: named( - // name of the file - name: $(c(regex(nonEmpty())), p('filename.csv')), - // content of the file - content: $(c(regex(nonEmpty())), p('file content'))) - ) - } - response { - status OK() - } - } - MethodBodyBuilder builder = methodBuilder(contractDsl) - BlockBuilder blockBuilder = new BlockBuilder(" ") - when: - builder.appendTo(blockBuilder) - def test = blockBuilder.toString() - then: - for (String requestString : requestStrings) { - assert test.contains(requestString) - } - and: - SyntaxChecker.tryToCompile(methodBuilderName, blockBuilder.toString()) - where: - methodBuilderName | methodBuilder | requestStrings - "MockMvcSpockMethodBuilder" | { Contract dsl -> new MockMvcSpockMethodRequestProcessingBodyBuilder(dsl, properties) } | ['"Content-Type", "multipart/form-data;boundary=AaB03x"', - """.param('formParameter', '"formParameterValue"'""", - """.param('someBooleanParameter', 'true')""", - """.multiPart('file', 'filename.csv', 'file content'.bytes)"""] - "MockMvcJUnitMethodBuilder" | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl, properties) } | ['"Content-Type", "multipart/form-data;boundary=AaB03x"', - '.param("formParameter", "\\"formParameterValue\\"")', - '.param("someBooleanParameter", "true")', - '.multiPart("file", "filename.csv", "file content".getBytes());'] - } - - @Issue('546') - def "should generate test code when having multipart parameters with byte array #methodBuilderName"() { - given: - // tag::multipartdsl[] - org.springframework.cloud.contract.spec.Contract contractDsl = org.springframework.cloud.contract.spec.Contract.make { - request { - method "PUT" - url "/multipart" - headers { - contentType('multipart/form-data;boundary=AaB03x') - } - multipart( - file: named( - name: value(stub(regex('.+')), test('file')), - content: value(stub(regex('.+')), test([100, 117, 100, 97] as byte[])) - ) - ) - } - response { - status 200 - } - } - // end::multipartdsl[] - MethodBodyBuilder builder = methodBuilder(contractDsl) - BlockBuilder blockBuilder = new BlockBuilder(" ") - when: - builder.appendTo(blockBuilder) - def test = blockBuilder.toString() - then: - for (String requestString : requestStrings) { - assert test.contains(requestString) - } - and: - SyntaxChecker.tryToCompile(methodBuilderName, blockBuilder.toString()) - where: - methodBuilderName | methodBuilder | requestStrings - "MockMvcSpockMethodBuilder" | { Contract dsl -> new MockMvcSpockMethodRequestProcessingBodyBuilder(dsl, properties) } | ['"Content-Type", "multipart/form-data;boundary=AaB03x"', - """.multiPart('file', 'file', [100, 117, 100, 97] as byte[])"""] - "MockMvcJUnitMethodBuilder" | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl, properties) } | ['"Content-Type", "multipart/form-data;boundary=AaB03x"', - '.multiPart("file", "file", new byte[] {100, 117, 100, 97});'] - } - - @Issue('541') - def "should generate proper test code when having multipart parameters that use execute with #methodBuilderName"() { - given: - org.springframework.cloud.contract.spec.Contract contractDsl = org.springframework.cloud.contract.spec.Contract.make { - request { - method "PUT" - url "/multipart" - headers { - contentType('multipart/form-data;boundary=AaB03x') - } - multipart( - formParameter: $(c(regex('".+"')), p('"formParameterValue"')), - someBooleanParameter: $(c(regex(anyBoolean())), p('true')), - file: named( - name: $(c(regex(nonEmpty())), p(execute("toString()"))), - content: $(c(regex(nonEmpty())), p('file content'))) - ) - } - response { - status OK() - } - } - MethodBodyBuilder builder = methodBuilder(contractDsl) - BlockBuilder blockBuilder = new BlockBuilder(" ") - when: - builder.appendTo(blockBuilder) - def test = blockBuilder.toString() - then: - for (String requestString : requestStrings) { - assert test.contains(requestString) - } - and: - SyntaxChecker.tryToCompile(methodBuilderName, blockBuilder.toString()) - where: - methodBuilderName | methodBuilder | requestStrings - "MockMvcSpockMethodBuilder" | { Contract dsl -> new MockMvcSpockMethodRequestProcessingBodyBuilder(dsl, properties) } | ['"Content-Type", "multipart/form-data;boundary=AaB03x"', - """.param('formParameter', '"formParameterValue"'""", - """.param('someBooleanParameter', 'true')""", - """.multiPart('file', toString(), 'file content'.bytes)"""] - "MockMvcJUnitMethodBuilder" | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl, properties) } | ['"Content-Type", "multipart/form-data;boundary=AaB03x"', - '.param("formParameter", "\\"formParameterValue\\"")', - '.param("someBooleanParameter", "true")', - '.multiPart("file", toString(), "file content".getBytes());'] - } - - @Issue('180') - def "should generate proper test code when having multipart parameters with named as map with #methodBuilderName"() { - given: - org.springframework.cloud.contract.spec.Contract contractDsl = org.springframework.cloud.contract.spec.Contract.make { - request { - method "PUT" - url "/multipart" - headers { - contentType('multipart/form-data;boundary=AaB03x') - } - multipart( - // key (parameter name), value (parameter value) pair - formParameter: $(c(regex('".+"')), p('"formParameterValue"')), - someBooleanParameter: $(c(regex(anyBoolean())), p('true')), - // a named parameter (e.g. with `file` name) that represents file with - // `name` and `content`. You can also call `named("fileName", "fileContent")` - file: named( - // name of the file - name: $(c(regex(nonEmpty())), p('filename.csv')), - // content of the file - content: $(c(regex(nonEmpty())), p('file content'))) - ) - } - response { - status OK() - } - } - MethodBodyBuilder builder = methodBuilder(contractDsl) - BlockBuilder blockBuilder = new BlockBuilder(" ") - when: - builder.given(blockBuilder) - def test = blockBuilder.toString() - then: - test.contains('.multiPart') - and: - SyntaxChecker.tryToCompile(methodBuilderName, blockBuilder.toString()) - where: - methodBuilderName | methodBuilder - "MockMvcSpockMethodBuilder" | { Contract dsl -> new MockMvcSpockMethodRequestProcessingBodyBuilder(dsl, properties) } - "MockMvcJUnitMethodBuilder" | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl, properties) } - } - - @Issue('#216') - def "should parse JSON with arrays using Spock"() { - given: - Contract contractDsl = Contract.make { - request { - method "GET" - urlPath('/auth/oauth/check_token') { - queryParameters { - parameter 'token': value( - consumer(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}')), - producer('6973b31d-7140-402a-bca6-1cdb954e03a7') - ) - } - } - } - response { - status OK() - body( - authorities: [ - value(consumer('ROLE_ADMIN'), producer(regex('^[a-zA-Z0-9_\\- ]+$'))) - ] - ) - } - } - MethodBodyBuilder builder = new MockMvcSpockMethodRequestProcessingBodyBuilder(contractDsl, properties) - BlockBuilder blockBuilder = new BlockBuilder(" ") - when: - builder.appendTo(blockBuilder) - def test = blockBuilder.toString() - then: - test.contains('''assertThatJson(parsedJson).array("[\'authorities']").arrayField().matches("^[a-zA-Z0-9_\\\\- ]+\\$").value()''') - and: - SyntaxChecker.tryToCompileGroovy(blockBuilder.toString()) - } - - @Issue('#216') - def "should parse JSON with arrays using JUnit"() { - given: - Contract contractDsl = Contract.make { - request { - method "GET" - urlPath('/auth/oauth/check_token') { - queryParameters { - parameter 'token': value( - consumer(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}')), - producer('6973b31d-7140-402a-bca6-1cdb954e03a7') - ) - } - } - } - response { - status OK() - body( - authorities: [ - value(consumer('ROLE_ADMIN'), producer(regex('^[a-zA-Z0-9_\\- ]+$'))) - ] - ) - } - } - MethodBodyBuilder builder = new MockMvcJUnitMethodBodyBuilder(contractDsl, properties) - BlockBuilder blockBuilder = new BlockBuilder(" ") - when: - builder.appendTo(blockBuilder) - def test = blockBuilder.toString() - then: - test.contains('''assertThatJson(parsedJson).array("[\'authorities']").arrayField().matches("^[a-zA-Z0-9_\\\\- ]+$").value()''') - and: - SyntaxChecker.tryToCompileJava(blockBuilder.toString()) - } - - def "should work with execution property with #methodBuilderName"() { - given: - Contract contractDsl = Contract.make { - request { - method 'PUT' - url '/fraudcheck' - } - response { - status OK() - body( - fraudCheckStatus: "OK", - rejectionReason: $(consumer(null), producer(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" | { Contract dsl -> new MockMvcSpockMethodRequestProcessingBodyBuilder(dsl, properties) } - "MockMvcJUnitMethodBuilder" | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl, properties) } - } - - @Issue('262') - def "should generate proper test code with map inside list"() { - given: - Contract contractDsl = Contract.make { - request { - method 'GET' - urlPath '/foos' - } - response { - status OK() - body([[id: value( - consumer('123'), - producer(regex('[0-9]+')) - )], [id: value( - consumer('567'), - producer(regex('[0-9]+')) - )]]) - headers { - contentType(applicationJsonUtf8()) - } - } - } - MethodBodyBuilder builder = new MockMvcSpockMethodRequestProcessingBodyBuilder(contractDsl, properties) - BlockBuilder blockBuilder = new BlockBuilder(" ") - when: - builder.appendTo(blockBuilder) - def test = blockBuilder.toString() - then: - test.contains('assertThatJson(parsedJson).array().contains("[\'id\']").matches("[0-9]+")') - and: - SyntaxChecker.tryToCompileGroovy(blockBuilder.toString()) - } - - @Issue('266') - def "should generate proper test code with top level array using #methodBuilderName"() { - given: - Contract contractDsl = Contract.make { - request { - method 'GET' - urlPath '/api/tags' - } - response { - status OK() - body(["Java", "Java8", "Spring", "SpringBoot", "Stream"]) - headers { - header('Content-Type': 'application/json;charset=UTF-8') - } - } - } - MethodBodyBuilder builder = methodBuilder(contractDsl) - BlockBuilder blockBuilder = new BlockBuilder(" ") - when: - builder.appendTo(blockBuilder) - def test = blockBuilder.toString() - then: - test.contains('assertThatJson(parsedJson).arrayField().contains("Java8").value()') - test.contains('assertThatJson(parsedJson).arrayField().contains("Spring").value()') - test.contains('assertThatJson(parsedJson).arrayField().contains("Java").value()') - test.contains('assertThatJson(parsedJson).arrayField().contains("Stream").value()') - test.contains('assertThatJson(parsedJson).arrayField().contains("SpringBoot").value()') - and: - SyntaxChecker.tryToCompile(methodBuilderName, blockBuilder.toString()) - where: - methodBuilderName | methodBuilder - "MockMvcSpockMethodBuilder" | { Contract dsl -> new MockMvcSpockMethodRequestProcessingBodyBuilder(dsl, properties) } - "MockMvcJUnitMethodBuilder" | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl, properties) } - } - - @Issue('266') - @RestoreSystemProperties - def "should generate proper test code with top level array using #methodBuilderName with array size check"() { - given: - System.setProperty('spring.cloud.contract.verifier.assert.size', 'true') - Contract contractDsl = Contract.make { - request { - method 'GET' - urlPath '/api/tags' - } - response { - status OK() - body(["Java", "Java8", "Spring", "SpringBoot", "Stream"]) - headers { - header('Content-Type': 'application/json;charset=UTF-8') - } - } - } - MethodBodyBuilder builder = methodBuilder(contractDsl) - BlockBuilder blockBuilder = new BlockBuilder(" ") - when: - builder.appendTo(blockBuilder) - def test = blockBuilder.toString() - then: - test.contains('assertThatJson(parsedJson).hasSize(5)') - test.contains('assertThatJson(parsedJson).arrayField().contains("Java8").value()') - test.contains('assertThatJson(parsedJson).arrayField().contains("Spring").value()') - test.contains('assertThatJson(parsedJson).arrayField().contains("Java").value()') - test.contains('assertThatJson(parsedJson).arrayField().contains("Stream").value()') - test.contains('assertThatJson(parsedJson).arrayField().contains("SpringBoot").value()') - and: - SyntaxChecker.tryToCompile(methodBuilderName, blockBuilder.toString()) - where: - methodBuilderName | methodBuilder - "MockMvcSpockMethodBuilder" | { Contract dsl -> new MockMvcSpockMethodRequestProcessingBodyBuilder(dsl, properties) } - "MockMvcJUnitMethodBuilder" | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl, properties) } - } - - @Issue('266') - def "should generate proper test code with top level array or arrays using #methodBuilderName"() { - given: - Contract contractDsl = Contract.make { - request { - method 'GET' - urlPath '/api/categories' - } - response { - status OK() - body([["Programming", "Java"], ["Programming", "Java", "Spring", "Boot"]]) - headers { - header('Content-Type': 'application/json;charset=UTF-8') - } - } - } - MethodBodyBuilder builder = methodBuilder(contractDsl) - BlockBuilder blockBuilder = new BlockBuilder(" ") - when: - builder.appendTo(blockBuilder) - def test = blockBuilder.toString() - then: - test.contains('assertThatJson(parsedJson).array().array().arrayField().isEqualTo("Programming").value()') - test.contains('assertThatJson(parsedJson).array().array().arrayField().isEqualTo("Java").value()') - test.contains('assertThatJson(parsedJson).array().array().arrayField().isEqualTo("Spring").value()') - test.contains('assertThatJson(parsedJson).array().array().arrayField().isEqualTo("Boot").value()') - and: - SyntaxChecker.tryToCompile(methodBuilderName, blockBuilder.toString()) - where: - methodBuilderName | methodBuilder - "MockMvcSpockMethodBuilder" | { Contract dsl -> new MockMvcSpockMethodRequestProcessingBodyBuilder(dsl, properties) } - "MockMvcJUnitMethodBuilder" | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl, properties) } - } - - @Issue('47') - def "should generate async body when async flag set in response"() { - given: - Contract contractDsl = Contract.make { - request { - method 'GET' - url '/test' - } - response { - status OK() - async() - } - } - MethodBodyBuilder builder = methodBuilder(contractDsl) - BlockBuilder blockBuilder = new BlockBuilder(" ") - when: - builder.appendTo(blockBuilder) - def test = blockBuilder.toString() - then: - test.contains(bodyDefinitionString) - and: - stubMappingIsValidWireMockStub(contractDsl) - and: - SyntaxChecker.tryToCompile(methodBuilderName, blockBuilder.toString()) - where: - methodBuilderName | methodBuilder | bodyDefinitionString - "MockMvcSpockMethodBuilder" | { Contract dsl -> new MockMvcSpockMethodRequestProcessingBodyBuilder(dsl, properties) } | '.when().async()' - "MockMvcJUnitMethodBuilder" | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl, properties) } | '.when().async()' - } - - @Issue('372') - def "should generate async body after queryParams when async flag set in response and queryParams set in request"() { - given: - Contract contractDsl = Contract.make { - request { - method 'GET' - url('/test') { - queryParameters { - parameter("param", "value") - } - } - } - response { - status OK() - async() - } - } - MethodBodyBuilder builder = methodBuilder(contractDsl) - BlockBuilder blockBuilder = new BlockBuilder(" ") - when: - builder.appendTo(blockBuilder) - def test = blockBuilder.toString() - def strippedTest = test.replace('\n', '').replace(' ', '').stripIndent().stripMargin() - then: - strippedTest.contains('.queryParam("param","value").when().async().get("/test")') - and: - stubMappingIsValidWireMockStub(contractDsl) - and: - SyntaxChecker.tryToCompile(methodBuilderName, blockBuilder.toString()) - where: - methodBuilderName | methodBuilder - "MockMvcSpockMethodBuilder" | { Contract dsl -> new MockMvcSpockMethodRequestProcessingBodyBuilder(dsl, properties) } - "MockMvcJUnitMethodBuilder" | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl, properties) } - } - - def "should generate proper test code with array of primitives using #methodBuilderName"() { - given: - Contract contractDsl = Contract.make { - request { - method 'GET' - urlPath '/api/tags' - } - response { - status OK() - body('''{ - "partners":[ - { - "payment_methods":[ "BANK", "CASH" ] - } - ] - } - ''') - } - } - MethodBodyBuilder builder = methodBuilder(contractDsl) - BlockBuilder blockBuilder = new BlockBuilder(" ") - when: - builder.appendTo(blockBuilder) - def test = blockBuilder.toString() - then: - test.contains('assertThatJson(parsedJson).array("[\'partners\']").array("[\'payment_methods\']").arrayField().isEqualTo("BANK").value()') - test.contains('assertThatJson(parsedJson).array("[\'partners\']").array("[\'payment_methods\']").arrayField().isEqualTo("CASH").value()') - and: - SyntaxChecker.tryToCompile(methodBuilderName, blockBuilder.toString()) - where: - methodBuilderName | methodBuilder - "MockMvcSpockMethodBuilder" | { Contract dsl -> new MockMvcSpockMethodRequestProcessingBodyBuilder(dsl, properties) } - "MockMvcJUnitMethodBuilder" | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl, properties) } - } - - @Issue('#273') - def "should not escape dollar in Spock regex tests"() { - given: - Contract contractDsl = Contract.make { - request { - method 'GET' - urlPath '/get' - } - response { - status OK() - body( code: 9, message: $(consumer('Wrong credentials'), producer(regex('^(?!\\s*$).+'))) ) - } - } - MethodBodyBuilder builder = new MockMvcSpockMethodRequestProcessingBodyBuilder(contractDsl, properties) - BlockBuilder blockBuilder = new BlockBuilder(" ") - when: - builder.appendTo(blockBuilder) - def test = blockBuilder.toString() - then: - test.contains('assertThatJson(parsedJson).field("[\'message\']").matches("^(?!\\\\s*\\$).+")') - and: - SyntaxChecker.tryToCompileGroovy(blockBuilder.toString(), false) - } - - Contract dslForDocs = - // tag::dsl_example[] - org.springframework.cloud.contract.spec.Contract.make { - request { - method 'PUT' - url '/api/12' - headers { - header 'Content-Type': 'application/vnd.org.springframework.cloud.contract.verifier.twitter-places-analyzer.v1+json' - } - body '''\ - [{ - "created_at": "Sat Jul 26 09:38:57 +0000 2014", - "id": 492967299297845248, - "id_str": "492967299297845248", - "text": "Gonna see you at Warsaw", - "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" - } - }] - ''' - } - response { - status OK() - } - } - // end::dsl_example[] - - Contract dslWithOnlyOneSideForDocs = - // tag::dsl_one_side_data_generation_example[] - org.springframework.cloud.contract.spec.Contract.make { - request { - method 'PUT' - url value(consumer(regex('/foo/[0-9]{5}'))) - body([ - requestElement: $(consumer(regex('[0-9]{5}'))) - ]) - headers { - header('header', $(consumer(regex('application\\/vnd\\.fraud\\.v1\\+json;.*')))) - } - } - response { - status OK() - body([ - responseElement: $(producer(regex('[0-9]{7}'))) - ]) - headers { - contentType("application/vnd.fraud.v1+json") - } - } - } - // end::dsl_one_side_data_generation_example[] - - @Issue('#32') - def "should generate the regular expression for the other side of communication"() { - given: - MethodBodyBuilder builder = new MockMvcSpockMethodRequestProcessingBodyBuilder( - dslWithOnlyOneSideForDocs, properties) - BlockBuilder blockBuilder = new BlockBuilder(" ") - when: - builder.appendTo(blockBuilder) - def test = blockBuilder.toString() - def strippedTest = test.replace('\n', '').stripIndent().stripMargin() - then: - strippedTest.matches(""".*header\\("header", "application\\/vnd\\.fraud\\.v1\\+json;.*"\\).*""") - strippedTest.matches(""".*body\\('''\\{"requestElement":"[0-9]{5}"\\}'''\\).*""") - strippedTest.matches(""".*put\\("/foo/[0-9]{5}"\\).*""") - strippedTest.contains("""response.header('Content-Type') ==~ java.util.regex.Pattern.compile('application/vnd\\\\.fraud\\\\.v1\\\\+json.*')""") - "application/vnd.fraud.v1+json;charset=UTF-8".matches('application/vnd\\.fraud\\.v1\\+json.*') - strippedTest.contains("""assertThatJson(parsedJson).field("['responseElement']").matches("[0-9]{7}")""") - and: - SyntaxChecker.tryToCompileGroovy(blockBuilder.toString()) - } - - @Issue('#85') - def "should execute custom method for complex structures on the response side"() { - given: - Contract contractDsl = Contract.make { - request { - method 'GET' - urlPath '/get' - } - response { - status OK() - body([ - fraudCheckStatus: "OK", - rejectionReason : [ - title: $(consumer(null), producer(execute('assertThatRejectionReasonIsNull($it)'))) - ] - ]) - } - } - MethodBodyBuilder builder = new MockMvcSpockMethodRequestProcessingBodyBuilder(contractDsl, properties) - BlockBuilder blockBuilder = new BlockBuilder(" ") - when: - builder.then(blockBuilder) - def test = blockBuilder.toString() - then: - test.contains('assertThatRejectionReasonIsNull(parsedJson.read(\'\'\'$.rejectionReason.title\'\'\'))') - when: - SyntaxChecker.tryToCompileGroovy(blockBuilder.toString()) - then: - def e = thrown(MultipleCompilationErrorsException) - e.message.contains("Cannot find matching method Script1#assertThatRejectionReasonIsNull") - } - - @Issue('#85') - def "should execute custom method for more complex structures on the response side when using Spock"() { - given: - Contract contractDsl = Contract.make { - request { - method 'GET' - urlPath '/get' - } - response { - status OK() - body([ - [ - name: $(consumer("userName 1"), producer(execute('assertThatUserNameIsNotNull($it)'))) - ], - [ - name: $(consumer("userName 2"), producer(execute('assertThatUserNameIsNotNull($it)'))) - ] - ]) - } - } - MethodBodyBuilder builder = new MockMvcSpockMethodRequestProcessingBodyBuilder(contractDsl, properties) - BlockBuilder blockBuilder = new BlockBuilder(" ") - when: - builder.then(blockBuilder) - def test = blockBuilder.toString() - then: - test.contains('''assertThatUserNameIsNotNull(parsedJson.read(\'\'\'$.[0].name\'\'\')''') - test.contains('''assertThatUserNameIsNotNull(parsedJson.read(\'\'\'$.[1].name\'\'\')''') - } - - @Issue('#85') - def "should execute custom method for more complex structures on the response side when using JUnit"() { - given: - Contract contractDsl = Contract.make { - request { - method 'GET' - urlPath '/get' - } - response { - status OK() - body([ - [ - name: $(consumer("userName 1"), producer(execute('assertThatUserNameIsNotNull($it)'))) - ], - [ - name: $(consumer("userName 2"), producer(execute('assertThatUserNameIsNotNull($it)'))) - ] - ]) - } - } - MethodBodyBuilder builder = new MockMvcJUnitMethodBodyBuilder(contractDsl, properties) - BlockBuilder blockBuilder = new BlockBuilder(" ") - when: - builder.then(blockBuilder) - def test = blockBuilder.toString() - then: - test.contains('''assertThatUserNameIsNotNull(parsedJson.read("$.[0].name")''') - test.contains('''assertThatUserNameIsNotNull(parsedJson.read("$.[1].name")''') - } - - @Issue('#111') - def "should execute custom method for request headers"() { - given: - Contract contractDsl = Contract.make { - request { - method 'GET' - urlPath '/get' - headers { - header('authorization', value(consumer('Bearer token'), producer(execute('getOAuthTokenHeader()')))) - } - } - response { - status OK() - body([ - fraudCheckStatus: "OK", - rejectionReason : [ - title: $(consumer(null), producer(execute('assertThatRejectionReasonIsNull($it)'))) - ] - ]) - } - } - MethodBodyBuilder builder = new MockMvcSpockMethodRequestProcessingBodyBuilder(contractDsl, properties) - BlockBuilder blockBuilder = new BlockBuilder(" ") - when: - builder.given(blockBuilder) - def test = blockBuilder.toString() - then: - test.contains('.header("authorization", getOAuthTokenHeader())') - when: - SyntaxChecker.tryToCompileGroovy(blockBuilder.toString()) - then: - def e = thrown(MultipleCompilationErrorsException) - e.message.contains("Cannot find matching method Script1#getOAuthTokenHeader") - } - - @Issue('#150') - def "should support body matching in response"() { - given: - Contract contractDsl = Contract.make { - request { - method 'GET' - url '/get' - } - response { - status OK() - body(value(stub("HELLO FROM STUB"), server(regex(".*")))) - } - } - MethodBodyBuilder builder = new MockMvcSpockMethodRequestProcessingBodyBuilder(contractDsl, properties) - BlockBuilder blockBuilder = new BlockBuilder(" ") - when: - builder.appendTo(blockBuilder) - def test = blockBuilder.toString() - then: - test.contains("responseBody ==~ java.util.regex.Pattern.compile('.*')") - and: - SyntaxChecker.tryToCompileGroovy(blockBuilder.toString()) - } - - @Issue('#150') - def "should support custom method execution in response"() { - given: - Contract contractDsl = Contract.make { - request { - method 'GET' - url '/get' - } - response { - status OK() - body(value(stub("HELLO FROM STUB"), server(execute('foo($it)')))) - } - } - MethodBodyBuilder builder = new MockMvcSpockMethodRequestProcessingBodyBuilder(contractDsl, properties) - BlockBuilder blockBuilder = new BlockBuilder(" ") - when: - builder.appendTo(blockBuilder) - def test = blockBuilder.toString() - then: - test.contains("foo(responseBody)") - when: - SyntaxChecker.tryToCompileGroovy(blockBuilder.toString()) - then: - def e = thrown(MultipleCompilationErrorsException) - e.message.contains("Cannot find matching method Script1#foo") - } - - @Issue('#149') - def "should allow c/p version of consumer producer"() { - given: - Contract contractDsl = Contract.make { - request { - method 'GET' - urlPath '/get' - headers { - header('authorization', $(c('Bearer token'), p(execute('getOAuthTokenHeader()')))) - } - } - response { - status OK() - body([ - fraudCheckStatus: "OK", - rejectionReason : [ - title: $(c(null), p(execute('assertThatRejectionReasonIsNull($it)'))) - ] - ]) - } - } - MethodBodyBuilder builder = new MockMvcSpockMethodRequestProcessingBodyBuilder(contractDsl, properties) - BlockBuilder blockBuilder = new BlockBuilder(" ") - when: - builder.given(blockBuilder) - def test = blockBuilder.toString() - then: - test.contains('.header("authorization", getOAuthTokenHeader())') - when: - SyntaxChecker.tryToCompileGroovy(blockBuilder.toString()) - then: - def e = thrown(MultipleCompilationErrorsException) - e.message.contains("Cannot find matching method Script1#getOAuthTokenHeader()") - } - - @Issue('#149') - def "should allow easier way of providing dynamic values for [#methodBuilderName]"() { - given: - Contract contractDsl = Contract.make { - request { - method 'GET' - urlPath '/get' - body([ - duck: $(regex("[0-9]")), - alpha: $(anyAlphaUnicode()), - number: $(anyNumber()), - anInteger: $(anyInteger()), - positiveInt: $(positiveInt()), - aDouble: $(anyDouble()), - aBoolean: $(aBoolean()), - ip: $(anyIpAddress()), - hostname: $(anyHostname()), - email: $(anyEmail()), - url: $(anyUrl()), - httpsUrl: $(anyHttpsUrl()), - uuid: $(anyUuid()), - date: $(anyDate()), - dateTime: $(anyDateTime()), - time: $(anyTime()), - iso8601WithOffset: $(anyIso8601WithOffset()), - nonBlankString: $(anyNonBlankString()), - nonEmptyString: $(anyNonEmptyString()), - anyOf: $(anyOf('foo', 'bar')) - ]) - headers { - contentType(applicationJson()) - } - } - response { - status OK() - body([ - alpha: $(anyAlphaUnicode()), - number: $(anyNumber()), - anInteger: $(anyInteger()), - positiveInt: $(positiveInt()), - aDouble: $(anyDouble()), - aBoolean: $(aBoolean()), - ip: $(anyIpAddress()), - hostname: $(anyHostname()), - email: $(anyEmail()), - url: $(anyUrl()), - httpsUrl: $(anyHttpsUrl()), - uuid: $(anyUuid()), - date: $(anyDate()), - dateTime: $(anyDateTime()), - time: $(anyTime()), - iso8601WithOffset: $(anyIso8601WithOffset()), - nonBlankString: $(anyNonBlankString()), - nonEmptyString: $(anyNonEmptyString()), - anyOf: $(anyOf('foo', 'bar')) - ]) - headers { - contentType(applicationJson()) - } - } - } - MethodBodyBuilder builder = methodBuilder(contractDsl) - BlockBuilder blockBuilder = new BlockBuilder(" ") - when: - builder.appendTo(blockBuilder) - def test = blockBuilder.toString() - then: - test.contains('assertThatJson(parsedJson).field("[\'aBoolean\']").matches("(true|false)")') - test.contains('assertThatJson(parsedJson).field("[\'alpha\']").matches("[\\\\p{L}]*")') - test.contains('assertThatJson(parsedJson).field("[\'hostname\']").matches("((http[s]?|ftp):/)/?([^:/\\\\s]+)(:[0-9]{1,5})?")') - test.contains('assertThatJson(parsedJson).field("[\'number\']").matches("-?(\\\\d*\\\\.\\\\d+|\\\\d+)")') - test.contains('assertThatJson(parsedJson).field("[\'anInteger\']").matches("-?(\\\\d+)")') - test.contains('assertThatJson(parsedJson).field("[\'positiveInt\']").matches("([1-9]\\\\d*)")') - test.contains('assertThatJson(parsedJson).field("[\'aDouble\']").matches("-?(\\\\d*\\\\.\\\\d+)")') - test.contains('assertThatJson(parsedJson).field("[\'email\']").matches("[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\\\.[a-zA-Z]{2,6}")') - test.contains('assertThatJson(parsedJson).field("[\'ip\']").matches("([01]?\\\\d\\\\d?|2[0-4]\\\\d|25[0-5])\\\\.([01]?\\\\d\\\\d?|2[0-4]\\\\d|25[0-5])\\\\.([01]?\\\\d\\\\d?|2[0-4]\\\\d|25[0-5])\\\\.([01]?\\\\d\\\\d?|2[0-4]\\\\d|25[0-5])")') - test.contains('assertThatJson(parsedJson).field("[\'url\']").matches("^(?:(?:[A-Za-z][+-.\\\\w^_]*:/{2})?(?:\\\\S+(?::\\\\S*)?@)?(?:(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\\\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)|(?:(?:[a-z\\\\u00a1-\\\\uffff0-9]-*)*[a-z\\\\u00a1-\\\\uffff0-9]+)(?:\\\\.(?:[a-z\\\\u00a1-\\\\uffff0-9]-*)*[a-z\\\\u00a1-\\\\uffff0-9]+)*(?:\\\\.(?:[a-z\\\\u00a1-\\\\uffff]{2,})))(?::\\\\d{2,5})?(?:/\\\\S*)?)') - test.contains('assertThatJson(parsedJson).field("[\'httpsUrl\']").matches("^(?:https:/{2}(?:\\\\S+(?::\\\\S*)?@)?(?:(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\\\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)|(?:(?:[a-z\\\\u00a1-\\\\uffff0-9]-*)*[a-z\\\\u00a1-\\\\uffff0-9]+)(?:\\\\.(?:[a-z\\\\u00a1-\\\\uffff0-9]-*)*[a-z\\\\u00a1-\\\\uffff0-9]+)*(?:\\\\.(?:[a-z\\\\u00a1-\\\\uffff]{2,})))(?::\\\\d{2,5})?(?:/\\\\S*)?)') - test.contains('assertThatJson(parsedJson).field("[\'uuid\']").matches("[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}")') - test.contains('assertThatJson(parsedJson).field("[\'date\']").matches("(\\\\d\\\\d\\\\d\\\\d)-(0[1-9]|1[012])-(0[1-9]|[12][0-9]|3[01])') - test.contains('assertThatJson(parsedJson).field("[\'dateTime\']").matches("([0-9]{4})-(1[0-2]|0[1-9])-(3[01]|0[1-9]|[12][0-9])T(2[0-3]|[01][0-9]):([0-5][0-9]):([0-5][0-9])') - test.contains('assertThatJson(parsedJson).field("[\'time\']").matches("(2[0-3]|[01][0-9]):([0-5][0-9]):([0-5][0-9])")') - test.contains('assertThatJson(parsedJson).field("[\'iso8601WithOffset\']").matches("([0-9]{4})-(1[0-2]|0[1-9])-(3[01]|0[1-9]|[12][0-9])T(2[0-3]|[01][0-9]):([0-5][0-9]):([0-5][0-9])(\\\\.\\\\d{3})?(Z|[+-][01]\\\\d:[0-5]\\\\d)")') - test.contains('assertThatJson(parsedJson).field("[\'nonBlankString\']").matches("^\\\\s*\\\\S[\\\\S\\\\s]*")') - test.contains('assertThatJson(parsedJson).field("[\'nonEmptyString\']").matches("[\\\\S\\\\s]+")') - test.contains('assertThatJson(parsedJson).field("[\'anyOf\']").matches("^foo' + endOfLineRegExSymbol + '|^bar' + endOfLineRegExSymbol + '")') - !test.contains('cursor') - !test.contains('REGEXP>>') - and: - SyntaxChecker.tryToCompile(methodBuilderName, blockBuilder.toString()) - and: - String jsonSample = '''\ -String json = "{\\"duck\\":\\"8\\",\\"alpha\\":\\"YAJEOWYGMFBEWPMEMAZI\\",\\"number\\":-2095030871,\\"anInteger\\":1780305902,\\"positiveInt\\":345,\\"aDouble\\":42.345,\\"aBoolean\\":true,\\"ip\\":\\"129.168.99.100\\",\\"hostname\\":\\"http://foo389886219.com\\",\\"email\\":\\"foo@bar1367573183.com\\",\\"url\\":\\"http://foo-597104692.com\\",\\"httpsUrl\\":\\"https://baz-486093581.com\\",\\"uuid\\":\\"e436b817-b764-49a2-908e-967f2f99eb9f\\",\\"date\\":\\"2014-04-14\\",\\"dateTime\\":\\"2011-01-11T12:23:34\\",\\"time\\":\\"12:20:30\\",\\"iso8601WithOffset\\":\\"2015-05-15T12:23:34.123Z\\",\\"nonBlankString\\":\\"EPZWVIRHSUAPBJMMQSFO\\",\\"nonEmptyString\\":\\"RVMFDSEQFHRQFVUVQPIA\\",\\"anyOf\\":\\"foo\\"}"; -DocumentContext parsedJson = JsonPath.parse(json); -''' - and: - LinkedList lines = [] as LinkedList - test.eachLine { if (it.contains("assertThatJson")) lines << it else it } - lines.addFirst(jsonSample) - SyntaxChecker.tryToRun(methodBuilderName, lines.join("\n")) - where: - methodBuilderName | methodBuilder | endOfLineRegExSymbol - "MockMvcSpockMethodBuilder" | { Contract dsl -> new MockMvcSpockMethodRequestProcessingBodyBuilder(dsl, properties) } | '\\$' - "MockMvcJUnitMethodBuilder" | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl, properties) } | '$' - } - - @Issue('#162') - def "should escape regex properly for content type"() { - given: - Contract contractDsl = Contract.make { - request { - method GET() - url 'get' - headers { - contentType("application/vnd.fraud.v1+json") - } - } - response { - status OK() - headers { - contentType("application/vnd.fraud.v1+json") - } - } - } - MethodBodyBuilder builder = methodBuilder(contractDsl) - BlockBuilder blockBuilder = new BlockBuilder(" ") - when: - builder.appendTo(blockBuilder) - def test = blockBuilder.toString() - then: - test.contains('application/vnd\\\\.fraud\\\\.v1\\\\+json.*') - and: - SyntaxChecker.tryToCompile(methodBuilderName, blockBuilder.toString()) - where: - methodBuilderName | methodBuilder - "MockMvcSpockMethodBuilder" | { Contract dsl -> new MockMvcSpockMethodRequestProcessingBodyBuilder(dsl, properties) } - "MockMvcJUnitMethodBuilder" | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl, properties) } - } - - @Issue('#173') - def "should resolve Optional object when used in query parameters"() { - given: - Contract contractDsl = Contract.make { - request { - method 'GET' - urlPath('/blacklist') { - queryParameters { - parameter 'isActive': value(consumer(optional(regex('(true|false)')))) - parameter 'limit': value(consumer(optional(regex('([0-9]{1,10})')))) - parameter 'offset': value(consumer(optional(regex('([0-9]{1,10})')))) - } - } - headers { - header 'Content-Type': 'application/json' - } - } - response { - status(200) - } - } - MethodBodyBuilder builder = methodBuilder(contractDsl) - BlockBuilder blockBuilder = new BlockBuilder(" ") - when: - builder.appendTo(blockBuilder) - def test = blockBuilder.toString() - then: - !test.contains('org.springframework.cloud.contract.spec.internal.OptionalProperty') - test.contains('(([0-9]{1,10}))?') - and: - SyntaxChecker.tryToCompile(methodBuilderName, blockBuilder.toString()) - where: - methodBuilderName | methodBuilder - "MockMvcSpockMethodBuilder" | { Contract dsl -> new MockMvcSpockMethodRequestProcessingBodyBuilder(dsl, properties) } - "MockMvcJUnitMethodBuilder" | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl, properties) } - } - - @Issue('#172') - def "should resolve plain text properly via headers"() { - given: - Contract contractDsl = Contract.make { - request { - method 'GET' - url("/foo") - } - response { - status(200) - body '{"a":1}\n{"a":2}' - headers { - contentType(textPlain()) - } - } - } - MethodBodyBuilder builder = methodBuilder(contractDsl) - BlockBuilder blockBuilder = new BlockBuilder(" ") - when: - builder.appendTo(blockBuilder) - def test = blockBuilder.toString() - then: - !test.contains('assertThatJson(parsedJson).field("[\'a\']").isEqualTo(1)') - test.contains(expectedAssertion) - and: - SyntaxChecker.tryToCompile(methodBuilderName, blockBuilder.toString()) - where: - //order is inverted cause Intellij didn't parse this properly - methodBuilderName | methodBuilder | expectedAssertion - "MockMvcSpockMethodBuilder" | { Contract dsl -> new MockMvcSpockMethodRequestProcessingBodyBuilder(dsl, properties) } | '''responseBody == "{\\"a\\":1}\\n{\\"a\\":2}"''' - "MockMvcJUnitMethodBuilder" | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl, properties) } | '''assertThat(responseBody).isEqualTo("{\\"a\\":1}\\n{\\"a\\":2}''' - } - - @Issue('#443') - def "should resolve plain text that happens to be a valid json for [#methodBuilderName]"() { - given: - Contract contractDsl = Contract.make { - request { - method 'GET' - url '/foo' - } - response { - status OK() - headers { - contentType(applicationJsonUtf8()) - } - body( - value(client('true'), server(regex("true|false"))) - ) - } - } - MethodBodyBuilder builder = methodBuilder(contractDsl) - BlockBuilder blockBuilder = new BlockBuilder(" ") - when: - builder.appendTo(blockBuilder) - def test = blockBuilder.toString() - then: - testAssertion(test) - and: - SyntaxChecker.tryToCompile(methodBuilderName, blockBuilder.toString()) - where: - methodBuilderName | methodBuilder | testAssertion - "MockMvcSpockMethodBuilder" | { Contract dsl -> new MockMvcSpockMethodRequestProcessingBodyBuilder(dsl, properties) } | { String testContents -> testContents.contains("""responseBody ==~ java.util.regex.Pattern.compile('true|false')""") } - "MockMvcJUnitMethodBuilder" | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl, properties) } | { String testContents -> testContents.contains("""assertThat(responseBody).matches("true|false");""") } - "JaxRsClientSpockMethodRequestProcessingBodyBuilder" | { Contract dsl -> new JaxRsClientSpockMethodRequestProcessingBodyBuilder(dsl, properties) } | { String testContents -> testContents.contains("""responseBody ==~ java.util.regex.Pattern.compile('true|false')""") } - "JaxRsClientJUnitMethodBodyBuilder" | { Contract dsl -> new JaxRsClientJUnitMethodBodyBuilder(dsl, properties) } | { String testContents -> testContents.contains("""assertThat(responseBody).matches("true|false");""") } - } - - @Issue('#169') - def "should escape quotes properly using [#methodBuilderName]"() { - given: - Contract contractDsl = Contract.make { - request { - method 'POST' - url '/foo' - body( - xyz: 'abc' - ) - headers { header('Content-Type', 'application/json;charset=UTF-8') } - } - response { - status OK() - body( - bar: $(producer(regex('some value \u0022with quote\u0022|bar'))) - ) - headers { header('Content-Type': 'application/json;charset=UTF-8') } - } - } - MethodBodyBuilder builder = methodBuilder(contractDsl) - BlockBuilder blockBuilder = new BlockBuilder(" ") - when: - builder.appendTo(blockBuilder) - def test = blockBuilder.toString() - then: - test.contains('assertThatJson(parsedJson).field("[\'bar\']").matches("some value \\"with quote\\"|bar")') - and: - SyntaxChecker.tryToCompile(methodBuilderName, blockBuilder.toString()) - where: - //order is inverted cause Intellij didn't parse this properly - methodBuilderName | methodBuilder | expectedAssertion - "MockMvcSpockMethodBuilder" | { Contract dsl -> new MockMvcSpockMethodRequestProcessingBodyBuilder(dsl, properties) } | '''responseBody == "{\\"a\\":1}\\n{\\"a\\":2}"''' - "MockMvcJUnitMethodBuilder" | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl, properties) } | '''assertThat(responseBody).isEqualTo("{\\"a\\":1}\\n{\\"a\\":2}''' - } - - @Issue('#169') - def "should make the execute method work in a url for [#methodBuilderName]"() { - given: - Contract contractDsl = Contract.make { - request { - method 'POST' - url $(c("foo"), p(execute("executedMethod()"))) - } - response { - status OK() - } - } - MethodBodyBuilder builder = methodBuilder(contractDsl) - BlockBuilder blockBuilder = new BlockBuilder(" ") - and: - builder.appendTo(blockBuilder) - String test = blockBuilder.toString() - when: - SyntaxChecker.tryToCompile(methodBuilderName, test) - then: - def e = thrown(Throwable) - missingMethodAssertion(e, capture) - and: - test.contains("executedMethod()") - !test.contains("\"executedMethod()\"") - !test.contains("'executedMethod()'") - where: - methodBuilderName | methodBuilder | missingMethodAssertion - "MockMvcSpockMethodBuilder" | { Contract dsl -> new MockMvcSpockMethodRequestProcessingBodyBuilder(dsl, properties) } | { Throwable t, OutputCapture capture -> t.message.contains("Cannot find matching method Script1#executedMethod") } - "MockMvcJUnitMethodBuilder" | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl, properties) } | { Throwable t, OutputCapture capture -> t.message.contains("Truncated class file") && capture.toString().contains("post(executedMethod())") } - "JaxRsClientSpockMethodRequestProcessingBodyBuilder" | { Contract dsl -> new JaxRsClientSpockMethodRequestProcessingBodyBuilder(dsl, properties) } | { Throwable t, OutputCapture capture -> t.message.contains("Cannot find matching method Script1#executedMethod") } - "JaxRsClientJUnitMethodBodyBuilder" | { Contract dsl -> new JaxRsClientJUnitMethodBodyBuilder(dsl, properties) } | { Throwable t, OutputCapture capture -> t.message.contains("Truncated class file") && capture.toString().contains("path(executedMethod())") } - } - - @Issue('#203') - def "should create an assertion for an empty list for [#methodBuilderName]"() { - given: - Contract contractDsl = Contract.make { - request { - method 'GET' - url '/api/v1/xxxx' - } - response { - status OK() - body([ - status: '200', - list: [], - foo: ["bar", "baz"] - ]) - } - } - MethodBodyBuilder builder = methodBuilder(contractDsl) - BlockBuilder blockBuilder = new BlockBuilder(" ") - and: - builder.appendTo(blockBuilder) - String test = blockBuilder.toString() - when: - SyntaxChecker.tryToCompile(methodBuilderName, test) - then: - test.contains('assertThatJson(parsedJson).array("[\'list\']").isEmpty()') - !test.contains('assertThatJson(parsedJson).array("[\'foo\']").isEmpty()') - where: - methodBuilderName | methodBuilder - "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) } - } - - @Issue("#226") - def "should work properly when body is an integer [#methodBuilderName]"() { - given: - Contract contractDsl = Contract.make { - request { - method 'GET' - url '/api/v1/xxxx' - body(12000) - } - response { - status OK() - body(12000) - } - } - MethodBodyBuilder builder = methodBuilder(contractDsl) - BlockBuilder blockBuilder = new BlockBuilder(" ") - and: - builder.appendTo(blockBuilder) - String test = blockBuilder.toString() - when: - SyntaxChecker.tryToCompile(methodBuilderName, test) - then: - requestAssertion(test) - responseAssertion(test) - where: - methodBuilderName | methodBuilder | requestAssertion | responseAssertion - "MockMvcSpockMethodBuilder" | { Contract dsl -> new MockMvcSpockMethodRequestProcessingBodyBuilder(dsl, properties) } | { String body -> body.contains("body('''12000''')") } | { String body -> body.contains('responseBody == "12000"') } - "MockMvcJUnitMethodBuilder" | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl, properties) } | { String body -> body.contains('body("12000")') } | { String body -> body.contains('assertThat(responseBody).isEqualTo("12000");') } - "JaxRsClientSpockMethodRequestProcessingBodyBuilder" | { Contract dsl -> new JaxRsClientSpockMethodRequestProcessingBodyBuilder(dsl, properties) } | { String body -> body.contains(""".method('GET', entity('12000', 'text/plain'))""") } | { String body -> body.contains('responseBody == "12000"') } - "JaxRsClientJUnitMethodBodyBuilder" | { Contract dsl -> new JaxRsClientJUnitMethodBodyBuilder(dsl, properties) } | { String body -> body.contains(""".method("GET", entity("12000", "text/plain"))""") } | { String body -> body.contains('assertThat(responseBody).isEqualTo("12000")') } - } - - @Issue("#230") - def "should manage to reference request in response [#methodBuilderName]"() { - given: - //tag::template_contract[] - Contract contractDsl = Contract.make { - request { - method 'GET' - url('/api/v1/xxxx') { - queryParameters { - parameter("foo", "bar") - parameter("foo", "bar2") - } - } - headers { - header(authorization(), "secret") - header(authorization(), "secret2") - } - body(foo: "bar", baz: 5) - } - response { - status OK() - headers { - header(authorization(), "foo ${fromRequest().header(authorization())} bar") - } - body( - url: fromRequest().url(), - path: fromRequest().path(), - pathIndex: fromRequest().path(1), - param: fromRequest().query("foo"), - paramIndex: fromRequest().query("foo", 1), - authorization: fromRequest().header("Authorization"), - authorization2: fromRequest().header("Authorization", 1), - fullBody: fromRequest().body(), - responseFoo: fromRequest().body('$.foo'), - responseBaz: fromRequest().body('$.baz'), - responseBaz2: "Bla bla ${fromRequest().body('$.foo')} bla bla", - rawUrl: fromRequest().rawUrl(), - rawPath: fromRequest().rawPath(), - rawPathIndex: fromRequest().rawPath(1), - rawParam: fromRequest().rawQuery("foo"), - rawParamIndex: fromRequest().rawQuery("foo", 1), - rawAuthorization: fromRequest().rawHeader("Authorization"), - rawAuthorization2: fromRequest().rawHeader("Authorization", 1), - rawResponseFoo: fromRequest().rawBody('$.foo'), - rawResponseBaz: fromRequest().rawBody('$.baz'), - rawResponseBaz2: "Bla bla ${fromRequest().rawBody('$.foo')} bla bla" - ) - } - } - //end::template_contract[] - MethodBodyBuilder builder = methodBuilder(contractDsl) - BlockBuilder blockBuilder = new BlockBuilder(" ") - and: - builder.appendTo(blockBuilder) - String test = blockBuilder.toString() - when: - SyntaxChecker.tryToCompileWithoutCompileStatic(methodBuilderName, test) - then: - !test.contains('''DslProperty''') - !test.contains('''ERROR: ''') - test.contains('''assertThatJson(parsedJson).field("['url']").isEqualTo("/api/v1/xxxx?foo=bar&foo=bar2")''') - test.contains('''assertThatJson(parsedJson).field("['path']").isEqualTo("/api/v1/xxxx")''') - test.contains('''assertThatJson(parsedJson).field("['pathIndex']").isEqualTo("v1")''') - test.contains('''assertThatJson(parsedJson).field("['fullBody']").isEqualTo("{\\"foo\\":\\"bar\\",\\"baz\\":5}")''') - test.contains('''assertThatJson(parsedJson).field("['paramIndex']").isEqualTo("bar2")''') - test.contains('''assertThatJson(parsedJson).field("['responseFoo']").isEqualTo("bar")''') - test.contains('''assertThatJson(parsedJson).field("['authorization']").isEqualTo("secret")''') - test.contains('''assertThatJson(parsedJson).field("['authorization2']").isEqualTo("secret2")''') - test.contains('''assertThatJson(parsedJson).field("['responseBaz']").isEqualTo(5)''') - test.contains('''assertThatJson(parsedJson).field("['responseBaz2']").isEqualTo("Bla bla bar bla bla")''') - test.contains('''assertThatJson(parsedJson).field("['param']").isEqualTo("bar")''') - test.contains('''assertThatJson(parsedJson).field("['rawUrl']").isEqualTo("/api/v1/xxxx?foo=bar&foo=bar2")''') - test.contains('''assertThatJson(parsedJson).field("['rawPath']").isEqualTo("/api/v1/xxxx")''') - test.contains('''assertThatJson(parsedJson).field("['rawPathIndex']").isEqualTo("v1")''') - test.contains('''assertThatJson(parsedJson).field("['rawParamIndex']").isEqualTo("bar2")''') - test.contains('''assertThatJson(parsedJson).field("['rawResponseFoo']").isEqualTo("bar")''') - test.contains('''assertThatJson(parsedJson).field("['rawAuthorization']").isEqualTo("secret")''') - test.contains('''assertThatJson(parsedJson).field("['rawAuthorization2']").isEqualTo("secret2")''') - test.contains('''assertThatJson(parsedJson).field("['rawResponseBaz']").isEqualTo(5)''') - test.contains('''assertThatJson(parsedJson).field("['rawResponseBaz2']").isEqualTo("Bla bla bar bla bla")''') - test.contains('''assertThatJson(parsedJson).field("['rawParam']").isEqualTo("bar")''') - responseAssertion(test) - where: - methodBuilderName | methodBuilder | responseAssertion - "MockMvcSpockMethodBuilder" | { Contract dsl -> new MockMvcSpockMethodRequestProcessingBodyBuilder(dsl, properties) } | { String body -> body.contains("response.header('Authorization') == 'foo secret bar'") } - "MockMvcJUnitMethodBuilder" | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl, properties) } | { String body -> body.contains('assertThat(response.header("Authorization")).isEqualTo("foo secret bar");') } - "JaxRsClientSpockMethodRequestProcessingBodyBuilder" | { Contract dsl -> new JaxRsClientSpockMethodRequestProcessingBodyBuilder(dsl, properties) } | { String body -> body.contains("response.getHeaderString('Authorization') == 'foo secret bar'") } - "JaxRsClientJUnitMethodBodyBuilder" | { Contract dsl -> new JaxRsClientJUnitMethodBodyBuilder(dsl, properties) } | { String body -> body.contains('assertThat(response.getHeaderString("Authorization")).isEqualTo("foo secret bar");') } - } - - @Issue("#230") - def "should manage to reference request in response via WireMock native entries [#methodBuilderName]"() { - given: - //tag::template_contract[] - Contract contractDsl = Contract.make { - request { - method 'GET' - url('/api/v1/xxxx') { - queryParameters { - parameter("foo", "bar") - parameter("foo", "bar2") - } - } - headers { - header(authorization(), "secret") - header(authorization(), "secret2") - } - body(foo: "bar", baz: 5) - } - response { - status OK() - headers { - contentType(applicationJson()) - } - body(''' - { - "responseFoo": "{{{ jsonPath request.body '$.foo' }}}", - "responseBaz": {{{ jsonPath request.body '$.baz' }}}, - "responseBaz2": "Bla bla {{{ jsonPath request.body '$.foo' }}} bla bla" - } - '''.toString()) - } - } - //end::template_contract[] - MethodBodyBuilder builder = methodBuilder(contractDsl) - BlockBuilder blockBuilder = new BlockBuilder(" ") - and: - builder.appendTo(blockBuilder) - String test = blockBuilder.toString() - when: - SyntaxChecker.tryToCompileWithoutCompileStatic(methodBuilderName, test) - then: - !test.contains('''DslProperty''') - test.contains('''assertThatJson(parsedJson).field("['responseFoo']").isEqualTo("bar")''') - test.contains('''assertThatJson(parsedJson).field("['responseBaz']").isEqualTo(5)''') - test.contains('''assertThatJson(parsedJson).field("['responseBaz2']").isEqualTo("Bla bla bar bla bla")''') - where: - methodBuilderName | methodBuilder - "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) } - } - - def "should generate JUnit assertions with cookies"() { - given: - MethodBodyBuilder builder = new MockMvcJUnitMethodBodyBuilder(contractDslWithCookiesValue, properties) - BlockBuilder blockBuilder = new BlockBuilder(" ") - when: - builder.appendTo(blockBuilder) - def test = blockBuilder.toString() - then: - test.contains('''.cookie("cookie-key", "cookie-value")''') - test.contains('''assertThat(response.getCookie("cookie-key")).isNotNull();''') - test.contains('''assertThat(response.getCookie("cookie-key")).isEqualTo("new-cookie-value");''') - and: - SyntaxChecker.tryToCompile("MockMvcJUnitMethodBodyBuilder", blockBuilder.toString()) - } - - def "should generate JUnit assertions with cookies pattern"() { - given: - MethodBodyBuilder builder = new MockMvcJUnitMethodBodyBuilder(contractDslWithCookiesPattern, properties) - BlockBuilder blockBuilder = new BlockBuilder(" ") - when: - builder.appendTo(blockBuilder) - def test = blockBuilder.toString() - then: - test.contains('''.cookie("cookie-key", "[A-Za-z]+")''') - test.contains('''assertThat(response.getCookie("cookie-key")).isNotNull();''') - test.contains('''assertThat(response.getCookie("cookie-key")).matches("[A-Za-z]+");''') - and: - SyntaxChecker.tryToCompile("MockMvcJUnitMethodBodyBuilder", blockBuilder.toString()) - } - - def "should not generate JUnit cookie assertion with absent cookie"() { - given: - MethodBodyBuilder builder = new MockMvcJUnitMethodBodyBuilder(contractDslWithAbsentCookies, properties) - BlockBuilder blockBuilder = new BlockBuilder(" ") - when: - builder.appendTo(blockBuilder) - def test = blockBuilder.toString() - then: - !test.contains("cookie") - and: - SyntaxChecker.tryToCompile("MockMvcJUnitMethodBodyBuilder", blockBuilder.toString()) - } - - def "should generate spock assertions with cookies"() { - given: - MethodBodyBuilder builder = new MockMvcSpockMethodRequestProcessingBodyBuilder(contractDslWithCookiesValue, properties) - BlockBuilder blockBuilder = new BlockBuilder(" ") - when: - builder.appendTo(blockBuilder) - def test = blockBuilder.toString() - then: - test.contains('''.cookie("cookie-key", "cookie-value")''') - test.contains('''response.cookie('cookie-key') != null''') - test.contains('''response.cookie('cookie-key') == 'new-cookie-value''') - and: - SyntaxChecker.tryToCompile("MockMvcSpockMethodRequestProcessingBodyBuilder", blockBuilder.toString()) - } - - def "should generate spock assertions with cookies pattern"() { - given: - MethodBodyBuilder builder = new MockMvcSpockMethodRequestProcessingBodyBuilder(contractDslWithCookiesPattern, properties) - BlockBuilder blockBuilder = new BlockBuilder(" ") - when: - builder.appendTo(blockBuilder) - def test = blockBuilder.toString() - then: - test.contains('''.cookie("cookie-key", "[A-Za-z]+")''') - test.contains('''response.cookie('cookie-key') != null''') - test.contains('''response.cookie('cookie-key') ==~ java.util.regex.Pattern.compile('[A-Za-z]+')''') - and: - SyntaxChecker.tryToCompile("MockMvcSpockMethodRequestProcessingBodyBuilder", blockBuilder.toString()) - } - - def "should not generate spock cookie assertion with absent cookie"() { - given: - MethodBodyBuilder builder = new MockMvcSpockMethodRequestProcessingBodyBuilder(contractDslWithAbsentCookies, properties) - BlockBuilder blockBuilder = new BlockBuilder(" ") - when: - builder.appendTo(blockBuilder) - def test = blockBuilder.toString() - then: - !test.contains("cookie") - and: - SyntaxChecker.tryToCompile("MockMvcSpockMethodRequestProcessingBodyBuilder", blockBuilder.toString()) - } - - @Issue('#554') - def "should create an assertion for an empty map or Object for [#methodBuilderName]"() { - given: - Contract contractDsl = Contract.make { - request { - method 'GET' - url '/api/v1/xxxx' - } - response { - status 200 - body([ - aMap : ["foo": "bar"], - anEmptyMap: [:] - ]) - } - } - MethodBodyBuilder builder = methodBuilder(contractDsl) - BlockBuilder blockBuilder = new BlockBuilder(" ") - and: - builder.appendTo(blockBuilder) - String test = blockBuilder.toString() - when: - SyntaxChecker.tryToRun(methodBuilderName, test.join("\n")) - then: - test.contains('''assertThatJson(parsedJson).field("['aMap']").field("['foo']").isEqualTo("bar")''') - test.contains('''assertThatJson(parsedJson).field("['anEmptyMap']").isEmpty()''') - where: - methodBuilderName | methodBuilder - "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) } - } -} 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 ce7b49fa2d..454eb61f72 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 @@ -28,430 +28,438 @@ import spock.lang.Specification class MockMvcMethodBodyBuilderWithMatchersSpec extends Specification implements WireMockStubVerifier { - @Rule OutputCapture outputCapture = new OutputCapture() + @Rule + OutputCapture outputCapture = new OutputCapture() - @Shared ContractVerifierConfigProperties properties = new ContractVerifierConfigProperties( - assertJsonSize: true - ) + @Shared + ContractVerifierConfigProperties properties = new ContractVerifierConfigProperties( + assertJsonSize: true + ) - @Issue('#185') - def "should allow to set dynamic values via stub / test matchers for [#methodBuilderName]"() { - given: - //tag::matchers[] - Contract contractDsl = Contract.make { - request { - method 'GET' - urlPath '/get' - body([ - duck: 123, - alpha: "abc", - number: 123, - aBoolean: true, - date: "2017-01-01", - dateTime: "2017-01-01T01:23:45", - time: "01:02:34", - valueWithoutAMatcher: "foo", - valueWithTypeMatch: "string", - key: [ - 'complex.key' : 'foo' - ] - ]) - bodyMatchers { - jsonPath('$.duck', byRegex("[0-9]{3}")) - jsonPath('$.duck', byEquality()) - jsonPath('$.alpha', byRegex(onlyAlphaUnicode())) - jsonPath('$.alpha', byEquality()) - jsonPath('$.number', byRegex(number())) - jsonPath('$.aBoolean', byRegex(anyBoolean())) - jsonPath('$.date', byDate()) - jsonPath('$.dateTime', byTimestamp()) - jsonPath('$.time', byTime()) - jsonPath("\$.['key'].['complex.key']", byEquality()) - } - headers { - contentType(applicationJson()) - } - } - response { - status OK() - body([ - duck: 123, - alpha: "abc", - number: 123, - positiveInteger: 1234567890, - negativeInteger: -1234567890, - positiveDecimalNumber: 123.4567890, - negativeDecimalNumber: -123.4567890, - aBoolean: true, - date: "2017-01-01", - dateTime: "2017-01-01T01:23:45", - time: "01:02:34", - valueWithoutAMatcher: "foo", - valueWithTypeMatch: "string", - valueWithMin: [ - 1,2,3 - ], - valueWithMax: [ - 1,2,3 - ], - valueWithMinMax: [ - 1,2,3 - ], - valueWithMinEmpty: [], - valueWithMaxEmpty: [], - key: [ - 'complex.key' : 'foo' - ], - nullValue: null - ]) - bodyMatchers { - // asserts the jsonpath value against manual regex - jsonPath('$.duck', byRegex("[0-9]{3}")) - // asserts the jsonpath value against the provided value - jsonPath('$.duck', byEquality()) - // asserts the jsonpath value against some default regex - jsonPath('$.alpha', byRegex(onlyAlphaUnicode())) - jsonPath('$.alpha', byEquality()) - jsonPath('$.number', byRegex(number())) - jsonPath('$.positiveInteger', byRegex(anInteger())) - jsonPath('$.negativeInteger', byRegex(anInteger())) - jsonPath('$.positiveDecimalNumber', byRegex(aDouble())) - jsonPath('$.negativeDecimalNumber', byRegex(aDouble())) - jsonPath('$.aBoolean', byRegex(anyBoolean())) - // asserts vs inbuilt time related regex - jsonPath('$.date', byDate()) - jsonPath('$.dateTime', byTimestamp()) - jsonPath('$.time', byTime()) - // asserts that the resulting type is the same as in response body - jsonPath('$.valueWithTypeMatch', byType()) - jsonPath('$.valueWithMin', byType { - // results in verification of size of array (min 1) - minOccurrence(1) - }) - jsonPath('$.valueWithMax', byType { - // results in verification of size of array (max 3) - maxOccurrence(3) - }) - jsonPath('$.valueWithMinMax', byType { - // results in verification of size of array (min 1 & max 3) - minOccurrence(1) - maxOccurrence(3) - }) - jsonPath('$.valueWithMinEmpty', byType { - // results in verification of size of array (min 0) - minOccurrence(0) - }) - jsonPath('$.valueWithMaxEmpty', byType { - // results in verification of size of array (max 0) - maxOccurrence(0) - }) - // will execute a method `assertThatValueIsANumber` - jsonPath('$.duck', byCommand('assertThatValueIsANumber($it)')) - jsonPath("\$.['key'].['complex.key']", byEquality()) - jsonPath('$.nullValue', byNull()) - } - headers { - contentType(applicationJson()) - header('Some-Header', $(c('someValue'), p(regex('[a-zA-Z]{9}')))) - } - } - } - //end::matchers[] - MethodBodyBuilder builder = methodBuilder(contractDsl) - BlockBuilder blockBuilder = new BlockBuilder(" ") - when: - builder.appendTo(blockBuilder) - def test = blockBuilder.toString() - then: - test.contains('assertThat(parsedJson.read("' + rootElement + '.duck", String.class)).matches("[0-9]{3}")') - test.contains('assertThat(parsedJson.read("' + rootElement + '.duck", Integer.class)).isEqualTo(123)') - test.contains('assertThat(parsedJson.read("' + rootElement + '.alpha", String.class)).matches("[\\\\p{L}]*")') - test.contains('assertThat(parsedJson.read("' + rootElement + '.alpha", String.class)).isEqualTo("abc")') - test.contains('assertThat(parsedJson.read("' + rootElement + '.number", String.class)).matches("-?(\\\\d*\\\\.\\\\d+|\\\\d+)")') - test.contains('assertThat(parsedJson.read("' + rootElement + '.positiveInteger", String.class)).matches("-?(\\\\d+)")') - test.contains('assertThat(parsedJson.read("' + rootElement + '.negativeInteger", String.class)).matches("-?(\\\\d+)")') - test.contains('assertThat(parsedJson.read("' + rootElement + '.positiveDecimalNumber", String.class)).matches("-?(\\\\d*\\\\.\\\\d+)")') - test.contains('assertThat(parsedJson.read("' + rootElement + '.negativeDecimalNumber", String.class)).matches("-?(\\\\d*\\\\.\\\\d+)")') - test.contains('assertThat(parsedJson.read("' + rootElement + '.aBoolean", String.class)).matches("(true|false)")') - test.contains('assertThat(parsedJson.read("' + rootElement + '.date", String.class)).matches("(\\\\d\\\\d\\\\d\\\\d)-(0[1-9]|1[012])-(0[1-9]|[12][0-9]|3[01])")') - test.contains('assertThat(parsedJson.read("' + rootElement + '.dateTime", String.class)).matches("([0-9]{4})-(1[0-2]|0[1-9])-(3[01]|0[1-9]|[12][0-9])T(2[0-3]|[01][0-9]):([0-5][0-9]):([0-5][0-9])")') - test.contains('assertThat(parsedJson.read("' + rootElement + '.time", String.class)).matches("(2[0-3]|[01][0-9]):([0-5][0-9]):([0-5][0-9])")') - test.contains('assertThat((Object) parsedJson.read("' + rootElement + '.valueWithTypeMatch")).isInstanceOf(java.lang.String.class)') - test.contains('assertThat((Object) parsedJson.read("' + rootElement + '.valueWithMin")).isInstanceOf(java.util.List.class)') - test.contains('assertThat((java.lang.Iterable) parsedJson.read("' + rootElement + '.valueWithMin", java.util.Collection.class)).as("' + rootElement + '.valueWithMin").hasSizeGreaterThanOrEqualTo(1)') - test.contains('assertThat((Object) parsedJson.read("' + rootElement + '.valueWithMax")).isInstanceOf(java.util.List.class)') - test.contains('assertThat((java.lang.Iterable) parsedJson.read("' + rootElement + '.valueWithMax", java.util.Collection.class)).as("' + rootElement + '.valueWithMax").hasSizeLessThanOrEqualTo(3)') - test.contains('assertThat((Object) parsedJson.read("' + rootElement + '.valueWithMinMax")).isInstanceOf(java.util.List.class)') - test.contains('assertThat((java.lang.Iterable) parsedJson.read("' + rootElement + '.valueWithMinMax", java.util.Collection.class)).as("' + rootElement + '.valueWithMinMax").hasSizeBetween(1, 3)') - test.contains('assertThat((Object) parsedJson.read("' + rootElement + '.valueWithMinEmpty")).isInstanceOf(java.util.List.class)') - test.contains('assertThat((java.lang.Iterable) parsedJson.read("' + rootElement + '.valueWithMinEmpty", java.util.Collection.class)).as("' + rootElement + '.valueWithMinEmpty").hasSizeGreaterThanOrEqualTo(0)') - test.contains('assertThat((Object) parsedJson.read("' + rootElement + '.valueWithMaxEmpty")).isInstanceOf(java.util.List.class)') - test.contains('assertThat((java.lang.Iterable) parsedJson.read("' + rootElement + '.valueWithMaxEmpty", java.util.Collection.class)).as("' + rootElement + '.valueWithMaxEmpty").hasSizeLessThanOrEqualTo(0)') - test.contains('assertThatValueIsANumber(parsedJson.read("' + rootElement + '.duck")') - test.contains('assertThat(parsedJson.read("' + rootElement + '''.['key'].['complex.key']", String.class)).isEqualTo("foo")''') - test.contains('assertThat(parsedJson.read("' + rootElement + '.nullValue")).isNull()') - !test.contains('cursor') - and: - try { - SyntaxChecker.tryToCompileWithoutCompileStatic(methodBuilderName, blockBuilder.toString()) - } catch (ClassFormatError classFormatError) { - String output = outputCapture.toString() - assert output.contains('error: cannot find symbol') - assert output.contains('assertThatValueIsANumber(parsedJson.read("$.duck"));') - } - 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) } | '$' - } + @Issue('#185') + def 'should allow to set dynamic values via stub / test matchers for [#methodBuilderName]'() { + given: + //tag::matchers[] + Contract contractDsl = Contract.make { + request { + method 'GET' + urlPath '/get' + body([ + duck : 123, + alpha : 'abc', + number : 123, + aBoolean : true, + date : '2017-01-01', + dateTime : '2017-01-01T01:23:45', + time : '01:02:34', + valueWithoutAMatcher: 'foo', + valueWithTypeMatch : 'string', + key : [ + 'complex.key': 'foo' + ] + ]) + bodyMatchers { + jsonPath('$.duck', byRegex("[0-9]{3}")) + jsonPath('$.duck', byEquality()) + jsonPath('$.alpha', byRegex(onlyAlphaUnicode())) + jsonPath('$.alpha', byEquality()) + jsonPath('$.number', byRegex(number())) + jsonPath('$.aBoolean', byRegex(anyBoolean())) + jsonPath('$.date', byDate()) + jsonPath('$.dateTime', byTimestamp()) + jsonPath('$.time', byTime()) + jsonPath("\$.['key'].['complex.key']", byEquality()) + } + headers { + contentType(applicationJson()) + } + } + response { + status OK() + body([ + duck : 123, + alpha : 'abc', + number : 123, + positiveInteger : 1234567890, + negativeInteger : -1234567890, + positiveDecimalNumber: 123.4567890, + negativeDecimalNumber: -123.4567890, + aBoolean : true, + date : '2017-01-01', + dateTime : '2017-01-01T01:23:45', + time : "01:02:34", + valueWithoutAMatcher : 'foo', + valueWithTypeMatch : 'string', + valueWithMin : [ + 1, 2, 3 + ], + valueWithMax : [ + 1, 2, 3 + ], + valueWithMinMax : [ + 1, 2, 3 + ], + valueWithMinEmpty : [], + valueWithMaxEmpty : [], + key : [ + 'complex.key': 'foo' + ], + nullValue : null + ]) + bodyMatchers { + // asserts the jsonpath value against manual regex + jsonPath('$.duck', byRegex("[0-9]{3}")) + // asserts the jsonpath value against the provided value + jsonPath('$.duck', byEquality()) + // asserts the jsonpath value against some default regex + jsonPath('$.alpha', byRegex(onlyAlphaUnicode())) + jsonPath('$.alpha', byEquality()) + jsonPath('$.number', byRegex(number())) + jsonPath('$.positiveInteger', byRegex(anInteger())) + jsonPath('$.negativeInteger', byRegex(anInteger())) + jsonPath('$.positiveDecimalNumber', byRegex(aDouble())) + jsonPath('$.negativeDecimalNumber', byRegex(aDouble())) + jsonPath('$.aBoolean', byRegex(anyBoolean())) + // asserts vs inbuilt time related regex + jsonPath('$.date', byDate()) + jsonPath('$.dateTime', byTimestamp()) + jsonPath('$.time', byTime()) + // asserts that the resulting type is the same as in response body + jsonPath('$.valueWithTypeMatch', byType()) + jsonPath('$.valueWithMin', byType { + // results in verification of size of array (min 1) + minOccurrence(1) + }) + jsonPath('$.valueWithMax', byType { + // results in verification of size of array (max 3) + maxOccurrence(3) + }) + jsonPath('$.valueWithMinMax', byType { + // results in verification of size of array (min 1 & max 3) + minOccurrence(1) + maxOccurrence(3) + }) + jsonPath('$.valueWithMinEmpty', byType { + // results in verification of size of array (min 0) + minOccurrence(0) + }) + jsonPath('$.valueWithMaxEmpty', byType { + // results in verification of size of array (max 0) + maxOccurrence(0) + }) + // will execute a method `assertThatValueIsANumber` + jsonPath('$.duck', byCommand('assertThatValueIsANumber($it)')) + jsonPath("\$.['key'].['complex.key']", byEquality()) + jsonPath('$.nullValue', byNull()) + } + headers { + contentType(applicationJson()) + header('Some-Header', $(c('someValue'), p(regex('[a-zA-Z]{9}')))) + } + } + } + //end::matchers[] + MethodBodyBuilder builder = methodBuilder(contractDsl) + BlockBuilder blockBuilder = new BlockBuilder(" ") + when: + builder.appendTo(blockBuilder) + def test = blockBuilder.toString() + then: + test.contains('assertThat(parsedJson.read("' + rootElement + '.duck", String.class)).matches("[0-9]{3}")') + test.contains('assertThat(parsedJson.read("' + rootElement + '.duck", Integer.class)).isEqualTo(123)') + test.contains('assertThat(parsedJson.read("' + rootElement + '.alpha", String.class)).matches("[\\\\p{L}]*")') + test.contains('assertThat(parsedJson.read("' + rootElement + '.alpha", String.class)).isEqualTo("abc")') + test.contains('assertThat(parsedJson.read("' + rootElement + '.number", String.class)).matches("-?(\\\\d*\\\\.\\\\d+|\\\\d+)")') + test.contains('assertThat(parsedJson.read("' + rootElement + '.positiveInteger", String.class)).matches("-?(\\\\d+)")') + test.contains('assertThat(parsedJson.read("' + rootElement + '.negativeInteger", String.class)).matches("-?(\\\\d+)")') + test.contains('assertThat(parsedJson.read("' + rootElement + '.positiveDecimalNumber", String.class)).matches("-?(\\\\d*\\\\.\\\\d+)")') + test.contains('assertThat(parsedJson.read("' + rootElement + '.negativeDecimalNumber", String.class)).matches("-?(\\\\d*\\\\.\\\\d+)")') + test.contains('assertThat(parsedJson.read("' + rootElement + '.aBoolean", String.class)).matches("(true|false)")') + test.contains('assertThat(parsedJson.read("' + rootElement + '.date", String.class)).matches("(\\\\d\\\\d\\\\d\\\\d)-(0[1-9]|1[012])-(0[1-9]|[12][0-9]|3[01])")') + test.contains('assertThat(parsedJson.read("' + rootElement + '.dateTime", String.class)).matches("([0-9]{4})-(1[0-2]|0[1-9])-(3[01]|0[1-9]|[12][0-9])T(2[0-3]|[01][0-9]):([0-5][0-9]):([0-5][0-9])")') + test.contains('assertThat(parsedJson.read("' + rootElement + '.time", String.class)).matches("(2[0-3]|[01][0-9]):([0-5][0-9]):([0-5][0-9])")') + test.contains('assertThat((Object) parsedJson.read("' + rootElement + '.valueWithTypeMatch")).isInstanceOf(java.lang.String.class)') + test.contains('assertThat((Object) parsedJson.read("' + rootElement + '.valueWithMin")).isInstanceOf(java.util.List.class)') + test.contains('assertThat((java.lang.Iterable) parsedJson.read("' + rootElement + '.valueWithMin", java.util.Collection.class)).as("' + rootElement + '.valueWithMin").hasSizeGreaterThanOrEqualTo(1)') + test.contains('assertThat((Object) parsedJson.read("' + rootElement + '.valueWithMax")).isInstanceOf(java.util.List.class)') + test.contains('assertThat((java.lang.Iterable) parsedJson.read("' + rootElement + '.valueWithMax", java.util.Collection.class)).as("' + rootElement + '.valueWithMax").hasSizeLessThanOrEqualTo(3)') + test.contains('assertThat((Object) parsedJson.read("' + rootElement + '.valueWithMinMax")).isInstanceOf(java.util.List.class)') + test.contains('assertThat((java.lang.Iterable) parsedJson.read("' + rootElement + '.valueWithMinMax", java.util.Collection.class)).as("' + rootElement + '.valueWithMinMax").hasSizeBetween(1, 3)') + test.contains('assertThat((Object) parsedJson.read("' + rootElement + '.valueWithMinEmpty")).isInstanceOf(java.util.List.class)') + test.contains('assertThat((java.lang.Iterable) parsedJson.read("' + rootElement + '.valueWithMinEmpty", java.util.Collection.class)).as("' + rootElement + '.valueWithMinEmpty").hasSizeGreaterThanOrEqualTo(0)') + test.contains('assertThat((Object) parsedJson.read("' + rootElement + '.valueWithMaxEmpty")).isInstanceOf(java.util.List.class)') + test.contains('assertThat((java.lang.Iterable) parsedJson.read("' + rootElement + '.valueWithMaxEmpty", java.util.Collection.class)).as("' + rootElement + '.valueWithMaxEmpty").hasSizeLessThanOrEqualTo(0)') + test.contains('assertThatValueIsANumber(parsedJson.read("' + rootElement + '.duck")') + test.contains('assertThat(parsedJson.read("' + rootElement + '''.['key'].['complex.key']", String.class)).isEqualTo("foo")''') + test.contains('assertThat(parsedJson.read("' + rootElement + '.nullValue")).isNull()') + !test.contains('cursor') + and: + try { + SyntaxChecker.tryToCompileWithoutCompileStatic(methodBuilderName, blockBuilder.toString()) + } catch (ClassFormatError classFormatError) { + String output = outputCapture.toString() + assert output.contains('error: cannot find symbol') + assert output.contains('assertThatValueIsANumber(parsedJson.read("$.duck"));') + } + where: + methodBuilderName | methodBuilder | rootElement + HttpSpockMethodRequestProcessingBodyBuilder.simpleName | { Contract dsl -> new HttpSpockMethodRequestProcessingBodyBuilder(dsl, properties) } | '\\$' + MockMvcJUnitMethodBodyBuilder.simpleName | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl, properties) } | '$' + JaxRsClientSpockMethodRequestProcessingBodyBuilder.simpleName | { Contract dsl -> new JaxRsClientSpockMethodRequestProcessingBodyBuilder(dsl, properties) } | '\\$' + JaxRsClientJUnitMethodBodyBuilder.simpleName | { Contract dsl -> new JaxRsClientJUnitMethodBodyBuilder(dsl, properties) } | '$' + WebTestClientJUnitMethodBodyBuilder.simpleName | { Contract dsl -> new WebTestClientJUnitMethodBodyBuilder(dsl, properties) } | '$' + } - @Issue('#217') - def "should allow complex matchers for [#methodBuilderName]"() { - given: - Contract contractDsl = Contract.make { - request { - method 'GET' - url 'person' - } - response { - status OK() - body([ - "firstName": "Jane", - "lastName": "Doe", - "isAlive": true, - "address": [ - "postalCode": "98101", - ], - "phoneNumbers": [ - [ - "type": "home", - "number": "999 999-9999", - ] - ], - "gender": [ - "type": "female", - ], - "children": [ - [ - "firstName": "Kid", - "age": 55, - ] - ], - ]) - bodyMatchers { - jsonPath('$.phoneNumbers', byType { - minOccurrence(0) // min occurrence of 1 - maxOccurrence(4) // max occurrence of 3 - }) - 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') - } - } - } - MethodBodyBuilder builder = methodBuilder(contractDsl) - BlockBuilder blockBuilder = new BlockBuilder(" ") - when: - builder.appendTo(blockBuilder) - def test = blockBuilder.toString() - then: - test.contains('assertThat((java.lang.Iterable) parsedJson.read("' + rootElement + '.phoneNumbers[*].number", java.util.Collection.class)).as("' + rootElement + '.phoneNumbers[*].number").allElementsMatch("^[0-9]{3} [0-9]{3}-[0-9]{4}' + rootElement + '")') - test.contains('assertThat((java.lang.Iterable) parsedJson.read("' + rootElement + '..number", java.util.Collection.class)).as("' + rootElement + '..number").allElementsMatch("^[0-9]{3} [0-9]{3}-[0-9]{4}' + rootElement + '")') - !test.contains('cursor') - and: - try { - SyntaxChecker.tryToCompileWithoutCompileStatic(methodBuilderName, blockBuilder.toString()) - } catch(NoClassDefFoundError error) { - // that's actually expected since we're creating an anonymous class - } - 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) } | '$' - } + @Issue('#217') + def 'should allow complex matchers for [#methodBuilderName]'() { + given: + Contract contractDsl = Contract.make { + request { + method 'GET' + url 'person' + } + response { + status OK() + body([ + "firstName" : 'Jane', + "lastName" : 'Doe', + "isAlive" : true, + "address" : [ + "postalCode": '98101', + ], + "phoneNumbers": [ + [ + "type" : 'home', + "number": '999 999-9999', + ] + ], + "gender" : [ + "type": 'female', + ], + "children" : [ + [ + "firstName": 'Kid', + "age" : 55, + ] + ], + ]) + bodyMatchers { + jsonPath('$.phoneNumbers', byType { + minOccurrence(0) // min occurrence of 1 + maxOccurrence(4) // max occurrence of 3 + }) + 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') + } + } + } + MethodBodyBuilder builder = methodBuilder(contractDsl) + BlockBuilder blockBuilder = new BlockBuilder(" ") + when: + builder.appendTo(blockBuilder) + def test = blockBuilder.toString() + then: + test.contains('assertThat((java.lang.Iterable) parsedJson.read("' + rootElement + '.phoneNumbers[*].number", java.util.Collection.class)).as("' + rootElement + '.phoneNumbers[*].number").allElementsMatch("^[0-9]{3} [0-9]{3}-[0-9]{4}' + rootElement + '")') + test.contains('assertThat((java.lang.Iterable) parsedJson.read("' + rootElement + '..number", java.util.Collection.class)).as("' + rootElement + '..number").allElementsMatch("^[0-9]{3} [0-9]{3}-[0-9]{4}' + rootElement + '")') + !test.contains('cursor') + and: + try { + SyntaxChecker.tryToCompileWithoutCompileStatic(methodBuilderName, blockBuilder.toString()) + } catch (NoClassDefFoundError error) { + // that's actually expected since we're creating an anonymous class + } + where: + methodBuilderName | methodBuilder | rootElement + HttpSpockMethodRequestProcessingBodyBuilder.simpleName | { Contract dsl -> new HttpSpockMethodRequestProcessingBodyBuilder(dsl, properties) } | '\\$' + MockMvcJUnitMethodBodyBuilder.simpleName | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl, properties) } | '$' + JaxRsClientSpockMethodRequestProcessingBodyBuilder.simpleName | { Contract dsl -> new JaxRsClientSpockMethodRequestProcessingBodyBuilder(dsl, properties) } | '\\$' + JaxRsClientJUnitMethodBodyBuilder.simpleName | { Contract dsl -> new JaxRsClientJUnitMethodBodyBuilder(dsl, properties) } | '$' + WebTestClientJUnitMethodBodyBuilder.simpleName | { Contract dsl -> new WebTestClientJUnitMethodBodyBuilder(dsl, properties) } | '$' + } - @Issue('#217') - def "should use the flattened assertions when jsonpath contains [*] for [#methodBuilderName]"() { - given: - Contract contractDsl = Contract.make { - request { - method 'GET' - url 'person' - } - response { - status OK() - body([ - "phoneNumbers": [ - number: "foo" - ] - ]) - bodyMatchers { - jsonPath('$.phoneNumbers[*].number', byType { - minOccurrence(0) - maxOccurrence(4) - }) - jsonPath('$.phoneNumbers[*].number', byType { - minOccurrence(0) - }) - jsonPath('$.phoneNumbers[*].number', byType { - maxOccurrence(4) - }) - } - } - } - MethodBodyBuilder builder = methodBuilder(contractDsl) - BlockBuilder blockBuilder = new BlockBuilder(" ") - when: - builder.appendTo(blockBuilder) - def test = blockBuilder.toString() - then: - test.contains('assertThat((java.lang.Iterable) parsedJson.read("' + rootElement + '.phoneNumbers[*].number", java.util.Collection.class)).as("' + rootElement + '.phoneNumbers[*].number").hasFlattenedSizeBetween(0, 4)') - test.contains('assertThat((java.lang.Iterable) parsedJson.read("' + rootElement + '.phoneNumbers[*].number", java.util.Collection.class)).as("' + rootElement + '.phoneNumbers[*].number").hasFlattenedSizeGreaterThanOrEqualTo(0)') - test.contains('assertThat((java.lang.Iterable) parsedJson.read("' + rootElement + '.phoneNumbers[*].number", java.util.Collection.class)).as("' + rootElement + '.phoneNumbers[*].number").hasFlattenedSizeLessThanOrEqualTo(4)') - !test.contains('cursor') - and: - try { - SyntaxChecker.tryToCompileWithoutCompileStatic(methodBuilderName, blockBuilder.toString()) - } catch(NoClassDefFoundError error) { - // that's actually expected since we're creating an anonymous class - } - 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) } | '$' - } + @Issue('#217') + def 'should use the flattened assertions when jsonpath contains [*] for [#methodBuilderName]'() { + given: + Contract contractDsl = Contract.make { + request { + method 'GET' + url 'person' + } + response { + status OK() + body([ + "phoneNumbers": [ + number: 'foo' + ] + ]) + bodyMatchers { + jsonPath('$.phoneNumbers[*].number', byType { + minOccurrence(0) + maxOccurrence(4) + }) + jsonPath('$.phoneNumbers[*].number', byType { + minOccurrence(0) + }) + jsonPath('$.phoneNumbers[*].number', byType { + maxOccurrence(4) + }) + } + } + } + MethodBodyBuilder builder = methodBuilder(contractDsl) + BlockBuilder blockBuilder = new BlockBuilder(" ") + when: + builder.appendTo(blockBuilder) + def test = blockBuilder.toString() + then: + test.contains('assertThat((java.lang.Iterable) parsedJson.read("' + rootElement + '.phoneNumbers[*].number", java.util.Collection.class)).as("' + rootElement + '.phoneNumbers[*].number").hasFlattenedSizeBetween(0, 4)') + test.contains('assertThat((java.lang.Iterable) parsedJson.read("' + rootElement + '.phoneNumbers[*].number", java.util.Collection.class)).as("' + rootElement + '.phoneNumbers[*].number").hasFlattenedSizeGreaterThanOrEqualTo(0)') + test.contains('assertThat((java.lang.Iterable) parsedJson.read("' + rootElement + '.phoneNumbers[*].number", java.util.Collection.class)).as("' + rootElement + '.phoneNumbers[*].number").hasFlattenedSizeLessThanOrEqualTo(4)') + !test.contains('cursor') + and: + try { + SyntaxChecker.tryToCompileWithoutCompileStatic(methodBuilderName, blockBuilder.toString()) + } catch (NoClassDefFoundError error) { + // that's actually expected since we're creating an anonymous class + } + where: + methodBuilderName | methodBuilder | rootElement + HttpSpockMethodRequestProcessingBodyBuilder.simpleName | { Contract dsl -> new HttpSpockMethodRequestProcessingBodyBuilder(dsl, properties) } | '\\$' + MockMvcJUnitMethodBodyBuilder.simpleName | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl, properties) } | '$' + JaxRsClientSpockMethodRequestProcessingBodyBuilder.simpleName | { Contract dsl -> new JaxRsClientSpockMethodRequestProcessingBodyBuilder(dsl, properties) } | '\\$' + JaxRsClientJUnitMethodBodyBuilder.simpleName | { Contract dsl -> new JaxRsClientJUnitMethodBodyBuilder(dsl, properties) } | '$' + WebTestClientJUnitMethodBodyBuilder.simpleName | { Contract dsl -> new WebTestClientJUnitMethodBodyBuilder(dsl, properties) } | '$' + } - @Issue('#217') - def "should allow matcher with command to execute [#methodBuilderName]"() { - given: - Contract contractDsl = Contract.make { - request { - method 'GET' - url 'person' - } - response { - status OK() - body([ - "phoneNumbers": [ - number: "foo" - ] - ]) - bodyMatchers { - jsonPath('$.phoneNumbers[*].number', byCommand('foo($it)')) - } - } - } - MethodBodyBuilder builder = methodBuilder(contractDsl) - BlockBuilder blockBuilder = new BlockBuilder(" ") - when: - builder.appendTo(blockBuilder) - def test = blockBuilder.toString() - then: - test.contains('foo(parsedJson.read("' + rootElement + '.phoneNumbers[*].number")') - 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) } | '$' - } + @Issue('#217') + def 'should allow matcher with command to execute [#methodBuilderName]'() { + given: + Contract contractDsl = Contract.make { + request { + method 'GET' + url 'person' + } + response { + status OK() + body([ + "phoneNumbers": [ + number: 'foo' + ] + ]) + bodyMatchers { + jsonPath('$.phoneNumbers[*].number', byCommand('foo($it)')) + } + } + } + MethodBodyBuilder builder = methodBuilder(contractDsl) + BlockBuilder blockBuilder = new BlockBuilder(" ") + when: + builder.appendTo(blockBuilder) + def test = blockBuilder.toString() + then: + test.contains('foo(parsedJson.read("' + rootElement + '.phoneNumbers[*].number")') + where: + methodBuilderName | methodBuilder | rootElement + HttpSpockMethodRequestProcessingBodyBuilder.simpleName | { Contract dsl -> new HttpSpockMethodRequestProcessingBodyBuilder(dsl, properties) } | '\\$' + MockMvcJUnitMethodBodyBuilder.simpleName | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl, properties) } | '$' + JaxRsClientSpockMethodRequestProcessingBodyBuilder.simpleName | { Contract dsl -> new JaxRsClientSpockMethodRequestProcessingBodyBuilder(dsl, properties) } | '\\$' + JaxRsClientJUnitMethodBodyBuilder.simpleName | { Contract dsl -> new JaxRsClientJUnitMethodBodyBuilder(dsl, properties) } | '$' + WebTestClientJUnitMethodBodyBuilder.simpleName | { Contract dsl -> new WebTestClientJUnitMethodBodyBuilder(dsl, properties) } | '$' + } - @Issue('#217') - def "should throw an exception when command to execute references a non existing entry in the body [#methodBuilderName]"() { - given: - Contract contractDsl = Contract.make { - request { - method 'GET' - url 'person' - } - response { - status OK() - body([ - "phoneNumbers": [ - number: "foo" - ] - ]) - bodyMatchers { - jsonPath('$.nonExistingPhoneNumbers[*].number', byCommand('foo($it)')) - } - } - } - MethodBodyBuilder builder = methodBuilder(contractDsl) - BlockBuilder blockBuilder = new BlockBuilder(" ") - when: - builder.appendTo(blockBuilder) - then: - IllegalStateException e = thrown(IllegalStateException) - e.message.contains("Entry for the provided JSON path <\$.nonExistingPhoneNumbers[*].number> doesn't exist in the body") - 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) } | '$' - } + @Issue('#217') + def 'should throw an exception when command to execute references a non existing entry in the body [#methodBuilderName]'() { + given: + Contract contractDsl = Contract.make { + request { + method 'GET' + url 'person' + } + response { + status OK() + body([ + "phoneNumbers": [ + number: 'foo' + ] + ]) + bodyMatchers { + jsonPath('$.nonExistingPhoneNumbers[*].number', byCommand('foo($it)')) + } + } + } + MethodBodyBuilder builder = methodBuilder(contractDsl) + BlockBuilder blockBuilder = new BlockBuilder(" ") + when: + builder.appendTo(blockBuilder) + then: + IllegalStateException e = thrown(IllegalStateException) + e.message.contains('Entry for the provided JSON path <$.nonExistingPhoneNumbers[*].number> doesn\'t exist in the body') + where: + methodBuilderName | methodBuilder | rootElement + HttpSpockMethodRequestProcessingBodyBuilder.simpleName | { Contract dsl -> new HttpSpockMethodRequestProcessingBodyBuilder(dsl, properties) } | '\\$' + MockMvcJUnitMethodBodyBuilder.simpleName | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl, properties) } | '$' + JaxRsClientSpockMethodRequestProcessingBodyBuilder.simpleName | { Contract dsl -> new JaxRsClientSpockMethodRequestProcessingBodyBuilder(dsl, properties) } | '\\$' + JaxRsClientJUnitMethodBodyBuilder.simpleName | { Contract dsl -> new JaxRsClientJUnitMethodBodyBuilder(dsl, properties) } | '$' + WebTestClientJUnitMethodBodyBuilder.simpleName | { Contract dsl -> new WebTestClientJUnitMethodBodyBuilder(dsl, properties) } | '$' + } - @Issue("#229") - def "should work for matchers and body with json array[#methodBuilderName]"() { - given: - Contract contractDsl = Contract.make { - request { - method 'GET' - url '/api/v1/xxxx' - body(12000) - } - response { - status OK() - body ([[ - [ access_token: '123'] - ]]) - headers { - contentType(applicationJson()) - } - bodyMatchers { - jsonPath('''$[0][0].access_token''', byEquality()) - } - } - } - MethodBodyBuilder builder = methodBuilder(contractDsl) - BlockBuilder blockBuilder = new BlockBuilder(" ") - and: - builder.appendTo(blockBuilder) - String test = blockBuilder.toString() - when: - SyntaxChecker.tryToCompile(methodBuilderName, test) - then: - test.contains('assertThat(parsedJson.read("' + rootElement + '[0][0].access_token", String.class)).isEqualTo("123")') - 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) } | '$' - } + @Issue('#229') + def 'should work for matchers and body with json array[#methodBuilderName]'() { + given: + Contract contractDsl = Contract.make { + request { + method 'GET' + url '/api/v1/xxxx' + body(12000) + } + response { + status OK() + body([[ + [access_token: '123'] + ]]) + headers { + contentType(applicationJson()) + } + bodyMatchers { + jsonPath('''$[0][0].access_token''', byEquality()) + } + } + } + MethodBodyBuilder builder = methodBuilder(contractDsl) + BlockBuilder blockBuilder = new BlockBuilder(" ") + and: + builder.appendTo(blockBuilder) + String test = blockBuilder.toString() + when: + SyntaxChecker.tryToCompile(methodBuilderName, test) + then: + test.contains('assertThat(parsedJson.read("' + rootElement + '[0][0].access_token", String.class)).isEqualTo("123")') + where: + methodBuilderName | methodBuilder | rootElement + HttpSpockMethodRequestProcessingBodyBuilder.simpleName | { Contract dsl -> new HttpSpockMethodRequestProcessingBodyBuilder(dsl, properties) } | '\\$' + MockMvcJUnitMethodBodyBuilder.simpleName | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl, properties) } | '$' + JaxRsClientSpockMethodRequestProcessingBodyBuilder.simpleName | { Contract dsl -> new JaxRsClientSpockMethodRequestProcessingBodyBuilder(dsl, properties) } | '\\$' + JaxRsClientJUnitMethodBodyBuilder.simpleName | { Contract dsl -> new JaxRsClientJUnitMethodBodyBuilder(dsl, properties) } | '$' + WebTestClientJUnitMethodBodyBuilder.simpleName | { Contract dsl -> new WebTestClientJUnitMethodBodyBuilder(dsl, properties) } | '$' + } - @Issue("#391") - def "should work for matchers and body with multiline string for [#methodBuilderName]"() { - given: - Contract contractDsl = Contract.make { - request { - name "ISSUE 391" - method 'GET' - urlPath '/item/factsheet?size=2&page=1' - headers { header "accept", "application/...json" } - } - response { - status OK() - body(""" + @Issue('#391') + def 'should work for matchers and body with multiline string for [#methodBuilderName]'() { + given: + Contract contractDsl = Contract.make { + request { + name 'ISSUE 391' + method 'GET' + urlPath '/item/factsheet?size=2&page=1' + headers { header 'accept', 'application/...json' } + } + response { + status OK() + body(''' { "items": [ { @@ -460,73 +468,75 @@ class MockMvcMethodBodyBuilderWithMatchersSpec extends Specification implements } ] } - """) - bodyMatchers { - jsonPath('$.items[*].id', byRegex(nonBlank())) - jsonPath('$.items[*].title', byRegex(nonBlank())) - jsonPath('$.items[*]', byType { minOccurrence(2); maxOccurrence(2) }) - } - headers {header "content-type", "application/...json;charset=UTF-8"} - } - } - MethodBodyBuilder builder = methodBuilder(contractDsl) - BlockBuilder blockBuilder = new BlockBuilder(" ") - and: - builder.appendTo(blockBuilder) - String test = blockBuilder.toString() - when: - SyntaxChecker.tryToCompile(methodBuilderName, test) - then: - !test.contains('''assertThatJson(parsedJson).array("['items']").isEmpty()''') - where: - methodBuilderName | methodBuilder - "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) } - } + ''') + bodyMatchers { + jsonPath('$.items[*].id', byRegex(nonBlank())) + jsonPath('$.items[*].title', byRegex(nonBlank())) + jsonPath('$.items[*]', byType { minOccurrence(2); maxOccurrence(2) }) + } + headers { header 'content-type', 'application/...json;charset=UTF-8' } + } + } + MethodBodyBuilder builder = methodBuilder(contractDsl) + BlockBuilder blockBuilder = new BlockBuilder(" ") + and: + builder.appendTo(blockBuilder) + String test = blockBuilder.toString() + when: + SyntaxChecker.tryToCompile(methodBuilderName, test) + then: + !test.contains('''assertThatJson(parsedJson).array("['items']").isEmpty()''') + where: + methodBuilderName | methodBuilder + HttpSpockMethodRequestProcessingBodyBuilder.simpleName | { Contract dsl -> new HttpSpockMethodRequestProcessingBodyBuilder(dsl, properties) } + MockMvcJUnitMethodBodyBuilder.simpleName | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl, properties) } + JaxRsClientSpockMethodRequestProcessingBodyBuilder.simpleName | { Contract dsl -> new JaxRsClientSpockMethodRequestProcessingBodyBuilder(dsl, properties) } + JaxRsClientJUnitMethodBodyBuilder.simpleName | { Contract dsl -> new JaxRsClientJUnitMethodBodyBuilder(dsl, properties) } + WebTestClientJUnitMethodBodyBuilder.simpleName | { Contract dsl -> new WebTestClientJUnitMethodBodyBuilder(dsl, properties) } + } - @Issue("#391") - def "should work for matchers and body with multiline string with map body for [#methodBuilderName]"() { - given: - Contract contractDsl = Contract.make { - request { - name "ISSUE 391" - method 'GET' - urlPath '/item/factsheet?size=2&page=1' - headers { header "accept", "application/...json" } - } - response { - status OK() - body([ - "items": [ - "id" : "35309", - "title": "lorem ipsum" - ] - ]) - bodyMatchers { - jsonPath('$.items[*].id', byRegex(nonBlank())) - jsonPath('$.items[*].title', byRegex(nonBlank())) - jsonPath('$.items[*]', byType { minOccurrence(2); maxOccurrence(2) }) - } - headers {header "content-type", "application/...json;charset=UTF-8"} - } - } - MethodBodyBuilder builder = methodBuilder(contractDsl) - BlockBuilder blockBuilder = new BlockBuilder(" ") - and: - builder.appendTo(blockBuilder) - String test = blockBuilder.toString() - when: - SyntaxChecker.tryToCompile(methodBuilderName, test) - then: - !test.contains('''assertThatJson(parsedJson).array("['items']").isEmpty()''') - where: - methodBuilderName | methodBuilder - "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) } - } + @Issue('#391') + def 'should work for matchers and body with multiline string with map body for [#methodBuilderName]'() { + given: + Contract contractDsl = Contract.make { + request { + name "ISSUE 391" + method 'GET' + urlPath '/item/factsheet?size=2&page=1' + headers { header 'accept', 'application/...json' } + } + response { + status OK() + body([ + "items": [ + "id" : "35309", + "title": "lorem ipsum" + ] + ]) + bodyMatchers { + jsonPath('$.items[*].id', byRegex(nonBlank())) + jsonPath('$.items[*].title', byRegex(nonBlank())) + jsonPath('$.items[*]', byType { minOccurrence(2); maxOccurrence(2) }) + } + headers { header 'content-type', 'application/...json;charset=UTF-8' } + } + } + MethodBodyBuilder builder = methodBuilder(contractDsl) + BlockBuilder blockBuilder = new BlockBuilder(" ") + and: + builder.appendTo(blockBuilder) + String test = blockBuilder.toString() + when: + SyntaxChecker.tryToCompile(methodBuilderName, test) + then: + !test.contains('''assertThatJson(parsedJson).array("['items']").isEmpty()''') + where: + methodBuilderName | methodBuilder + HttpSpockMethodRequestProcessingBodyBuilder.simpleName | { Contract dsl -> new HttpSpockMethodRequestProcessingBodyBuilder(dsl, properties) } + MockMvcJUnitMethodBodyBuilder.simpleName | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl, properties) } + JaxRsClientSpockMethodRequestProcessingBodyBuilder.simpleName | { Contract dsl -> new JaxRsClientSpockMethodRequestProcessingBodyBuilder(dsl, properties) } + JaxRsClientJUnitMethodBodyBuilder.simpleName | { Contract dsl -> new JaxRsClientJUnitMethodBodyBuilder(dsl, properties) } + WebTestClientJUnitMethodBodyBuilder.simpleName | { Contract dsl -> new WebTestClientJUnitMethodBodyBuilder(dsl, properties) } + } } diff --git a/spring-cloud-contract-verifier/src/test/groovy/org/springframework/cloud/contract/verifier/builder/SpringTestMethodBodyBuildersSpec.groovy b/spring-cloud-contract-verifier/src/test/groovy/org/springframework/cloud/contract/verifier/builder/SpringTestMethodBodyBuildersSpec.groovy new file mode 100644 index 0000000000..0174ee4884 --- /dev/null +++ b/spring-cloud-contract-verifier/src/test/groovy/org/springframework/cloud/contract/verifier/builder/SpringTestMethodBodyBuildersSpec.groovy @@ -0,0 +1,2899 @@ +/* + * Copyright 2013-2018 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.cloud.contract.verifier.builder + +import org.codehaus.groovy.control.MultipleCompilationErrorsException +import org.junit.Rule +import org.springframework.boot.test.rule.OutputCapture +import org.springframework.cloud.contract.spec.Contract +import org.springframework.cloud.contract.verifier.config.ContractVerifierConfigProperties +import org.springframework.cloud.contract.verifier.dsl.WireMockStubVerifier +import org.springframework.cloud.contract.verifier.util.SyntaxChecker +import spock.lang.Issue +import spock.lang.Shared +import spock.lang.Specification +import spock.util.environment.RestoreSystemProperties + +import java.util.regex.Pattern + +/** + * @author Jakub Kubrynski, codearte.io + * @author Tim Ysewyn + */ +class SpringTestMethodBodyBuildersSpec extends Specification implements WireMockStubVerifier { + + @Rule + OutputCapture capture = new OutputCapture() + + @Shared + ContractVerifierConfigProperties properties = new ContractVerifierConfigProperties( + assertJsonSize: true + ) + + @Shared + Contract contractDslWithCookiesValue = Contract.make { + request { + method "GET" + url "/foo" + headers { + header 'Accept': 'application/json' + } + cookies { + cookie 'cookie-key': 'cookie-value' + } + } + response { + status 200 + headers { + header 'Content-Type': 'application/json' + } + cookies { + cookie 'cookie-key': 'new-cookie-value' + } + body([status: 'OK']) + } + } + + @Shared + Contract contractDslWithCookiesPattern = Contract.make { + request { + method "GET" + url "/foo" + headers { + header 'Accept': 'application/json' + } + cookies { + cookie 'cookie-key': regex('[A-Za-z]+') + } + } + response { + status 200 + headers { + header 'Content-Type': 'application/json' + } + cookies { + cookie 'cookie-key': regex('[A-Za-z]+') + } + body([status: 'OK']) + } + } + + @Shared + Contract contractDslWithAbsentCookies = Contract.make { + request { + method "GET" + url "/foo" + cookies { + cookie 'cookie-key': absent() + } + } + response { + status 200 + body([status: 'OK']) + } + } + + @Shared + // tag::contract_with_regex[] + Contract dslWithOptionalsInString = Contract.make { + priority 1 + request { + method POST() + url '/users/password' + headers { + contentType(applicationJson()) + } + body( + email: $(consumer(optional(regex(email()))), producer('abc@abc.com')), + callback_url: $(consumer(regex(hostname())), producer('http://partners.com')) + ) + } + response { + status 404 + headers { + contentType(applicationJson()) + } + body( + code: value(consumer("123123"), producer(optional("123123"))), + message: "User not found by email = [${value(producer(regex(email())), consumer('not.existing@user.com'))}]" + ) + } + } + // end::contract_with_regex[] + + @Shared + Contract dslWithOptionals = Contract.make { + priority 1 + request { + method POST() + url '/users/password' + headers { + contentType(applicationJson()) + } + body( + """ { + "email" : "${ + value(consumer(optional(regex(email()))), producer('abc@abc.com')) + }", + "callback_url" : "${ + value(consumer(regex(hostname())), producer('http://partners.com')) + }" + } + """ + ) + } + response { + status 404 + headers { + contentType(applicationJson()) + } + body( + """ { + "code" : "${value(consumer(123123), producer(optional(123123)))}", + "message" : "User not found by email = [${ + value(producer(regex(email())), consumer('not.existing@user.com')) + }]" + } + """ + ) + } + } + + def 'should generate assertions for simple response body with #methodBuilderName'() { + given: + Contract contractDsl = Contract.make { + request { + method GET() + url "test" + } + response { + status OK() + body """{ + "property1": "a", + "property2": "b" +}""" + } + } + MethodBodyBuilder builder = methodBuilder(contractDsl) + BlockBuilder blockBuilder = new BlockBuilder(" ") + when: + builder.appendTo(blockBuilder) + then: + blockBuilder.toString().contains("""assertThatJson(parsedJson).field("['property1']").isEqualTo("a")""") + blockBuilder.toString().contains("""assertThatJson(parsedJson).field("['property2']").isEqualTo("b")""") + and: + stubMappingIsValidWireMockStub(contractDsl) + and: + SyntaxChecker.tryToCompile(methodBuilderName, blockBuilder.toString()) + where: + methodBuilderName | methodBuilder + HttpSpockMethodRequestProcessingBodyBuilder.simpleName | { Contract dsl -> new HttpSpockMethodRequestProcessingBodyBuilder(dsl, properties) } + MockMvcJUnitMethodBodyBuilder.simpleName | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl, properties) } + WebTestClientJUnitMethodBodyBuilder.simpleName | { Contract dsl -> new WebTestClientJUnitMethodBodyBuilder(dsl, properties) } + } + + @Issue('#187') + def 'should generate assertions for null and boolean values with #methodBuilderName'() { + given: + Contract contractDsl = Contract.make { + request { + method GET() + url 'test' + } + response { + status OK() + body """{ + "property1": "true", + "property2": null, + "property3": false +}""" + } + } + MethodBodyBuilder builder = methodBuilder(contractDsl) + BlockBuilder blockBuilder = new BlockBuilder(' ') + when: + builder.appendTo(blockBuilder) + then: + blockBuilder.toString().contains("""assertThatJson(parsedJson).field("['property1']").isEqualTo("true")""") + blockBuilder.toString().contains("""assertThatJson(parsedJson).field("['property2']").isNull()""") + blockBuilder.toString().contains("""assertThatJson(parsedJson).field("['property3']").isEqualTo(false)""") + and: + stubMappingIsValidWireMockStub(contractDsl) + and: + SyntaxChecker.tryToCompile(methodBuilderName, blockBuilder.toString()) + where: + methodBuilderName | methodBuilder + HttpSpockMethodRequestProcessingBodyBuilder.simpleName | { Contract dsl -> new HttpSpockMethodRequestProcessingBodyBuilder(dsl, properties) } + MockMvcJUnitMethodBodyBuilder.simpleName | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl, properties) } + WebTestClientJUnitMethodBodyBuilder.simpleName | { Contract dsl -> new WebTestClientJUnitMethodBodyBuilder(dsl, properties) } + } + + @Issue('#79') + def 'should generate assertions for simple response body constructed from map with a list with #methodBuilderName'() { + given: + Contract contractDsl = Contract.make { + request { + method "GET" + url "test" + } + response { + status OK() + body( + property1: 'a', + property2: [ + [a: 'sth'], + [b: 'sthElse'] + ] + ) + } + } + MethodBodyBuilder builder = methodBuilder(contractDsl) + BlockBuilder blockBuilder = new BlockBuilder(" ") + when: + builder.appendTo(blockBuilder) + then: + blockBuilder.toString().contains("""assertThatJson(parsedJson).field("['property1']").isEqualTo("a")""") + blockBuilder.toString().contains("""assertThatJson(parsedJson).array("['property2']").contains("['a']").isEqualTo("sth")""") + blockBuilder.toString().contains("""assertThatJson(parsedJson).array("['property2']").contains("['b']").isEqualTo("sthElse")""") + and: + stubMappingIsValidWireMockStub(contractDsl) + and: + SyntaxChecker.tryToCompile(methodBuilderName, blockBuilder.toString()) + where: + methodBuilderName | methodBuilder + HttpSpockMethodRequestProcessingBodyBuilder.simpleName | { Contract dsl -> new HttpSpockMethodRequestProcessingBodyBuilder(dsl, properties) } + MockMvcJUnitMethodBodyBuilder.simpleName | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl, properties) } + WebTestClientJUnitMethodBodyBuilder.simpleName | { Contract dsl -> new WebTestClientJUnitMethodBodyBuilder(dsl, properties) } + } + + @Issue('#79') + @RestoreSystemProperties + def 'should generate assertions for simple response body constructed from map with a list with #methodBuilderName with array size check'() { + given: + System.setProperty('spring.cloud.contract.verifier.assert.size', 'true') + Contract contractDsl = Contract.make { + request { + method 'GET' + url 'test' + } + response { + status OK() + body( + property1: 'a', + property2: [ + [a: 'sth'], + [b: 'sthElse'] + ] + ) + } + } + MethodBodyBuilder builder = methodBuilder(contractDsl) + BlockBuilder blockBuilder = new BlockBuilder(" ") + when: + builder.appendTo(blockBuilder) + then: + blockBuilder.toString().contains("""assertThatJson(parsedJson).field("['property1']").isEqualTo("a")""") + blockBuilder.toString().contains("""assertThatJson(parsedJson).array("['property2']").contains("['a']").isEqualTo("sth")""") + blockBuilder.toString().contains("""assertThatJson(parsedJson).array("['property2']").hasSize(2)""") + blockBuilder.toString().contains("""assertThatJson(parsedJson).array("['property2']").contains("['b']").isEqualTo("sthElse")""") + and: + stubMappingIsValidWireMockStub(contractDsl) + and: + SyntaxChecker.tryToCompile(methodBuilderName, blockBuilder.toString()) + where: + methodBuilderName | methodBuilder + HttpSpockMethodRequestProcessingBodyBuilder.simpleName | { Contract dsl -> new HttpSpockMethodRequestProcessingBodyBuilder(dsl, properties) } + MockMvcJUnitMethodBodyBuilder.simpleName | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl, properties) } + WebTestClientJUnitMethodBodyBuilder.simpleName | { Contract dsl -> new WebTestClientJUnitMethodBodyBuilder(dsl, properties) } + } + + @Issue('#82') + def 'should generate proper request when body constructed from map with a list #methodBuilderName'() { + given: + Contract contractDsl = Contract.make { + request { + method "GET" + url "test" + body( + items: ['HOP'] + ) + } + response { + status OK() + } + } + MethodBodyBuilder builder = methodBuilder(contractDsl) + BlockBuilder blockBuilder = new BlockBuilder(" ") + when: + builder.appendTo(blockBuilder) + then: + blockBuilder.toString().contains(bodyString) + and: + stubMappingIsValidWireMockStub(contractDsl) + and: + SyntaxChecker.tryToCompile(methodBuilderName, blockBuilder.toString()) + where: + methodBuilderName | methodBuilder | bodyString + HttpSpockMethodRequestProcessingBodyBuilder.simpleName | { Contract dsl -> new HttpSpockMethodRequestProcessingBodyBuilder(dsl, properties) } | """.body('''{\"items\":[\"HOP\"]}''')""" + MockMvcJUnitMethodBodyBuilder.simpleName | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl, properties) } | '.body("{\\"items\\":[\\"HOP\\"]}")' + WebTestClientJUnitMethodBodyBuilder.simpleName | { Contract dsl -> new WebTestClientJUnitMethodBodyBuilder(dsl, properties) } | '.body("{\\"items\\":[\\"HOP\\"]}")' + } + + @Issue('#88') + def 'should generate proper request when body constructed from GString with #methodBuilderName'() { + given: + Contract contractDsl = Contract.make { + request { + method 'GET' + url 'test' + body( + 'property1=VAL1' + ) + } + response { + status OK() + } + } + MethodBodyBuilder builder = methodBuilder(contractDsl) + BlockBuilder blockBuilder = new BlockBuilder(' ') + when: + builder.appendTo(blockBuilder) + then: + blockBuilder.toString().contains(bodyString) + and: + SyntaxChecker.tryToCompile(methodBuilderName, blockBuilder.toString()) + and: + stubMappingIsValidWireMockStub(contractDsl) + where: + methodBuilderName | methodBuilder | bodyString + HttpSpockMethodRequestProcessingBodyBuilder.simpleName | { Contract dsl -> new HttpSpockMethodRequestProcessingBodyBuilder(dsl, properties) } | """.body('''property1=VAL1''')""" + MockMvcJUnitMethodBodyBuilder.simpleName | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl, properties) } | '.body("property1=VAL1")' + WebTestClientJUnitMethodBodyBuilder.simpleName | { Contract dsl -> new WebTestClientJUnitMethodBodyBuilder(dsl, properties) } | '.body("property1=VAL1")' + } + + @Issue('185') + def 'should generate assertions for a response body containing map with integers as keys with #methodBuilderName'() { + given: + Contract contractDsl = Contract.make { + request { + method 'GET' + url 'test' + } + response { + status OK() + body( + property: [ + 14: 0.0, + 7 : 0.0 + ] + ) + } + } + MethodBodyBuilder builder = methodBuilder(contractDsl) + BlockBuilder blockBuilder = new BlockBuilder(" ") + when: + builder.appendTo(blockBuilder) + then: + blockBuilder.toString().contains("""assertThatJson(parsedJson).field("['property']").field(7).isEqualTo(0.0)""") + blockBuilder.toString().contains("""assertThatJson(parsedJson).field("['property']").field(14).isEqualTo(0.0)""") + and: + stubMappingIsValidWireMockStub(contractDsl) + and: + SyntaxChecker.tryToCompile(methodBuilderName, blockBuilder.toString()) + where: + methodBuilderName | methodBuilder + HttpSpockMethodRequestProcessingBodyBuilder.simpleName | { Contract dsl -> new HttpSpockMethodRequestProcessingBodyBuilder(dsl, properties) } + MockMvcJUnitMethodBodyBuilder.simpleName | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl, properties) } + WebTestClientJUnitMethodBodyBuilder.simpleName | { Contract dsl -> new WebTestClientJUnitMethodBodyBuilder(dsl, properties) } + } + + def 'should generate assertions for array in response body with #methodBuilderName'() { + given: + Contract contractDsl = Contract.make { + request { + method 'GET' + url 'test' + } + response { + status OK() + body """[ +{ + "property1": "a" +}, +{ + "property2": "b" +}]""" + } + } + MethodBodyBuilder builder = methodBuilder(contractDsl) + BlockBuilder blockBuilder = new BlockBuilder(" ") + when: + builder.appendTo(blockBuilder) + then: + blockBuilder.toString().contains("""assertThatJson(parsedJson).array().contains("['property2']").isEqualTo("b")""") + blockBuilder.toString().contains("""assertThatJson(parsedJson).array().contains("['property1']").isEqualTo("a")""") + and: + stubMappingIsValidWireMockStub(contractDsl) + and: + SyntaxChecker.tryToCompile(methodBuilderName, blockBuilder.toString()) + where: + methodBuilderName | methodBuilder + HttpSpockMethodRequestProcessingBodyBuilder.simpleName | { Contract dsl -> new HttpSpockMethodRequestProcessingBodyBuilder(dsl, properties) } + MockMvcJUnitMethodBodyBuilder.simpleName | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl, properties) } + WebTestClientJUnitMethodBodyBuilder.simpleName | { Contract dsl -> new WebTestClientJUnitMethodBodyBuilder(dsl, properties) } + } + + def 'should generate assertions for array inside response body element with #methodBuilderName'() { + given: + Contract contractDsl = Contract.make { + request { + method "GET" + url "test" + } + response { + status OK() + body """{ + "property1": [ + { "property2": "test1"}, + { "property3": "test2"} + ] +}""" + } + } + MethodBodyBuilder builder = methodBuilder(contractDsl) + BlockBuilder blockBuilder = new BlockBuilder(" ") + when: + builder.appendTo(blockBuilder) + then: + blockBuilder.toString().contains("""assertThatJson(parsedJson).array("['property1']").contains("['property2']").isEqualTo("test1")""") + blockBuilder.toString().contains("""assertThatJson(parsedJson).array("['property1']").contains("['property3']").isEqualTo("test2")""") + and: + stubMappingIsValidWireMockStub(contractDsl) + and: + SyntaxChecker.tryToCompile(methodBuilderName, blockBuilder.toString()) + where: + methodBuilderName | methodBuilder + HttpSpockMethodRequestProcessingBodyBuilder.simpleName | { Contract dsl -> new HttpSpockMethodRequestProcessingBodyBuilder(dsl, properties) } + MockMvcJUnitMethodBodyBuilder.simpleName | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl, properties) } + WebTestClientJUnitMethodBodyBuilder.simpleName | { Contract dsl -> new WebTestClientJUnitMethodBodyBuilder(dsl, properties) } + } + + def 'should generate assertions for nested objects in response body with #methodBuilderName'() { + given: + Contract contractDsl = Contract.make { + request { + method "GET" + url "test" + } + response { + status OK() + body '''\ +{ + "property1": "a", + "property2": {"property3": "b"} +} +''' + } + } + MethodBodyBuilder builder = methodBuilder(contractDsl) + BlockBuilder blockBuilder = new BlockBuilder(" ") + when: + builder.appendTo(blockBuilder) + then: + blockBuilder.toString().contains("""assertThatJson(parsedJson).field("['property2']").field("['property3']").isEqualTo("b")""") + blockBuilder.toString().contains("""assertThatJson(parsedJson).field("['property1']").isEqualTo("a")""") + and: + stubMappingIsValidWireMockStub(contractDsl) + and: + SyntaxChecker.tryToCompile(methodBuilderName, blockBuilder.toString()) + where: + methodBuilderName | methodBuilder + HttpSpockMethodRequestProcessingBodyBuilder.simpleName | { Contract dsl -> new HttpSpockMethodRequestProcessingBodyBuilder(dsl, properties) } + MockMvcJUnitMethodBodyBuilder.simpleName | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl, properties) } + WebTestClientJUnitMethodBodyBuilder.simpleName | { Contract dsl -> new WebTestClientJUnitMethodBodyBuilder(dsl, properties) } + } + + def 'should generate regex assertions for map objects in response body with #methodBuilderName'() { + given: + Contract contractDsl = Contract.make { + request { + method "GET" + url "test" + } + response { + status OK() + body( + property1: "a", + property2: value( + consumer('123'), + producer(regex('[0-9]{3}')) + ) + ) + headers { + contentType(applicationJson()) + } + } + } + MethodBodyBuilder builder = methodBuilder(contractDsl) + BlockBuilder blockBuilder = new BlockBuilder(" ") + when: + builder.appendTo(blockBuilder) + then: + blockBuilder.toString().contains("""assertThatJson(parsedJson).field("['property2']").matches("[0-9]{3}")""") + blockBuilder.toString().contains("""assertThatJson(parsedJson).field("['property1']").isEqualTo("a")""") + and: + stubMappingIsValidWireMockStub(contractDsl) + and: + SyntaxChecker.tryToCompile(methodBuilderName, blockBuilder.toString()) + where: + methodBuilderName | methodBuilder + HttpSpockMethodRequestProcessingBodyBuilder.simpleName | { Contract dsl -> new HttpSpockMethodRequestProcessingBodyBuilder(dsl, properties) } + MockMvcJUnitMethodBodyBuilder.simpleName | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl, properties) } + WebTestClientJUnitMethodBodyBuilder.simpleName | { Contract dsl -> new WebTestClientJUnitMethodBodyBuilder(dsl, properties) } + } + + def 'should generate regex assertions for string objects in response body with #methodBuilderName'() { + given: + Contract contractDsl = Contract.make { + request { + method 'GET' + url 'test' + } + response { + status OK() + body("""{"property1":"a","property2":"${ + value(consumer('123'), producer(regex('[0-9]{3}'))) + }"}""") + headers { + contentType(applicationJson()) + } + } + } + MethodBodyBuilder builder = methodBuilder(contractDsl) + BlockBuilder blockBuilder = new BlockBuilder(" ") + when: + builder.appendTo(blockBuilder) + then: + blockBuilder.toString().contains("""assertThatJson(parsedJson).field("['property2']").matches("[0-9]{3}")""") + blockBuilder.toString().contains("""assertThatJson(parsedJson).field("['property1']").isEqualTo("a")""") + and: + stubMappingIsValidWireMockStub(contractDsl) + and: + SyntaxChecker.tryToCompile(methodBuilderName, blockBuilder.toString()) + where: + methodBuilderName | methodBuilder + HttpSpockMethodRequestProcessingBodyBuilder.simpleName | { Contract dsl -> new HttpSpockMethodRequestProcessingBodyBuilder(dsl, properties) } + MockMvcJUnitMethodBodyBuilder.simpleName | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl, properties) } + WebTestClientJUnitMethodBodyBuilder.simpleName | { Contract dsl -> new WebTestClientJUnitMethodBodyBuilder(dsl, properties) } + } + + @Issue(['#126', '#143']) + def 'should generate escaped regex assertions for string objects in response body with #methodBuilderName'() { + given: + Contract contractDsl = Contract.make { + request { + method 'GET' + url 'test' + } + response { + status OK() + body("""{"property":" ${ + value(consumer('123'), producer(regex('\\d+'))) + }"}""") + headers { + contentType(applicationJson()) + } + } + } + MethodBodyBuilder builder = methodBuilder(contractDsl) + BlockBuilder blockBuilder = new BlockBuilder(" ") + when: + builder.appendTo(blockBuilder) + then: + blockBuilder.toString().contains("""assertThatJson(parsedJson).field("['property']").matches("\\\\d+")""") + and: + stubMappingIsValidWireMockStub(contractDsl) + and: + SyntaxChecker.tryToCompile(methodBuilderName, blockBuilder.toString()) + where: + methodBuilderName | methodBuilder + HttpSpockMethodRequestProcessingBodyBuilder.simpleName | { Contract dsl -> new HttpSpockMethodRequestProcessingBodyBuilder(dsl, properties) } + MockMvcJUnitMethodBodyBuilder.simpleName | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl, properties) } + WebTestClientJUnitMethodBodyBuilder.simpleName | { Contract dsl -> new WebTestClientJUnitMethodBodyBuilder(dsl, properties) } + } + + def 'should generate a call with an url path and query parameters with #methodBuilderName'() { + given: + Contract contractDsl = Contract.make { + request { + method 'GET' + urlPath('/users') { + queryParameters { + parameter 'limit': $(consumer(equalTo('20')), producer(equalTo('10'))) + parameter 'offset': $(consumer(containing("20")), producer(equalTo('20'))) + parameter 'filter': 'email' + parameter 'sort': equalTo("name") + parameter 'search': $(consumer(notMatching(~/^\/[0-9]{2}$/)), producer('55')) + parameter 'age': $(consumer(notMatching("^\\w*\$")), producer('99')) + parameter 'name': $(consumer(matching('Denis.*')), producer('Denis.Stepanov')) + parameter 'email': 'bob@email.com' + parameter 'hello': $(consumer(matching('Denis.*')), producer(absent())) + parameter 'hello': absent() + } + } + } + response { + status OK() + body """ + { + "property1": "a", + "property2": "b" + } + """ + } + } + MethodBodyBuilder builder = methodBuilder(contractDsl) + BlockBuilder blockBuilder = new BlockBuilder(" ") + when: + builder.appendTo(blockBuilder) + def test = blockBuilder.toString() + then: + test.contains('''.queryParam("limit","10")''') + test.contains('''.queryParam("offset","20")''') + test.contains('''.queryParam("filter","email")''') + test.contains('''.queryParam("sort","name")''') + test.contains('''.queryParam("search","55")''') + test.contains('''.queryParam("age","99")''') + test.contains('''.queryParam("name","Denis.Stepanov")''') + test.contains('''.queryParam("email","bob@email.com")''') + test.contains('''.get("/users")''') + test.contains('assertThatJson(parsedJson).field("[\'property1\']").isEqualTo("a")') + test.contains('assertThatJson(parsedJson).field("[\'property2\']").isEqualTo("b")') + and: + stubMappingIsValidWireMockStub(contractDsl) + and: + SyntaxChecker.tryToCompile(methodBuilderName, blockBuilder.toString()) + where: + methodBuilderName | methodBuilder + HttpSpockMethodRequestProcessingBodyBuilder.simpleName | { Contract dsl -> new HttpSpockMethodRequestProcessingBodyBuilder(dsl, properties) } + MockMvcJUnitMethodBodyBuilder.simpleName | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl, properties) } + WebTestClientJUnitMethodBodyBuilder.simpleName | { Contract dsl -> new WebTestClientJUnitMethodBodyBuilder(dsl, properties) } + } + + @Issue('#169') + def 'should generate a call with an url path and query parameters with url containing a pattern with #methodBuilderName'() { + given: + Contract contractDsl = Contract.make { + request { + method 'GET' + url($(consumer(regex('/foo/[0-9]+')), producer('/foo/123456'))) { + queryParameters { + parameter 'limit': $(consumer(equalTo('20')), producer(equalTo('10'))) + parameter 'offset': $(consumer(containing('20')), producer(equalTo('20'))) + parameter 'filter': 'email' + parameter 'sort': equalTo('name') + parameter 'search': $(consumer(notMatching(~/^\/[0-9]{2}$/)), producer('55')) + parameter 'age': $(consumer(notMatching("^\\w*\$")), producer('99')) + parameter 'name': $(consumer(matching('Denis.*')), producer('Denis.Stepanov')) + parameter 'email': 'bob@email.com' + parameter 'hello': $(consumer(matching('Denis.*')), producer(absent())) + parameter 'hello': absent() + } + } + } + response { + status OK() + body """ + { + "property1": "a", + "property2": "b" + } + """ + } + } + MethodBodyBuilder builder = methodBuilder(contractDsl) + BlockBuilder blockBuilder = new BlockBuilder(" ") + when: + builder.appendTo(blockBuilder) + def test = blockBuilder.toString() + then: + test.contains('''.queryParam("limit","10")''') + test.contains('''.queryParam("offset","20")''') + test.contains('''.queryParam("filter","email")''') + test.contains('''.queryParam("sort","name")''') + test.contains('''.queryParam("search","55")''') + test.contains('''.queryParam("age","99")''') + test.contains('''.queryParam("name","Denis.Stepanov")''') + test.contains('''.queryParam("email","bob@email.com")''') + test.contains('''.get("/foo/123456")''') + test.contains('assertThatJson(parsedJson).field("[\'property1\']").isEqualTo("a")') + test.contains('assertThatJson(parsedJson).field("[\'property2\']").isEqualTo("b")') + and: + stubMappingIsValidWireMockStub(contractDsl) + and: + SyntaxChecker.tryToCompile(methodBuilderName, blockBuilder.toString()) + where: + methodBuilderName | methodBuilder + HttpSpockMethodRequestProcessingBodyBuilder.simpleName | { Contract dsl -> new HttpSpockMethodRequestProcessingBodyBuilder(dsl, properties) } + MockMvcJUnitMethodBodyBuilder.simpleName | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl, properties) } + WebTestClientJUnitMethodBodyBuilder.simpleName | { Contract dsl -> new WebTestClientJUnitMethodBodyBuilder(dsl, properties) } + } + + def 'should generate test for empty body with #methodBuilderName'() { + given: + Contract contractDsl = Contract.make { + request { + method(POST()) + url('/ws/payments') + body("") + } + response { + status 406 + } + } + MethodBodyBuilder builder = methodBuilder(contractDsl) + BlockBuilder blockBuilder = new BlockBuilder(' ') + when: + builder.appendTo(blockBuilder) + def test = blockBuilder.toString() + then: + test.contains(bodyString) + and: + stubMappingIsValidWireMockStub(contractDsl) + and: + SyntaxChecker.tryToCompile(methodBuilderName, blockBuilder.toString()) + where: + methodBuilderName | methodBuilder | bodyString + HttpSpockMethodRequestProcessingBodyBuilder.simpleName | { Contract dsl -> new HttpSpockMethodRequestProcessingBodyBuilder(dsl, properties) } | ".body('''''')" + MockMvcJUnitMethodBodyBuilder.simpleName | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl, properties) } | '.body("")' + WebTestClientJUnitMethodBodyBuilder.simpleName | { Contract dsl -> new WebTestClientJUnitMethodBodyBuilder(dsl, properties) } | '.body("")' + } + + def 'should generate test for String in response body with #methodBuilderName'() { + given: + Contract contractDsl = Contract.make { + request { + method 'POST' + url 'test' + } + response { + status OK() + body 'test' + } + } + MethodBodyBuilder builder = methodBuilder(contractDsl) + BlockBuilder blockBuilder = new BlockBuilder(' ') + when: + builder.appendTo(blockBuilder) + def test = blockBuilder.toString() + then: + test.contains(bodyDefinitionString) + test.contains(bodyEvaluationString) + and: + stubMappingIsValidWireMockStub(contractDsl) + and: + SyntaxChecker.tryToCompile(methodBuilderName, blockBuilder.toString()) + where: + methodBuilderName | methodBuilder | bodyDefinitionString | bodyEvaluationString + HttpSpockMethodRequestProcessingBodyBuilder.simpleName | { Contract dsl -> new HttpSpockMethodRequestProcessingBodyBuilder(dsl, properties) } | 'def responseBody = (response.body.asString())' | 'responseBody == "test"' + MockMvcJUnitMethodBodyBuilder.simpleName | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl, properties) } | 'String responseBody = response.getBody().asString();' | 'assertThat(responseBody).isEqualTo("test");' + WebTestClientJUnitMethodBodyBuilder.simpleName | { Contract dsl -> new WebTestClientJUnitMethodBodyBuilder(dsl, properties) } | 'String responseBody = response.getBody().asString();' | 'assertThat(responseBody).isEqualTo("test");' + } + + @Issue('113') + def 'should generate regex test for String in response header with #methodBuilderName'() { + given: + Contract contractDsl = Contract.make { + request { + method 'POST' + url $(consumer(regex('/partners/[0-9]+/users')), producer('/partners/1000/users')) + headers { contentType(applicationJson()) } + body( + first_name: 'John', + last_name: 'Smith', + personal_id: '12345678901', + phone_number: '500500500', + invitation_token: '00fec7141bb94793bfe7ae1d0f39bda0', + password: 'john' + ) + } + response { + status 201 + headers { + header 'Location': $(consumer('http://localhost/partners/1000/users/1001'), producer(regex('http://localhost/partners/[0-9]+/users/[0-9]+'))) + } + } + } + MethodBodyBuilder builder = methodBuilder(contractDsl) + BlockBuilder blockBuilder = new BlockBuilder(" ") + when: + builder.appendTo(blockBuilder) + def test = blockBuilder.toString() + then: + test.contains(headerEvaluationString) + and: + stubMappingIsValidWireMockStub(contractDsl) + and: + SyntaxChecker.tryToCompile(methodBuilderName, blockBuilder.toString()) + where: + methodBuilderName | methodBuilder | headerEvaluationString + HttpSpockMethodRequestProcessingBodyBuilder.simpleName | { Contract dsl -> new HttpSpockMethodRequestProcessingBodyBuilder(dsl, properties) } | '''response.header('Location') ==~ java.util.regex.Pattern.compile('http://localhost/partners/[0-9]+/users/[0-9]+')''' + MockMvcJUnitMethodBodyBuilder.simpleName | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl, properties) } | 'assertThat(response.header("Location")).matches("http://localhost/partners/[0-9]+/users/[0-9]+");' + WebTestClientJUnitMethodBodyBuilder.simpleName | { Contract dsl -> new WebTestClientJUnitMethodBodyBuilder(dsl, properties) } | 'assertThat(response.header("Location")).matches("http://localhost/partners/[0-9]+/users/[0-9]+");' + } + + @Issue('115') + def 'should generate regex with helper method with #methodBuilderName'() { + given: + Contract contractDsl = Contract.make { + request { + method 'POST' + url $(consumer(regex('/partners/[0-9]+/users')), producer('/partners/1000/users')) + headers { contentType(applicationJson()) } + body( + first_name: 'John', + last_name: 'Smith', + personal_id: '12345678901', + phone_number: '500500500', + invitation_token: '00fec7141bb94793bfe7ae1d0f39bda0', + password: 'john' + ) + } + response { + status 201 + headers { + header 'Location': $(consumer('http://localhost/partners/1000/users/1001'), producer(regex("^${hostname()}/partners/[0-9]+/users/[0-9]+"))) + } + } + } + MethodBodyBuilder builder = methodBuilder(contractDsl) + BlockBuilder blockBuilder = new BlockBuilder(" ") + when: + builder.appendTo(blockBuilder) + def test = blockBuilder.toString() + then: + test.contains(headerEvaluationString) + and: + stubMappingIsValidWireMockStub(contractDsl) + and: + SyntaxChecker.tryToCompile(methodBuilderName, blockBuilder.toString()) + where: + methodBuilderName | methodBuilder | headerEvaluationString + HttpSpockMethodRequestProcessingBodyBuilder.simpleName | { Contract dsl -> new HttpSpockMethodRequestProcessingBodyBuilder(dsl, properties) } | '''response.header('Location') ==~ java.util.regex.Pattern.compile('^((http[s]?|ftp):/)/?([^:/s]+)(:[0-9]{1,5})?/partners/[0-9]+/users/[0-9]+')''' + MockMvcJUnitMethodBodyBuilder.simpleName | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl, properties) } | 'assertThat(response.header("Location")).matches("^((http[s]?|ftp):/)/?([^:/s]+)(:[0-9]{1,5})?/partners/[0-9]+/users/[0-9]+");' + WebTestClientJUnitMethodBodyBuilder.simpleName | { Contract dsl -> new WebTestClientJUnitMethodBodyBuilder(dsl, properties) } | 'assertThat(response.header("Location")).matches("^((http[s]?|ftp):/)/?([^:/s]+)(:[0-9]{1,5})?/partners/[0-9]+/users/[0-9]+");' + } + + def 'should work with more complex stuff and jsonpaths with #methodBuilderName'() { + given: + Contract contractDsl = Contract.make { + priority 10 + request { + method 'POST' + url '/validation/client' + headers { + contentType(applicationJson()) + } + body( + bank_account_number: '0014282912345698765432161182', + email: 'foo@bar.com', + phone_number: '100299300', + personal_id: 'ABC123456' + ) + } + + response { + status OK() + body(errors: [ + [property: "bank_account_number", message: "incorrect_format"] + ]) + } + } + MethodBodyBuilder builder = methodBuilder(contractDsl) + BlockBuilder blockBuilder = new BlockBuilder(" ") + when: + builder.appendTo(blockBuilder) + def test = blockBuilder.toString() + then: + test.contains("""assertThatJson(parsedJson).array("['errors']").contains("['property']").isEqualTo("bank_account_number")""") + test.contains("""assertThatJson(parsedJson).array("['errors']").contains("['message']").isEqualTo("incorrect_format")""") + and: + stubMappingIsValidWireMockStub(contractDsl) + and: + SyntaxChecker.tryToCompile(methodBuilderName, blockBuilder.toString()) + where: + methodBuilderName | methodBuilder + HttpSpockMethodRequestProcessingBodyBuilder.simpleName | { Contract dsl -> new HttpSpockMethodRequestProcessingBodyBuilder(dsl, properties) } + MockMvcJUnitMethodBodyBuilder.simpleName | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl, properties) } + WebTestClientJUnitMethodBodyBuilder.simpleName | { Contract dsl -> new WebTestClientJUnitMethodBodyBuilder(dsl, properties) } + } + + def 'should work properly with GString url with #methodBuilderName'() { + given: + Contract contractDsl = Contract.make { + + request { + method PUT() + url "/partners/${value(consumer(regex('^[0-9]*$')), producer('11'))}/agents/11/customers/09665703Z" + headers { + contentType(applicationJson()) + } + body( + first_name: 'Josef', + ) + } + response { + status 422 + } + } + MethodBodyBuilder builder = methodBuilder(contractDsl) + BlockBuilder blockBuilder = new BlockBuilder(" ") + when: + builder.appendTo(blockBuilder) + def test = blockBuilder.toString() + then: + test.contains('''/partners/11/agents/11/customers/09665703Z''') + and: + stubMappingIsValidWireMockStub(contractDsl) + and: + SyntaxChecker.tryToCompile(methodBuilderName, blockBuilder.toString()) + where: + methodBuilderName | methodBuilder + HttpSpockMethodRequestProcessingBodyBuilder.simpleName | { Contract dsl -> new HttpSpockMethodRequestProcessingBodyBuilder(dsl, properties) } + MockMvcJUnitMethodBodyBuilder.simpleName | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl, properties) } + WebTestClientJUnitMethodBodyBuilder.simpleName | { Contract dsl -> new WebTestClientJUnitMethodBodyBuilder(dsl, properties) } + } + + def 'should resolve properties in GString with regular expression with #methodBuilderName'() { + given: + Contract contractDsl = Contract.make { + priority 1 + request { + method POST() + url '/users/password' + headers { + contentType(applicationJson()) + } + body( + email: $(consumer(regex(email())), producer('not.existing@user.com')), + callback_url: $(consumer(regex(hostname())), producer('http://partners.com')) + ) + } + response { + status 404 + headers { + contentType(applicationJson()) + } + body( + code: 4, + message: "User not found by email = [${value(producer(regex(email())), consumer('not.existing@user.com'))}]" + ) + } + } + MethodBodyBuilder builder = methodBuilder(contractDsl) + BlockBuilder blockBuilder = new BlockBuilder(" ") + when: + builder.appendTo(blockBuilder) + def test = blockBuilder.toString() + then: + test.contains("""assertThatJson(parsedJson).field("['message']").matches("User not found by email = \\\\\\\\[[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\\\\\\\.[a-zA-Z]{2,6}\\\\\\\\]")""") + and: + // no static compilation due to bug in Groovy https://issues.apache.org/jira/browse/GROOVY-8055 + SyntaxChecker.tryToCompileWithoutCompileStatic(methodBuilderName, blockBuilder.toString()) + where: + methodBuilderName | methodBuilder + HttpSpockMethodRequestProcessingBodyBuilder.simpleName | { Contract dsl -> new HttpSpockMethodRequestProcessingBodyBuilder(dsl, properties) } + MockMvcJUnitMethodBodyBuilder.simpleName | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl, properties) } + WebTestClientJUnitMethodBodyBuilder.simpleName | { Contract dsl -> new WebTestClientJUnitMethodBodyBuilder(dsl, properties) } + } + + @Issue('42') + def 'should not omit the optional field in the test creation with MockMvcSpockMethodBodyBuilder'() { + given: + MethodBodyBuilder builder = new HttpSpockMethodRequestProcessingBodyBuilder(contractDsl, properties) + BlockBuilder blockBuilder = new BlockBuilder(" ") + when: + builder.appendTo(blockBuilder) + def test = blockBuilder.toString() + then: + test.contains('''"email":"abc@abc.com"''') + test.contains("""assertThatJson(parsedJson).field("['code']").matches("(123123)?")""") + !test.contains('''REGEXP''') + !test.contains('''OPTIONAL''') + !test.contains('''OptionalProperty''') + and: + SyntaxChecker.tryToCompileGroovy(HttpSpockMethodRequestProcessingBodyBuilder.simpleName, blockBuilder.toString()) + where: + contractDsl << [dslWithOptionals, dslWithOptionalsInString] + } + + @Issue('42') + def "should not omit the optional field in the test creation with MockMvcJUnitMethodBodyBuilder"() { + given: + MethodBodyBuilder builder = new MockMvcJUnitMethodBodyBuilder(contractDsl, properties) + BlockBuilder blockBuilder = new BlockBuilder(" ") + when: + builder.appendTo(blockBuilder) + def test = blockBuilder.toString() + then: + test.contains('\\"email\\":\\"abc@abc.com\\"') + test.contains('assertThatJson(parsedJson).field("[\'code\']").matches("(123123)?");') + !test.contains('''REGEXP''') + !test.contains('''OPTIONAL''') + !test.contains('''OptionalProperty''') + and: + SyntaxChecker.tryToCompileJava(MockMvcJUnitMethodBodyBuilder.simpleName, blockBuilder.toString()) + where: + contractDsl << [dslWithOptionals, dslWithOptionalsInString] + } + + @Issue('72') + def 'should make the execute method work with #methodBuilderName'() { + given: + Contract contractDsl = Contract.make { + request { + method """PUT""" + url """/fraudcheck""" + body(""" + { + "clientPesel":"${ + value(consumer(regex('[0-9]{10}')), producer('1234567890')) + }", + "loanAmount":123.123 + } + """ + ) + headers { + header("""Content-Type""", """application/vnd.fraud.v1+json""") + } + + } + response { + status OK() + body("""{ + "fraudCheckStatus": "OK", + "rejectionReason": ${ + value(consumer(null), producer(execute('assertThatRejectionReasonIsNull($it)'))) + } +}""") + headers { + header('Content-Type': 'application/vnd.fraud.v1+json') + header 'Location': value( + consumer(null), + producer(execute('assertThatLocationIsNull($it)')) + ) + } + } + } + MethodBodyBuilder builder = methodBuilder(contractDsl) + BlockBuilder blockBuilder = new BlockBuilder(" ") + when: + builder.appendTo(blockBuilder) + String test = blockBuilder.toString() + then: + assertionStrings.each { String assertionString -> + assert test.contains(assertionString) + } + where: + methodBuilderName | methodBuilder | assertionStrings + HttpSpockMethodRequestProcessingBodyBuilder.simpleName | { Contract dsl -> new HttpSpockMethodRequestProcessingBodyBuilder(dsl, properties) } | ['''assertThatRejectionReasonIsNull(parsedJson.read(\'\'\'$.rejectionReason\'\'\'))''', '''assertThatLocationIsNull(response.header('Location'))'''] + MockMvcJUnitMethodBodyBuilder.simpleName | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl, properties) } | ['''assertThatRejectionReasonIsNull(parsedJson.read("$.rejectionReason"))''', '''assertThatLocationIsNull(response.header("Location"))'''] + WebTestClientJUnitMethodBodyBuilder.simpleName | { Contract dsl -> new WebTestClientJUnitMethodBodyBuilder(dsl, properties) } | ['''assertThatRejectionReasonIsNull(parsedJson.read("$.rejectionReason"))''', '''assertThatLocationIsNull(response.header("Location"))'''] + } + + def 'should support inner map and list definitions with #methodBuilderName'() { + given: + + Pattern PHONE_NUMBER = Pattern.compile(/[+\w]*/) + Pattern ANYSTRING = Pattern.compile(/.*/) + Pattern NUMBERS = Pattern.compile(/[\d\.]*/) + Pattern DATETIME = ANYSTRING + + Contract contractDsl = Contract.make { + request { + method "PUT" + url "/v1/payments/e86df6f693de4b35ae648464c5b0dc09/client_data" + headers { + contentType(applicationJson()) + } + body( + client: [ + first_name : $(consumer(regex(onlyAlphaUnicode())), producer('Denis')), + last_name : $(consumer(regex(onlyAlphaUnicode())), producer('FakeName')), + email : $(consumer(regex(email())), producer('fakemail@fakegmail.com')), + fax : $(consumer(PHONE_NUMBER), producer('+xx001213214')), + phone : $(consumer(PHONE_NUMBER), producer('2223311')), + data_of_birth: $(consumer(DATETIME), producer('2002-10-22T00:00:00Z')) + ], + client_id_card: [ + id : $(consumer(ANYSTRING), producer('ABC12345')), + date_of_issue: $(consumer(ANYSTRING), producer('2002-10-02T00:00:00Z')), + address : [ + street : $(consumer(ANYSTRING), producer('Light Street')), + city : $(consumer(ANYSTRING), producer('Fire')), + region : $(consumer(ANYSTRING), producer('Skys')), + country: $(consumer(ANYSTRING), producer('HG')), + zip : $(consumer(NUMBERS), producer('658965')) + ] + ], + incomes_and_expenses: [ + monthly_income : $(consumer(NUMBERS), producer('0.0')), + monthly_loan_repayments: $(consumer(NUMBERS), producer('100')), + monthly_living_expenses: $(consumer(NUMBERS), producer('22')) + ], + additional_info: [ + allow_to_contact: $(consumer(optional(regex(anyBoolean()))), producer('true')) + ] + ) + } + response { + status OK() + headers { + contentType(applicationJson()) + } + } + } + MethodBodyBuilder builder = methodBuilder(contractDsl) + BlockBuilder blockBuilder = new BlockBuilder(" ") + when: + builder.appendTo(blockBuilder) + def test = blockBuilder.toString() + then: + test.contains bodyString + !test.contains("clientValue") + !test.contains("cursor") + and: + SyntaxChecker.tryToCompile(methodBuilderName, blockBuilder.toString()) + where: + methodBuilderName | methodBuilder | bodyString + HttpSpockMethodRequestProcessingBodyBuilder.simpleName | { Contract dsl -> new HttpSpockMethodRequestProcessingBodyBuilder(dsl, properties) } | '"street":"Light Street"' + MockMvcJUnitMethodBodyBuilder.simpleName | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl, properties) } | '\\"street\\":\\"Light Street\\"' + WebTestClientJUnitMethodBodyBuilder.simpleName | { Contract dsl -> new WebTestClientJUnitMethodBodyBuilder(dsl, properties) } | '\\"street\\":\\"Light Street\\"' + + } + + def 'should work with optional fields that have null #methodBuilderName'() { + given: + Contract contractDsl = Contract.make { + request { + method "PUT" + url "/v1/payments/e86df6f693de4b35ae648464c5b0dc09/client_data" + headers { + contentType(applicationJson()) + } + } + response { + status OK() + headers { + contentType(applicationJson()) + } + body( + code: $(optional(regex('123123'))) + ) + } + } + MethodBodyBuilder builder = methodBuilder(contractDsl) + BlockBuilder blockBuilder = new BlockBuilder(" ") + when: + builder.appendTo(blockBuilder) + def test = blockBuilder.toString() + then: + SyntaxChecker.tryToCompile(methodBuilderName, blockBuilder.toString()) + and: + String jsonSample = '''\ +String json = "{\\"code\\":null}"; +DocumentContext parsedJson = JsonPath.parse(json); +''' + and: + LinkedList lines = [] as LinkedList + test.eachLine { if (it.contains("assertThatJson")) lines << it else it } + lines.addFirst(jsonSample) + SyntaxChecker.tryToRun(methodBuilderName, lines.join("\n")) + where: + methodBuilderName | methodBuilder | bodyString + HttpSpockMethodRequestProcessingBodyBuilder.simpleName | { Contract dsl -> new HttpSpockMethodRequestProcessingBodyBuilder(dsl, properties) } | '"street":"Light Street"' + MockMvcJUnitMethodBodyBuilder.simpleName | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl, properties) } | '\\"street\\":\\"Light Street\\"' + WebTestClientJUnitMethodBodyBuilder.simpleName | { Contract dsl -> new WebTestClientJUnitMethodBodyBuilder(dsl, properties) } | '\\"street\\":\\"Light Street\\"' + + } + + def "shouldn't generate unicode escape characters with #methodBuilderName"() { + given: + Pattern ONLY_ALPHA_UNICODE = Pattern.compile(/[\p{L}]*/) + + Contract contractDsl = Contract.make { + request { + method "PUT" + url '/v1/payments/e86df6f693de4b35ae648464c5b0dc09/енев' + headers { + contentType(applicationJson()) + } + body( + client: [ + first_name: $(consumer(ONLY_ALPHA_UNICODE), producer('Пенева')), + last_name : $(consumer(ONLY_ALPHA_UNICODE), producer('Пенева')) + ] + ) + } + response { + status OK() + headers { + contentType(applicationJson()) + } + } + } + MethodBodyBuilder builder = methodBuilder(contractDsl) + BlockBuilder blockBuilder = new BlockBuilder(" ") + when: + builder.appendTo(blockBuilder) + def test = blockBuilder.toString() + then: + !test.contains("\\u041f") + and: + SyntaxChecker.tryToCompile(methodBuilderName, blockBuilder.toString()) + where: + methodBuilderName | methodBuilder + HttpSpockMethodRequestProcessingBodyBuilder.simpleName | { Contract dsl -> new HttpSpockMethodRequestProcessingBodyBuilder(dsl, properties) } + MockMvcJUnitMethodBodyBuilder.simpleName | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl, properties) } + WebTestClientJUnitMethodBodyBuilder.simpleName | { Contract dsl -> new WebTestClientJUnitMethodBodyBuilder(dsl, properties) } + } + + @Issue('177') + def 'should generate proper test code when having multiline body with #methodBuilderName'() { + given: + Contract contractDsl = Contract.make { + request { + method 'PUT' + url '/multiline' + body('''hello, +World.''') + } + response { + status OK() + } + } + MethodBodyBuilder builder = methodBuilder(contractDsl) + BlockBuilder blockBuilder = new BlockBuilder(" ") + when: + builder.given(blockBuilder) + def test = blockBuilder.toString() + then: + test.contains(bodyString) + and: + SyntaxChecker.tryToCompile(methodBuilderName, blockBuilder.toString()) + where: + methodBuilderName | methodBuilder | bodyString + HttpSpockMethodRequestProcessingBodyBuilder.simpleName | { Contract dsl -> new HttpSpockMethodRequestProcessingBodyBuilder(dsl, properties) } | """'''hello, +World.'''""" + MockMvcJUnitMethodBodyBuilder.simpleName | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl, properties) } | '"hello,\\nWorld."' + WebTestClientJUnitMethodBodyBuilder.simpleName | { Contract dsl -> new WebTestClientJUnitMethodBodyBuilder(dsl, properties) } | '"hello,\\nWorld."' + } + + @Issue('180') + def 'should generate proper test code when having multipart parameters with #methodBuilderName'() { + given: + // tag::multipartdsl[] + org.springframework.cloud.contract.spec.Contract contractDsl = org.springframework.cloud.contract.spec.Contract.make { + request { + method 'PUT' + url '/multipart' + headers { + contentType('multipart/form-data;boundary=AaB03x') + } + multipart( + // key (parameter name), value (parameter value) pair + formParameter: $(c(regex('".+"')), p('"formParameterValue"')), + someBooleanParameter: $(c(regex(anyBoolean())), p('true')), + // a named parameter (e.g. with `file` name) that represents file with + // `name` and `content`. You can also call `named("fileName", "fileContent")` + file: named( + // name of the file + name: $(c(regex(nonEmpty())), p('filename.csv')), + // content of the file + content: $(c(regex(nonEmpty())), p('file content')), + // content type for the part + contentType: $(c(regex(nonEmpty())), p('application/json'))) + ) + } + response { + status OK() + } + } + // end::multipartdsl[] + MethodBodyBuilder builder = methodBuilder(contractDsl) + BlockBuilder blockBuilder = new BlockBuilder(" ") + when: + builder.appendTo(blockBuilder) + def test = blockBuilder.toString() + then: + for (String requestString : requestStrings) { + assert test.contains(requestString) + } + and: + SyntaxChecker.tryToCompile(methodBuilderName, blockBuilder.toString()) + where: + methodBuilderName | methodBuilder | requestStrings + HttpSpockMethodRequestProcessingBodyBuilder.simpleName | { Contract dsl -> new HttpSpockMethodRequestProcessingBodyBuilder(dsl, properties) } | ['"Content-Type", "multipart/form-data;boundary=AaB03x"', + """.param('formParameter', '"formParameterValue"'""", + """.param('someBooleanParameter', 'true')""", + """.multiPart('file', 'filename.csv', 'file content'.bytes, 'application/json')"""] + MockMvcJUnitMethodBodyBuilder.simpleName | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl, properties) } | ['"Content-Type", "multipart/form-data;boundary=AaB03x"', + '.param("formParameter", "\\"formParameterValue\\"")', + '.param("someBooleanParameter", "true")', + '.multiPart("file", "filename.csv", "file content".getBytes(), "application/json");'] + WebTestClientJUnitMethodBodyBuilder.simpleName | { Contract dsl -> new WebTestClientJUnitMethodBodyBuilder(dsl, properties) } | ['"Content-Type", "multipart/form-data;boundary=AaB03x"', + '.param("formParameter", "\\"formParameterValue\\"")', + '.param("someBooleanParameter", "true")', + '.multiPart("file", "filename.csv", "file content".getBytes(), "application/json");'] + + } + + @Issue('180') + def 'should generate proper test code when having multipart parameters without content type with #methodBuilderName'() { + given: + org.springframework.cloud.contract.spec.Contract contractDsl = org.springframework.cloud.contract.spec.Contract.make { + request { + method 'PUT' + url '/multipart' + headers { + contentType('multipart/form-data;boundary=AaB03x') + } + multipart( + // key (parameter name), value (parameter value) pair + formParameter: $(c(regex('".+"')), p('"formParameterValue"')), + someBooleanParameter: $(c(regex(anyBoolean())), p('true')), + // a named parameter (e.g. with `file` name) that represents file with + // `name` and `content`. You can also call `named("fileName", "fileContent")` + file: named( + // name of the file + name: $(c(regex(nonEmpty())), p('filename.csv')), + // content of the file + content: $(c(regex(nonEmpty())), p('file content'))) + ) + } + response { + status OK() + } + } + MethodBodyBuilder builder = methodBuilder(contractDsl) + BlockBuilder blockBuilder = new BlockBuilder(" ") + when: + builder.appendTo(blockBuilder) + def test = blockBuilder.toString() + then: + for (String requestString : requestStrings) { + assert test.contains(requestString) + } + and: + SyntaxChecker.tryToCompile(methodBuilderName, blockBuilder.toString()) + where: + methodBuilderName | methodBuilder | requestStrings + HttpSpockMethodRequestProcessingBodyBuilder.simpleName | { Contract dsl -> new HttpSpockMethodRequestProcessingBodyBuilder(dsl, properties) } | ['"Content-Type", "multipart/form-data;boundary=AaB03x"', + """.param('formParameter', '"formParameterValue"'""", + """.param('someBooleanParameter', 'true')""", + """.multiPart('file', 'filename.csv', 'file content'.bytes)"""] + MockMvcJUnitMethodBodyBuilder.simpleName | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl, properties) } | ['"Content-Type", "multipart/form-data;boundary=AaB03x"', + '.param("formParameter", "\\"formParameterValue\\"")', + '.param("someBooleanParameter", "true")', + '.multiPart("file", "filename.csv", "file content".getBytes());'] + WebTestClientJUnitMethodBodyBuilder.simpleName | { Contract dsl -> new WebTestClientJUnitMethodBodyBuilder(dsl, properties) } | ['"Content-Type", "multipart/form-data;boundary=AaB03x"', + '.param("formParameter", "\\"formParameterValue\\"")', + '.param("someBooleanParameter", "true")', + '.multiPart("file", "filename.csv", "file content".getBytes());'] + } + + @Issue('546') + def 'should generate test code when having multipart parameters with byte array #methodBuilderName'() { + given: + // tag::multipartdsl[] + org.springframework.cloud.contract.spec.Contract contractDsl = org.springframework.cloud.contract.spec.Contract.make { + request { + method "PUT" + url "/multipart" + headers { + contentType('multipart/form-data;boundary=AaB03x') + } + multipart( + file: named( + name: value(stub(regex('.+')), test('file')), + content: value(stub(regex('.+')), test([100, 117, 100, 97] as byte[])) + ) + ) + } + response { + status 200 + } + } + // end::multipartdsl[] + MethodBodyBuilder builder = methodBuilder(contractDsl) + BlockBuilder blockBuilder = new BlockBuilder(" ") + when: + builder.appendTo(blockBuilder) + def test = blockBuilder.toString() + then: + for (String requestString : requestStrings) { + assert test.contains(requestString) + } + and: + SyntaxChecker.tryToCompile(methodBuilderName, blockBuilder.toString()) + where: + methodBuilderName | methodBuilder | requestStrings + HttpSpockMethodRequestProcessingBodyBuilder.simpleName | { Contract dsl -> new HttpSpockMethodRequestProcessingBodyBuilder(dsl, properties) } | ['"Content-Type", "multipart/form-data;boundary=AaB03x"', + """.multiPart('file', 'file', [100, 117, 100, 97] as byte[])"""] + MockMvcJUnitMethodBodyBuilder.simpleName | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl, properties) } | ['"Content-Type", "multipart/form-data;boundary=AaB03x"', + '.multiPart("file", "file", new byte[] {100, 117, 100, 97});'] + WebTestClientJUnitMethodBodyBuilder.simpleName | { Contract dsl -> new WebTestClientJUnitMethodBodyBuilder(dsl, properties) } | ['"Content-Type", "multipart/form-data;boundary=AaB03x"', + '.multiPart("file", "file", new byte[] {100, 117, 100, 97});'] + + } + + @Issue('541') + def 'should generate proper test code when having multipart parameters that use execute with #methodBuilderName'() { + given: + org.springframework.cloud.contract.spec.Contract contractDsl = org.springframework.cloud.contract.spec.Contract.make { + request { + method "PUT" + url "/multipart" + headers { + contentType('multipart/form-data;boundary=AaB03x') + } + multipart( + formParameter: $(c(regex('".+"')), p('"formParameterValue"')), + someBooleanParameter: $(c(regex(anyBoolean())), p('true')), + file: named( + name: $(c(regex(nonEmpty())), p(execute('toString()'))), + content: $(c(regex(nonEmpty())), p('file content'))) + ) + } + response { + status OK() + } + } + MethodBodyBuilder builder = methodBuilder(contractDsl) + BlockBuilder blockBuilder = new BlockBuilder(" ") + when: + builder.appendTo(blockBuilder) + def test = blockBuilder.toString() + then: + for (String requestString : requestStrings) { + assert test.contains(requestString) + } + and: + SyntaxChecker.tryToCompile(methodBuilderName, blockBuilder.toString()) + where: + methodBuilderName | methodBuilder | requestStrings + HttpSpockMethodRequestProcessingBodyBuilder.simpleName | { Contract dsl -> new HttpSpockMethodRequestProcessingBodyBuilder(dsl, properties) } | ['"Content-Type", "multipart/form-data;boundary=AaB03x"', + """.param('formParameter', '"formParameterValue"'""", + """.param('someBooleanParameter', 'true')""", + """.multiPart('file', toString(), 'file content'.bytes)"""] + MockMvcJUnitMethodBodyBuilder.simpleName | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl, properties) } | ['"Content-Type", "multipart/form-data;boundary=AaB03x"', + '.param("formParameter", "\\"formParameterValue\\"")', + '.param("someBooleanParameter", "true")', + '.multiPart("file", toString(), "file content".getBytes());'] + WebTestClientJUnitMethodBodyBuilder.simpleName | { Contract dsl -> new WebTestClientJUnitMethodBodyBuilder(dsl, properties) } | ['"Content-Type", "multipart/form-data;boundary=AaB03x"', + '.param("formParameter", "\\"formParameterValue\\"")', + '.param("someBooleanParameter", "true")', + '.multiPart("file", toString(), "file content".getBytes());'] + + } + + @Issue('180') + def 'should generate proper test code when having multipart parameters with named as map with #methodBuilderName'() { + given: + org.springframework.cloud.contract.spec.Contract contractDsl = org.springframework.cloud.contract.spec.Contract.make { + request { + method 'PUT' + url "/multipart" + headers { + contentType('multipart/form-data;boundary=AaB03x') + } + multipart( + // key (parameter name), value (parameter value) pair + formParameter: $(c(regex('".+"')), p('"formParameterValue"')), + someBooleanParameter: $(c(regex(anyBoolean())), p('true')), + // a named parameter (e.g. with `file` name) that represents file with + // `name` and `content`. You can also call `named("fileName", "fileContent")` + file: named( + // name of the file + name: $(c(regex(nonEmpty())), p('filename.csv')), + // content of the file + content: $(c(regex(nonEmpty())), p('file content'))) + ) + } + response { + status OK() + } + } + MethodBodyBuilder builder = methodBuilder(contractDsl) + BlockBuilder blockBuilder = new BlockBuilder(" ") + when: + builder.given(blockBuilder) + def test = blockBuilder.toString() + then: + test.contains('.multiPart') + and: + SyntaxChecker.tryToCompile(methodBuilderName, blockBuilder.toString()) + where: + methodBuilderName | methodBuilder + HttpSpockMethodRequestProcessingBodyBuilder.simpleName | { Contract dsl -> new HttpSpockMethodRequestProcessingBodyBuilder(dsl, properties) } + MockMvcJUnitMethodBodyBuilder.simpleName | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl, properties) } + WebTestClientJUnitMethodBodyBuilder.simpleName | { Contract dsl -> new WebTestClientJUnitMethodBodyBuilder(dsl, properties) } + } + + @Issue('#216') + def 'should parse JSON with arrays using Spock'() { + given: + Contract contractDsl = Contract.make { + request { + method "GET" + urlPath('/auth/oauth/check_token') { + queryParameters { + parameter 'token': value( + consumer(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}')), + producer('6973b31d-7140-402a-bca6-1cdb954e03a7') + ) + } + } + } + response { + status OK() + body( + authorities: [ + value(consumer('ROLE_ADMIN'), producer(regex('^[a-zA-Z0-9_\\- ]+$'))) + ] + ) + } + } + MethodBodyBuilder builder = new HttpSpockMethodRequestProcessingBodyBuilder(contractDsl, properties) + BlockBuilder blockBuilder = new BlockBuilder(" ") + when: + builder.appendTo(blockBuilder) + def test = blockBuilder.toString() + then: + test.contains('''assertThatJson(parsedJson).array("[\'authorities']").arrayField().matches("^[a-zA-Z0-9_\\\\- ]+\\$").value()''') + and: + SyntaxChecker.tryToCompileGroovy(HttpSpockMethodRequestProcessingBodyBuilder.simpleName, blockBuilder.toString()) + } + + @Issue('#216') + def 'should parse JSON with arrays using JUnit'() { + given: + Contract contractDsl = Contract.make { + request { + method "GET" + urlPath('/auth/oauth/check_token') { + queryParameters { + parameter 'token': value( + consumer(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}')), + producer('6973b31d-7140-402a-bca6-1cdb954e03a7') + ) + } + } + } + response { + status OK() + body( + authorities: [ + value(consumer('ROLE_ADMIN'), producer(regex('^[a-zA-Z0-9_\\- ]+$'))) + ] + ) + } + } + MethodBodyBuilder builder = new MockMvcJUnitMethodBodyBuilder(contractDsl, properties) + BlockBuilder blockBuilder = new BlockBuilder(" ") + when: + builder.appendTo(blockBuilder) + def test = blockBuilder.toString() + then: + test.contains('''assertThatJson(parsedJson).array("[\'authorities']").arrayField().matches("^[a-zA-Z0-9_\\\\- ]+$").value()''') + and: + SyntaxChecker.tryToCompileJava(MockMvcJUnitMethodBodyBuilder.simpleName, blockBuilder.toString()) + } + + def 'should work with execution property with #methodBuilderName'() { + given: + Contract contractDsl = Contract.make { + request { + method 'PUT' + url '/fraudcheck' + } + response { + status OK() + body( + fraudCheckStatus: "OK", + rejectionReason: $(consumer(null), producer(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 + HttpSpockMethodRequestProcessingBodyBuilder.simpleName | { Contract dsl -> new HttpSpockMethodRequestProcessingBodyBuilder(dsl, properties) } + MockMvcJUnitMethodBodyBuilder.simpleName | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl, properties) } + WebTestClientJUnitMethodBodyBuilder.simpleName | { Contract dsl -> new WebTestClientJUnitMethodBodyBuilder(dsl, properties) } + } + + @Issue('262') + def 'should generate proper test code with map inside list'() { + given: + Contract contractDsl = Contract.make { + request { + method 'GET' + urlPath '/foos' + } + response { + status OK() + body([[id: value( + consumer('123'), + producer(regex('[0-9]+')) + )], [id: value( + consumer('567'), + producer(regex('[0-9]+')) + )]]) + headers { + contentType(applicationJsonUtf8()) + } + } + } + MethodBodyBuilder builder = new HttpSpockMethodRequestProcessingBodyBuilder(contractDsl, properties) + BlockBuilder blockBuilder = new BlockBuilder(" ") + when: + builder.appendTo(blockBuilder) + def test = blockBuilder.toString() + then: + test.contains('assertThatJson(parsedJson).array().contains("[\'id\']").matches("[0-9]+")') + and: + SyntaxChecker.tryToCompileGroovy(MockMvcJUnitMethodBodyBuilder.simpleName, blockBuilder.toString()) + } + + @Issue('266') + def 'should generate proper test code with top level array using #methodBuilderName'() { + given: + Contract contractDsl = Contract.make { + request { + method 'GET' + urlPath '/api/tags' + } + response { + status OK() + body(["Java", "Java8", "Spring", "SpringBoot", "Stream"]) + headers { + header('Content-Type': 'application/json;charset=UTF-8') + } + } + } + MethodBodyBuilder builder = methodBuilder(contractDsl) + BlockBuilder blockBuilder = new BlockBuilder(" ") + when: + builder.appendTo(blockBuilder) + def test = blockBuilder.toString() + then: + test.contains('assertThatJson(parsedJson).arrayField().contains("Java8").value()') + test.contains('assertThatJson(parsedJson).arrayField().contains("Spring").value()') + test.contains('assertThatJson(parsedJson).arrayField().contains("Java").value()') + test.contains('assertThatJson(parsedJson).arrayField().contains("Stream").value()') + test.contains('assertThatJson(parsedJson).arrayField().contains("SpringBoot").value()') + and: + SyntaxChecker.tryToCompile(methodBuilderName, blockBuilder.toString()) + where: + methodBuilderName | methodBuilder + HttpSpockMethodRequestProcessingBodyBuilder.simpleName | { Contract dsl -> new HttpSpockMethodRequestProcessingBodyBuilder(dsl, properties) } + MockMvcJUnitMethodBodyBuilder.simpleName | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl, properties) } + WebTestClientJUnitMethodBodyBuilder.simpleName | { Contract dsl -> new WebTestClientJUnitMethodBodyBuilder(dsl, properties) } + } + + @Issue('266') + @RestoreSystemProperties + def 'should generate proper test code with top level array using #methodBuilderName with array size check'() { + given: + System.setProperty('spring.cloud.contract.verifier.assert.size', 'true') + Contract contractDsl = Contract.make { + request { + method 'GET' + urlPath '/api/tags' + } + response { + status OK() + body(['Java', 'Java8', 'Spring', 'SpringBoot', 'Stream']) + headers { + header('Content-Type': 'application/json;charset=UTF-8') + } + } + } + MethodBodyBuilder builder = methodBuilder(contractDsl) + BlockBuilder blockBuilder = new BlockBuilder(" ") + when: + builder.appendTo(blockBuilder) + def test = blockBuilder.toString() + then: + test.contains('assertThatJson(parsedJson).hasSize(5)') + test.contains('assertThatJson(parsedJson).arrayField().contains("Java8").value()') + test.contains('assertThatJson(parsedJson).arrayField().contains("Spring").value()') + test.contains('assertThatJson(parsedJson).arrayField().contains("Java").value()') + test.contains('assertThatJson(parsedJson).arrayField().contains("Stream").value()') + test.contains('assertThatJson(parsedJson).arrayField().contains("SpringBoot").value()') + and: + SyntaxChecker.tryToCompile(methodBuilderName, blockBuilder.toString()) + where: + methodBuilderName | methodBuilder + HttpSpockMethodRequestProcessingBodyBuilder.simpleName | { Contract dsl -> new HttpSpockMethodRequestProcessingBodyBuilder(dsl, properties) } + MockMvcJUnitMethodBodyBuilder.simpleName | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl, properties) } + WebTestClientJUnitMethodBodyBuilder.simpleName | { Contract dsl -> new WebTestClientJUnitMethodBodyBuilder(dsl, properties) } + } + + @Issue('266') + def 'should generate proper test code with top level array or arrays using #methodBuilderName'() { + given: + Contract contractDsl = Contract.make { + request { + method 'GET' + urlPath '/api/categories' + } + response { + status OK() + body([["Programming", "Java"], ["Programming", "Java", "Spring", "Boot"]]) + headers { + header('Content-Type': 'application/json;charset=UTF-8') + } + } + } + MethodBodyBuilder builder = methodBuilder(contractDsl) + BlockBuilder blockBuilder = new BlockBuilder(" ") + when: + builder.appendTo(blockBuilder) + def test = blockBuilder.toString() + then: + test.contains('assertThatJson(parsedJson).array().array().arrayField().isEqualTo("Programming").value()') + test.contains('assertThatJson(parsedJson).array().array().arrayField().isEqualTo("Java").value()') + test.contains('assertThatJson(parsedJson).array().array().arrayField().isEqualTo("Spring").value()') + test.contains('assertThatJson(parsedJson).array().array().arrayField().isEqualTo("Boot").value()') + and: + SyntaxChecker.tryToCompile(methodBuilderName, blockBuilder.toString()) + where: + methodBuilderName | methodBuilder + HttpSpockMethodRequestProcessingBodyBuilder.simpleName | { Contract dsl -> new HttpSpockMethodRequestProcessingBodyBuilder(dsl, properties) } + MockMvcJUnitMethodBodyBuilder.simpleName | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl, properties) } + WebTestClientJUnitMethodBodyBuilder.simpleName | { Contract dsl -> new WebTestClientJUnitMethodBodyBuilder(dsl, properties) } + } + + @Issue('47') + def 'should generate async body when async flag set in response'() { + given: + Contract contractDsl = Contract.make { + request { + method 'GET' + url '/test' + } + response { + status OK() + async() + } + } + MethodBodyBuilder builder = methodBuilder(contractDsl) + BlockBuilder blockBuilder = new BlockBuilder(" ") + when: + builder.appendTo(blockBuilder) + def test = blockBuilder.toString() + then: + test.contains(bodyDefinitionString) + and: + stubMappingIsValidWireMockStub(contractDsl) + and: + SyntaxChecker.tryToCompile(methodBuilderName, blockBuilder.toString()) + where: + methodBuilderName | methodBuilder | bodyDefinitionString + HttpSpockMethodRequestProcessingBodyBuilder.simpleName | { Contract dsl -> new HttpSpockMethodRequestProcessingBodyBuilder(dsl, properties) } | '.when().async()' + MockMvcJUnitMethodBodyBuilder.simpleName | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl, properties) } | '.when().async()' + } + + @Issue('372') + def "should generate async body after queryParams when async flag set in response and queryParams set in request"() { + given: + Contract contractDsl = Contract.make { + request { + method 'GET' + url('/test') { + queryParameters { + parameter("param", "value") + } + } + } + response { + status OK() + async() + } + } + MethodBodyBuilder builder = methodBuilder(contractDsl) + BlockBuilder blockBuilder = new BlockBuilder(" ") + when: + builder.appendTo(blockBuilder) + def test = blockBuilder.toString() + def strippedTest = test.replace('\n', '').replace(' ', '').stripIndent().stripMargin() + then: + strippedTest.contains('.queryParam("param","value").when().async().get("/test")') + and: + stubMappingIsValidWireMockStub(contractDsl) + and: + SyntaxChecker.tryToCompile(methodBuilderName, blockBuilder.toString()) + where: + methodBuilderName | methodBuilder + HttpSpockMethodRequestProcessingBodyBuilder.simpleName | { Contract dsl -> new HttpSpockMethodRequestProcessingBodyBuilder(dsl, properties) } + MockMvcJUnitMethodBodyBuilder.simpleName | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl, properties) } + } + + def 'should generate proper test code with array of primitives using #methodBuilderName'() { + given: + Contract contractDsl = Contract.make { + request { + method 'GET' + urlPath '/api/tags' + } + response { + status OK() + body('''{ + "partners":[ + { + "payment_methods":[ "BANK", "CASH" ] + } + ] + } + ''') + } + } + MethodBodyBuilder builder = methodBuilder(contractDsl) + BlockBuilder blockBuilder = new BlockBuilder(" ") + when: + builder.appendTo(blockBuilder) + def test = blockBuilder.toString() + then: + test.contains('assertThatJson(parsedJson).array("[\'partners\']").array("[\'payment_methods\']").arrayField().isEqualTo("BANK").value()') + test.contains('assertThatJson(parsedJson).array("[\'partners\']").array("[\'payment_methods\']").arrayField().isEqualTo("CASH").value()') + and: + SyntaxChecker.tryToCompile(methodBuilderName, blockBuilder.toString()) + where: + methodBuilderName | methodBuilder + HttpSpockMethodRequestProcessingBodyBuilder.simpleName | { Contract dsl -> new HttpSpockMethodRequestProcessingBodyBuilder(dsl, properties) } + MockMvcJUnitMethodBodyBuilder.simpleName | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl, properties) } + WebTestClientJUnitMethodBodyBuilder.simpleName | { Contract dsl -> new WebTestClientJUnitMethodBodyBuilder(dsl, properties) } + } + + @Issue('#273') + def "should not escape dollar in Spock regex tests"() { + given: + Contract contractDsl = Contract.make { + request { + method 'GET' + urlPath '/get' + } + response { + status OK() + body(code: 9, message: $(consumer('Wrong credentials'), producer(regex('^(?!\\s*$).+')))) + } + } + MethodBodyBuilder builder = new HttpSpockMethodRequestProcessingBodyBuilder(contractDsl, properties) + BlockBuilder blockBuilder = new BlockBuilder(" ") + when: + builder.appendTo(blockBuilder) + def test = blockBuilder.toString() + then: + test.contains('assertThatJson(parsedJson).field("[\'message\']").matches("^(?!\\\\s*\\$).+")') + and: + SyntaxChecker.tryToCompileGroovy(MockMvcJUnitMethodBodyBuilder.simpleName, blockBuilder.toString(), false) + } + + Contract dslForDocs = + // tag::dsl_example[] + org.springframework.cloud.contract.spec.Contract.make { + request { + method 'PUT' + url '/api/12' + headers { + header 'Content-Type': 'application/vnd.org.springframework.cloud.contract.verifier.twitter-places-analyzer.v1+json' + } + body '''\ + [{ + "created_at": "Sat Jul 26 09:38:57 +0000 2014", + "id": 492967299297845248, + "id_str": "492967299297845248", + "text": "Gonna see you at Warsaw", + "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" + } + }] + ''' + } + response { + status OK() + } + } + // end::dsl_example[] + + Contract dslWithOnlyOneSideForDocs = + // tag::dsl_one_side_data_generation_example[] + org.springframework.cloud.contract.spec.Contract.make { + request { + method 'PUT' + url value(consumer(regex('/foo/[0-9]{5}'))) + body([ + requestElement: $(consumer(regex('[0-9]{5}'))) + ]) + headers { + header('header', $(consumer(regex('application\\/vnd\\.fraud\\.v1\\+json;.*')))) + } + } + response { + status OK() + body([ + responseElement: $(producer(regex('[0-9]{7}'))) + ]) + headers { + contentType("application/vnd.fraud.v1+json") + } + } + } + // end::dsl_one_side_data_generation_example[] + + @Issue('#32') + def 'should generate the regular expression for the other side of communication'() { + given: + MethodBodyBuilder builder = new HttpSpockMethodRequestProcessingBodyBuilder( + dslWithOnlyOneSideForDocs, properties) + BlockBuilder blockBuilder = new BlockBuilder(" ") + when: + builder.appendTo(blockBuilder) + def test = blockBuilder.toString() + def strippedTest = test.replace('\n', '').stripIndent().stripMargin() + then: + strippedTest.matches(""".*header\\("header", "application\\/vnd\\.fraud\\.v1\\+json;.*"\\).*""") + strippedTest.matches(""".*body\\('''\\{"requestElement":"[0-9]{5}"\\}'''\\).*""") + strippedTest.matches(""".*put\\("/foo/[0-9]{5}"\\).*""") + strippedTest.contains("""response.header('Content-Type') ==~ java.util.regex.Pattern.compile('application/vnd\\\\.fraud\\\\.v1\\\\+json.*')""") + "application/vnd.fraud.v1+json;charset=UTF-8".matches('application/vnd\\.fraud\\.v1\\+json.*') + strippedTest.contains("""assertThatJson(parsedJson).field("['responseElement']").matches("[0-9]{7}")""") + and: + SyntaxChecker.tryToCompileGroovy(HttpSpockMethodRequestProcessingBodyBuilder.simpleName, blockBuilder.toString()) + } + + @Issue('#85') + def 'should execute custom method for complex structures on the response side'() { + given: + Contract contractDsl = Contract.make { + request { + method 'GET' + urlPath '/get' + } + response { + status OK() + body([ + fraudCheckStatus: "OK", + rejectionReason : [ + title: $(consumer(null), producer(execute('assertThatRejectionReasonIsNull($it)'))) + ] + ]) + } + } + MethodBodyBuilder builder = new HttpSpockMethodRequestProcessingBodyBuilder(contractDsl, properties) + BlockBuilder blockBuilder = new BlockBuilder(" ") + when: + builder.then(blockBuilder) + def test = blockBuilder.toString() + then: + test.contains('assertThatRejectionReasonIsNull(parsedJson.read(\'\'\'$.rejectionReason.title\'\'\'))') + when: + SyntaxChecker.tryToCompileGroovy(HttpSpockMethodRequestProcessingBodyBuilder.simpleName, blockBuilder.toString()) + then: + def e = thrown(MultipleCompilationErrorsException) + e.message.contains("Cannot find matching method Script1#assertThatRejectionReasonIsNull") + } + + @Issue('#85') + def 'should execute custom method for more complex structures on the response side when using Spock'() { + given: + Contract contractDsl = Contract.make { + request { + method 'GET' + urlPath '/get' + } + response { + status OK() + body([ + [ + name: $(consumer("userName 1"), producer(execute('assertThatUserNameIsNotNull($it)'))) + ], + [ + name: $(consumer("userName 2"), producer(execute('assertThatUserNameIsNotNull($it)'))) + ] + ]) + } + } + MethodBodyBuilder builder = new HttpSpockMethodRequestProcessingBodyBuilder(contractDsl, properties) + BlockBuilder blockBuilder = new BlockBuilder(" ") + when: + builder.then(blockBuilder) + def test = blockBuilder.toString() + then: + test.contains('''assertThatUserNameIsNotNull(parsedJson.read(\'\'\'$.[0].name\'\'\')''') + test.contains('''assertThatUserNameIsNotNull(parsedJson.read(\'\'\'$.[1].name\'\'\')''') + } + + @Issue('#85') + def 'should execute custom method for more complex structures on the response side when using JUnit'() { + given: + Contract contractDsl = Contract.make { + request { + method 'GET' + urlPath '/get' + } + response { + status OK() + body([ + [ + name: $(consumer("userName 1"), producer(execute('assertThatUserNameIsNotNull($it)'))) + ], + [ + name: $(consumer("userName 2"), producer(execute('assertThatUserNameIsNotNull($it)'))) + ] + ]) + } + } + MethodBodyBuilder builder = new MockMvcJUnitMethodBodyBuilder(contractDsl, properties) + BlockBuilder blockBuilder = new BlockBuilder(" ") + when: + builder.then(blockBuilder) + def test = blockBuilder.toString() + then: + test.contains('''assertThatUserNameIsNotNull(parsedJson.read("$.[0].name")''') + test.contains('''assertThatUserNameIsNotNull(parsedJson.read("$.[1].name")''') + } + + @Issue('#111') + def 'should execute custom method for request headers'() { + given: + Contract contractDsl = Contract.make { + request { + method 'GET' + urlPath '/get' + headers { + header('authorization', value(consumer('Bearer token'), producer(execute('getOAuthTokenHeader()')))) + } + } + response { + status OK() + body([ + fraudCheckStatus: "OK", + rejectionReason : [ + title: $(consumer(null), producer(execute('assertThatRejectionReasonIsNull($it)'))) + ] + ]) + } + } + MethodBodyBuilder builder = new HttpSpockMethodRequestProcessingBodyBuilder(contractDsl, properties) + BlockBuilder blockBuilder = new BlockBuilder(" ") + when: + builder.given(blockBuilder) + def test = blockBuilder.toString() + then: + test.contains('.header("authorization", getOAuthTokenHeader())') + when: + SyntaxChecker.tryToCompileGroovy(HttpSpockMethodRequestProcessingBodyBuilder.simpleName, blockBuilder.toString()) + then: + def e = thrown(MultipleCompilationErrorsException) + e.message.contains("Cannot find matching method Script1#getOAuthTokenHeader") + } + + @Issue('#150') + def 'should support body matching in response'() { + given: + Contract contractDsl = Contract.make { + request { + method 'GET' + url '/get' + } + response { + status OK() + body(value(stub("HELLO FROM STUB"), server(regex(".*")))) + } + } + MethodBodyBuilder builder = new HttpSpockMethodRequestProcessingBodyBuilder(contractDsl, properties) + BlockBuilder blockBuilder = new BlockBuilder(" ") + when: + builder.appendTo(blockBuilder) + def test = blockBuilder.toString() + then: + test.contains("responseBody ==~ java.util.regex.Pattern.compile('.*')") + and: + SyntaxChecker.tryToCompileGroovy(HttpSpockMethodRequestProcessingBodyBuilder.simpleName, blockBuilder.toString()) + } + + @Issue('#150') + def 'should support custom method execution in response'() { + given: + Contract contractDsl = Contract.make { + request { + method 'GET' + url '/get' + } + response { + status OK() + body(value(stub("HELLO FROM STUB"), server(execute('foo($it)')))) + } + } + MethodBodyBuilder builder = new HttpSpockMethodRequestProcessingBodyBuilder(contractDsl, properties) + BlockBuilder blockBuilder = new BlockBuilder(" ") + when: + builder.appendTo(blockBuilder) + def test = blockBuilder.toString() + then: + test.contains("foo(responseBody)") + when: + SyntaxChecker.tryToCompileGroovy(HttpSpockMethodRequestProcessingBodyBuilder.simpleName, blockBuilder.toString()) + then: + def e = thrown(MultipleCompilationErrorsException) + e.message.contains("Cannot find matching method Script1#foo") + } + + @Issue('#149') + def 'should allow c/p version of consumer producer'() { + given: + Contract contractDsl = Contract.make { + request { + method 'GET' + urlPath '/get' + headers { + header('authorization', $(c('Bearer token'), p(execute('getOAuthTokenHeader()')))) + } + } + response { + status OK() + body([ + fraudCheckStatus: "OK", + rejectionReason : [ + title: $(c(null), p(execute('assertThatRejectionReasonIsNull($it)'))) + ] + ]) + } + } + MethodBodyBuilder builder = new HttpSpockMethodRequestProcessingBodyBuilder(contractDsl, properties) + BlockBuilder blockBuilder = new BlockBuilder(" ") + when: + builder.given(blockBuilder) + def test = blockBuilder.toString() + then: + test.contains('.header("authorization", getOAuthTokenHeader())') + when: + SyntaxChecker.tryToCompileGroovy(HttpSpockMethodRequestProcessingBodyBuilder.simpleName, blockBuilder.toString()) + then: + def e = thrown(MultipleCompilationErrorsException) + e.message.contains("Cannot find matching method Script1#getOAuthTokenHeader()") + } + + @Issue('#149') + def 'should allow easier way of providing dynamic values for [#methodBuilderName]'() { + given: + Contract contractDsl = Contract.make { + request { + method 'GET' + urlPath '/get' + body([ + duck : $(regex("[0-9]")), + alpha : $(anyAlphaUnicode()), + number : $(anyNumber()), + anInteger : $(anyInteger()), + positiveInt : $(positiveInt()), + aDouble : $(anyDouble()), + aBoolean : $(aBoolean()), + ip : $(anyIpAddress()), + hostname : $(anyHostname()), + email : $(anyEmail()), + url : $(anyUrl()), + httpsUrl : $(anyHttpsUrl()), + uuid : $(anyUuid()), + date : $(anyDate()), + dateTime : $(anyDateTime()), + time : $(anyTime()), + iso8601WithOffset: $(anyIso8601WithOffset()), + nonBlankString : $(anyNonBlankString()), + nonEmptyString : $(anyNonEmptyString()), + anyOf : $(anyOf('foo', 'bar')) + ]) + headers { + contentType(applicationJson()) + } + } + response { + status OK() + body([ + alpha : $(anyAlphaUnicode()), + number : $(anyNumber()), + anInteger : $(anyInteger()), + positiveInt : $(positiveInt()), + aDouble : $(anyDouble()), + aBoolean : $(aBoolean()), + ip : $(anyIpAddress()), + hostname : $(anyHostname()), + email : $(anyEmail()), + url : $(anyUrl()), + httpsUrl : $(anyHttpsUrl()), + uuid : $(anyUuid()), + date : $(anyDate()), + dateTime : $(anyDateTime()), + time : $(anyTime()), + iso8601WithOffset: $(anyIso8601WithOffset()), + nonBlankString : $(anyNonBlankString()), + nonEmptyString : $(anyNonEmptyString()), + anyOf : $(anyOf('foo', 'bar')) + ]) + headers { + contentType(applicationJson()) + } + } + } + MethodBodyBuilder builder = methodBuilder(contractDsl) + BlockBuilder blockBuilder = new BlockBuilder(" ") + when: + builder.appendTo(blockBuilder) + def test = blockBuilder.toString() + then: + test.contains('assertThatJson(parsedJson).field("[\'aBoolean\']").matches("(true|false)")') + test.contains('assertThatJson(parsedJson).field("[\'alpha\']").matches("[\\\\p{L}]*")') + test.contains('assertThatJson(parsedJson).field("[\'hostname\']").matches("((http[s]?|ftp):/)/?([^:/\\\\s]+)(:[0-9]{1,5})?")') + test.contains('assertThatJson(parsedJson).field("[\'number\']").matches("-?(\\\\d*\\\\.\\\\d+|\\\\d+)")') + test.contains('assertThatJson(parsedJson).field("[\'anInteger\']").matches("-?(\\\\d+)")') + test.contains('assertThatJson(parsedJson).field("[\'positiveInt\']").matches("([1-9]\\\\d*)")') + test.contains('assertThatJson(parsedJson).field("[\'aDouble\']").matches("-?(\\\\d*\\\\.\\\\d+)")') + test.contains('assertThatJson(parsedJson).field("[\'email\']").matches("[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\\\.[a-zA-Z]{2,6}")') + test.contains('assertThatJson(parsedJson).field("[\'ip\']").matches("([01]?\\\\d\\\\d?|2[0-4]\\\\d|25[0-5])\\\\.([01]?\\\\d\\\\d?|2[0-4]\\\\d|25[0-5])\\\\.([01]?\\\\d\\\\d?|2[0-4]\\\\d|25[0-5])\\\\.([01]?\\\\d\\\\d?|2[0-4]\\\\d|25[0-5])")') + test.contains('assertThatJson(parsedJson).field("[\'url\']").matches("^(?:(?:[A-Za-z][+-.\\\\w^_]*:/{2})?(?:\\\\S+(?::\\\\S*)?@)?(?:(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\\\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)|(?:(?:[a-z\\\\u00a1-\\\\uffff0-9]-*)*[a-z\\\\u00a1-\\\\uffff0-9]+)(?:\\\\.(?:[a-z\\\\u00a1-\\\\uffff0-9]-*)*[a-z\\\\u00a1-\\\\uffff0-9]+)*(?:\\\\.(?:[a-z\\\\u00a1-\\\\uffff]{2,})))(?::\\\\d{2,5})?(?:/\\\\S*)?)') + test.contains('assertThatJson(parsedJson).field("[\'httpsUrl\']").matches("^(?:https:/{2}(?:\\\\S+(?::\\\\S*)?@)?(?:(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\\\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)|(?:(?:[a-z\\\\u00a1-\\\\uffff0-9]-*)*[a-z\\\\u00a1-\\\\uffff0-9]+)(?:\\\\.(?:[a-z\\\\u00a1-\\\\uffff0-9]-*)*[a-z\\\\u00a1-\\\\uffff0-9]+)*(?:\\\\.(?:[a-z\\\\u00a1-\\\\uffff]{2,})))(?::\\\\d{2,5})?(?:/\\\\S*)?)') + test.contains('assertThatJson(parsedJson).field("[\'uuid\']").matches("[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}")') + test.contains('assertThatJson(parsedJson).field("[\'date\']").matches("(\\\\d\\\\d\\\\d\\\\d)-(0[1-9]|1[012])-(0[1-9]|[12][0-9]|3[01])') + test.contains('assertThatJson(parsedJson).field("[\'dateTime\']").matches("([0-9]{4})-(1[0-2]|0[1-9])-(3[01]|0[1-9]|[12][0-9])T(2[0-3]|[01][0-9]):([0-5][0-9]):([0-5][0-9])') + test.contains('assertThatJson(parsedJson).field("[\'time\']").matches("(2[0-3]|[01][0-9]):([0-5][0-9]):([0-5][0-9])")') + test.contains('assertThatJson(parsedJson).field("[\'iso8601WithOffset\']").matches("([0-9]{4})-(1[0-2]|0[1-9])-(3[01]|0[1-9]|[12][0-9])T(2[0-3]|[01][0-9]):([0-5][0-9]):([0-5][0-9])(\\\\.\\\\d{3})?(Z|[+-][01]\\\\d:[0-5]\\\\d)")') + test.contains('assertThatJson(parsedJson).field("[\'nonBlankString\']").matches("^\\\\s*\\\\S[\\\\S\\\\s]*")') + test.contains('assertThatJson(parsedJson).field("[\'nonEmptyString\']").matches("[\\\\S\\\\s]+")') + test.contains('assertThatJson(parsedJson).field("[\'anyOf\']").matches("^foo' + endOfLineRegExSymbol + '|^bar' + endOfLineRegExSymbol + '")') + !test.contains('cursor') + !test.contains('REGEXP>>') + and: + SyntaxChecker.tryToCompile(methodBuilderName, blockBuilder.toString()) + and: + String jsonSample = '''\ +String json = "{\\"duck\\":\\"8\\",\\"alpha\\":\\"YAJEOWYGMFBEWPMEMAZI\\",\\"number\\":-2095030871,\\"anInteger\\":1780305902,\\"positiveInt\\":345,\\"aDouble\\":42.345,\\"aBoolean\\":true,\\"ip\\":\\"129.168.99.100\\",\\"hostname\\":\\"http://foo389886219.com\\",\\"email\\":\\"foo@bar1367573183.com\\",\\"url\\":\\"http://foo-597104692.com\\",\\"httpsUrl\\":\\"https://baz-486093581.com\\",\\"uuid\\":\\"e436b817-b764-49a2-908e-967f2f99eb9f\\",\\"date\\":\\"2014-04-14\\",\\"dateTime\\":\\"2011-01-11T12:23:34\\",\\"time\\":\\"12:20:30\\",\\"iso8601WithOffset\\":\\"2015-05-15T12:23:34.123Z\\",\\"nonBlankString\\":\\"EPZWVIRHSUAPBJMMQSFO\\",\\"nonEmptyString\\":\\"RVMFDSEQFHRQFVUVQPIA\\",\\"anyOf\\":\\"foo\\"}"; +DocumentContext parsedJson = JsonPath.parse(json); +''' + and: + LinkedList lines = [] as LinkedList + test.eachLine { if (it.contains("assertThatJson")) lines << it else it } + lines.addFirst(jsonSample) + SyntaxChecker.tryToRun(methodBuilderName, lines.join("\n")) + where: + methodBuilderName | methodBuilder | endOfLineRegExSymbol + HttpSpockMethodRequestProcessingBodyBuilder.simpleName | { Contract dsl -> new HttpSpockMethodRequestProcessingBodyBuilder(dsl, properties) } | '\\$' + MockMvcJUnitMethodBodyBuilder.simpleName | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl, properties) } | '$' + WebTestClientJUnitMethodBodyBuilder.simpleName | { Contract dsl -> new WebTestClientJUnitMethodBodyBuilder(dsl, properties) } | '$' + } + + @Issue('#162') + def 'should escape regex properly for content type'() { + given: + Contract contractDsl = Contract.make { + request { + method GET() + url 'get' + headers { + contentType("application/vnd.fraud.v1+json") + } + } + response { + status OK() + headers { + contentType("application/vnd.fraud.v1+json") + } + } + } + MethodBodyBuilder builder = methodBuilder(contractDsl) + BlockBuilder blockBuilder = new BlockBuilder(" ") + when: + builder.appendTo(blockBuilder) + def test = blockBuilder.toString() + then: + test.contains('application/vnd\\\\.fraud\\\\.v1\\\\+json.*') + and: + SyntaxChecker.tryToCompile(methodBuilderName, blockBuilder.toString()) + where: + methodBuilderName | methodBuilder + HttpSpockMethodRequestProcessingBodyBuilder.simpleName | { Contract dsl -> new HttpSpockMethodRequestProcessingBodyBuilder(dsl, properties) } + MockMvcJUnitMethodBodyBuilder.simpleName | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl, properties) } + WebTestClientJUnitMethodBodyBuilder.simpleName | { Contract dsl -> new WebTestClientJUnitMethodBodyBuilder(dsl, properties) } + } + + @Issue('#173') + def 'should resolve Optional object when used in query parameters'() { + given: + Contract contractDsl = Contract.make { + request { + method 'GET' + urlPath('/blacklist') { + queryParameters { + parameter 'isActive': value(consumer(optional(regex('(true|false)')))) + parameter 'limit': value(consumer(optional(regex('([0-9]{1,10})')))) + parameter 'offset': value(consumer(optional(regex('([0-9]{1,10})')))) + } + } + headers { + header 'Content-Type': 'application/json' + } + } + response { + status(200) + } + } + MethodBodyBuilder builder = methodBuilder(contractDsl) + BlockBuilder blockBuilder = new BlockBuilder(" ") + when: + builder.appendTo(blockBuilder) + def test = blockBuilder.toString() + then: + !test.contains('org.springframework.cloud.contract.spec.internal.OptionalProperty') + test.contains('(([0-9]{1,10}))?') + and: + SyntaxChecker.tryToCompile(methodBuilderName, blockBuilder.toString()) + where: + methodBuilderName | methodBuilder + HttpSpockMethodRequestProcessingBodyBuilder.simpleName | { Contract dsl -> new HttpSpockMethodRequestProcessingBodyBuilder(dsl, properties) } + MockMvcJUnitMethodBodyBuilder.simpleName | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl, properties) } + WebTestClientJUnitMethodBodyBuilder.simpleName | { Contract dsl -> new WebTestClientJUnitMethodBodyBuilder(dsl, properties) } + } + + @Issue('#172') + def 'should resolve plain text properly via headers'() { + given: + Contract contractDsl = Contract.make { + request { + method 'GET' + url("/foo") + } + response { + status(200) + body '{"a":1}\n{"a":2}' + headers { + contentType(textPlain()) + } + } + } + MethodBodyBuilder builder = methodBuilder(contractDsl) + BlockBuilder blockBuilder = new BlockBuilder(" ") + when: + builder.appendTo(blockBuilder) + def test = blockBuilder.toString() + then: + !test.contains('assertThatJson(parsedJson).field("[\'a\']").isEqualTo(1)') + test.contains(expectedAssertion) + and: + SyntaxChecker.tryToCompile(methodBuilderName, blockBuilder.toString()) + where: + //order is inverted cause Intellij didn't parse this properly + methodBuilderName | methodBuilder | expectedAssertion + HttpSpockMethodRequestProcessingBodyBuilder.simpleName | { Contract dsl -> new HttpSpockMethodRequestProcessingBodyBuilder(dsl, properties) } | '''responseBody == "{\\"a\\":1}\\n{\\"a\\":2}"''' + MockMvcJUnitMethodBodyBuilder.simpleName | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl, properties) } | '''assertThat(responseBody).isEqualTo("{\\"a\\":1}\\n{\\"a\\":2}''' + WebTestClientJUnitMethodBodyBuilder.simpleName | { Contract dsl -> new WebTestClientJUnitMethodBodyBuilder(dsl, properties) } | '''assertThat(responseBody).isEqualTo("{\\"a\\":1}\\n{\\"a\\":2}''' + } + + @Issue('#443') + def "should resolve plain text that happens to be a valid json for [#methodBuilderName]"() { + given: + Contract contractDsl = Contract.make { + request { + method 'GET' + url '/foo' + } + response { + status OK() + headers { + contentType(applicationJsonUtf8()) + } + body( + value(client('true'), server(regex("true|false"))) + ) + } + } + MethodBodyBuilder builder = methodBuilder(contractDsl) + BlockBuilder blockBuilder = new BlockBuilder(" ") + when: + builder.appendTo(blockBuilder) + def test = blockBuilder.toString() + then: + testAssertion(test) + and: + SyntaxChecker.tryToCompile(methodBuilderName, blockBuilder.toString()) + where: + methodBuilderName | methodBuilder | testAssertion + HttpSpockMethodRequestProcessingBodyBuilder.simpleName | { Contract dsl -> new HttpSpockMethodRequestProcessingBodyBuilder(dsl, properties) } | { String testContents -> testContents.contains("""responseBody ==~ java.util.regex.Pattern.compile('true|false')""") } + MockMvcJUnitMethodBodyBuilder.simpleName | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl, properties) } | { String testContents -> testContents.contains("""assertThat(responseBody).matches("true|false");""") } + JaxRsClientSpockMethodRequestProcessingBodyBuilder.simpleName | { Contract dsl -> new JaxRsClientSpockMethodRequestProcessingBodyBuilder(dsl, properties) } | { String testContents -> testContents.contains("""responseBody ==~ java.util.regex.Pattern.compile('true|false')""") } + JaxRsClientJUnitMethodBodyBuilder.simpleName | { Contract dsl -> new JaxRsClientJUnitMethodBodyBuilder(dsl, properties) } | { String testContents -> testContents.contains("""assertThat(responseBody).matches("true|false");""") } + WebTestClientJUnitMethodBodyBuilder.simpleName | { Contract dsl -> new WebTestClientJUnitMethodBodyBuilder(dsl, properties) } | { String testContents -> testContents.contains("""assertThat(responseBody).matches("true|false");""") } + } + + @Issue('#169') + def 'should escape quotes properly using [#methodBuilderName]'() { + given: + Contract contractDsl = Contract.make { + request { + method 'POST' + url '/foo' + body( + xyz: 'abc' + ) + headers { header('Content-Type', 'application/json;charset=UTF-8') } + } + response { + status OK() + body( + bar: $(producer(regex('some value \u0022with quote\u0022|bar'))) + ) + headers { header('Content-Type': 'application/json;charset=UTF-8') } + } + } + MethodBodyBuilder builder = methodBuilder(contractDsl) + BlockBuilder blockBuilder = new BlockBuilder(" ") + when: + builder.appendTo(blockBuilder) + def test = blockBuilder.toString() + then: + test.contains('assertThatJson(parsedJson).field("[\'bar\']").matches("some value \\"with quote\\"|bar")') + and: + SyntaxChecker.tryToCompile(methodBuilderName, blockBuilder.toString()) + where: + //order is inverted cause Intellij didn't parse this properly + methodBuilderName | methodBuilder | expectedAssertion + HttpSpockMethodRequestProcessingBodyBuilder.simpleName | { Contract dsl -> new HttpSpockMethodRequestProcessingBodyBuilder(dsl, properties) } | '''responseBody == "{\\"a\\":1}\\n{\\"a\\":2}"''' + MockMvcJUnitMethodBodyBuilder.simpleName | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl, properties) } | '''assertThat(responseBody).isEqualTo("{\\"a\\":1}\\n{\\"a\\":2}''' + WebTestClientJUnitMethodBodyBuilder.simpleName | { Contract dsl -> new WebTestClientJUnitMethodBodyBuilder(dsl, properties) } | '''assertThat(responseBody).isEqualTo("{\\"a\\":1}\\n{\\"a\\":2}''' + } + + @Issue('#169') + def 'should make the execute method work in a url for [#methodBuilderName]'() { + given: + Contract contractDsl = Contract.make { + request { + method 'POST' + url $(c("foo"), p(execute("executedMethod()"))) + } + response { + status OK() + } + } + MethodBodyBuilder builder = methodBuilder(contractDsl) + BlockBuilder blockBuilder = new BlockBuilder(" ") + and: + builder.appendTo(blockBuilder) + String test = blockBuilder.toString() + when: + SyntaxChecker.tryToCompile(methodBuilderName, test) + then: + def e = thrown(Throwable) + missingMethodAssertion(e, capture) + and: + test.contains("executedMethod()") + !test.contains("\"executedMethod()\"") + !test.contains("'executedMethod()'") + where: + methodBuilderName | methodBuilder | missingMethodAssertion + HttpSpockMethodRequestProcessingBodyBuilder.simpleName | { Contract dsl -> new HttpSpockMethodRequestProcessingBodyBuilder(dsl, properties) } | { Throwable t, OutputCapture capture -> t.message.contains("Cannot find matching method Script1#executedMethod") } + MockMvcJUnitMethodBodyBuilder.simpleName | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl, properties) } | { Throwable t, OutputCapture capture -> t.message.contains("Truncated class file") && capture.toString().contains("post(executedMethod())") } + JaxRsClientSpockMethodRequestProcessingBodyBuilder.simpleName | { Contract dsl -> new JaxRsClientSpockMethodRequestProcessingBodyBuilder(dsl, properties) } | { Throwable t, OutputCapture capture -> t.message.contains("Cannot find matching method Script1#executedMethod") } + JaxRsClientJUnitMethodBodyBuilder.simpleName | { Contract dsl -> new JaxRsClientJUnitMethodBodyBuilder(dsl, properties) } | { Throwable t, OutputCapture capture -> t.message.contains("Truncated class file") && capture.toString().contains("path(executedMethod())") } + WebTestClientJUnitMethodBodyBuilder.simpleName | { Contract dsl -> new WebTestClientJUnitMethodBodyBuilder(dsl, properties) } | { Throwable t, OutputCapture capture -> t.message.contains("Truncated class file") && capture.toString().contains("post(executedMethod())") } + } + + @Issue('#203') + def 'should create an assertion for an empty list for [#methodBuilderName]'() { + given: + Contract contractDsl = Contract.make { + request { + method 'GET' + url '/api/v1/xxxx' + } + response { + status OK() + body([ + status: '200', + list : [], + foo : ["bar", "baz"] + ]) + } + } + MethodBodyBuilder builder = methodBuilder(contractDsl) + BlockBuilder blockBuilder = new BlockBuilder(" ") + and: + builder.appendTo(blockBuilder) + String test = blockBuilder.toString() + when: + SyntaxChecker.tryToCompile(methodBuilderName, test) + then: + test.contains('assertThatJson(parsedJson).array("[\'list\']").isEmpty()') + !test.contains('assertThatJson(parsedJson).array("[\'foo\']").isEmpty()') + where: + methodBuilderName | methodBuilder + HttpSpockMethodRequestProcessingBodyBuilder.simpleName | { Contract dsl -> new HttpSpockMethodRequestProcessingBodyBuilder(dsl, properties) } + MockMvcJUnitMethodBodyBuilder.simpleName | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl, properties) } + JaxRsClientSpockMethodRequestProcessingBodyBuilder.simpleName | { Contract dsl -> new JaxRsClientSpockMethodRequestProcessingBodyBuilder(dsl, properties) } + JaxRsClientJUnitMethodBodyBuilder.simpleName | { Contract dsl -> new JaxRsClientJUnitMethodBodyBuilder(dsl, properties) } + WebTestClientJUnitMethodBodyBuilder.simpleName | { Contract dsl -> new WebTestClientJUnitMethodBodyBuilder(dsl, properties) } + } + + @Issue('#226') + def 'should work properly when body is an integer [#methodBuilderName]'() { + given: + Contract contractDsl = Contract.make { + request { + method 'GET' + url '/api/v1/xxxx' + body(12000) + } + response { + status OK() + body(12000) + } + } + MethodBodyBuilder builder = methodBuilder(contractDsl) + BlockBuilder blockBuilder = new BlockBuilder(" ") + and: + builder.appendTo(blockBuilder) + String test = blockBuilder.toString() + when: + SyntaxChecker.tryToCompile(methodBuilderName, test) + then: + requestAssertion(test) + responseAssertion(test) + where: + methodBuilderName | methodBuilder | requestAssertion | responseAssertion + HttpSpockMethodRequestProcessingBodyBuilder.simpleName | { Contract dsl -> new HttpSpockMethodRequestProcessingBodyBuilder(dsl, properties) } | { String body -> body.contains("body('''12000''')") } | { String body -> body.contains('responseBody == "12000"') } + MockMvcJUnitMethodBodyBuilder.simpleName | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl, properties) } | { String body -> body.contains('body("12000")') } | { String body -> body.contains('assertThat(responseBody).isEqualTo("12000");') } + JaxRsClientSpockMethodRequestProcessingBodyBuilder.simpleName | { Contract dsl -> new JaxRsClientSpockMethodRequestProcessingBodyBuilder(dsl, properties) } | { String body -> body.contains(""".method('GET', entity('12000', 'text/plain'))""") } | { String body -> body.contains('responseBody == "12000"') } + JaxRsClientJUnitMethodBodyBuilder.simpleName | { Contract dsl -> new JaxRsClientJUnitMethodBodyBuilder(dsl, properties) } | { String body -> body.contains(""".method("GET", entity("12000", "text/plain"))""") } | { String body -> body.contains('assertThat(responseBody).isEqualTo("12000")') } + WebTestClientJUnitMethodBodyBuilder.simpleName | { Contract dsl -> new WebTestClientJUnitMethodBodyBuilder(dsl, properties) } | { String body -> body.contains('body("12000")') } | { String body -> body.contains('assertThat(responseBody).isEqualTo("12000");') } + } + + @Issue('#230') + def 'should manage to reference request in response [#methodBuilderName]'() { + given: + //tag::template_contract[] + Contract contractDsl = Contract.make { + request { + method 'GET' + url('/api/v1/xxxx') { + queryParameters { + parameter('foo', 'bar') + parameter('foo', 'bar2') + } + } + headers { + header(authorization(), 'secret') + header(authorization(), 'secret2') + } + body(foo: 'bar', baz: 5) + } + response { + status OK() + headers { + header(authorization(), "foo ${fromRequest().header(authorization())} bar") + } + body( + url: fromRequest().url(), + path: fromRequest().path(), + pathIndex: fromRequest().path(1), + param: fromRequest().query('foo'), + paramIndex: fromRequest().query('foo', 1), + authorization: fromRequest().header('Authorization'), + authorization2: fromRequest().header('Authorization', 1), + fullBody: fromRequest().body(), + responseFoo: fromRequest().body('$.foo'), + responseBaz: fromRequest().body('$.baz'), + responseBaz2: "Bla bla ${fromRequest().body('$.foo')} bla bla", + rawUrl: fromRequest().rawUrl(), + rawPath: fromRequest().rawPath(), + rawPathIndex: fromRequest().rawPath(1), + rawParam: fromRequest().rawQuery('foo'), + rawParamIndex: fromRequest().rawQuery('foo', 1), + rawAuthorization: fromRequest().rawHeader('Authorization'), + rawAuthorization2: fromRequest().rawHeader('Authorization', 1), + rawResponseFoo: fromRequest().rawBody('$.foo'), + rawResponseBaz: fromRequest().rawBody('$.baz'), + rawResponseBaz2: "Bla bla ${fromRequest().rawBody('$.foo')} bla bla" + ) + } + } + //end::template_contract[] + MethodBodyBuilder builder = methodBuilder(contractDsl) + BlockBuilder blockBuilder = new BlockBuilder(" ") + and: + builder.appendTo(blockBuilder) + String test = blockBuilder.toString() + when: + SyntaxChecker.tryToCompileWithoutCompileStatic(methodBuilderName, test) + then: + !test.contains('''DslProperty''') + !test.contains('''ERROR: ''') + test.contains('''assertThatJson(parsedJson).field("['url']").isEqualTo("/api/v1/xxxx?foo=bar&foo=bar2")''') + test.contains('''assertThatJson(parsedJson).field("['path']").isEqualTo("/api/v1/xxxx")''') + test.contains('''assertThatJson(parsedJson).field("['pathIndex']").isEqualTo("v1")''') + test.contains('''assertThatJson(parsedJson).field("['fullBody']").isEqualTo("{\\"foo\\":\\"bar\\",\\"baz\\":5}")''') + test.contains('''assertThatJson(parsedJson).field("['paramIndex']").isEqualTo("bar2")''') + test.contains('''assertThatJson(parsedJson).field("['responseFoo']").isEqualTo("bar")''') + test.contains('''assertThatJson(parsedJson).field("['authorization']").isEqualTo("secret")''') + test.contains('''assertThatJson(parsedJson).field("['authorization2']").isEqualTo("secret2")''') + test.contains('''assertThatJson(parsedJson).field("['responseBaz']").isEqualTo(5)''') + test.contains('''assertThatJson(parsedJson).field("['responseBaz2']").isEqualTo("Bla bla bar bla bla")''') + test.contains('''assertThatJson(parsedJson).field("['param']").isEqualTo("bar")''') + test.contains('''assertThatJson(parsedJson).field("['rawUrl']").isEqualTo("/api/v1/xxxx?foo=bar&foo=bar2")''') + test.contains('''assertThatJson(parsedJson).field("['rawPath']").isEqualTo("/api/v1/xxxx")''') + test.contains('''assertThatJson(parsedJson).field("['rawPathIndex']").isEqualTo("v1")''') + test.contains('''assertThatJson(parsedJson).field("['rawParamIndex']").isEqualTo("bar2")''') + test.contains('''assertThatJson(parsedJson).field("['rawResponseFoo']").isEqualTo("bar")''') + test.contains('''assertThatJson(parsedJson).field("['rawAuthorization']").isEqualTo("secret")''') + test.contains('''assertThatJson(parsedJson).field("['rawAuthorization2']").isEqualTo("secret2")''') + test.contains('''assertThatJson(parsedJson).field("['rawResponseBaz']").isEqualTo(5)''') + test.contains('''assertThatJson(parsedJson).field("['rawResponseBaz2']").isEqualTo("Bla bla bar bla bla")''') + test.contains('''assertThatJson(parsedJson).field("['rawParam']").isEqualTo("bar")''') + responseAssertion(test) + where: + methodBuilderName | methodBuilder | responseAssertion + HttpSpockMethodRequestProcessingBodyBuilder.simpleName | { Contract dsl -> new HttpSpockMethodRequestProcessingBodyBuilder(dsl, properties) } | { String body -> body.contains("response.header('Authorization') == 'foo secret bar'") } + MockMvcJUnitMethodBodyBuilder.simpleName | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl, properties) } | { String body -> body.contains('assertThat(response.header("Authorization")).isEqualTo("foo secret bar");') } + JaxRsClientSpockMethodRequestProcessingBodyBuilder.simpleName | { Contract dsl -> new JaxRsClientSpockMethodRequestProcessingBodyBuilder(dsl, properties) } | { String body -> body.contains("response.getHeaderString('Authorization') == 'foo secret bar'") } + JaxRsClientJUnitMethodBodyBuilder.simpleName | { Contract dsl -> new JaxRsClientJUnitMethodBodyBuilder(dsl, properties) } | { String body -> body.contains('assertThat(response.getHeaderString("Authorization")).isEqualTo("foo secret bar");') } + WebTestClientJUnitMethodBodyBuilder.simpleName | { Contract dsl -> new WebTestClientJUnitMethodBodyBuilder(dsl, properties) } | { String body -> body.contains('assertThat(response.header("Authorization")).isEqualTo("foo secret bar");') } + } + + @Issue('#230') + def 'should manage to reference request in response via WireMock native entries [#methodBuilderName]'() { + given: + //tag::template_contract[] + Contract contractDsl = Contract.make { + request { + method 'GET' + url('/api/v1/xxxx') { + queryParameters { + parameter('foo', 'bar') + parameter('foo', 'bar2') + } + } + headers { + header(authorization(), 'secret') + header(authorization(), 'secret2') + } + body(foo: "bar", baz: 5) + } + response { + status OK() + headers { + contentType(applicationJson()) + } + body(''' + { + "responseFoo": "{{{ jsonPath request.body '$.foo' }}}", + "responseBaz": {{{ jsonPath request.body '$.baz' }}}, + "responseBaz2": "Bla bla {{{ jsonPath request.body '$.foo' }}} bla bla" + } + '''.toString()) + } + } + //end::template_contract[] + MethodBodyBuilder builder = methodBuilder(contractDsl) + BlockBuilder blockBuilder = new BlockBuilder(" ") + and: + builder.appendTo(blockBuilder) + String test = blockBuilder.toString() + when: + SyntaxChecker.tryToCompileWithoutCompileStatic(methodBuilderName, test) + then: + !test.contains('''DslProperty''') + test.contains('''assertThatJson(parsedJson).field("['responseFoo']").isEqualTo("bar")''') + test.contains('''assertThatJson(parsedJson).field("['responseBaz']").isEqualTo(5)''') + test.contains('''assertThatJson(parsedJson).field("['responseBaz2']").isEqualTo("Bla bla bar bla bla")''') + where: + methodBuilderName | methodBuilder + HttpSpockMethodRequestProcessingBodyBuilder.simpleName | { Contract dsl -> new HttpSpockMethodRequestProcessingBodyBuilder(dsl, properties) } + MockMvcJUnitMethodBodyBuilder.simpleName | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl, properties) } + JaxRsClientSpockMethodRequestProcessingBodyBuilder.simpleName | { Contract dsl -> new JaxRsClientSpockMethodRequestProcessingBodyBuilder(dsl, properties) } + JaxRsClientJUnitMethodBodyBuilder.simpleName | { Contract dsl -> new JaxRsClientJUnitMethodBodyBuilder(dsl, properties) } + WebTestClientJUnitMethodBodyBuilder.simpleName | { Contract dsl -> new WebTestClientJUnitMethodBodyBuilder(dsl, properties) } + } + + def 'should generate JUnit assertions with cookies [#methodBuilderName]'() { + given: + MethodBodyBuilder builder = methodBuilder(contractDslWithCookiesValue) + BlockBuilder blockBuilder = new BlockBuilder(' ') + when: + builder.appendTo(blockBuilder) + def test = blockBuilder.toString() + then: + test.contains('''.cookie("cookie-key", "cookie-value")''') + test.contains('''assertThat(response.getCookie("cookie-key")).isNotNull();''') + test.contains('''assertThat(response.getCookie("cookie-key")).isEqualTo("new-cookie-value");''') + and: + SyntaxChecker.tryToCompile(methodBuilderName, blockBuilder.toString()) + where: + methodBuilderName | methodBuilder + MockMvcJUnitMethodBodyBuilder.simpleName | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl, properties) } + WebTestClientJUnitMethodBodyBuilder.simpleName | { Contract dsl -> new WebTestClientJUnitMethodBodyBuilder(dsl, properties) } + } + + def 'should generate JUnit assertions with cookies pattern [#methodBuilderName]'() { + given: + MethodBodyBuilder builder = methodBuilder(contractDslWithCookiesPattern) + BlockBuilder blockBuilder = new BlockBuilder(' ') + when: + builder.appendTo(blockBuilder) + def test = blockBuilder.toString() + then: + test.contains('''.cookie("cookie-key", "[A-Za-z]+")''') + test.contains('''assertThat(response.getCookie("cookie-key")).isNotNull();''') + test.contains('''assertThat(response.getCookie("cookie-key")).matches("[A-Za-z]+");''') + and: + SyntaxChecker.tryToCompile(methodBuilderName, blockBuilder.toString()) + where: + methodBuilderName | methodBuilder + MockMvcJUnitMethodBodyBuilder.simpleName | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl, properties) } + WebTestClientJUnitMethodBodyBuilder.simpleName | { Contract dsl -> new WebTestClientJUnitMethodBodyBuilder(dsl, properties) } + } + + def 'should not generate JUnit cookie assertion with absent cookie [#methodBuilderName]'() { + given: + MethodBodyBuilder builder = methodBuilder(contractDslWithAbsentCookies) + BlockBuilder blockBuilder = new BlockBuilder(' ') + when: + builder.appendTo(blockBuilder) + def test = blockBuilder.toString() + then: + !test.contains('cookie') + and: + SyntaxChecker.tryToCompile(methodBuilderName, blockBuilder.toString()) + where: + methodBuilderName | methodBuilder + MockMvcJUnitMethodBodyBuilder.simpleName | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl, properties) } + WebTestClientJUnitMethodBodyBuilder.simpleName | { Contract dsl -> new WebTestClientJUnitMethodBodyBuilder(dsl, properties) } + } + + def 'should generate spock assertions with cookies'() { + given: + MethodBodyBuilder builder = new HttpSpockMethodRequestProcessingBodyBuilder(contractDslWithCookiesValue, properties) + BlockBuilder blockBuilder = new BlockBuilder(" ") + when: + builder.appendTo(blockBuilder) + def test = blockBuilder.toString() + then: + test.contains('''.cookie("cookie-key", "cookie-value")''') + test.contains('''response.cookie('cookie-key') != null''') + test.contains('''response.cookie('cookie-key') == 'new-cookie-value''') + and: + SyntaxChecker.tryToCompile(HttpSpockMethodRequestProcessingBodyBuilder.simpleName, blockBuilder.toString()) + } + + def 'should generate spock assertions with cookies pattern'() { + given: + MethodBodyBuilder builder = new HttpSpockMethodRequestProcessingBodyBuilder(contractDslWithCookiesPattern, properties) + BlockBuilder blockBuilder = new BlockBuilder(" ") + when: + builder.appendTo(blockBuilder) + def test = blockBuilder.toString() + then: + test.contains('''.cookie("cookie-key", "[A-Za-z]+")''') + test.contains('''response.cookie('cookie-key') != null''') + test.contains('''response.cookie('cookie-key') ==~ java.util.regex.Pattern.compile('[A-Za-z]+')''') + and: + SyntaxChecker.tryToCompile(HttpSpockMethodRequestProcessingBodyBuilder.simpleName, blockBuilder.toString()) + } + + def 'should not generate spock cookie assertion with absent cookie'() { + given: + MethodBodyBuilder builder = new HttpSpockMethodRequestProcessingBodyBuilder(contractDslWithAbsentCookies, properties) + BlockBuilder blockBuilder = new BlockBuilder(" ") + when: + builder.appendTo(blockBuilder) + def test = blockBuilder.toString() + then: + !test.contains("cookie") + and: + SyntaxChecker.tryToCompile(HttpSpockMethodRequestProcessingBodyBuilder.simpleName, blockBuilder.toString()) + } + + @Issue('#554') + def 'should create an assertion for an empty map or Object for [#methodBuilderName]'() { + given: + Contract contractDsl = Contract.make { + request { + method 'GET' + url '/api/v1/xxxx' + } + response { + status 200 + body([ + aMap : ["foo": "bar"], + anEmptyMap: [:] + ]) + } + } + MethodBodyBuilder builder = methodBuilder(contractDsl) + BlockBuilder blockBuilder = new BlockBuilder(" ") + and: + builder.appendTo(blockBuilder) + String test = blockBuilder.toString() + when: + SyntaxChecker.tryToRun(methodBuilderName, test.join("\n")) + then: + test.contains('''assertThatJson(parsedJson).field("['aMap']").field("['foo']").isEqualTo("bar")''') + test.contains('''assertThatJson(parsedJson).field("['anEmptyMap']").isEmpty()''') + where: + methodBuilderName | methodBuilder + HttpSpockMethodRequestProcessingBodyBuilder.simpleName | { Contract dsl -> new HttpSpockMethodRequestProcessingBodyBuilder(dsl, properties) } + MockMvcJUnitMethodBodyBuilder.simpleName | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl, properties) } + JaxRsClientSpockMethodRequestProcessingBodyBuilder.simpleName | { Contract dsl -> new JaxRsClientSpockMethodRequestProcessingBodyBuilder(dsl, properties) } + JaxRsClientJUnitMethodBodyBuilder.simpleName | { Contract dsl -> new JaxRsClientJUnitMethodBodyBuilder(dsl, properties) } + WebTestClientJUnitMethodBodyBuilder.simpleName | { Contract dsl -> new WebTestClientJUnitMethodBodyBuilder(dsl, properties) } + } +} diff --git a/spring-cloud-contract-verifier/src/test/groovy/org/springframework/cloud/contract/verifier/builder/YamlMockMvcMethodBodyBuilderSpec.groovy b/spring-cloud-contract-verifier/src/test/groovy/org/springframework/cloud/contract/verifier/builder/YamlMockMvcMethodBodyBuilderSpec.groovy index b6cfc2e0df..969392e85d 100644 --- a/spring-cloud-contract-verifier/src/test/groovy/org/springframework/cloud/contract/verifier/builder/YamlMockMvcMethodBodyBuilderSpec.groovy +++ b/spring-cloud-contract-verifier/src/test/groovy/org/springframework/cloud/contract/verifier/builder/YamlMockMvcMethodBodyBuilderSpec.groovy @@ -16,46 +16,45 @@ package org.springframework.cloud.contract.verifier.builder - import org.codehaus.groovy.control.MultipleCompilationErrorsException import org.junit.Rule -import spock.lang.Issue -import spock.lang.Shared -import spock.lang.Specification -import spock.util.environment.RestoreSystemProperties - import org.springframework.boot.test.rule.OutputCapture import org.springframework.cloud.contract.spec.Contract import org.springframework.cloud.contract.verifier.config.ContractVerifierConfigProperties import org.springframework.cloud.contract.verifier.converter.YamlContractConverter import org.springframework.cloud.contract.verifier.dsl.WireMockStubVerifier import org.springframework.cloud.contract.verifier.util.SyntaxChecker +import spock.lang.Issue +import spock.lang.Shared +import spock.lang.Specification +import spock.util.environment.RestoreSystemProperties + /** * @author Jakub Kubrynski, codearte.io * @author Tim Ysewyn */ class YamlMockMvcMethodBodyBuilderSpec extends Specification implements WireMockStubVerifier { - @Rule - OutputCapture capture = new OutputCapture() + @Rule + OutputCapture capture = new OutputCapture() - @Shared - ContractVerifierConfigProperties properties = new ContractVerifierConfigProperties( - assertJsonSize: true - ) + @Shared + ContractVerifierConfigProperties properties = new ContractVerifierConfigProperties( + assertJsonSize: true + ) - static File textToFile(String text) { - File temp = File.createTempFile("yaml", ".yml") - temp.text = text - return temp - } + static File textToFile(String text) { + File temp = File.createTempFile("yaml", ".yml") + temp.text = text + return temp + } - static Contract fromYaml(String text) { - return new YamlContractConverter().convertFrom(textToFile(text))[0] - } + static Contract fromYaml(String text) { + return new YamlContractConverter().convertFrom(textToFile(text))[0] + } - @Shared - String contractDslWithCookiesValue = """\ + @Shared + String contractDslWithCookiesValue = """\ --- request: method: "GET" @@ -74,8 +73,8 @@ response: status: 'OK' """ - @Shared - String contractDslWithCookiesPattern = """\ + @Shared + String contractDslWithCookiesPattern = """\ --- request: method: "GET" @@ -102,9 +101,9 @@ response: regex: '[A-Za-z]+' """ - // TODO: Add absent - @Shared - String contractDslWithAbsentCookies = """\ + // TODO: Add absent + @Shared + String contractDslWithAbsentCookies = """\ --- request: method: "GET" @@ -131,9 +130,9 @@ response: absent """ - @Shared - // tag::contract_with_regex[] - String dslWithOptionalsInString = """\ + @Shared + // tag::contract_with_regex[] + String dslWithOptionalsInString = """\ --- priority: 1 request: @@ -172,11 +171,11 @@ response: type: by_regex value: "User not found by email = [[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,6}]" """ - // end::contract_with_regex[] + // end::contract_with_regex[] - def "should generate assertions for simple response body with #methodBuilderName"() { - given: - String contract = """\ + def 'should generate assertions for simple response body with #methodBuilderName'() { + given: + String contract = """\ --- request: method: "GET" @@ -187,28 +186,28 @@ response: "property1": "a" "property2": "b" """ - Contract contractDsl = fromYaml(contract) - MethodBodyBuilder builder = methodBuilder(contractDsl) - BlockBuilder blockBuilder = new BlockBuilder(" ") - when: - builder.appendTo(blockBuilder) - then: - blockBuilder.toString().contains("""assertThatJson(parsedJson).field("['property1']").isEqualTo("a")""") - blockBuilder.toString().contains("""assertThatJson(parsedJson).field("['property2']").isEqualTo("b")""") - and: - stubMappingIsValidWireMockStub(contractDsl) - and: - SyntaxChecker.tryToCompile(methodBuilderName, blockBuilder.toString()) - where: - methodBuilderName | methodBuilder - "MockMvcSpockMethodBuilder" | { Contract dsl -> new MockMvcSpockMethodRequestProcessingBodyBuilder(dsl, properties) } - "MockMvcJUnitMethodBuilder" | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl, properties) } - } + Contract contractDsl = fromYaml(contract) + MethodBodyBuilder builder = methodBuilder(contractDsl) + BlockBuilder blockBuilder = new BlockBuilder(" ") + when: + builder.appendTo(blockBuilder) + then: + blockBuilder.toString().contains("""assertThatJson(parsedJson).field("['property1']").isEqualTo("a")""") + blockBuilder.toString().contains("""assertThatJson(parsedJson).field("['property2']").isEqualTo("b")""") + and: + stubMappingIsValidWireMockStub(contractDsl) + and: + SyntaxChecker.tryToCompile(methodBuilderName, blockBuilder.toString()) + where: + methodBuilderName | methodBuilder + HttpSpockMethodRequestProcessingBodyBuilder.simpleName | { Contract dsl -> new HttpSpockMethodRequestProcessingBodyBuilder(dsl, properties) } + MockMvcJUnitMethodBodyBuilder.simpleName | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl, properties) } + } - @Issue("#187") - def "should generate assertions for null and boolean values with #methodBuilderName"() { - given: - String contract = """\ + @Issue("#187") + def "should generate assertions for null and boolean values with #methodBuilderName"() { + given: + String contract = """\ --- request: method: "GET" @@ -220,29 +219,29 @@ response: "property2": null "property3": false """ - Contract contractDsl = fromYaml(contract) - MethodBodyBuilder builder = methodBuilder(contractDsl) - BlockBuilder blockBuilder = new BlockBuilder(" ") - when: - builder.appendTo(blockBuilder) - then: - blockBuilder.toString().contains("""assertThatJson(parsedJson).field("['property1']").isEqualTo("true")""") - blockBuilder.toString().contains("""assertThatJson(parsedJson).field("['property2']").isNull()""") - blockBuilder.toString().contains("""assertThatJson(parsedJson).field("['property3']").isEqualTo(false)""") - and: - stubMappingIsValidWireMockStub(contractDsl) - and: - SyntaxChecker.tryToCompile(methodBuilderName, blockBuilder.toString()) - where: - methodBuilderName | methodBuilder - "MockMvcSpockMethodBuilder" | { Contract dsl -> new MockMvcSpockMethodRequestProcessingBodyBuilder(dsl, properties) } - "MockMvcJUnitMethodBuilder" | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl, properties) } - } + Contract contractDsl = fromYaml(contract) + MethodBodyBuilder builder = methodBuilder(contractDsl) + BlockBuilder blockBuilder = new BlockBuilder(" ") + when: + builder.appendTo(blockBuilder) + then: + blockBuilder.toString().contains("""assertThatJson(parsedJson).field("['property1']").isEqualTo("true")""") + blockBuilder.toString().contains("""assertThatJson(parsedJson).field("['property2']").isNull()""") + blockBuilder.toString().contains("""assertThatJson(parsedJson).field("['property3']").isEqualTo(false)""") + and: + stubMappingIsValidWireMockStub(contractDsl) + and: + SyntaxChecker.tryToCompile(methodBuilderName, blockBuilder.toString()) + where: + methodBuilderName | methodBuilder + HttpSpockMethodRequestProcessingBodyBuilder.simpleName | { Contract dsl -> new HttpSpockMethodRequestProcessingBodyBuilder(dsl, properties) } + MockMvcJUnitMethodBodyBuilder.simpleName | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl, properties) } + } - @Issue("#79") - def "should generate assertions for simple response body constructed from map with a list with #methodBuilderName"() { - given: - String contract = """\ + @Issue('#79') + def 'should generate assertions for simple response body constructed from map with a list with #methodBuilderName'() { + given: + String contract = """\ --- request: method: "GET" @@ -255,31 +254,33 @@ response: - "a" : "sth" - "b" : "sthElse" """ - Contract contractDsl = fromYaml(contract) - MethodBodyBuilder builder = methodBuilder(contractDsl) - BlockBuilder blockBuilder = new BlockBuilder(" ") - when: - builder.appendTo(blockBuilder) - then: - blockBuilder.toString().contains("""assertThatJson(parsedJson).field("['property1']").isEqualTo("a")""") - blockBuilder.toString().contains("""assertThatJson(parsedJson).array("['property2']").contains("['a']").isEqualTo("sth")""") - blockBuilder.toString().contains("""assertThatJson(parsedJson).array("['property2']").contains("['b']").isEqualTo("sthElse")""") - and: - stubMappingIsValidWireMockStub(contractDsl) - and: - SyntaxChecker.tryToCompile(methodBuilderName, blockBuilder.toString()) - where: - methodBuilderName | methodBuilder - "MockMvcSpockMethodBuilder" | { Contract dsl -> new MockMvcSpockMethodRequestProcessingBodyBuilder(dsl, properties) } - "MockMvcJUnitMethodBuilder" | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl, properties) } - } + Contract contractDsl = fromYaml(contract) + MethodBodyBuilder builder = methodBuilder(contractDsl) + BlockBuilder blockBuilder = new BlockBuilder(" ") + when: + builder.appendTo(blockBuilder) + then: + blockBuilder.toString().contains("""assertThatJson(parsedJson).field("['property1']").isEqualTo("a")""") + blockBuilder.toString().contains("""assertThatJson(parsedJson).array("['property2']").contains("['a']").isEqualTo("sth")""") + blockBuilder.toString().contains("""assertThatJson(parsedJson).array("['property2']").contains("['b']").isEqualTo("sthElse")""") + and: + stubMappingIsValidWireMockStub(contractDsl) + and: + SyntaxChecker.tryToCompile(methodBuilderName, blockBuilder.toString()) + where: + methodBuilderName | methodBuilder + HttpSpockMethodRequestProcessingBodyBuilder.simpleName | { Contract dsl -> new HttpSpockMethodRequestProcessingBodyBuilder(dsl, properties) } + MockMvcJUnitMethodBodyBuilder.simpleName | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl, properties) } + WebTestClientJUnitMethodBodyBuilder.simpleName | { Contract dsl -> new WebTestClientJUnitMethodBodyBuilder(dsl, properties) } + WebTestClientJUnitMethodBodyBuilder.simpleName | { Contract dsl -> new WebTestClientJUnitMethodBodyBuilder(dsl, properties) } + } - @Issue("#79") - @RestoreSystemProperties - def "should generate assertions for simple response body constructed from map with a list with #methodBuilderName with array size check"() { - given: - System.setProperty('spring.cloud.contract.verifier.assert.size', 'true') - String contract = """\ + @Issue('#79') + @RestoreSystemProperties + def 'should generate assertions for simple response body constructed from map with a list with #methodBuilderName with array size check'() { + given: + System.setProperty('spring.cloud.contract.verifier.assert.size', 'true') + String contract = """\ --- request: method: "GET" @@ -292,30 +293,31 @@ response: - "a" : "sth" - "b" : "sthElse" """ - Contract contractDsl = fromYaml(contract) - MethodBodyBuilder builder = methodBuilder(contractDsl) - BlockBuilder blockBuilder = new BlockBuilder(" ") - when: - builder.appendTo(blockBuilder) - then: - blockBuilder.toString().contains("""assertThatJson(parsedJson).field("['property1']").isEqualTo("a")""") - blockBuilder.toString().contains("""assertThatJson(parsedJson).array("['property2']").contains("['a']").isEqualTo("sth")""") - blockBuilder.toString().contains("""assertThatJson(parsedJson).array("['property2']").hasSize(2)""") - blockBuilder.toString().contains("""assertThatJson(parsedJson).array("['property2']").contains("['b']").isEqualTo("sthElse")""") - and: - stubMappingIsValidWireMockStub(contractDsl) - and: - SyntaxChecker.tryToCompile(methodBuilderName, blockBuilder.toString()) - where: - methodBuilderName | methodBuilder - "MockMvcSpockMethodBuilder" | { Contract dsl -> new MockMvcSpockMethodRequestProcessingBodyBuilder(dsl, properties) } - "MockMvcJUnitMethodBuilder" | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl, properties) } - } + Contract contractDsl = fromYaml(contract) + MethodBodyBuilder builder = methodBuilder(contractDsl) + BlockBuilder blockBuilder = new BlockBuilder(" ") + when: + builder.appendTo(blockBuilder) + then: + blockBuilder.toString().contains("""assertThatJson(parsedJson).field("['property1']").isEqualTo("a")""") + blockBuilder.toString().contains("""assertThatJson(parsedJson).array("['property2']").contains("['a']").isEqualTo("sth")""") + blockBuilder.toString().contains("""assertThatJson(parsedJson).array("['property2']").hasSize(2)""") + blockBuilder.toString().contains("""assertThatJson(parsedJson).array("['property2']").contains("['b']").isEqualTo("sthElse")""") + and: + stubMappingIsValidWireMockStub(contractDsl) + and: + SyntaxChecker.tryToCompile(methodBuilderName, blockBuilder.toString()) + where: + methodBuilderName | methodBuilder + HttpSpockMethodRequestProcessingBodyBuilder.simpleName | { Contract dsl -> new HttpSpockMethodRequestProcessingBodyBuilder(dsl, properties) } + MockMvcJUnitMethodBodyBuilder.simpleName | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl, properties) } + WebTestClientJUnitMethodBodyBuilder.simpleName | { Contract dsl -> new WebTestClientJUnitMethodBodyBuilder(dsl, properties) } + } - @Issue("#82") - def "should generate proper request when body constructed from map with a list #methodBuilderName"() { - given: - String contract = """\ + @Issue('#82') + def 'should generate proper request when body constructed from map with a list #methodBuilderName'() { + given: + String contract = """\ --- request: method: "GET" @@ -326,27 +328,28 @@ request: response: status: 200 """ - Contract contractDsl = fromYaml(contract) - MethodBodyBuilder builder = methodBuilder(contractDsl) - BlockBuilder blockBuilder = new BlockBuilder(" ") - when: - builder.appendTo(blockBuilder) - then: - blockBuilder.toString().contains(bodyString) - and: - stubMappingIsValidWireMockStub(contractDsl) - and: - SyntaxChecker.tryToCompile(methodBuilderName, blockBuilder.toString()) - where: - methodBuilderName | methodBuilder | bodyString - "MockMvcSpockMethodBuilder" | { Contract dsl -> new MockMvcSpockMethodRequestProcessingBodyBuilder(dsl, properties) } | """.body('''{\"items\":[\"HOP\"]}''')""" - "MockMvcJUnitMethodBuilder" | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl, properties) } | '.body("{\\"items\\":[\\"HOP\\"]}")' - } + Contract contractDsl = fromYaml(contract) + MethodBodyBuilder builder = methodBuilder(contractDsl) + BlockBuilder blockBuilder = new BlockBuilder(" ") + when: + builder.appendTo(blockBuilder) + then: + blockBuilder.toString().contains(bodyString) + and: + stubMappingIsValidWireMockStub(contractDsl) + and: + SyntaxChecker.tryToCompile(methodBuilderName, blockBuilder.toString()) + where: + methodBuilderName | methodBuilder | bodyString + HttpSpockMethodRequestProcessingBodyBuilder.simpleName | { Contract dsl -> new HttpSpockMethodRequestProcessingBodyBuilder(dsl, properties) } | """.body('''{\"items\":[\"HOP\"]}''')""" + MockMvcJUnitMethodBodyBuilder.simpleName | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl, properties) } | '.body("{\\"items\\":[\\"HOP\\"]}")' + WebTestClientJUnitMethodBodyBuilder.simpleName | { Contract dsl -> new WebTestClientJUnitMethodBodyBuilder(dsl, properties) } | '.body("{\\"items\\":[\\"HOP\\"]}")' + } - @Issue("#88") - def "should generate proper request when body constructed from GString with #methodBuilderName"() { - given: - String contract = """\ + @Issue('#88') + def 'should generate proper request when body constructed from GString with #methodBuilderName'() { + given: + String contract = """\ --- request: method: "GET" @@ -355,28 +358,29 @@ request: response: status: 200 """ - Contract contractDsl = fromYaml(contract) - MethodBodyBuilder builder = methodBuilder(contractDsl) - BlockBuilder blockBuilder = new BlockBuilder(" ") - when: - builder.appendTo(blockBuilder) - then: - blockBuilder.toString().contains(bodyString) - and: - SyntaxChecker.tryToCompile(methodBuilderName, blockBuilder.toString()) - and: - stubMappingIsValidWireMockStub(contractDsl) - where: - methodBuilderName | methodBuilder | bodyString - "MockMvcSpockMethodBuilder" | { Contract dsl -> new MockMvcSpockMethodRequestProcessingBodyBuilder(dsl, properties) } | """.body('''property1=VAL1''')""" - "MockMvcJUnitMethodBuilder" | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl, properties) } | '.body("property1=VAL1")' - } + Contract contractDsl = fromYaml(contract) + MethodBodyBuilder builder = methodBuilder(contractDsl) + BlockBuilder blockBuilder = new BlockBuilder(" ") + when: + builder.appendTo(blockBuilder) + then: + blockBuilder.toString().contains(bodyString) + and: + SyntaxChecker.tryToCompile(methodBuilderName, blockBuilder.toString()) + and: + stubMappingIsValidWireMockStub(contractDsl) + where: + methodBuilderName | methodBuilder | bodyString + HttpSpockMethodRequestProcessingBodyBuilder.simpleName | { Contract dsl -> new HttpSpockMethodRequestProcessingBodyBuilder(dsl, properties) } | """.body('''property1=VAL1''')""" + MockMvcJUnitMethodBodyBuilder.simpleName | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl, properties) } | '.body("property1=VAL1")' + WebTestClientJUnitMethodBodyBuilder.simpleName | { Contract dsl -> new WebTestClientJUnitMethodBodyBuilder(dsl, properties) } | '.body("property1=VAL1")' + } - @Issue("185") - def "should generate assertions for a response body containing map with integers as keys with #methodBuilderName"() { - given: - // YAML CAN'T HAVE INTEGER KEYS - String contract = """\ + @Issue('185') + def 'should generate assertions for a response body containing map with integers as keys with #methodBuilderName'() { + given: + // YAML CAN'T HAVE INTEGER KEYS + String contract = """\ --- request: method: "GET" @@ -388,27 +392,28 @@ response: 14: 0.0 7: 0.0 """ - Contract contractDsl = fromYaml(contract) - MethodBodyBuilder builder = methodBuilder(contractDsl) - BlockBuilder blockBuilder = new BlockBuilder(" ") - when: - builder.appendTo(blockBuilder) - then: - blockBuilder.toString().contains("""assertThatJson(parsedJson).field("['property']").field("['7']").isEqualTo(0.0)""") - blockBuilder.toString().contains("""assertThatJson(parsedJson).field("['property']").field("['14']").isEqualTo(0.0)""") - and: - stubMappingIsValidWireMockStub(contractDsl) - and: - SyntaxChecker.tryToCompile(methodBuilderName, blockBuilder.toString()) - where: - methodBuilderName | methodBuilder - "MockMvcSpockMethodBuilder" | { Contract dsl -> new MockMvcSpockMethodRequestProcessingBodyBuilder(dsl, properties) } - "MockMvcJUnitMethodBuilder" | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl, properties) } - } + Contract contractDsl = fromYaml(contract) + MethodBodyBuilder builder = methodBuilder(contractDsl) + BlockBuilder blockBuilder = new BlockBuilder(" ") + when: + builder.appendTo(blockBuilder) + then: + blockBuilder.toString().contains("""assertThatJson(parsedJson).field("['property']").field("['7']").isEqualTo(0.0)""") + blockBuilder.toString().contains("""assertThatJson(parsedJson).field("['property']").field("['14']").isEqualTo(0.0)""") + and: + stubMappingIsValidWireMockStub(contractDsl) + and: + SyntaxChecker.tryToCompile(methodBuilderName, blockBuilder.toString()) + where: + methodBuilderName | methodBuilder + HttpSpockMethodRequestProcessingBodyBuilder.simpleName | { Contract dsl -> new HttpSpockMethodRequestProcessingBodyBuilder(dsl, properties) } + MockMvcJUnitMethodBodyBuilder.simpleName | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl, properties) } + WebTestClientJUnitMethodBodyBuilder.simpleName | { Contract dsl -> new WebTestClientJUnitMethodBodyBuilder(dsl, properties) } + } - def "should generate assertions for array in response body with #methodBuilderName"() { - given: - String contract = """\ + def 'should generate assertions for array in response body with #methodBuilderName'() { + given: + String contract = """\ --- request: method: "GET" @@ -425,28 +430,29 @@ response: } ]' """ - Contract contractDsl = fromYaml(contract) - MethodBodyBuilder builder = methodBuilder(contractDsl) - BlockBuilder blockBuilder = new BlockBuilder(" ") - when: - builder.appendTo(blockBuilder) - then: - blockBuilder.toString().contains("""assertThatJson(parsedJson).array().contains("['property2']").isEqualTo("b")""") - blockBuilder.toString().contains("""assertThatJson(parsedJson).array().contains("['property1']").isEqualTo("a")""") - and: - stubMappingIsValidWireMockStub(contractDsl) - and: - SyntaxChecker.tryToCompile(methodBuilderName, blockBuilder.toString()) - where: - methodBuilderName | methodBuilder - "MockMvcSpockMethodBuilder" | { Contract dsl -> new MockMvcSpockMethodRequestProcessingBodyBuilder(dsl, properties) } - "MockMvcJUnitMethodBuilder" | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl, properties) } - } + Contract contractDsl = fromYaml(contract) + MethodBodyBuilder builder = methodBuilder(contractDsl) + BlockBuilder blockBuilder = new BlockBuilder(" ") + when: + builder.appendTo(blockBuilder) + then: + blockBuilder.toString().contains("""assertThatJson(parsedJson).array().contains("['property2']").isEqualTo("b")""") + blockBuilder.toString().contains("""assertThatJson(parsedJson).array().contains("['property1']").isEqualTo("a")""") + and: + stubMappingIsValidWireMockStub(contractDsl) + and: + SyntaxChecker.tryToCompile(methodBuilderName, blockBuilder.toString()) + where: + methodBuilderName | methodBuilder + HttpSpockMethodRequestProcessingBodyBuilder.simpleName | { Contract dsl -> new HttpSpockMethodRequestProcessingBodyBuilder(dsl, properties) } + MockMvcJUnitMethodBodyBuilder.simpleName | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl, properties) } + WebTestClientJUnitMethodBodyBuilder.simpleName | { Contract dsl -> new WebTestClientJUnitMethodBodyBuilder(dsl, properties) } + } - def "should generate assertions for array inside response body element with #methodBuilderName"() { - given: + def 'should generate assertions for array inside response body element with #methodBuilderName'() { + given: - String contract = """\ + String contract = """\ --- request: method: "GET" @@ -461,27 +467,28 @@ response: ] }' """ - Contract contractDsl = fromYaml(contract) - MethodBodyBuilder builder = methodBuilder(contractDsl) - BlockBuilder blockBuilder = new BlockBuilder(" ") - when: - builder.appendTo(blockBuilder) - then: - blockBuilder.toString().contains("""assertThatJson(parsedJson).array("['property1']").contains("['property2']").isEqualTo("test1")""") - blockBuilder.toString().contains("""assertThatJson(parsedJson).array("['property1']").contains("['property3']").isEqualTo("test2")""") - and: - stubMappingIsValidWireMockStub(contractDsl) - and: - SyntaxChecker.tryToCompile(methodBuilderName, blockBuilder.toString()) - where: - methodBuilderName | methodBuilder - "MockMvcSpockMethodBuilder" | { Contract dsl -> new MockMvcSpockMethodRequestProcessingBodyBuilder(dsl, properties) } - "MockMvcJUnitMethodBuilder" | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl, properties) } - } + Contract contractDsl = fromYaml(contract) + MethodBodyBuilder builder = methodBuilder(contractDsl) + BlockBuilder blockBuilder = new BlockBuilder(" ") + when: + builder.appendTo(blockBuilder) + then: + blockBuilder.toString().contains("""assertThatJson(parsedJson).array("['property1']").contains("['property2']").isEqualTo("test1")""") + blockBuilder.toString().contains("""assertThatJson(parsedJson).array("['property1']").contains("['property3']").isEqualTo("test2")""") + and: + stubMappingIsValidWireMockStub(contractDsl) + and: + SyntaxChecker.tryToCompile(methodBuilderName, blockBuilder.toString()) + where: + methodBuilderName | methodBuilder + HttpSpockMethodRequestProcessingBodyBuilder.simpleName | { Contract dsl -> new HttpSpockMethodRequestProcessingBodyBuilder(dsl, properties) } + MockMvcJUnitMethodBodyBuilder.simpleName | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl, properties) } + WebTestClientJUnitMethodBodyBuilder.simpleName | { Contract dsl -> new WebTestClientJUnitMethodBodyBuilder(dsl, properties) } + } - def "should generate assertions for nested objects in response body with #methodBuilderName"() { - given: - String contract = """\ + def 'should generate assertions for nested objects in response body with #methodBuilderName'() { + given: + String contract = """\ --- request: method: "GET" @@ -494,27 +501,28 @@ response: "property2": {"property3": "b"} }' """ - Contract contractDsl = fromYaml(contract) - MethodBodyBuilder builder = methodBuilder(contractDsl) - BlockBuilder blockBuilder = new BlockBuilder(" ") - when: - builder.appendTo(blockBuilder) - then: - blockBuilder.toString().contains("""assertThatJson(parsedJson).field("['property2']").field("['property3']").isEqualTo("b")""") - blockBuilder.toString().contains("""assertThatJson(parsedJson).field("['property1']").isEqualTo("a")""") - and: - stubMappingIsValidWireMockStub(contractDsl) - and: - SyntaxChecker.tryToCompile(methodBuilderName, blockBuilder.toString()) - where: - methodBuilderName | methodBuilder - "MockMvcSpockMethodBuilder" | { Contract dsl -> new MockMvcSpockMethodRequestProcessingBodyBuilder(dsl, properties) } - "MockMvcJUnitMethodBuilder" | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl, properties) } - } + Contract contractDsl = fromYaml(contract) + MethodBodyBuilder builder = methodBuilder(contractDsl) + BlockBuilder blockBuilder = new BlockBuilder(" ") + when: + builder.appendTo(blockBuilder) + then: + blockBuilder.toString().contains("""assertThatJson(parsedJson).field("['property2']").field("['property3']").isEqualTo("b")""") + blockBuilder.toString().contains("""assertThatJson(parsedJson).field("['property1']").isEqualTo("a")""") + and: + stubMappingIsValidWireMockStub(contractDsl) + and: + SyntaxChecker.tryToCompile(methodBuilderName, blockBuilder.toString()) + where: + methodBuilderName | methodBuilder + HttpSpockMethodRequestProcessingBodyBuilder.simpleName | { Contract dsl -> new HttpSpockMethodRequestProcessingBodyBuilder(dsl, properties) } + MockMvcJUnitMethodBodyBuilder.simpleName | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl, properties) } + WebTestClientJUnitMethodBodyBuilder.simpleName | { Contract dsl -> new WebTestClientJUnitMethodBodyBuilder(dsl, properties) } + } - def "should generate regex assertions for map objects in response body with #methodBuilderName"() { - given: - String contract = '''\ + def 'should generate regex assertions for map objects in response body with #methodBuilderName'() { + given: + String contract = '''\ --- request: method: "GET" @@ -530,27 +538,28 @@ response: type: by_regex value: "[0-9]{3}" ''' - Contract contractDsl = fromYaml(contract) - MethodBodyBuilder builder = methodBuilder(contractDsl) - BlockBuilder blockBuilder = new BlockBuilder(" ") - when: - builder.appendTo(blockBuilder) - then: - blockBuilder.toString().contains("""\$.property2", String.class)).matches("[0-9]{3}")""") - blockBuilder.toString().contains("""assertThatJson(parsedJson).field("['property1']").isEqualTo("a")""") - and: - stubMappingIsValidWireMockStub(contractDsl) - and: - SyntaxChecker.tryToCompileWithoutCompileStatic(methodBuilderName, blockBuilder.toString()) - where: - methodBuilderName | methodBuilder - "MockMvcSpockMethodBuilder" | { Contract dsl -> new MockMvcSpockMethodRequestProcessingBodyBuilder(dsl, properties) } - "MockMvcJUnitMethodBuilder" | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl, properties) } - } + Contract contractDsl = fromYaml(contract) + MethodBodyBuilder builder = methodBuilder(contractDsl) + BlockBuilder blockBuilder = new BlockBuilder(" ") + when: + builder.appendTo(blockBuilder) + then: + blockBuilder.toString().contains("""\$.property2", String.class)).matches("[0-9]{3}")""") + blockBuilder.toString().contains("""assertThatJson(parsedJson).field("['property1']").isEqualTo("a")""") + and: + stubMappingIsValidWireMockStub(contractDsl) + and: + SyntaxChecker.tryToCompileWithoutCompileStatic(methodBuilderName, blockBuilder.toString()) + where: + methodBuilderName | methodBuilder + HttpSpockMethodRequestProcessingBodyBuilder.simpleName | { Contract dsl -> new HttpSpockMethodRequestProcessingBodyBuilder(dsl, properties) } + MockMvcJUnitMethodBodyBuilder.simpleName | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl, properties) } + WebTestClientJUnitMethodBodyBuilder.simpleName | { Contract dsl -> new WebTestClientJUnitMethodBodyBuilder(dsl, properties) } + } - def "should generate a call with an url path and query parameters with #methodBuilderName"() { - given: - String contract = '''\ + def "should generate a call with an url path and query parameters with #methodBuilderName"() { + given: + String contract = '''\ --- request: method: "GET" @@ -592,38 +601,39 @@ response: property1: "a" property2: "b" ''' - Contract contractDsl = fromYaml(contract) - MethodBodyBuilder builder = methodBuilder(contractDsl) - BlockBuilder blockBuilder = new BlockBuilder(" ") - when: - builder.appendTo(blockBuilder) - def test = blockBuilder.toString() - then: - test.contains('''.queryParam("limit","10")''') - test.contains('''.queryParam("offset","20")''') - test.contains('''.queryParam("filter","email")''') - test.contains('''.queryParam("sort","name")''') - test.contains('''.queryParam("search","55")''') - test.contains('''.queryParam("age","99")''') - test.contains('''.queryParam("name","Denis.Stepanov")''') - test.contains('''.queryParam("email","bob@email.com")''') - test.contains('''.get("/users")''') - test.contains('assertThatJson(parsedJson).field("[\'property1\']").isEqualTo("a")') - test.contains('assertThatJson(parsedJson).field("[\'property2\']").isEqualTo("b")') - and: - stubMappingIsValidWireMockStub(contractDsl) - and: - SyntaxChecker.tryToCompile(methodBuilderName, blockBuilder.toString()) - where: - methodBuilderName | methodBuilder - "MockMvcSpockMethodBuilder" | { Contract dsl -> new MockMvcSpockMethodRequestProcessingBodyBuilder(dsl, properties) } - "MockMvcJUnitMethodBuilder" | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl, properties) } - } + Contract contractDsl = fromYaml(contract) + MethodBodyBuilder builder = methodBuilder(contractDsl) + BlockBuilder blockBuilder = new BlockBuilder(" ") + when: + builder.appendTo(blockBuilder) + def test = blockBuilder.toString() + then: + test.contains('''.queryParam("limit","10")''') + test.contains('''.queryParam("offset","20")''') + test.contains('''.queryParam("filter","email")''') + test.contains('''.queryParam("sort","name")''') + test.contains('''.queryParam("search","55")''') + test.contains('''.queryParam("age","99")''') + test.contains('''.queryParam("name","Denis.Stepanov")''') + test.contains('''.queryParam("email","bob@email.com")''') + test.contains('''.get("/users")''') + test.contains('assertThatJson(parsedJson).field("[\'property1\']").isEqualTo("a")') + test.contains('assertThatJson(parsedJson).field("[\'property2\']").isEqualTo("b")') + and: + stubMappingIsValidWireMockStub(contractDsl) + and: + SyntaxChecker.tryToCompile(methodBuilderName, blockBuilder.toString()) + where: + methodBuilderName | methodBuilder + HttpSpockMethodRequestProcessingBodyBuilder.simpleName | { Contract dsl -> new HttpSpockMethodRequestProcessingBodyBuilder(dsl, properties) } + MockMvcJUnitMethodBodyBuilder.simpleName | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl, properties) } + WebTestClientJUnitMethodBodyBuilder.simpleName | { Contract dsl -> new WebTestClientJUnitMethodBodyBuilder(dsl, properties) } + } - @Issue('#169') - def "should generate a call with an url path and query parameters with url containing a pattern with #methodBuilderName"() { - given: - String contract = '''\ + @Issue('#169') + def 'should generate a call with an url path and query parameters with url containing a pattern with #methodBuilderName'() { + given: + String contract = '''\ --- request: method: "GET" @@ -667,37 +677,38 @@ response: property1: "a" property2: "b" ''' - Contract contractDsl = fromYaml(contract) - MethodBodyBuilder builder = methodBuilder(contractDsl) - BlockBuilder blockBuilder = new BlockBuilder(" ") - when: - builder.appendTo(blockBuilder) - def test = blockBuilder.toString() - then: - test.contains('''.queryParam("limit","10")''') - test.contains('''.queryParam("offset","20")''') - test.contains('''.queryParam("filter","email")''') - test.contains('''.queryParam("sort","name")''') - test.contains('''.queryParam("search","55")''') - test.contains('''.queryParam("age","99")''') - test.contains('''.queryParam("name","Denis.Stepanov")''') - test.contains('''.queryParam("email","bob@email.com")''') - test.contains('''.get("/foo/123456")''') - test.contains('assertThatJson(parsedJson).field("[\'property1\']").isEqualTo("a")') - test.contains('assertThatJson(parsedJson).field("[\'property2\']").isEqualTo("b")') - and: - stubMappingIsValidWireMockStub(contractDsl) - and: - SyntaxChecker.tryToCompile(methodBuilderName, blockBuilder.toString()) - where: - methodBuilderName | methodBuilder - "MockMvcSpockMethodBuilder" | { Contract dsl -> new MockMvcSpockMethodRequestProcessingBodyBuilder(dsl, properties) } - "MockMvcJUnitMethodBuilder" | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl, properties) } - } + Contract contractDsl = fromYaml(contract) + MethodBodyBuilder builder = methodBuilder(contractDsl) + BlockBuilder blockBuilder = new BlockBuilder(" ") + when: + builder.appendTo(blockBuilder) + def test = blockBuilder.toString() + then: + test.contains('''.queryParam("limit","10")''') + test.contains('''.queryParam("offset","20")''') + test.contains('''.queryParam("filter","email")''') + test.contains('''.queryParam("sort","name")''') + test.contains('''.queryParam("search","55")''') + test.contains('''.queryParam("age","99")''') + test.contains('''.queryParam("name","Denis.Stepanov")''') + test.contains('''.queryParam("email","bob@email.com")''') + test.contains('''.get("/foo/123456")''') + test.contains('assertThatJson(parsedJson).field("[\'property1\']").isEqualTo("a")') + test.contains('assertThatJson(parsedJson).field("[\'property2\']").isEqualTo("b")') + and: + stubMappingIsValidWireMockStub(contractDsl) + and: + SyntaxChecker.tryToCompile(methodBuilderName, blockBuilder.toString()) + where: + methodBuilderName | methodBuilder + HttpSpockMethodRequestProcessingBodyBuilder.simpleName | { Contract dsl -> new HttpSpockMethodRequestProcessingBodyBuilder(dsl, properties) } + MockMvcJUnitMethodBodyBuilder.simpleName | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl, properties) } + WebTestClientJUnitMethodBodyBuilder.simpleName | { Contract dsl -> new WebTestClientJUnitMethodBodyBuilder(dsl, properties) } + } - def "should generate test for empty body with #methodBuilderName"() { - given: - String contract = '''\ + def 'should generate test for empty body with #methodBuilderName'() { + given: + String contract = '''\ --- request: method: "POST" @@ -706,27 +717,28 @@ request: response: status: 406 ''' - Contract contractDsl = fromYaml(contract) - MethodBodyBuilder builder = methodBuilder(contractDsl) - BlockBuilder blockBuilder = new BlockBuilder(" ") - when: - builder.appendTo(blockBuilder) - def test = blockBuilder.toString() - then: - test.contains(bodyString) - and: - stubMappingIsValidWireMockStub(contractDsl) - and: - SyntaxChecker.tryToCompile(methodBuilderName, blockBuilder.toString()) - where: - methodBuilderName | methodBuilder | bodyString - "MockMvcSpockMethodBuilder" | { Contract dsl -> new MockMvcSpockMethodRequestProcessingBodyBuilder(dsl, properties) } | ".body('''''')" - "MockMvcJUnitMethodBuilder" | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl, properties) } | '.body("")' - } + Contract contractDsl = fromYaml(contract) + MethodBodyBuilder builder = methodBuilder(contractDsl) + BlockBuilder blockBuilder = new BlockBuilder(" ") + when: + builder.appendTo(blockBuilder) + def test = blockBuilder.toString() + then: + test.contains(bodyString) + and: + stubMappingIsValidWireMockStub(contractDsl) + and: + SyntaxChecker.tryToCompile(methodBuilderName, blockBuilder.toString()) + where: + methodBuilderName | methodBuilder | bodyString + HttpSpockMethodRequestProcessingBodyBuilder.simpleName | { Contract dsl -> new HttpSpockMethodRequestProcessingBodyBuilder(dsl, properties) } | ".body('''''')" + MockMvcJUnitMethodBodyBuilder.simpleName | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl, properties) } | '.body("")' + WebTestClientJUnitMethodBodyBuilder.simpleName | { Contract dsl -> new WebTestClientJUnitMethodBodyBuilder(dsl, properties) } | '.body("")' + } - def "should generate test for String in response body with #methodBuilderName"() { - given: - String contract = '''\ + def 'should generate test for String in response body with #methodBuilderName'() { + given: + String contract = '''\ --- request: method: "POST" @@ -736,29 +748,30 @@ response: status: 200 body: "test" ''' - Contract contractDsl = fromYaml(contract) - MethodBodyBuilder builder = methodBuilder(contractDsl) - BlockBuilder blockBuilder = new BlockBuilder(" ") - when: - builder.appendTo(blockBuilder) - def test = blockBuilder.toString() - then: - test.contains(bodyDefinitionString) - test.contains(bodyEvaluationString) - and: - stubMappingIsValidWireMockStub(contractDsl) - and: - SyntaxChecker.tryToCompile(methodBuilderName, blockBuilder.toString()) - where: - methodBuilderName | methodBuilder | bodyDefinitionString | bodyEvaluationString - "MockMvcSpockMethodBuilder" | { Contract dsl -> new MockMvcSpockMethodRequestProcessingBodyBuilder(dsl, properties) } | 'def responseBody = (response.body.asString())' | 'responseBody == "test"' - "MockMvcJUnitMethodBuilder" | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl, properties) } | 'String responseBody = response.getBody().asString();' | 'assertThat(responseBody).isEqualTo("test");' - } + Contract contractDsl = fromYaml(contract) + MethodBodyBuilder builder = methodBuilder(contractDsl) + BlockBuilder blockBuilder = new BlockBuilder(" ") + when: + builder.appendTo(blockBuilder) + def test = blockBuilder.toString() + then: + test.contains(bodyDefinitionString) + test.contains(bodyEvaluationString) + and: + stubMappingIsValidWireMockStub(contractDsl) + and: + SyntaxChecker.tryToCompile(methodBuilderName, blockBuilder.toString()) + where: + methodBuilderName | methodBuilder | bodyDefinitionString | bodyEvaluationString + HttpSpockMethodRequestProcessingBodyBuilder.simpleName | { Contract dsl -> new HttpSpockMethodRequestProcessingBodyBuilder(dsl, properties) } | 'def responseBody = (response.body.asString())' | 'responseBody == "test"' + MockMvcJUnitMethodBodyBuilder.simpleName | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl, properties) } | 'String responseBody = response.getBody().asString();' | 'assertThat(responseBody).isEqualTo("test");' + WebTestClientJUnitMethodBodyBuilder.simpleName | { Contract dsl -> new WebTestClientJUnitMethodBodyBuilder(dsl, properties) } | 'String responseBody = response.getBody().asString();' | 'assertThat(responseBody).isEqualTo("test");' + } - @Issue('113') - def "should generate regex test for String in response header with #methodBuilderName"() { - given: - String contract = '''\ + @Issue('113') + def 'should generate regex test for String in response header with #methodBuilderName'() { + given: + String contract = '''\ --- request: method: "POST" @@ -787,27 +800,28 @@ response: - key: 'Location' regex: 'http://localhost/partners/[0-9]+/users/[0-9]+' ''' - Contract contractDsl = fromYaml(contract) - MethodBodyBuilder builder = methodBuilder(contractDsl) - BlockBuilder blockBuilder = new BlockBuilder(" ") - when: - builder.appendTo(blockBuilder) - def test = blockBuilder.toString() - then: - test.contains(headerEvaluationString) - and: - stubMappingIsValidWireMockStub(contractDsl) - and: - SyntaxChecker.tryToCompile(methodBuilderName, blockBuilder.toString()) - where: - methodBuilderName | methodBuilder | headerEvaluationString - "MockMvcSpockMethodBuilder" | { Contract dsl -> new MockMvcSpockMethodRequestProcessingBodyBuilder(dsl, properties) } | '''response.header('Location') ==~ java.util.regex.Pattern.compile('http://localhost/partners/[0-9]+/users/[0-9]+')''' - "MockMvcJUnitMethodBuilder" | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl, properties) } | 'assertThat(response.header("Location")).matches("http://localhost/partners/[0-9]+/users/[0-9]+");' - } + Contract contractDsl = fromYaml(contract) + MethodBodyBuilder builder = methodBuilder(contractDsl) + BlockBuilder blockBuilder = new BlockBuilder(" ") + when: + builder.appendTo(blockBuilder) + def test = blockBuilder.toString() + then: + test.contains(headerEvaluationString) + and: + stubMappingIsValidWireMockStub(contractDsl) + and: + SyntaxChecker.tryToCompile(methodBuilderName, blockBuilder.toString()) + where: + methodBuilderName | methodBuilder | headerEvaluationString + HttpSpockMethodRequestProcessingBodyBuilder.simpleName | { Contract dsl -> new HttpSpockMethodRequestProcessingBodyBuilder(dsl, properties) } | '''response.header('Location') ==~ java.util.regex.Pattern.compile('http://localhost/partners/[0-9]+/users/[0-9]+')''' + MockMvcJUnitMethodBodyBuilder.simpleName | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl, properties) } | 'assertThat(response.header("Location")).matches("http://localhost/partners/[0-9]+/users/[0-9]+");' + WebTestClientJUnitMethodBodyBuilder.simpleName | { Contract dsl -> new WebTestClientJUnitMethodBodyBuilder(dsl, properties) } | 'assertThat(response.header("Location")).matches("http://localhost/partners/[0-9]+/users/[0-9]+");' + } - def "should work with more complex stuff and jsonpaths with #methodBuilderName"() { - given: - String contract = '''\ + def 'should work with more complex stuff and jsonpaths with #methodBuilderName'() { + given: + String contract = '''\ --- priority: 10 request: @@ -833,29 +847,30 @@ response: - property: "bank_account_number" message: "incorrect_format" ''' - Contract contractDsl = fromYaml(contract) - MethodBodyBuilder builder = methodBuilder(contractDsl) - BlockBuilder blockBuilder = new BlockBuilder(" ") - when: - builder.appendTo(blockBuilder) - def test = blockBuilder.toString() - then: - test.contains("""assertThatJson(parsedJson).array("['errors']").contains("['property']").isEqualTo("bank_account_number")""") - test.contains("""assertThatJson(parsedJson).array("['errors']").contains("['message']").isEqualTo("incorrect_format")""") - and: - stubMappingIsValidWireMockStub(contractDsl) - and: - SyntaxChecker.tryToCompile(methodBuilderName, blockBuilder.toString()) - where: - methodBuilderName | methodBuilder - "MockMvcSpockMethodBuilder" | { Contract dsl -> new MockMvcSpockMethodRequestProcessingBodyBuilder(dsl, properties) } - "MockMvcJUnitMethodBuilder" | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl, properties) } - } + Contract contractDsl = fromYaml(contract) + MethodBodyBuilder builder = methodBuilder(contractDsl) + BlockBuilder blockBuilder = new BlockBuilder(" ") + when: + builder.appendTo(blockBuilder) + def test = blockBuilder.toString() + then: + test.contains("""assertThatJson(parsedJson).array("['errors']").contains("['property']").isEqualTo("bank_account_number")""") + test.contains("""assertThatJson(parsedJson).array("['errors']").contains("['message']").isEqualTo("incorrect_format")""") + and: + stubMappingIsValidWireMockStub(contractDsl) + and: + SyntaxChecker.tryToCompile(methodBuilderName, blockBuilder.toString()) + where: + methodBuilderName | methodBuilder + HttpSpockMethodRequestProcessingBodyBuilder.simpleName | { Contract dsl -> new HttpSpockMethodRequestProcessingBodyBuilder(dsl, properties) } + MockMvcJUnitMethodBodyBuilder.simpleName | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl, properties) } + WebTestClientJUnitMethodBodyBuilder.simpleName | { Contract dsl -> new WebTestClientJUnitMethodBodyBuilder(dsl, properties) } + } - @Issue('72') - def "should make the execute method work with #methodBuilderName"() { - given: - String contract = '''\ + @Issue('72') + def 'should make the execute method work with #methodBuilderName'() { + given: + String contract = '''\ --- priority: 10 request: @@ -876,24 +891,26 @@ response: - key: "Location" command: assertThatLocationIsNull($it) ''' - Contract contractDsl = fromYaml(contract) - MethodBodyBuilder builder = methodBuilder(contractDsl) - BlockBuilder blockBuilder = new BlockBuilder(" ") - when: - builder.appendTo(blockBuilder) - String test = blockBuilder.toString() - then: - assertionStrings.each { String assertionString -> - assert test.contains(assertionString) - } - where: - methodBuilderName | methodBuilder | assertionStrings - "MockMvcSpockMethodBuilder" | { Contract dsl -> new MockMvcSpockMethodRequestProcessingBodyBuilder(dsl, properties) } | ['''assertThatRejectionReasonIsNull(parsedJson.read("\\\$.rejectionReason"))''', '''assertThatLocationIsNull(response.header('Location'))'''] - "MockMvcJUnitMethodBuilder" | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl, properties) } | ['''assertThatRejectionReasonIsNull(parsedJson.read("$.rejectionReason"))''', '''assertThatLocationIsNull(response.header("Location"))'''] - } - def "shouldn't generate unicode escape characters with #methodBuilderName"() { - given: - String contract = '''\ + Contract contractDsl = fromYaml(contract) + MethodBodyBuilder builder = methodBuilder(contractDsl) + BlockBuilder blockBuilder = new BlockBuilder(" ") + when: + builder.appendTo(blockBuilder) + String test = blockBuilder.toString() + then: + assertionStrings.each { String assertionString -> + assert test.contains(assertionString) + } + where: + methodBuilderName | methodBuilder | assertionStrings + HttpSpockMethodRequestProcessingBodyBuilder.simpleName | { Contract dsl -> new HttpSpockMethodRequestProcessingBodyBuilder(dsl, properties) } | ['''assertThatRejectionReasonIsNull(parsedJson.read("\\\$.rejectionReason"))''', '''assertThatLocationIsNull(response.header('Location'))'''] + MockMvcJUnitMethodBodyBuilder.simpleName | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl, properties) } | ['''assertThatRejectionReasonIsNull(parsedJson.read("$.rejectionReason"))''', '''assertThatLocationIsNull(response.header("Location"))'''] + WebTestClientJUnitMethodBodyBuilder.simpleName | { Contract dsl -> new WebTestClientJUnitMethodBodyBuilder(dsl, properties) } | ['''assertThatRejectionReasonIsNull(parsedJson.read("$.rejectionReason"))''', '''assertThatLocationIsNull(response.header("Location"))'''] + } + + def "shouldn't generate unicode escape characters with #methodBuilderName"() { + given: + String contract = '''\ --- priority: 10 request: @@ -923,26 +940,27 @@ response: - key: 'Content-Type' regex: 'application/json.*' ''' - Contract contractDsl = fromYaml(contract) - MethodBodyBuilder builder = methodBuilder(contractDsl) - BlockBuilder blockBuilder = new BlockBuilder(" ") - when: - builder.appendTo(blockBuilder) - def test = blockBuilder.toString() - then: - !test.contains("\\u041f") - and: - SyntaxChecker.tryToCompile(methodBuilderName, blockBuilder.toString()) - where: - methodBuilderName | methodBuilder - "MockMvcSpockMethodBuilder" | { Contract dsl -> new MockMvcSpockMethodRequestProcessingBodyBuilder(dsl, properties) } - "MockMvcJUnitMethodBuilder" | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl, properties) } - } + Contract contractDsl = fromYaml(contract) + MethodBodyBuilder builder = methodBuilder(contractDsl) + BlockBuilder blockBuilder = new BlockBuilder(" ") + when: + builder.appendTo(blockBuilder) + def test = blockBuilder.toString() + then: + !test.contains("\\u041f") + and: + SyntaxChecker.tryToCompile(methodBuilderName, blockBuilder.toString()) + where: + methodBuilderName | methodBuilder + HttpSpockMethodRequestProcessingBodyBuilder.simpleName | { Contract dsl -> new HttpSpockMethodRequestProcessingBodyBuilder(dsl, properties) } + MockMvcJUnitMethodBodyBuilder.simpleName | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl, properties) } + WebTestClientJUnitMethodBodyBuilder.simpleName | { Contract dsl -> new WebTestClientJUnitMethodBodyBuilder(dsl, properties) } + } - @Issue('180') - def "should generate proper test code when having multipart parameters with #methodBuilderName"() { - given: - String contract = '''\ + @Issue('180') + def 'should generate proper test code when having multipart parameters with #methodBuilderName'() { + given: + String contract = '''\ --- request: method: "PUT" @@ -983,34 +1001,39 @@ response: - key: 'Content-Type' regex: 'application/json.*' ''' - Contract contractDsl = fromYaml(contract) - MethodBodyBuilder builder = methodBuilder(contractDsl) - BlockBuilder blockBuilder = new BlockBuilder(" ") - when: - builder.appendTo(blockBuilder) - def test = blockBuilder.toString() - then: - for (String requestString : requestStrings) { - assert test.contains(requestString) - } - and: - SyntaxChecker.tryToCompile(methodBuilderName, blockBuilder.toString()) - where: - methodBuilderName | methodBuilder | requestStrings - "MockMvcSpockMethodBuilder" | { Contract dsl -> new MockMvcSpockMethodRequestProcessingBodyBuilder(dsl, properties) } | ['"Content-Type", "multipart/form-data;boundary=AaB03x"', - """.param('formParameter', '"formParameterValue"'""", - """.param('someBooleanParameter', 'true')""", - """.multiPart('file', 'filename.csv', 'file content'.bytes, 'application/json')"""] - "MockMvcJUnitMethodBuilder" | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl, properties) } | ['"Content-Type", "multipart/form-data;boundary=AaB03x"', - '.param("formParameter", "\\"formParameterValue\\"")', - '.param("someBooleanParameter", "true")', - '.multiPart("file", "filename.csv", "file content".getBytes(), "application/json");'] - } + Contract contractDsl = fromYaml(contract) + MethodBodyBuilder builder = methodBuilder(contractDsl) + BlockBuilder blockBuilder = new BlockBuilder(" ") + when: + builder.appendTo(blockBuilder) + def test = blockBuilder.toString() + then: + for (String requestString : requestStrings) { + assert test.contains(requestString) + } + and: + SyntaxChecker.tryToCompile(methodBuilderName, blockBuilder.toString()) + where: + methodBuilderName | methodBuilder | requestStrings + HttpSpockMethodRequestProcessingBodyBuilder.simpleName | { Contract dsl -> new HttpSpockMethodRequestProcessingBodyBuilder(dsl, properties) } | ['"Content-Type", "multipart/form-data;boundary=AaB03x"', + """.param('formParameter', '"formParameterValue"'""", + """.param('someBooleanParameter', 'true')""", + """.multiPart('file', 'filename.csv', 'file content'.bytes, 'application/json')"""] + MockMvcJUnitMethodBodyBuilder.simpleName | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl, properties) } | ['"Content-Type", "multipart/form-data;boundary=AaB03x"', + '.param("formParameter", "\\"formParameterValue\\"")', + '.param("someBooleanParameter", "true")', + '.multiPart("file", "filename.csv", "file content".getBytes(), "application/json");'] + WebTestClientJUnitMethodBodyBuilder.simpleName | { Contract dsl -> new WebTestClientJUnitMethodBodyBuilder(dsl, properties) } | ['"Content-Type", "multipart/form-data;boundary=AaB03x"', + '.param("formParameter", "\\"formParameterValue\\"")', + '.param("someBooleanParameter", "true")', + '.multiPart("file", "filename.csv", "file content".getBytes(), "application/json");'] - @Issue('546') - def "should generate test code when having multipart parameters with byte array #methodBuilderName"() { - given: - String contract = '''\ + } + + @Issue('546') + def 'should generate test code when having multipart parameters with byte array #methodBuilderName'() { + given: + String contract = '''\ --- request: method: "PUT" @@ -1051,30 +1074,33 @@ response: - key: 'Content-Type' regex: 'application/json.*' ''' - Contract contractDsl = fromYaml(contract) - MethodBodyBuilder builder = methodBuilder(contractDsl) - BlockBuilder blockBuilder = new BlockBuilder(" ") - when: - builder.appendTo(blockBuilder) - def test = blockBuilder.toString() - then: - for (String requestString : requestStrings) { - assert test.contains(requestString) - } - and: - SyntaxChecker.tryToCompile(methodBuilderName, blockBuilder.toString()) - where: - methodBuilderName | methodBuilder | requestStrings - "MockMvcSpockMethodBuilder" | { Contract dsl -> new MockMvcSpockMethodRequestProcessingBodyBuilder(dsl, properties) } | ['"Content-Type", "multipart/form-data;boundary=AaB03x"', - """.multiPart('file', 'filename.csv', 'file content'.bytes, 'application/json')"""] - "MockMvcJUnitMethodBuilder" | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl, properties) } | ['"Content-Type", "multipart/form-data;boundary=AaB03x"', - '.multiPart("file", "filename.csv", "file content".getBytes(), "application/json");'] - } + Contract contractDsl = fromYaml(contract) + MethodBodyBuilder builder = methodBuilder(contractDsl) + BlockBuilder blockBuilder = new BlockBuilder(" ") + when: + builder.appendTo(blockBuilder) + def test = blockBuilder.toString() + then: + for (String requestString : requestStrings) { + assert test.contains(requestString) + } + and: + SyntaxChecker.tryToCompile(methodBuilderName, blockBuilder.toString()) + where: + methodBuilderName | methodBuilder | requestStrings + HttpSpockMethodRequestProcessingBodyBuilder.simpleName | { Contract dsl -> new HttpSpockMethodRequestProcessingBodyBuilder(dsl, properties) } | ['"Content-Type", "multipart/form-data;boundary=AaB03x"', + """.multiPart('file', 'filename.csv', 'file content'.bytes, 'application/json')"""] + MockMvcJUnitMethodBodyBuilder.simpleName | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl, properties) } | ['"Content-Type", "multipart/form-data;boundary=AaB03x"', + '.multiPart("file", "filename.csv", "file content".getBytes(), "application/json");'] + WebTestClientJUnitMethodBodyBuilder.simpleName | { Contract dsl -> new WebTestClientJUnitMethodBodyBuilder(dsl, properties) } | ['"Content-Type", "multipart/form-data;boundary=AaB03x"', + '.multiPart("file", "filename.csv", "file content".getBytes(), "application/json");'] - @Issue('541') - def "should generate proper test code when having multipart parameters that use execute with #methodBuilderName"() { - given: - String contract = '''\ + } + + @Issue('541') + def 'should generate proper test code when having multipart parameters that use execute with #methodBuilderName'() { + given: + String contract = '''\ --- request: method: "PUT" @@ -1115,34 +1141,39 @@ response: - key: 'Content-Type' regex: 'application/json.*' ''' - Contract contractDsl = fromYaml(contract) - MethodBodyBuilder builder = methodBuilder(contractDsl) - BlockBuilder blockBuilder = new BlockBuilder(" ") - when: - builder.appendTo(blockBuilder) - def test = blockBuilder.toString() - then: - for (String requestString : requestStrings) { - assert test.contains(requestString) - } - and: - SyntaxChecker.tryToCompile(methodBuilderName, blockBuilder.toString()) - where: - methodBuilderName | methodBuilder | requestStrings - "MockMvcSpockMethodBuilder" | { Contract dsl -> new MockMvcSpockMethodRequestProcessingBodyBuilder(dsl, properties) } | ['"Content-Type", "multipart/form-data;boundary=AaB03x"', - """.param('formParameter', '"formParameterValue"'""", - """.param('someBooleanParameter', 'true')""", - """.multiPart('file', toString(), 'file content'.bytes, 'application/json')"""] - "MockMvcJUnitMethodBuilder" | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl, properties) } | ['"Content-Type", "multipart/form-data;boundary=AaB03x"', - '.param("formParameter", "\\"formParameterValue\\"")', - '.param("someBooleanParameter", "true")', - '.multiPart("file", toString(), "file content".getBytes(), "application/json");'] - } + Contract contractDsl = fromYaml(contract) + MethodBodyBuilder builder = methodBuilder(contractDsl) + BlockBuilder blockBuilder = new BlockBuilder(" ") + when: + builder.appendTo(blockBuilder) + def test = blockBuilder.toString() + then: + for (String requestString : requestStrings) { + assert test.contains(requestString) + } + and: + SyntaxChecker.tryToCompile(methodBuilderName, blockBuilder.toString()) + where: + methodBuilderName | methodBuilder | requestStrings + HttpSpockMethodRequestProcessingBodyBuilder.simpleName | { Contract dsl -> new HttpSpockMethodRequestProcessingBodyBuilder(dsl, properties) } | ['"Content-Type", "multipart/form-data;boundary=AaB03x"', + """.param('formParameter', '"formParameterValue"'""", + """.param('someBooleanParameter', 'true')""", + """.multiPart('file', toString(), 'file content'.bytes, 'application/json')"""] + MockMvcJUnitMethodBodyBuilder.simpleName | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl, properties) } | ['"Content-Type", "multipart/form-data;boundary=AaB03x"', + '.param("formParameter", "\\"formParameterValue\\"")', + '.param("someBooleanParameter", "true")', + '.multiPart("file", toString(), "file content".getBytes(), "application/json");'] + WebTestClientJUnitMethodBodyBuilder.simpleName | { Contract dsl -> new WebTestClientJUnitMethodBodyBuilder(dsl, properties) } | ['"Content-Type", "multipart/form-data;boundary=AaB03x"', + '.param("formParameter", "\\"formParameterValue\\"")', + '.param("someBooleanParameter", "true")', + '.multiPart("file", toString(), "file content".getBytes(), "application/json");'] - @Issue('#216') - def "should parse JSON with arrays using Spock"() { - given: - String contract = '''\ + } + + @Issue('#216') + def 'should parse JSON with arrays using Spock'() { + given: + String contract = '''\ --- request: method: "GET" @@ -1158,22 +1189,22 @@ response: type: by_regex value: '^[a-zA-Z0-9_\\- ]+$' ''' - Contract contractDsl = fromYaml(contract) - MethodBodyBuilder builder = new MockMvcSpockMethodRequestProcessingBodyBuilder(contractDsl, properties) - BlockBuilder blockBuilder = new BlockBuilder(" ") - when: - builder.appendTo(blockBuilder) - def test = blockBuilder.toString() - then: - test.contains('''assertThat(parsedJson.read("\\$.authorities[0]", String.class)).matches("^[a-zA-Z0-9_\\\\- ]+\\$")''') - and: - SyntaxChecker.tryToCompileWithoutCompileStatic("spock", blockBuilder.toString()) - } + Contract contractDsl = fromYaml(contract) + MethodBodyBuilder builder = new HttpSpockMethodRequestProcessingBodyBuilder(contractDsl, properties) + BlockBuilder blockBuilder = new BlockBuilder(" ") + when: + builder.appendTo(blockBuilder) + def test = blockBuilder.toString() + then: + test.contains('''assertThat(parsedJson.read("\\$.authorities[0]", String.class)).matches("^[a-zA-Z0-9_\\\\- ]+\\$")''') + and: + SyntaxChecker.tryToCompileWithoutCompileStatic("spock", blockBuilder.toString()) + } - @Issue('#216') - def "should parse JSON with arrays using JUnit"() { - given: - String contract = '''\ + @Issue('#216') + def 'should parse JSON with arrays using JUnit'() { + given: + String contract = '''\ --- request: method: "GET" @@ -1189,21 +1220,21 @@ response: type: by_regex value: '^[a-zA-Z0-9_\\- ]+$' ''' - Contract contractDsl = fromYaml(contract) - MethodBodyBuilder builder = new MockMvcJUnitMethodBodyBuilder(contractDsl, properties) - BlockBuilder blockBuilder = new BlockBuilder(" ") - when: - builder.appendTo(blockBuilder) - def test = blockBuilder.toString() - then: - test.contains('''assertThat(parsedJson.read("$.authorities[0]", String.class)).matches("^[a-zA-Z0-9_\\\\- ]+$")''') - and: - SyntaxChecker.tryToCompileJava(blockBuilder.toString()) - } + Contract contractDsl = fromYaml(contract) + MethodBodyBuilder builder = new MockMvcJUnitMethodBodyBuilder(contractDsl, properties) + BlockBuilder blockBuilder = new BlockBuilder(" ") + when: + builder.appendTo(blockBuilder) + def test = blockBuilder.toString() + then: + test.contains('''assertThat(parsedJson.read("$.authorities[0]", String.class)).matches("^[a-zA-Z0-9_\\\\- ]+$")''') + and: + SyntaxChecker.tryToCompileJava(MockMvcJUnitMethodBodyBuilder.simpleName, blockBuilder.toString()) + } - def "should work with execution property with #methodBuilderName"() { - given: - String contract = '''\ + def 'should work with execution property with #methodBuilderName'() { + given: + String contract = '''\ --- request: method: "PUT" @@ -1219,25 +1250,25 @@ response: type: by_command value: "assertThatRejectionReasonIsNull($it)" ''' - Contract contractDsl = fromYaml(contract) - 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" | { Contract dsl -> new MockMvcSpockMethodRequestProcessingBodyBuilder(dsl, properties) } - "MockMvcJUnitMethodBuilder" | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl, properties) } - } + Contract contractDsl = fromYaml(contract) + 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 + HttpSpockMethodRequestProcessingBodyBuilder.simpleName | { Contract dsl -> new HttpSpockMethodRequestProcessingBodyBuilder(dsl, properties) } + MockMvcJUnitMethodBodyBuilder.simpleName | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl, properties) } + } - @Issue('262') - def "should generate proper test code with map inside list"() { - given: - String contract = '''\ + @Issue('262') + def "should generate proper test code with map inside list"() { + given: + String contract = '''\ --- request: method: "GET" @@ -1258,23 +1289,23 @@ response: type: by_regex value: "[0-9]+" ''' - Contract contractDsl = fromYaml(contract) - MethodBodyBuilder builder = new MockMvcSpockMethodRequestProcessingBodyBuilder(contractDsl, properties) - BlockBuilder blockBuilder = new BlockBuilder(" ") - when: - builder.appendTo(blockBuilder) - def test = blockBuilder.toString() - then: - test.contains('assertThat(parsedJson.read("\\$[0].id", String.class)).matches("[0-9]+")') - test.contains('assertThat(parsedJson.read("\\$[1].id", String.class)).matches("[0-9]+")') - and: - SyntaxChecker.tryToCompileWithoutCompileStatic("spock", blockBuilder.toString()) - } + Contract contractDsl = fromYaml(contract) + MethodBodyBuilder builder = new HttpSpockMethodRequestProcessingBodyBuilder(contractDsl, properties) + BlockBuilder blockBuilder = new BlockBuilder(" ") + when: + builder.appendTo(blockBuilder) + def test = blockBuilder.toString() + then: + test.contains('assertThat(parsedJson.read("\\$[0].id", String.class)).matches("[0-9]+")') + test.contains('assertThat(parsedJson.read("\\$[1].id", String.class)).matches("[0-9]+")') + and: + SyntaxChecker.tryToCompileWithoutCompileStatic("spock", blockBuilder.toString()) + } - @Issue('266') - def "should generate proper test code with top level array using #methodBuilderName"() { - given: - String contract = '''\ + @Issue('266') + def "should generate proper test code with top level array using #methodBuilderName"() { + given: + String contract = '''\ --- request: method: "GET" @@ -1290,31 +1321,32 @@ response: headers: "Content-Type": "application/json;charset=UTF-8" ''' - Contract contractDsl = fromYaml(contract) - MethodBodyBuilder builder = methodBuilder(contractDsl) - BlockBuilder blockBuilder = new BlockBuilder(" ") - when: - builder.appendTo(blockBuilder) - def test = blockBuilder.toString() - then: - test.contains('assertThatJson(parsedJson).arrayField().contains("Java8").value()') - test.contains('assertThatJson(parsedJson).arrayField().contains("Spring").value()') - test.contains('assertThatJson(parsedJson).arrayField().contains("Java").value()') - test.contains('assertThatJson(parsedJson).arrayField().contains("Stream").value()') - test.contains('assertThatJson(parsedJson).arrayField().contains("SpringBoot").value()') - and: - SyntaxChecker.tryToCompile(methodBuilderName, blockBuilder.toString()) - where: - methodBuilderName | methodBuilder - "MockMvcSpockMethodBuilder" | { Contract dsl -> new MockMvcSpockMethodRequestProcessingBodyBuilder(dsl, properties) } - "MockMvcJUnitMethodBuilder" | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl, properties) } - } + Contract contractDsl = fromYaml(contract) + MethodBodyBuilder builder = methodBuilder(contractDsl) + BlockBuilder blockBuilder = new BlockBuilder(" ") + when: + builder.appendTo(blockBuilder) + def test = blockBuilder.toString() + then: + test.contains('assertThatJson(parsedJson).arrayField().contains("Java8").value()') + test.contains('assertThatJson(parsedJson).arrayField().contains("Spring").value()') + test.contains('assertThatJson(parsedJson).arrayField().contains("Java").value()') + test.contains('assertThatJson(parsedJson).arrayField().contains("Stream").value()') + test.contains('assertThatJson(parsedJson).arrayField().contains("SpringBoot").value()') + and: + SyntaxChecker.tryToCompile(methodBuilderName, blockBuilder.toString()) + where: + methodBuilderName | methodBuilder + HttpSpockMethodRequestProcessingBodyBuilder.simpleName | { Contract dsl -> new HttpSpockMethodRequestProcessingBodyBuilder(dsl, properties) } + MockMvcJUnitMethodBodyBuilder.simpleName | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl, properties) } + WebTestClientJUnitMethodBodyBuilder.simpleName | { Contract dsl -> new WebTestClientJUnitMethodBodyBuilder(dsl, properties) } + } - @Issue('266') - @RestoreSystemProperties - def "should generate proper test code with top level array using #methodBuilderName with array size check"() { - given: - String contract = '''\ + @Issue('266') + @RestoreSystemProperties + def 'should generate proper test code with top level array using #methodBuilderName with array size check'() { + given: + String contract = '''\ --- request: method: "GET" @@ -1325,32 +1357,33 @@ response: headers: "Content-Type": "application/json;charset=UTF-8" ''' - Contract contractDsl = fromYaml(contract) - System.setProperty('spring.cloud.contract.verifier.assert.size', 'true') - MethodBodyBuilder builder = methodBuilder(contractDsl) - BlockBuilder blockBuilder = new BlockBuilder(" ") - when: - builder.appendTo(blockBuilder) - def test = blockBuilder.toString() - then: - test.contains('assertThatJson(parsedJson).hasSize(5)') - test.contains('assertThatJson(parsedJson).arrayField().contains("Java8").value()') - test.contains('assertThatJson(parsedJson).arrayField().contains("Spring").value()') - test.contains('assertThatJson(parsedJson).arrayField().contains("Java").value()') - test.contains('assertThatJson(parsedJson).arrayField().contains("Stream").value()') - test.contains('assertThatJson(parsedJson).arrayField().contains("SpringBoot").value()') - and: - SyntaxChecker.tryToCompile(methodBuilderName, blockBuilder.toString()) - where: - methodBuilderName | methodBuilder - "MockMvcSpockMethodBuilder" | { Contract dsl -> new MockMvcSpockMethodRequestProcessingBodyBuilder(dsl, properties) } - "MockMvcJUnitMethodBuilder" | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl, properties) } - } + Contract contractDsl = fromYaml(contract) + System.setProperty('spring.cloud.contract.verifier.assert.size', 'true') + MethodBodyBuilder builder = methodBuilder(contractDsl) + BlockBuilder blockBuilder = new BlockBuilder(" ") + when: + builder.appendTo(blockBuilder) + def test = blockBuilder.toString() + then: + test.contains('assertThatJson(parsedJson).hasSize(5)') + test.contains('assertThatJson(parsedJson).arrayField().contains("Java8").value()') + test.contains('assertThatJson(parsedJson).arrayField().contains("Spring").value()') + test.contains('assertThatJson(parsedJson).arrayField().contains("Java").value()') + test.contains('assertThatJson(parsedJson).arrayField().contains("Stream").value()') + test.contains('assertThatJson(parsedJson).arrayField().contains("SpringBoot").value()') + and: + SyntaxChecker.tryToCompile(methodBuilderName, blockBuilder.toString()) + where: + methodBuilderName | methodBuilder + HttpSpockMethodRequestProcessingBodyBuilder.simpleName | { Contract dsl -> new HttpSpockMethodRequestProcessingBodyBuilder(dsl, properties) } + MockMvcJUnitMethodBodyBuilder.simpleName | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl, properties) } + WebTestClientJUnitMethodBodyBuilder.simpleName | { Contract dsl -> new WebTestClientJUnitMethodBodyBuilder(dsl, properties) } + } - @Issue('266') - def "should generate proper test code with top level array or arrays using #methodBuilderName"() { - given: - String contract = '''\ + @Issue('266') + def 'should generate proper test code with top level array or arrays using #methodBuilderName'() { + given: + String contract = '''\ --- request: method: "GET" @@ -1361,29 +1394,30 @@ response: headers: "Content-Type": "application/json;charset=UTF-8" ''' - Contract contractDsl = fromYaml(contract) - MethodBodyBuilder builder = methodBuilder(contractDsl) - BlockBuilder blockBuilder = new BlockBuilder(" ") - when: - builder.appendTo(blockBuilder) - def test = blockBuilder.toString() - then: - test.contains('assertThatJson(parsedJson).array().array().arrayField().isEqualTo("Programming").value()') - test.contains('assertThatJson(parsedJson).array().array().arrayField().isEqualTo("Java").value()') - test.contains('assertThatJson(parsedJson).array().array().arrayField().isEqualTo("Spring").value()') - test.contains('assertThatJson(parsedJson).array().array().arrayField().isEqualTo("Boot").value()') - and: - SyntaxChecker.tryToCompile(methodBuilderName, blockBuilder.toString()) - where: - methodBuilderName | methodBuilder - "MockMvcSpockMethodBuilder" | { Contract dsl -> new MockMvcSpockMethodRequestProcessingBodyBuilder(dsl, properties) } - "MockMvcJUnitMethodBuilder" | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl, properties) } - } + Contract contractDsl = fromYaml(contract) + MethodBodyBuilder builder = methodBuilder(contractDsl) + BlockBuilder blockBuilder = new BlockBuilder(" ") + when: + builder.appendTo(blockBuilder) + def test = blockBuilder.toString() + then: + test.contains('assertThatJson(parsedJson).array().array().arrayField().isEqualTo("Programming").value()') + test.contains('assertThatJson(parsedJson).array().array().arrayField().isEqualTo("Java").value()') + test.contains('assertThatJson(parsedJson).array().array().arrayField().isEqualTo("Spring").value()') + test.contains('assertThatJson(parsedJson).array().array().arrayField().isEqualTo("Boot").value()') + and: + SyntaxChecker.tryToCompile(methodBuilderName, blockBuilder.toString()) + where: + methodBuilderName | methodBuilder + HttpSpockMethodRequestProcessingBodyBuilder.simpleName | { Contract dsl -> new HttpSpockMethodRequestProcessingBodyBuilder(dsl, properties) } + MockMvcJUnitMethodBodyBuilder.simpleName | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl, properties) } + WebTestClientJUnitMethodBodyBuilder.simpleName | { Contract dsl -> new WebTestClientJUnitMethodBodyBuilder(dsl, properties) } + } - @Issue('47') - def "should generate async body when async flag set in response"() { - given: - String contract = '''\ + @Issue('47') + def 'should generate async body when async flag set in response'() { + given: + String contract = '''\ --- request: method: "GET" @@ -1392,28 +1426,28 @@ response: async: true status: 200 ''' - Contract contractDsl = fromYaml(contract) - MethodBodyBuilder builder = methodBuilder(contractDsl) - BlockBuilder blockBuilder = new BlockBuilder(" ") - when: - builder.appendTo(blockBuilder) - def test = blockBuilder.toString() - then: - test.contains(bodyDefinitionString) - and: - stubMappingIsValidWireMockStub(contractDsl) - and: - SyntaxChecker.tryToCompile(methodBuilderName, blockBuilder.toString()) - where: - methodBuilderName | methodBuilder | bodyDefinitionString - "MockMvcSpockMethodBuilder" | { Contract dsl -> new MockMvcSpockMethodRequestProcessingBodyBuilder(dsl, properties) } | '.when().async()' - "MockMvcJUnitMethodBuilder" | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl, properties) } | '.when().async()' - } + Contract contractDsl = fromYaml(contract) + MethodBodyBuilder builder = methodBuilder(contractDsl) + BlockBuilder blockBuilder = new BlockBuilder(" ") + when: + builder.appendTo(blockBuilder) + def test = blockBuilder.toString() + then: + test.contains(bodyDefinitionString) + and: + stubMappingIsValidWireMockStub(contractDsl) + and: + SyntaxChecker.tryToCompile(methodBuilderName, blockBuilder.toString()) + where: + methodBuilderName | methodBuilder | bodyDefinitionString + HttpSpockMethodRequestProcessingBodyBuilder.simpleName | { Contract dsl -> new HttpSpockMethodRequestProcessingBodyBuilder(dsl, properties) } | '.when().async()' + MockMvcJUnitMethodBodyBuilder.simpleName | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl, properties) } | '.when().async()' + } - @Issue('372') - def "should generate async body after queryParams when async flag set in response and queryParams set in request"() { - given: - String contract = '''\ + @Issue('372') + def 'should generate async body after queryParams when async flag set in response and queryParams set in request'() { + given: + String contract = '''\ --- request: method: "GET" @@ -1424,28 +1458,28 @@ response: async: true status: 200 ''' - Contract contractDsl = fromYaml(contract) - MethodBodyBuilder builder = methodBuilder(contractDsl) - BlockBuilder blockBuilder = new BlockBuilder(" ") - when: - builder.appendTo(blockBuilder) - def test = blockBuilder.toString() - def strippedTest = test.replace('\n', '').replace(' ', '').stripIndent().stripMargin() - then: - strippedTest.contains('.queryParam("param","value").when().async().get("/test")') - and: - stubMappingIsValidWireMockStub(contractDsl) - and: - SyntaxChecker.tryToCompile(methodBuilderName, blockBuilder.toString()) - where: - methodBuilderName | methodBuilder - "MockMvcSpockMethodBuilder" | { Contract dsl -> new MockMvcSpockMethodRequestProcessingBodyBuilder(dsl, properties) } - "MockMvcJUnitMethodBuilder" | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl, properties) } - } + Contract contractDsl = fromYaml(contract) + MethodBodyBuilder builder = methodBuilder(contractDsl) + BlockBuilder blockBuilder = new BlockBuilder(" ") + when: + builder.appendTo(blockBuilder) + def test = blockBuilder.toString() + def strippedTest = test.replace('\n', '').replace(' ', '').stripIndent().stripMargin() + then: + strippedTest.contains('.queryParam("param","value").when().async().get("/test")') + and: + stubMappingIsValidWireMockStub(contractDsl) + and: + SyntaxChecker.tryToCompile(methodBuilderName, blockBuilder.toString()) + where: + methodBuilderName | methodBuilder + HttpSpockMethodRequestProcessingBodyBuilder.simpleName | { Contract dsl -> new HttpSpockMethodRequestProcessingBodyBuilder(dsl, properties) } + MockMvcJUnitMethodBodyBuilder.simpleName | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl, properties) } + } - def "should generate proper test code with array of primitives using #methodBuilderName"() { - given: - String contract = '''\ + def 'should generate proper test code with array of primitives using #methodBuilderName'() { + given: + String contract = '''\ --- request: method: "GET" @@ -1458,27 +1492,28 @@ response: - BANK - CASH ''' - Contract contractDsl = fromYaml(contract) - MethodBodyBuilder builder = methodBuilder(contractDsl) - BlockBuilder blockBuilder = new BlockBuilder(" ") - when: - builder.appendTo(blockBuilder) - def test = blockBuilder.toString() - then: - test.contains('assertThatJson(parsedJson).array().field("[\'partners\']").array("[\'payment_methods\']").arrayField().isEqualTo("BANK").value()') - test.contains('assertThatJson(parsedJson).array().field("[\'partners\']").array("[\'payment_methods\']").arrayField().isEqualTo("CASH").value()') - and: - SyntaxChecker.tryToCompile(methodBuilderName, blockBuilder.toString()) - where: - methodBuilderName | methodBuilder - "MockMvcSpockMethodBuilder" | { Contract dsl -> new MockMvcSpockMethodRequestProcessingBodyBuilder(dsl, properties) } - "MockMvcJUnitMethodBuilder" | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl, properties) } - } + Contract contractDsl = fromYaml(contract) + MethodBodyBuilder builder = methodBuilder(contractDsl) + BlockBuilder blockBuilder = new BlockBuilder(" ") + when: + builder.appendTo(blockBuilder) + def test = blockBuilder.toString() + then: + test.contains('assertThatJson(parsedJson).array().field("[\'partners\']").array("[\'payment_methods\']").arrayField().isEqualTo("BANK").value()') + test.contains('assertThatJson(parsedJson).array().field("[\'partners\']").array("[\'payment_methods\']").arrayField().isEqualTo("CASH").value()') + and: + SyntaxChecker.tryToCompile(methodBuilderName, blockBuilder.toString()) + where: + methodBuilderName | methodBuilder + HttpSpockMethodRequestProcessingBodyBuilder.simpleName | { Contract dsl -> new HttpSpockMethodRequestProcessingBodyBuilder(dsl, properties) } + MockMvcJUnitMethodBodyBuilder.simpleName | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl, properties) } + WebTestClientJUnitMethodBodyBuilder.simpleName | { Contract dsl -> new WebTestClientJUnitMethodBodyBuilder(dsl, properties) } + } - @Issue('#273') - def "should not escape dollar in Spock regex tests"() { - given: - String contract = '''\ + @Issue('#273') + def 'should not escape dollar in Spock regex tests'() { + given: + String contract = '''\ --- request: method: "GET" @@ -1494,22 +1529,23 @@ response: type: by_regex value: '^(?!\\s*$).+' ''' - Contract contractDsl = fromYaml(contract) - MethodBodyBuilder builder = new MockMvcSpockMethodRequestProcessingBodyBuilder(contractDsl, properties) - BlockBuilder blockBuilder = new BlockBuilder(" ") - when: - builder.appendTo(blockBuilder) - def test = blockBuilder.toString() - then: - test.contains('assertThat(parsedJson.read("\\$.message", String.class)).matches("^(?!\\\\s*\\$).+")') - and: - SyntaxChecker.tryToCompileGroovy(blockBuilder.toString(), false) - } + Contract contractDsl = fromYaml(contract) + MethodBodyBuilder builder = new HttpSpockMethodRequestProcessingBodyBuilder(contractDsl, properties) + BlockBuilder blockBuilder = new BlockBuilder(" ") + when: + builder.appendTo(blockBuilder) + def test = blockBuilder.toString() + then: + test.contains('assertThat(parsedJson.read("\\$.message", String.class)).matches("^(?!\\\\s*\\$).+")') + and: + SyntaxChecker.tryToCompileGroovy(HttpSpockMethodRequestProcessingBodyBuilder.simpleName, blockBuilder.toString(), + false) + } - @Issue('#85') - def "should execute custom method for complex structures on the response side"() { - given: - String contract = '''\ + @Issue('#85') + def 'should execute custom method for complex structures on the response side'() { + given: + String contract = '''\ --- request: method: "GET" @@ -1526,25 +1562,25 @@ response: type: by_command value: "assertThatRejectionReasonIsNull($it)" ''' - Contract contractDsl = fromYaml(contract) - MethodBodyBuilder builder = new MockMvcSpockMethodRequestProcessingBodyBuilder(contractDsl, properties) - BlockBuilder blockBuilder = new BlockBuilder(" ") - when: - builder.then(blockBuilder) - def test = blockBuilder.toString() - then: - test.contains('assertThatRejectionReasonIsNull(parsedJson.read("\\\$.rejectionReason.title"))') - when: - SyntaxChecker.tryToCompileGroovy(blockBuilder.toString()) - then: - def e = thrown(MultipleCompilationErrorsException) - e.message.contains("Cannot find matching method Script1#assertThatRejectionReasonIsNull") - } + Contract contractDsl = fromYaml(contract) + MethodBodyBuilder builder = new HttpSpockMethodRequestProcessingBodyBuilder(contractDsl, properties) + BlockBuilder blockBuilder = new BlockBuilder(" ") + when: + builder.then(blockBuilder) + def test = blockBuilder.toString() + then: + test.contains('assertThatRejectionReasonIsNull(parsedJson.read("\\\$.rejectionReason.title"))') + when: + SyntaxChecker.tryToCompileGroovy(HttpSpockMethodRequestProcessingBodyBuilder.simpleName, blockBuilder.toString()) + then: + def e = thrown(MultipleCompilationErrorsException) + e.message.contains('Cannot find matching method Script1#assertThatRejectionReasonIsNull') + } - @Issue('#85') - def "should execute custom method for more complex structures on the response side when using Spock"() { - given: - String contract = '''\ + @Issue('#85') + def 'should execute custom method for more complex structures on the response side when using Spock'() { + given: + String contract = '''\ --- request: method: "GET" @@ -1563,21 +1599,21 @@ response: type: by_command value: "assertThatUserNameIsNotNull($it)" ''' - Contract contractDsl = fromYaml(contract) - MethodBodyBuilder builder = new MockMvcSpockMethodRequestProcessingBodyBuilder(contractDsl, properties) - BlockBuilder blockBuilder = new BlockBuilder(" ") - when: - builder.then(blockBuilder) - def test = blockBuilder.toString() - then: - test.contains('''assertThatUserNameIsNotNull(parsedJson.read("\\$[0].name"))''') - test.contains('''assertThatUserNameIsNotNull(parsedJson.read("\\$[1].name"))''') - } + Contract contractDsl = fromYaml(contract) + MethodBodyBuilder builder = new HttpSpockMethodRequestProcessingBodyBuilder(contractDsl, properties) + BlockBuilder blockBuilder = new BlockBuilder(" ") + when: + builder.then(blockBuilder) + def test = blockBuilder.toString() + then: + test.contains('''assertThatUserNameIsNotNull(parsedJson.read("\\$[0].name"))''') + test.contains('''assertThatUserNameIsNotNull(parsedJson.read("\\$[1].name"))''') + } - @Issue('#85') - def "should execute custom method for more complex structures on the response side when using JUnit"() { - given: - String contract = '''\ + @Issue('#85') + def 'should execute custom method for more complex structures on the response side when using JUnit'() { + given: + String contract = '''\ --- request: method: "GET" @@ -1596,21 +1632,21 @@ response: type: by_command value: "assertThatUserNameIsNotNull($it)" ''' - Contract contractDsl = fromYaml(contract) - MethodBodyBuilder builder = new MockMvcJUnitMethodBodyBuilder(contractDsl, properties) - BlockBuilder blockBuilder = new BlockBuilder(" ") - when: - builder.then(blockBuilder) - def test = blockBuilder.toString() - then: - test.contains('''assertThatUserNameIsNotNull(parsedJson.read("$[0].name")''') - test.contains('''assertThatUserNameIsNotNull(parsedJson.read("$[1].name")''') - } + Contract contractDsl = fromYaml(contract) + MethodBodyBuilder builder = new MockMvcJUnitMethodBodyBuilder(contractDsl, properties) + BlockBuilder blockBuilder = new BlockBuilder(" ") + when: + builder.then(blockBuilder) + def test = blockBuilder.toString() + then: + test.contains('''assertThatUserNameIsNotNull(parsedJson.read("$[0].name")''') + test.contains('''assertThatUserNameIsNotNull(parsedJson.read("$[1].name")''') + } - @Issue('#111') - def "should execute custom method for request headers"() { - given: - String contract = '''\ + @Issue('#111') + def 'should execute custom method for request headers'() { + given: + String contract = '''\ --- request: method: "GET" @@ -1624,25 +1660,25 @@ request: response: status: 200 ''' - Contract contractDsl = fromYaml(contract) - MethodBodyBuilder builder = new MockMvcSpockMethodRequestProcessingBodyBuilder(contractDsl, properties) - BlockBuilder blockBuilder = new BlockBuilder(" ") - when: - builder.given(blockBuilder) - def test = blockBuilder.toString() - then: - test.contains('.header("authorization", getOAuthTokenHeader())') - when: - SyntaxChecker.tryToCompileGroovy(blockBuilder.toString()) - then: - def e = thrown(MultipleCompilationErrorsException) - e.message.contains("Cannot find matching method Script1#getOAuthTokenHeader") - } + Contract contractDsl = fromYaml(contract) + MethodBodyBuilder builder = new HttpSpockMethodRequestProcessingBodyBuilder(contractDsl, properties) + BlockBuilder blockBuilder = new BlockBuilder(" ") + when: + builder.given(blockBuilder) + def test = blockBuilder.toString() + then: + test.contains('.header("authorization", getOAuthTokenHeader())') + when: + SyntaxChecker.tryToCompileGroovy(HttpSpockMethodRequestProcessingBodyBuilder.simpleName, blockBuilder.toString()) + then: + def e = thrown(MultipleCompilationErrorsException) + e.message.contains('Cannot find matching method Script1#getOAuthTokenHeader') + } - @Issue('#150') - def "should support body matching in response"() { - given: - String contract = '''\ + @Issue('#150') + def 'should support body matching in response'() { + given: + String contract = '''\ --- request: method: "GET" @@ -1655,22 +1691,22 @@ response: - type: by_regex value: ".*" ''' - Contract contractDsl = fromYaml(contract) - MethodBodyBuilder builder = new MockMvcSpockMethodRequestProcessingBodyBuilder(contractDsl, properties) - BlockBuilder blockBuilder = new BlockBuilder(" ") - when: - builder.appendTo(blockBuilder) - def test = blockBuilder.toString() - then: - test.contains("responseBody ==~ java.util.regex.Pattern.compile('.*')") - and: - SyntaxChecker.tryToCompileGroovy(blockBuilder.toString()) - } + Contract contractDsl = fromYaml(contract) + MethodBodyBuilder builder = new HttpSpockMethodRequestProcessingBodyBuilder(contractDsl, properties) + BlockBuilder blockBuilder = new BlockBuilder(" ") + when: + builder.appendTo(blockBuilder) + def test = blockBuilder.toString() + then: + test.contains("responseBody ==~ java.util.regex.Pattern.compile('.*')") + and: + SyntaxChecker.tryToCompileGroovy(HttpSpockMethodRequestProcessingBodyBuilder.simpleName, blockBuilder.toString()) + } - @Issue('#150') - def "should support custom method execution in response"() { - given: - String contract = '''\ + @Issue('#150') + def 'should support custom method execution in response'() { + given: + String contract = '''\ --- request: method: "GET" @@ -1683,25 +1719,25 @@ response: - type: by_command value: "foo($it)" ''' - Contract contractDsl = fromYaml(contract) - MethodBodyBuilder builder = new MockMvcSpockMethodRequestProcessingBodyBuilder(contractDsl, properties) - BlockBuilder blockBuilder = new BlockBuilder(" ") - when: - builder.appendTo(blockBuilder) - def test = blockBuilder.toString() - then: - test.contains("foo(responseBody)") - when: - SyntaxChecker.tryToCompileGroovy(blockBuilder.toString()) - then: - def e = thrown(MultipleCompilationErrorsException) - e.message.contains("Cannot find matching method Script1#foo") - } + Contract contractDsl = fromYaml(contract) + MethodBodyBuilder builder = new HttpSpockMethodRequestProcessingBodyBuilder(contractDsl, properties) + BlockBuilder blockBuilder = new BlockBuilder(" ") + when: + builder.appendTo(blockBuilder) + def test = blockBuilder.toString() + then: + test.contains('foo(responseBody)') + when: + SyntaxChecker.tryToCompileGroovy(HttpSpockMethodRequestProcessingBodyBuilder.simpleName, blockBuilder.toString()) + then: + def e = thrown(MultipleCompilationErrorsException) + e.message.contains('Cannot find matching method Script1#foo') + } - @Issue('#162') - def "should escape regex properly for content type"() { - given: - String contract = '''\ + @Issue('#162') + def 'should escape regex properly for content type'() { + given: + String contract = '''\ --- request: method: "GET" @@ -1721,26 +1757,27 @@ response: - key: 'Content-Type' regex: 'application.vnd.fraud.v1.json.*' ''' - Contract contractDsl = fromYaml(contract) - MethodBodyBuilder builder = methodBuilder(contractDsl) - BlockBuilder blockBuilder = new BlockBuilder(" ") - when: - builder.appendTo(blockBuilder) - def test = blockBuilder.toString() - then: - matcher(test) - and: - SyntaxChecker.tryToCompile(methodBuilderName, blockBuilder.toString()) - where: - methodBuilderName | methodBuilder | matcher - "MockMvcSpockMethodBuilder" | { Contract dsl -> new MockMvcSpockMethodRequestProcessingBodyBuilder(dsl, properties) } | { String s -> 'assertThat(response.header("Content-Type")).matches("application.vnd.fraud.v1.json.*")' } - "MockMvcJUnitMethodBuilder" | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl, properties) } | { String s -> "response.header('Content-Type') ==~ java.util.regex.Pattern.compile('application.vnd.fraud.v1.json.*')" } - } + Contract contractDsl = fromYaml(contract) + MethodBodyBuilder builder = methodBuilder(contractDsl) + BlockBuilder blockBuilder = new BlockBuilder(" ") + when: + builder.appendTo(blockBuilder) + def test = blockBuilder.toString() + then: + matcher(test) + and: + SyntaxChecker.tryToCompile(methodBuilderName, blockBuilder.toString()) + where: + methodBuilderName | methodBuilder | matcher + HttpSpockMethodRequestProcessingBodyBuilder.simpleName | { Contract dsl -> new HttpSpockMethodRequestProcessingBodyBuilder(dsl, properties) } | { String s -> 'assertThat(response.header("Content-Type")).matches("application.vnd.fraud.v1.json.*")' } + MockMvcJUnitMethodBodyBuilder.simpleName | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl, properties) } | { String s -> "response.header('Content-Type') ==~ java.util.regex.Pattern.compile('application.vnd.fraud.v1.json.*')" } + WebTestClientJUnitMethodBodyBuilder.simpleName | { Contract dsl -> new WebTestClientJUnitMethodBodyBuilder(dsl, properties) } | { String s -> "response.header('Content-Type') ==~ java.util.regex.Pattern.compile('application.vnd.fraud.v1.json.*')" } + } - @Issue('#172') - def "should resolve plain text properly via headers"() { - given: - String contract = '''\ + @Issue('#172') + def 'should resolve plain text properly via headers'() { + given: + String contract = '''\ --- request: method: "GET" @@ -1757,28 +1794,29 @@ response: - key: 'Content-Type' regex: 'text/plain.*' ''' - Contract contractDsl = fromYaml(contract) - MethodBodyBuilder builder = methodBuilder(contractDsl) - BlockBuilder blockBuilder = new BlockBuilder(" ") - when: - builder.appendTo(blockBuilder) - def test = blockBuilder.toString() - then: - !test.contains('assertThatJson(parsedJson).field("[\'a\']").isEqualTo(1)') - test.contains(expectedAssertion) - and: - SyntaxChecker.tryToCompile(methodBuilderName, blockBuilder.toString()) - where: - //order is inverted cause Intellij didn't parse this properly - methodBuilderName | methodBuilder | expectedAssertion - "MockMvcSpockMethodBuilder" | { Contract dsl -> new MockMvcSpockMethodRequestProcessingBodyBuilder(dsl, properties) } | '''responseBody == "{\\"a\\":1}\\n{\\"a\\":2}''' - "MockMvcJUnitMethodBuilder" | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl, properties) } | '''assertThat(responseBody).isEqualTo("{\\"a\\":1}\\n{\\"a\\":2}''' - } + Contract contractDsl = fromYaml(contract) + MethodBodyBuilder builder = methodBuilder(contractDsl) + BlockBuilder blockBuilder = new BlockBuilder(" ") + when: + builder.appendTo(blockBuilder) + def test = blockBuilder.toString() + then: + !test.contains('assertThatJson(parsedJson).field("[\'a\']").isEqualTo(1)') + test.contains(expectedAssertion) + and: + SyntaxChecker.tryToCompile(methodBuilderName, blockBuilder.toString()) + where: + //order is inverted cause Intellij didn't parse this properly + methodBuilderName | methodBuilder | expectedAssertion + HttpSpockMethodRequestProcessingBodyBuilder.simpleName | { Contract dsl -> new HttpSpockMethodRequestProcessingBodyBuilder(dsl, properties) } | '''responseBody == "{\\"a\\":1}\\n{\\"a\\":2}''' + MockMvcJUnitMethodBodyBuilder.simpleName | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl, properties) } | '''assertThat(responseBody).isEqualTo("{\\"a\\":1}\\n{\\"a\\":2}''' + WebTestClientJUnitMethodBodyBuilder.simpleName | { Contract dsl -> new WebTestClientJUnitMethodBodyBuilder(dsl, properties) } | '''assertThat(responseBody).isEqualTo("{\\"a\\":1}\\n{\\"a\\":2}''' + } - @Issue('#443') - def "should resolve plain text that happens to be a valid json for [#methodBuilderName]"() { - given: - String contract = '''\ + @Issue('#443') + def 'should resolve plain text that happens to be a valid json for [#methodBuilderName]'() { + given: + String contract = '''\ --- request: method: "GET" @@ -1796,28 +1834,28 @@ response: - key: 'Content-Type' regex: 'application/json;charset=utf-8.*' ''' - Contract contractDsl = fromYaml(contract) - MethodBodyBuilder builder = methodBuilder(contractDsl) - BlockBuilder blockBuilder = new BlockBuilder(" ") - when: - builder.appendTo(blockBuilder) - def test = blockBuilder.toString() - then: - testAssertion(test) - and: - SyntaxChecker.tryToCompile(methodBuilderName, blockBuilder.toString()) - where: - methodBuilderName | methodBuilder | testAssertion - "MockMvcSpockMethodBuilder" | { Contract dsl -> new MockMvcSpockMethodRequestProcessingBodyBuilder(dsl, properties) } | { String testContents -> testContents.contains("""responseBody ==~ java.util.regex.Pattern.compile('true|false')""") } - "MockMvcJUnitMethodBuilder" | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl, properties) } | { String testContents -> testContents.contains("""assertThat(responseBody).matches("true|false");""") } - "JaxRsClientSpockMethodRequestProcessingBodyBuilder" | { Contract dsl -> new JaxRsClientSpockMethodRequestProcessingBodyBuilder(dsl, properties) } | { String testContents -> testContents.contains("""responseBody ==~ java.util.regex.Pattern.compile('true|false')""") } - "JaxRsClientJUnitMethodBodyBuilder" | { Contract dsl -> new JaxRsClientJUnitMethodBodyBuilder(dsl, properties) } | { String testContents -> testContents.contains("""assertThat(responseBody).matches("true|false");""") } - } + Contract contractDsl = fromYaml(contract) + MethodBodyBuilder builder = methodBuilder(contractDsl) + BlockBuilder blockBuilder = new BlockBuilder(" ") + when: + builder.appendTo(blockBuilder) + def test = blockBuilder.toString() + then: + testAssertion(test) + and: + SyntaxChecker.tryToCompile(methodBuilderName, blockBuilder.toString()) + where: + methodBuilderName | methodBuilder | testAssertion + HttpSpockMethodRequestProcessingBodyBuilder.simpleName | { Contract dsl -> new HttpSpockMethodRequestProcessingBodyBuilder(dsl, properties) } | { String testContents -> testContents.contains("""responseBody ==~ java.util.regex.Pattern.compile('true|false')""") } + MockMvcJUnitMethodBodyBuilder.simpleName | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl, properties) } | { String testContents -> testContents.contains("""assertThat(responseBody).matches("true|false");""") } + JaxRsClientSpockMethodRequestProcessingBodyBuilder.simpleName | { Contract dsl -> new JaxRsClientSpockMethodRequestProcessingBodyBuilder(dsl, properties) } | { String testContents -> testContents.contains("""responseBody ==~ java.util.regex.Pattern.compile('true|false')""") } + JaxRsClientJUnitMethodBodyBuilder.simpleName | { Contract dsl -> new JaxRsClientJUnitMethodBodyBuilder(dsl, properties) } | { String testContents -> testContents.contains("""assertThat(responseBody).matches("true|false");""") } + } - @Issue('#169') - def "should escape quotes properly using [#methodBuilderName]"() { - given: - String contract = '''\ + @Issue('#169') + def "should escape quotes properly using [#methodBuilderName]"() { + given: + String contract = '''\ --- request: method: "POST" @@ -1837,61 +1875,61 @@ response: type: by_regex value: 'some value "with quote"|bar' ''' - Contract contractDsl = fromYaml(contract) - MethodBodyBuilder builder = methodBuilder(contractDsl) - BlockBuilder blockBuilder = new BlockBuilder(" ") - when: - builder.appendTo(blockBuilder) - def test = blockBuilder.toString() - then: - test.contains('.matches("some value \\"with quote\\"|bar")') - and: - SyntaxChecker.tryToCompileWithoutCompileStatic(methodBuilderName, blockBuilder.toString()) - where: - //order is inverted cause Intellij didn't parse this properly - methodBuilderName | methodBuilder | expectedAssertion - "MockMvcSpockMethodBuilder" | { Contract dsl -> new MockMvcSpockMethodRequestProcessingBodyBuilder(dsl, properties) } | '''responseBody == "{\\"a\\":1}\\n{\\"a\\":2}"''' - "MockMvcJUnitMethodBuilder" | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl, properties) } | '''assertThat(responseBody).isEqualTo("{\\"a\\":1}\\n{\\"a\\":2}''' - } + Contract contractDsl = fromYaml(contract) + MethodBodyBuilder builder = methodBuilder(contractDsl) + BlockBuilder blockBuilder = new BlockBuilder(" ") + when: + builder.appendTo(blockBuilder) + def test = blockBuilder.toString() + then: + test.contains('.matches("some value \\"with quote\\"|bar")') + and: + SyntaxChecker.tryToCompileWithoutCompileStatic(methodBuilderName, blockBuilder.toString()) + where: + //order is inverted cause Intellij didn't parse this properly + methodBuilderName | methodBuilder | expectedAssertion + HttpSpockMethodRequestProcessingBodyBuilder.simpleName | { Contract dsl -> new HttpSpockMethodRequestProcessingBodyBuilder(dsl, properties) } | '''responseBody == "{\\"a\\":1}\\n{\\"a\\":2}"''' + MockMvcJUnitMethodBodyBuilder.simpleName | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl, properties) } | '''assertThat(responseBody).isEqualTo("{\\"a\\":1}\\n{\\"a\\":2}''' + } - @Issue('#169') - def "should make the execute method work in a url for [#methodBuilderName]"() { - given: - Contract contractDsl = Contract.make { - request { - method 'POST' - url $(c("foo"), p(execute("executedMethod()"))) - } - response { - status OK() - } - } - MethodBodyBuilder builder = methodBuilder(contractDsl) - BlockBuilder blockBuilder = new BlockBuilder(" ") - and: - builder.appendTo(blockBuilder) - String test = blockBuilder.toString() - when: - SyntaxChecker.tryToCompile(methodBuilderName, test) - then: - def e = thrown(Throwable) - missingMethodAssertion(e, capture) - and: - test.contains("executedMethod()") - !test.contains("\"executedMethod()\"") - !test.contains("'executedMethod()'") - where: - methodBuilderName | methodBuilder | missingMethodAssertion - "MockMvcSpockMethodBuilder" | { Contract dsl -> new MockMvcSpockMethodRequestProcessingBodyBuilder(dsl, properties) } | { Throwable t, OutputCapture capture -> t.message.contains("Cannot find matching method Script1#executedMethod") } - "MockMvcJUnitMethodBuilder" | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl, properties) } | { Throwable t, OutputCapture capture -> t.message.contains("Truncated class file") && capture.toString().contains("post(executedMethod())") } - "JaxRsClientSpockMethodRequestProcessingBodyBuilder" | { Contract dsl -> new JaxRsClientSpockMethodRequestProcessingBodyBuilder(dsl, properties) } | { Throwable t, OutputCapture capture -> t.message.contains("Cannot find matching method Script1#executedMethod") } - "JaxRsClientJUnitMethodBodyBuilder" | { Contract dsl -> new JaxRsClientJUnitMethodBodyBuilder(dsl, properties) } | { Throwable t, OutputCapture capture -> t.message.contains("Truncated class file") && capture.toString().contains("path(executedMethod())") } - } + @Issue('#169') + def "should make the execute method work in a url for [#methodBuilderName]"() { + given: + Contract contractDsl = Contract.make { + request { + method 'POST' + url $(c("foo"), p(execute("executedMethod()"))) + } + response { + status OK() + } + } + MethodBodyBuilder builder = methodBuilder(contractDsl) + BlockBuilder blockBuilder = new BlockBuilder(" ") + and: + builder.appendTo(blockBuilder) + String test = blockBuilder.toString() + when: + SyntaxChecker.tryToCompile(methodBuilderName, test) + then: + def e = thrown(Throwable) + missingMethodAssertion(e, capture) + and: + test.contains("executedMethod()") + !test.contains("\"executedMethod()\"") + !test.contains("'executedMethod()'") + where: + methodBuilderName | methodBuilder | missingMethodAssertion + HttpSpockMethodRequestProcessingBodyBuilder.simpleName | { Contract dsl -> new HttpSpockMethodRequestProcessingBodyBuilder(dsl, properties) } | { Throwable t, OutputCapture capture -> t.message.contains("Cannot find matching method Script1#executedMethod") } + MockMvcJUnitMethodBodyBuilder.simpleName | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl, properties) } | { Throwable t, OutputCapture capture -> t.message.contains("Truncated class file") && capture.toString().contains("post(executedMethod())") } + JaxRsClientSpockMethodRequestProcessingBodyBuilder.simpleName | { Contract dsl -> new JaxRsClientSpockMethodRequestProcessingBodyBuilder(dsl, properties) } | { Throwable t, OutputCapture capture -> t.message.contains("Cannot find matching method Script1#executedMethod") } + JaxRsClientJUnitMethodBodyBuilder.simpleName | { Contract dsl -> new JaxRsClientJUnitMethodBodyBuilder(dsl, properties) } | { Throwable t, OutputCapture capture -> t.message.contains("Truncated class file") && capture.toString().contains("path(executedMethod())") } + } - @Issue('#203') - def "should create an assertion for an empty list for [#methodBuilderName]"() { - given: - String contract = '''\ + @Issue('#203') + def "should create an assertion for an empty list for [#methodBuilderName]"() { + given: + String contract = '''\ --- request: method: "GET" @@ -1905,29 +1943,30 @@ response: - "bar" - "baz" ''' - Contract contractDsl = fromYaml(contract) - MethodBodyBuilder builder = methodBuilder(contractDsl) - BlockBuilder blockBuilder = new BlockBuilder(" ") - and: - builder.appendTo(blockBuilder) - String test = blockBuilder.toString() - when: - SyntaxChecker.tryToCompile(methodBuilderName, test) - then: - test.contains('assertThatJson(parsedJson).array("[\'list\']").isEmpty()') - !test.contains('assertThatJson(parsedJson).array("[\'foo\']").isEmpty()') - where: - methodBuilderName | methodBuilder - "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) } - } + Contract contractDsl = fromYaml(contract) + MethodBodyBuilder builder = methodBuilder(contractDsl) + BlockBuilder blockBuilder = new BlockBuilder(" ") + and: + builder.appendTo(blockBuilder) + String test = blockBuilder.toString() + when: + SyntaxChecker.tryToCompile(methodBuilderName, test) + then: + test.contains('assertThatJson(parsedJson).array("[\'list\']").isEmpty()') + !test.contains('assertThatJson(parsedJson).array("[\'foo\']").isEmpty()') + where: + methodBuilderName | methodBuilder + HttpSpockMethodRequestProcessingBodyBuilder.simpleName | { Contract dsl -> new HttpSpockMethodRequestProcessingBodyBuilder(dsl, properties) } + MockMvcJUnitMethodBodyBuilder.simpleName | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl, properties) } + JaxRsClientSpockMethodRequestProcessingBodyBuilder.simpleName | { Contract dsl -> new JaxRsClientSpockMethodRequestProcessingBodyBuilder(dsl, properties) } + JaxRsClientJUnitMethodBodyBuilder.simpleName | { Contract dsl -> new JaxRsClientJUnitMethodBodyBuilder(dsl, properties) } + WebTestClientJUnitMethodBodyBuilder.simpleName | { Contract dsl -> new WebTestClientJUnitMethodBodyBuilder(dsl, properties) } + } - @Issue("#226") - def "should work properly when body is an integer [#methodBuilderName]"() { - given: - String contract = '''\ + @Issue('#226') + def 'should work properly when body is an integer [#methodBuilderName]'() { + given: + String contract = '''\ --- request: method: "GET" @@ -1937,22 +1976,23 @@ response: status: 200 body: 12000 ''' - Contract contractDsl = fromYaml(contract) - MethodBodyBuilder builder = methodBuilder(contractDsl) - BlockBuilder blockBuilder = new BlockBuilder(" ") - and: - builder.appendTo(blockBuilder) - String test = blockBuilder.toString() - when: - SyntaxChecker.tryToCompile(methodBuilderName, test) - then: - requestAssertion(test) - responseAssertion(test) - where: - methodBuilderName | methodBuilder | requestAssertion | responseAssertion - "MockMvcSpockMethodBuilder" | { Contract dsl -> new MockMvcSpockMethodRequestProcessingBodyBuilder(dsl, properties) } | { String body -> body.contains("body('''12000''')") } | { String body -> body.contains('responseBody == "12000"') } - "MockMvcJUnitMethodBuilder" | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl, properties) } | { String body -> body.contains('body("12000")') } | { String body -> body.contains('assertThat(responseBody).isEqualTo("12000");') } - "JaxRsClientSpockMethodRequestProcessingBodyBuilder" | { Contract dsl -> new JaxRsClientSpockMethodRequestProcessingBodyBuilder(dsl, properties) } | { String body -> body.contains(""".method('GET', entity('12000', 'text/plain'))""") } | { String body -> body.contains('responseBody == "12000"') } - "JaxRsClientJUnitMethodBodyBuilder" | { Contract dsl -> new JaxRsClientJUnitMethodBodyBuilder(dsl, properties) } | { String body -> body.contains(""".method("GET", entity("12000", "text/plain"))""") } | { String body -> body.contains('assertThat(responseBody).isEqualTo("12000")') } - } + Contract contractDsl = fromYaml(contract) + MethodBodyBuilder builder = methodBuilder(contractDsl) + BlockBuilder blockBuilder = new BlockBuilder(" ") + and: + builder.appendTo(blockBuilder) + String test = blockBuilder.toString() + when: + SyntaxChecker.tryToCompile(methodBuilderName, test) + then: + requestAssertion(test) + responseAssertion(test) + where: + methodBuilderName | methodBuilder | requestAssertion | responseAssertion + HttpSpockMethodRequestProcessingBodyBuilder.simpleName | { Contract dsl -> new HttpSpockMethodRequestProcessingBodyBuilder(dsl, properties) } | { String body -> body.contains("body('''12000''')") } | { String body -> body.contains('responseBody == "12000"') } + MockMvcJUnitMethodBodyBuilder.simpleName | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl, properties) } | { String body -> body.contains('body("12000")') } | { String body -> body.contains('assertThat(responseBody).isEqualTo("12000");') } + JaxRsClientSpockMethodRequestProcessingBodyBuilder.simpleName | { Contract dsl -> new JaxRsClientSpockMethodRequestProcessingBodyBuilder(dsl, properties) } | { String body -> body.contains(""".method('GET', entity('12000', 'text/plain'))""") } | { String body -> body.contains('responseBody == "12000"') } + JaxRsClientJUnitMethodBodyBuilder.simpleName | { Contract dsl -> new JaxRsClientJUnitMethodBodyBuilder(dsl, properties) } | { String body -> body.contains(""".method("GET", entity("12000", "text/plain"))""") } | { String body -> body.contains('assertThat(responseBody).isEqualTo("12000")') } + WebTestClientJUnitMethodBodyBuilder.simpleName | { Contract dsl -> new WebTestClientJUnitMethodBodyBuilder(dsl, properties) } | { String body -> body.contains('body("12000")') } | { String body -> body.contains('assertThat(responseBody).isEqualTo("12000");') } + } } diff --git a/spring-cloud-contract-verifier/src/test/groovy/org/springframework/cloud/contract/verifier/util/SyntaxChecker.groovy b/spring-cloud-contract-verifier/src/test/groovy/org/springframework/cloud/contract/verifier/util/SyntaxChecker.groovy index e6cb43bcf6..600077e7f5 100644 --- a/spring-cloud-contract-verifier/src/test/groovy/org/springframework/cloud/contract/verifier/util/SyntaxChecker.groovy +++ b/spring-cloud-contract-verifier/src/test/groovy/org/springframework/cloud/contract/verifier/util/SyntaxChecker.groovy @@ -1,17 +1,14 @@ package org.springframework.cloud.contract.verifier.util -import java.lang.reflect.Method -import javax.inject.Inject -import javax.ws.rs.client.Entity -import javax.ws.rs.client.WebTarget -import javax.ws.rs.core.Response - import com.jayway.jsonpath.DocumentContext import com.jayway.jsonpath.JsonPath import com.toomuchcoding.jsonassert.JsonAssertion import groovy.transform.CompileStatic import io.restassured.RestAssured import io.restassured.module.mockmvc.RestAssuredMockMvc +import io.restassured.module.webtestclient.RestAssuredWebTestClient +import io.restassured.module.webtestclient.response.WebTestClientResponse +import io.restassured.module.webtestclient.specification.WebTestClientRequestSpecification import io.restassured.response.ResponseOptions import org.codehaus.groovy.control.CompilerConfiguration import org.codehaus.groovy.control.customizers.ASTTransformationCustomizer @@ -19,7 +16,6 @@ import org.codehaus.groovy.control.customizers.ImportCustomizer import org.junit.Rule import org.junit.Test import org.mdkt.compiler.InMemoryJavaCompiler - import org.springframework.cloud.contract.spec.Contract import org.springframework.cloud.contract.verifier.assertion.SpringCloudContractAssertions import org.springframework.cloud.contract.verifier.messaging.internal.ContractVerifierMessage @@ -28,6 +24,12 @@ import org.springframework.cloud.contract.verifier.messaging.internal.ContractVe import org.springframework.cloud.contract.verifier.messaging.util.ContractVerifierMessagingUtil import org.springframework.util.ReflectionUtils +import javax.inject.Inject +import javax.ws.rs.client.Entity +import javax.ws.rs.client.WebTarget +import javax.ws.rs.core.Response +import java.lang.reflect.Method + /** * checking the syntax of produced scripts */ @@ -40,8 +42,8 @@ class SyntaxChecker { private static final String[] DEFAULT_IMPORTS = [ Contract.name, ResponseOptions.name, - "io.restassured.module.mockmvc.specification.*", - "io.restassured.module.mockmvc.*", + 'io.restassured.module.mockmvc.specification.*', + 'io.restassured.module.mockmvc.*', Test.name, Rule.name, DocumentContext.name, @@ -51,7 +53,9 @@ class SyntaxChecker { ContractVerifierMessage.name, ContractVerifierMessaging.name, WebTarget.name, - Response.name + Response.name, + WebTestClientRequestSpecification.name, + WebTestClientResponse.name ] private static final String DEFAULT_IMPORTS_AS_STRING = DEFAULT_IMPORTS.collect { @@ -68,20 +72,28 @@ class SyntaxChecker { "${SpringCloudContractAssertions.name}.assertThat" ].collect { "import static ${it};"}.join("\n") + private static final String WEB_TEST_CLIENT_STATIC_IMPORTS = [ + "${RestAssuredWebTestClient.name}.*", + "${Entity.name}.*", + "${ContractVerifierMessagingUtil.name}.headers", + "${JsonAssertion.name}.assertThatJson", + "${SpringCloudContractAssertions.name}.assertThat" + ].collect { "import static ${it};" }.join("\n") + static void tryToCompile(String builderName, String test) { if (builderName.toLowerCase().contains("spock")) { - tryToCompileGroovy(test) + tryToCompileGroovy(builderName, test) } else { - tryToCompileJava(test) + tryToCompileJava(builderName, test) } } static void tryToRun(String builderName, String test) { if (builderName.toLowerCase().contains("spock")) { - Script script = tryToCompileGroovy(test) + Script script = tryToCompileGroovy(builderName, test) script.run() } else { - Class clazz = tryToCompileJava(test) + Class clazz = tryToCompileJava(builderName, test) Method method = ReflectionUtils.findMethod(clazz, "method") method.invoke(clazz.newInstance()) } @@ -90,13 +102,13 @@ class SyntaxChecker { // no static compilation due to bug in Groovy https://issues.apache.org/jira/browse/GROOVY-8055 static void tryToCompileWithoutCompileStatic(String builderName, String test) { if (builderName.toLowerCase().contains("spock")) { - tryToCompileGroovy(test, false) + tryToCompileGroovy(builderName, test, false) } else { - tryToCompileJava(test) + tryToCompileJava(builderName, test) } } - static Script tryToCompileGroovy(String test, boolean compileStatic = true) { + static Script tryToCompileGroovy(String builderName, String test, boolean compileStatic = true) { def imports = new ImportCustomizer() CompilerConfiguration configuration = new CompilerConfiguration() if (compileStatic) { @@ -106,7 +118,7 @@ class SyntaxChecker { configuration.addCompilationCustomizers(imports) StringBuilder sourceCode = new StringBuilder() sourceCode.append("${DEFAULT_IMPORTS_AS_STRING}\n") - sourceCode.append("${STATIC_IMPORTS}\n") + sourceCode.append(getStaticImports(builderName)) sourceCode.append("\n") sourceCode.append("WebTarget webTarget") sourceCode.append("\n") @@ -114,7 +126,14 @@ class SyntaxChecker { return new GroovyShell(SyntaxChecker.classLoader, configuration).parse(sourceCode.toString()) } - static Class tryToCompileJava(String test) { + private static GString getStaticImports(String builderName) { + if (builderName.toLowerCase().contains('webtestclient')) { + return "$WEB_TEST_CLIENT_STATIC_IMPORTS\n" + } + return "$STATIC_IMPORTS\n" + } + + static Class tryToCompileJava(String builderName, String test) { Random random = new Random() int first = Math.abs(random.nextInt()) int hashCode = Math.abs(test.hashCode()) @@ -123,7 +142,7 @@ class SyntaxChecker { String fqnClassName = "com.example.${className}" sourceCode.append("package com.example;\n") sourceCode.append("${DEFAULT_IMPORTS_AS_STRING}\n") - sourceCode.append("${STATIC_IMPORTS}\n") + sourceCode.append(getStaticImports(builderName)) sourceCode.append("\n") sourceCode.append("public class ${className} {\n") sourceCode.append("\n")