From 8bd931cb4f6632f1f855e16348123134ba6e0a2e Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Wed, 29 Aug 2018 15:50:24 +0200 Subject: [PATCH 1/7] Added compatibility with WireMock helpers (cherry picked from commit 9fe36dc7479589310aa45ddbf6fce31bfaca122d) --- .../HandlebarsJsonPathHelper.groovy | 43 +++++++++++++++---- .../HandlebarsTemplateProcessor.groovy | 7 +++ 2 files changed, 41 insertions(+), 9 deletions(-) diff --git a/spring-cloud-contract-verifier/src/main/groovy/org/springframework/cloud/contract/verifier/builder/handlebars/HandlebarsJsonPathHelper.groovy b/spring-cloud-contract-verifier/src/main/groovy/org/springframework/cloud/contract/verifier/builder/handlebars/HandlebarsJsonPathHelper.groovy index 35ac89d92e..dffc6c9f72 100644 --- a/spring-cloud-contract-verifier/src/main/groovy/org/springframework/cloud/contract/verifier/builder/handlebars/HandlebarsJsonPathHelper.groovy +++ b/spring-cloud-contract-verifier/src/main/groovy/org/springframework/cloud/contract/verifier/builder/handlebars/HandlebarsJsonPathHelper.groovy @@ -1,5 +1,6 @@ package org.springframework.cloud.contract.verifier.builder.handlebars +import com.github.tomakehurst.wiremock.extension.responsetemplating.helpers.WireMockHelpers import wiremock.com.github.jknack.handlebars.Helper import wiremock.com.github.jknack.handlebars.Options import com.github.tomakehurst.wiremock.extension.responsetemplating.RequestTemplateModel @@ -22,14 +23,34 @@ class HandlebarsJsonPathHelper implements Helper> { @Override Object apply(Map context, Options options) throws IOException { - String jsonPath = options.param(0) - Object model = context.get(REQUEST_MODEL_NAME) - if (model instanceof TestSideRequestTemplateModel) { - return returnObjectForTest(model, jsonPath) - } else if (model instanceof RequestTemplateModel) { - return returnObjectForStub(model, jsonPath) + if (context instanceof Map) { + // legacy + Map oldContext = (Map) context + String jsonPath = options.param(0) + Object model = oldContext.get(REQUEST_MODEL_NAME) + if (model instanceof TestSideRequestTemplateModel) { + return returnObjectForTest(model, jsonPath) + } else if (model instanceof RequestTemplateModel) { + return returnObjectForStub(model, jsonPath) + } + throw new IllegalArgumentException("Unsupported model") + } else if (context instanceof String) { + Object value = WireMockHelpers.jsonPath.apply(context, options) + if (testSideModel(options)) { + return processTestResponseValue(value) + } + return value } - throw new IllegalArgumentException("Unsupported model") + throw new IllegalArgumentException("Unsupported context") + } + + private boolean testSideModel(Options options) { + Object model = options.context.model() + if (!(model instanceof Map)) { + return false + } + Map map = (Map) model + return map.values().any { it instanceof TestSideRequestTemplateModel } } private Object returnObjectForStub(Object model, String jsonPath) { @@ -37,10 +58,14 @@ class HandlebarsJsonPathHelper implements Helper> { return documentContext.read(jsonPath) } - private Object returnObjectForTest(Object model, String jsonPath) { - String body = removeSurroundingQuotes(((TestSideRequestTemplateModel) model).rawBody).replace('\\"', '"') + private Object returnObjectForTest(TestSideRequestTemplateModel model, String jsonPath) { + String body = removeSurroundingQuotes(model.rawBody).replace('\\"', '"') DocumentContext documentContext = JsonPath.parse(body) Object value = documentContext.read(jsonPath) + return processTestResponseValue(value) + } + + private Object processTestResponseValue(Object value) { if (value instanceof Long) { return String.valueOf(value) + "L" } diff --git a/spring-cloud-contract-verifier/src/main/groovy/org/springframework/cloud/contract/verifier/template/HandlebarsTemplateProcessor.groovy b/spring-cloud-contract-verifier/src/main/groovy/org/springframework/cloud/contract/verifier/template/HandlebarsTemplateProcessor.groovy index fa9c5d575a..a2f4b4b533 100644 --- a/spring-cloud-contract-verifier/src/main/groovy/org/springframework/cloud/contract/verifier/template/HandlebarsTemplateProcessor.groovy +++ b/spring-cloud-contract-verifier/src/main/groovy/org/springframework/cloud/contract/verifier/template/HandlebarsTemplateProcessor.groovy @@ -1,5 +1,6 @@ package org.springframework.cloud.contract.verifier.template +import com.github.tomakehurst.wiremock.extension.responsetemplating.helpers.WireMockHelpers import wiremock.com.github.jknack.handlebars.Handlebars import wiremock.com.github.jknack.handlebars.Template import groovy.transform.CompileStatic @@ -71,6 +72,12 @@ class HandlebarsTemplateProcessor implements TemplateProcessor, ContractTemplate try { Handlebars handlebars = new Handlebars() handlebars.registerHelper(HandlebarsJsonPathHelper.NAME, new HandlebarsJsonPathHelper()) + handlebars.registerHelper(WireMockHelpers.jsonPath.name(), new HandlebarsJsonPathHelper()) + WireMockHelpers.values() + .findAll { it != WireMockHelpers.jsonPath} + .each { WireMockHelpers helper -> + handlebars.registerHelper(helper.name(), helper) + } return handlebars.compileInline(content) } catch (IOException e) { throw new RuntimeException(e) From d22b94ab8375ad1cc1c6728475749483bab16584 Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Wed, 29 Aug 2018 16:19:41 +0200 Subject: [PATCH 2/7] Fixed broken compilation --- .../builder/handlebars/HandlebarsJsonPathHelper.groovy | 3 ++- .../verifier/template/HandlebarsTemplateProcessor.groovy | 9 +++++---- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/spring-cloud-contract-verifier/src/main/groovy/org/springframework/cloud/contract/verifier/builder/handlebars/HandlebarsJsonPathHelper.groovy b/spring-cloud-contract-verifier/src/main/groovy/org/springframework/cloud/contract/verifier/builder/handlebars/HandlebarsJsonPathHelper.groovy index dffc6c9f72..a8d4d0d9ec 100644 --- a/spring-cloud-contract-verifier/src/main/groovy/org/springframework/cloud/contract/verifier/builder/handlebars/HandlebarsJsonPathHelper.groovy +++ b/spring-cloud-contract-verifier/src/main/groovy/org/springframework/cloud/contract/verifier/builder/handlebars/HandlebarsJsonPathHelper.groovy @@ -1,6 +1,7 @@ package org.springframework.cloud.contract.verifier.builder.handlebars import com.github.tomakehurst.wiremock.extension.responsetemplating.helpers.WireMockHelpers +import com.github.tomakehurst.wiremock.extension.responsetemplating.helpers.WiremockHelpers import wiremock.com.github.jknack.handlebars.Helper import wiremock.com.github.jknack.handlebars.Options import com.github.tomakehurst.wiremock.extension.responsetemplating.RequestTemplateModel @@ -35,7 +36,7 @@ class HandlebarsJsonPathHelper implements Helper> { } throw new IllegalArgumentException("Unsupported model") } else if (context instanceof String) { - Object value = WireMockHelpers.jsonPath.apply(context, options) + Object value = WiremockHelpers.jsonPath.apply(context, options) if (testSideModel(options)) { return processTestResponseValue(value) } diff --git a/spring-cloud-contract-verifier/src/main/groovy/org/springframework/cloud/contract/verifier/template/HandlebarsTemplateProcessor.groovy b/spring-cloud-contract-verifier/src/main/groovy/org/springframework/cloud/contract/verifier/template/HandlebarsTemplateProcessor.groovy index a2f4b4b533..dc7b1ae022 100644 --- a/spring-cloud-contract-verifier/src/main/groovy/org/springframework/cloud/contract/verifier/template/HandlebarsTemplateProcessor.groovy +++ b/spring-cloud-contract-verifier/src/main/groovy/org/springframework/cloud/contract/verifier/template/HandlebarsTemplateProcessor.groovy @@ -1,6 +1,7 @@ package org.springframework.cloud.contract.verifier.template import com.github.tomakehurst.wiremock.extension.responsetemplating.helpers.WireMockHelpers +import com.github.tomakehurst.wiremock.extension.responsetemplating.helpers.WiremockHelpers import wiremock.com.github.jknack.handlebars.Handlebars import wiremock.com.github.jknack.handlebars.Template import groovy.transform.CompileStatic @@ -72,10 +73,10 @@ class HandlebarsTemplateProcessor implements TemplateProcessor, ContractTemplate try { Handlebars handlebars = new Handlebars() handlebars.registerHelper(HandlebarsJsonPathHelper.NAME, new HandlebarsJsonPathHelper()) - handlebars.registerHelper(WireMockHelpers.jsonPath.name(), new HandlebarsJsonPathHelper()) - WireMockHelpers.values() - .findAll { it != WireMockHelpers.jsonPath} - .each { WireMockHelpers helper -> + handlebars.registerHelper(WiremockHelpers.jsonPath.name(), new HandlebarsJsonPathHelper()) + WiremockHelpers.values() + .findAll { it != WiremockHelpers.jsonPath} + .each { WiremockHelpers helper -> handlebars.registerHelper(helper.name(), helper) } return handlebars.compileInline(content) From 83e700cc97260a159f1e762d635e8df1ad127aaa Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Wed, 29 Aug 2018 16:22:15 +0200 Subject: [PATCH 3/7] Fixed broken compilation --- .../verifier/template/HandlebarsTemplateProcessor.groovy | 1 - 1 file changed, 1 deletion(-) diff --git a/spring-cloud-contract-verifier/src/main/groovy/org/springframework/cloud/contract/verifier/template/HandlebarsTemplateProcessor.groovy b/spring-cloud-contract-verifier/src/main/groovy/org/springframework/cloud/contract/verifier/template/HandlebarsTemplateProcessor.groovy index dc7b1ae022..fd0b5b4c0d 100644 --- a/spring-cloud-contract-verifier/src/main/groovy/org/springframework/cloud/contract/verifier/template/HandlebarsTemplateProcessor.groovy +++ b/spring-cloud-contract-verifier/src/main/groovy/org/springframework/cloud/contract/verifier/template/HandlebarsTemplateProcessor.groovy @@ -1,6 +1,5 @@ package org.springframework.cloud.contract.verifier.template -import com.github.tomakehurst.wiremock.extension.responsetemplating.helpers.WireMockHelpers import com.github.tomakehurst.wiremock.extension.responsetemplating.helpers.WiremockHelpers import wiremock.com.github.jknack.handlebars.Handlebars import wiremock.com.github.jknack.handlebars.Template From 14498889f674747df0275fabf99517e0a6ee29ec Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Wed, 29 Aug 2018 16:23:56 +0200 Subject: [PATCH 4/7] Fixed broken compilation --- .../verifier/builder/handlebars/HandlebarsJsonPathHelper.groovy | 1 - 1 file changed, 1 deletion(-) diff --git a/spring-cloud-contract-verifier/src/main/groovy/org/springframework/cloud/contract/verifier/builder/handlebars/HandlebarsJsonPathHelper.groovy b/spring-cloud-contract-verifier/src/main/groovy/org/springframework/cloud/contract/verifier/builder/handlebars/HandlebarsJsonPathHelper.groovy index a8d4d0d9ec..de2cbd4159 100644 --- a/spring-cloud-contract-verifier/src/main/groovy/org/springframework/cloud/contract/verifier/builder/handlebars/HandlebarsJsonPathHelper.groovy +++ b/spring-cloud-contract-verifier/src/main/groovy/org/springframework/cloud/contract/verifier/builder/handlebars/HandlebarsJsonPathHelper.groovy @@ -1,6 +1,5 @@ package org.springframework.cloud.contract.verifier.builder.handlebars -import com.github.tomakehurst.wiremock.extension.responsetemplating.helpers.WireMockHelpers import com.github.tomakehurst.wiremock.extension.responsetemplating.helpers.WiremockHelpers import wiremock.com.github.jknack.handlebars.Helper import wiremock.com.github.jknack.handlebars.Options From 3befda64f457d4aa226fb70a141da109de3ea622 Mon Sep 17 00:00:00 2001 From: Olga Maciaszek-Sharma Date: Wed, 12 Sep 2018 14:12:56 +0200 Subject: [PATCH 5/7] Revert 077e18aa259e9ac0999d4435c056a3fca56a127f. (cherry picked from commit 67170ae0de8b7471a1be277e62d0efcaa7d81f12) --- .../JUnitMessagingMethodBodyBuilder.groovy | 2 +- .../JaxRsClientJUnitMethodBodyBuilder.groovy | 2 +- ...kMethodRequestProcessingBodyBuilder.groovy | 2 +- ...kMethodRequestProcessingBodyBuilder.groovy | 2 +- .../RestAssuredJUnitMethodBodyBuilder.groovy | 2 +- .../SpockMessagingMethodBodyBuilder.groovy | 2 +- .../MessagingMethodBodyBuilderSpec.groovy | 36 -- .../MockMvcMethodBodyBuilderSpec.groovy | 391 +++++++++++++----- 8 files changed, 288 insertions(+), 151 deletions(-) diff --git a/spring-cloud-contract-verifier/src/main/groovy/org/springframework/cloud/contract/verifier/builder/JUnitMessagingMethodBodyBuilder.groovy b/spring-cloud-contract-verifier/src/main/groovy/org/springframework/cloud/contract/verifier/builder/JUnitMessagingMethodBodyBuilder.groovy index f0a7687e8a..902aa99911 100644 --- a/spring-cloud-contract-verifier/src/main/groovy/org/springframework/cloud/contract/verifier/builder/JUnitMessagingMethodBodyBuilder.groovy +++ b/spring-cloud-contract-verifier/src/main/groovy/org/springframework/cloud/contract/verifier/builder/JUnitMessagingMethodBodyBuilder.groovy @@ -112,7 +112,7 @@ class JUnitMessagingMethodBodyBuilder extends MessagingMethodBodyBuilder { @Override protected void processHeaderElement(BlockBuilder blockBuilder, String property, ExecutionProperty exec) { blockBuilder.addLine("assertThat(response.getHeader(\"$property\")).isNotNull();") - blockBuilder.addLine("assertThat(response.getHeader(\"$property\")).isEqualTo(${exec.insertValue("response.getHeader(\"$property\").toString()")});") + blockBuilder.addLine("${exec.insertValue("response.getHeader(\"$property\").toString()")};") } @Override diff --git a/spring-cloud-contract-verifier/src/main/groovy/org/springframework/cloud/contract/verifier/builder/JaxRsClientJUnitMethodBodyBuilder.groovy b/spring-cloud-contract-verifier/src/main/groovy/org/springframework/cloud/contract/verifier/builder/JaxRsClientJUnitMethodBodyBuilder.groovy index 8d7613466e..47bd2eda22 100644 --- a/spring-cloud-contract-verifier/src/main/groovy/org/springframework/cloud/contract/verifier/builder/JaxRsClientJUnitMethodBodyBuilder.groovy +++ b/spring-cloud-contract-verifier/src/main/groovy/org/springframework/cloud/contract/verifier/builder/JaxRsClientJUnitMethodBodyBuilder.groovy @@ -203,7 +203,7 @@ class JaxRsClientJUnitMethodBodyBuilder extends JUnitMethodBodyBuilder { @Override protected void processHeaderElement(BlockBuilder blockBuilder, String property, ExecutionProperty exec) { - blockBuilder.addLine("assertThat(response.getHeaderString(\"$property\")).isEqualTo(${exec.insertValue("response.getHeaderString(\"$property\")")});") + blockBuilder.addLine("${exec.insertValue("response.getHeaderString(\"$property\")")};") } @Override diff --git a/spring-cloud-contract-verifier/src/main/groovy/org/springframework/cloud/contract/verifier/builder/JaxRsClientSpockMethodRequestProcessingBodyBuilder.groovy b/spring-cloud-contract-verifier/src/main/groovy/org/springframework/cloud/contract/verifier/builder/JaxRsClientSpockMethodRequestProcessingBodyBuilder.groovy index 7cc5a5b710..a6e7327a20 100644 --- a/spring-cloud-contract-verifier/src/main/groovy/org/springframework/cloud/contract/verifier/builder/JaxRsClientSpockMethodRequestProcessingBodyBuilder.groovy +++ b/spring-cloud-contract-verifier/src/main/groovy/org/springframework/cloud/contract/verifier/builder/JaxRsClientSpockMethodRequestProcessingBodyBuilder.groovy @@ -184,7 +184,7 @@ class JaxRsClientSpockMethodRequestProcessingBodyBuilder extends SpockMethodRequ @Override protected void processHeaderElement(BlockBuilder blockBuilder, String property, ExecutionProperty exec) { - blockBuilder.addLine("response.getHeaderString(\'$property\') == ${exec.insertValue("response.getHeaderString(\'$property\')")}") + blockBuilder.addLine("${exec.insertValue("response.getHeaderString(\'$property\')")}") } @Override 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/MockMvcSpockMethodRequestProcessingBodyBuilder.groovy index 37807b3a13..45f475d49e 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/MockMvcSpockMethodRequestProcessingBodyBuilder.groovy @@ -96,7 +96,7 @@ class MockMvcSpockMethodRequestProcessingBodyBuilder extends SpockMethodRequestP @Override protected void processHeaderElement(BlockBuilder blockBuilder, String property, ExecutionProperty exec) { - blockBuilder.addLine("response.header(\'$property\') == ${exec.insertValue("response.header(\'$property\')")}") + blockBuilder.addLine("${exec.insertValue("response.header(\'$property\')")}") } @Override diff --git a/spring-cloud-contract-verifier/src/main/groovy/org/springframework/cloud/contract/verifier/builder/RestAssuredJUnitMethodBodyBuilder.groovy b/spring-cloud-contract-verifier/src/main/groovy/org/springframework/cloud/contract/verifier/builder/RestAssuredJUnitMethodBodyBuilder.groovy index fdfabf0c72..51294f1160 100644 --- a/spring-cloud-contract-verifier/src/main/groovy/org/springframework/cloud/contract/verifier/builder/RestAssuredJUnitMethodBodyBuilder.groovy +++ b/spring-cloud-contract-verifier/src/main/groovy/org/springframework/cloud/contract/verifier/builder/RestAssuredJUnitMethodBodyBuilder.groovy @@ -103,7 +103,7 @@ class RestAssuredJUnitMethodBodyBuilder extends JUnitMethodBodyBuilder { @Override protected void processHeaderElement(BlockBuilder blockBuilder, String property, ExecutionProperty exec) { - blockBuilder.addLine("assertThat(response.header(\"$property\")).isEqualTo(${exec.insertValue("response.header(\"$property\")")});") + blockBuilder.addLine("${exec.insertValue("response.header(\"$property\")")};") } @Override diff --git a/spring-cloud-contract-verifier/src/main/groovy/org/springframework/cloud/contract/verifier/builder/SpockMessagingMethodBodyBuilder.groovy b/spring-cloud-contract-verifier/src/main/groovy/org/springframework/cloud/contract/verifier/builder/SpockMessagingMethodBodyBuilder.groovy index 81bbcfc49e..1c2777587d 100644 --- a/spring-cloud-contract-verifier/src/main/groovy/org/springframework/cloud/contract/verifier/builder/SpockMessagingMethodBodyBuilder.groovy +++ b/spring-cloud-contract-verifier/src/main/groovy/org/springframework/cloud/contract/verifier/builder/SpockMessagingMethodBodyBuilder.groovy @@ -80,7 +80,7 @@ class SpockMessagingMethodBodyBuilder extends MessagingMethodBodyBuilder { @Override protected void processHeaderElement(BlockBuilder blockBuilder, String property, ExecutionProperty exec) { - blockBuilder.addLine("response.getHeader('$property') == ${exec.insertValue("response.getHeader(\'$property\')?.toString()")}") + blockBuilder.addLine("${exec.insertValue("response.getHeader(\'$property\')?.toString()")}") } @Override diff --git a/spring-cloud-contract-verifier/src/test/groovy/org/springframework/cloud/contract/verifier/builder/MessagingMethodBodyBuilderSpec.groovy b/spring-cloud-contract-verifier/src/test/groovy/org/springframework/cloud/contract/verifier/builder/MessagingMethodBodyBuilderSpec.groovy index edcc5a411c..f1b158bfe0 100644 --- a/spring-cloud-contract-verifier/src/test/groovy/org/springframework/cloud/contract/verifier/builder/MessagingMethodBodyBuilderSpec.groovy +++ b/spring-cloud-contract-verifier/src/test/groovy/org/springframework/cloud/contract/verifier/builder/MessagingMethodBodyBuilderSpec.groovy @@ -853,40 +853,4 @@ Contract.make { ''' } - @Issue("#628") - def "should execute method in response header [#methodBuilderName]"() { - given: - Contract contractDsl = Contract.make { - label 'shouldPublishMessage' - // input to the contract - input { - // the contract will be triggered by a method - triggeredBy('foo()') - } - // output message of the contract - outputMessage { - // destination to which the output message will be sent - sentTo('messageExchange') - // the body of the output message - body([ - "field": "value" - ]) - headers { - header 'My-UUID': value(test(execute('property("my-uuid")')), stub('76c53386-ad9b-11e6-92dc-0370ae47c3b2')) - } - } - } - MethodBodyBuilder builder = methodBuilder(contractDsl) - BlockBuilder blockBuilder = new BlockBuilder(" ") - when: - builder.appendTo(blockBuilder) - String test = blockBuilder.toString() - then: - responseAssertion(test) - where: - methodBuilderName | methodBuilder | responseAssertion - "SpockMessagingMethodBodyBuilder" | { Contract dsl -> new SpockMessagingMethodBodyBuilder(dsl, properties) } | { String body -> body.contains("response.getHeader('My-UUID') == property(\"my-uuid\")") } - "JUnitMessagingMethodBodyBuilder" | { Contract dsl -> new JUnitMessagingMethodBodyBuilder(dsl, properties) } | { String body -> body.contains('assertThat(response.getHeader("My-UUID")).isEqualTo(property("my-uuid"));') } - } - } 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 index 4a61e3c4bf..79a558a0a2 100644 --- 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 @@ -1,5 +1,5 @@ /* - * Copyright 2013-2017 the original author or authors. + * 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. @@ -16,21 +16,23 @@ package org.springframework.cloud.contract.verifier.builder +import java.util.regex.Pattern + 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 +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 { @@ -177,7 +179,7 @@ class MockMvcMethodBodyBuilderSpec extends Specification implements WireMockStub url "test" } response { - status 200 + status OK() body """{ "property1": "a", "property2": "b" @@ -210,7 +212,7 @@ class MockMvcMethodBodyBuilderSpec extends Specification implements WireMockStub url "test" } response { - status 200 + status OK() body """{ "property1": "true", "property2": null, @@ -245,7 +247,7 @@ class MockMvcMethodBodyBuilderSpec extends Specification implements WireMockStub url "test" } response { - status 200 + status OK() body( property1: 'a', property2: [ @@ -284,7 +286,7 @@ class MockMvcMethodBodyBuilderSpec extends Specification implements WireMockStub url "test" } response { - status 200 + status OK() body( property1: 'a', property2: [ @@ -325,7 +327,7 @@ class MockMvcMethodBodyBuilderSpec extends Specification implements WireMockStub ) } response { - status 200 + status OK() } } MethodBodyBuilder builder = methodBuilder(contractDsl) @@ -356,7 +358,7 @@ class MockMvcMethodBodyBuilderSpec extends Specification implements WireMockStub ) } response { - status 200 + status OK() } } MethodBodyBuilder builder = methodBuilder(contractDsl) @@ -384,7 +386,7 @@ class MockMvcMethodBodyBuilderSpec extends Specification implements WireMockStub url "test" } response { - status 200 + status OK() body( property: [ 14: 0.0, @@ -418,7 +420,7 @@ class MockMvcMethodBodyBuilderSpec extends Specification implements WireMockStub url "test" } response { - status 200 + status OK() body """[ { "property1": "a" @@ -445,7 +447,7 @@ class MockMvcMethodBodyBuilderSpec extends Specification implements WireMockStub "MockMvcJUnitMethodBuilder" | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl, properties) } } - def "should generate assertions for array inside response body element with #methodBuilderName"() { + def "should generate assertions for array inside response body element with #methodBuilderName"() { given: Contract contractDsl = Contract.make { request { @@ -453,7 +455,7 @@ class MockMvcMethodBodyBuilderSpec extends Specification implements WireMockStub url "test" } response { - status 200 + status OK() body """{ "property1": [ { "property2": "test1"}, @@ -487,7 +489,7 @@ class MockMvcMethodBodyBuilderSpec extends Specification implements WireMockStub url "test" } response { - status 200 + status OK() body '''\ { "property1": "a", @@ -521,7 +523,7 @@ class MockMvcMethodBodyBuilderSpec extends Specification implements WireMockStub url "test" } response { - status 200 + status OK() body( property1: "a", property2: value( @@ -559,7 +561,7 @@ class MockMvcMethodBodyBuilderSpec extends Specification implements WireMockStub url "test" } response { - status 200 + status OK() body("""{"property1":"a","property2":"${ value(consumer('123'), producer(regex('[0-9]{3}'))) }"}""") @@ -594,7 +596,7 @@ class MockMvcMethodBodyBuilderSpec extends Specification implements WireMockStub url "test" } response { - status 200 + status OK() body("""{"property":" ${ value(consumer('123'), producer(regex('\\d+'))) }"}""") @@ -640,7 +642,7 @@ class MockMvcMethodBodyBuilderSpec extends Specification implements WireMockStub } } response { - status 200 + status OK() body """ { "property1": "a", @@ -698,7 +700,7 @@ class MockMvcMethodBodyBuilderSpec extends Specification implements WireMockStub } } response { - status 200 + status OK() body """ { "property1": "a", @@ -771,7 +773,7 @@ class MockMvcMethodBodyBuilderSpec extends Specification implements WireMockStub url "test" } response { - status 200 + status OK() body "test" } } @@ -894,7 +896,7 @@ class MockMvcMethodBodyBuilderSpec extends Specification implements WireMockStub } response { - status 200 + status OK() body(errors: [ [property: "bank_account_number", message: "incorrect_format"] ]) @@ -1057,7 +1059,7 @@ class MockMvcMethodBodyBuilderSpec extends Specification implements WireMockStub } response { - status 200 + status OK() body("""{ "fraudCheckStatus": "OK", "rejectionReason": ${ @@ -1134,7 +1136,7 @@ class MockMvcMethodBodyBuilderSpec extends Specification implements WireMockStub ) } response { - status 200 + status OK() headers { contentType(applicationJson()) } @@ -1156,6 +1158,50 @@ class MockMvcMethodBodyBuilderSpec extends Specification implements WireMockStub "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"() { @@ -1177,7 +1223,7 @@ class MockMvcMethodBodyBuilderSpec extends Specification implements WireMockStub ) } response { - status 200 + status OK() headers { contentType(applicationJson()) } @@ -1209,7 +1255,7 @@ class MockMvcMethodBodyBuilderSpec extends Specification implements WireMockStub World.''') } response { - status 200 + status OK() } } MethodBodyBuilder builder = methodBuilder(contractDsl) @@ -1255,42 +1301,42 @@ World.'''""" ) } response { - status 200 + status OK() } } - // end::multipartdsl[] - MethodBodyBuilder builder = methodBuilder(contractDsl) - BlockBuilder blockBuilder = new BlockBuilder(" ") + // end::multipartdsl[] + MethodBodyBuilder builder = methodBuilder(contractDsl) + BlockBuilder blockBuilder = new BlockBuilder(" ") when: - builder.appendTo(blockBuilder) - def test = blockBuilder.toString() + builder.appendTo(blockBuilder) + def test = blockBuilder.toString() then: - for (String requestString : requestStrings) { - assert test.contains(requestString) - } + for (String requestString : requestStrings) { + assert test.contains(requestString) + } and: - SyntaxChecker.tryToCompile(methodBuilderName, blockBuilder.toString()) + 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");'] + 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') + 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 @@ -1306,7 +1352,7 @@ World.'''""" ) } response { - status 200 + status OK() } } MethodBodyBuilder builder = methodBuilder(contractDsl) @@ -1332,6 +1378,48 @@ World.'''""" '.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: @@ -1351,7 +1439,7 @@ World.'''""" ) } response { - status 200 + status OK() } } MethodBodyBuilder builder = methodBuilder(contractDsl) @@ -1401,7 +1489,7 @@ World.'''""" ) } response { - status 200 + status OK() } } MethodBodyBuilder builder = methodBuilder(contractDsl) @@ -1427,8 +1515,7 @@ World.'''""" method "GET" urlPath('/auth/oauth/check_token') { queryParameters { - parameter 'token': - value( + 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') ) @@ -1436,7 +1523,7 @@ World.'''""" } } response { - status 200 + status OK() body( authorities: [ value(consumer('ROLE_ADMIN'), producer(regex('^[a-zA-Z0-9_\\- ]+$'))) @@ -1463,8 +1550,7 @@ World.'''""" method "GET" urlPath('/auth/oauth/check_token') { queryParameters { - parameter 'token': - value( + 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') ) @@ -1472,7 +1558,7 @@ World.'''""" } } response { - status 200 + status OK() body( authorities: [ value(consumer('ROLE_ADMIN'), producer(regex('^[a-zA-Z0-9_\\- ]+$'))) @@ -1499,7 +1585,7 @@ World.'''""" url '/fraudcheck' } response { - status 200 + status OK() body( fraudCheckStatus: "OK", rejectionReason: $(consumer(null), producer(execute('assertThatRejectionReasonIsNull($it)'))) @@ -1530,7 +1616,7 @@ World.'''""" urlPath '/foos' } response { - status 200 + status OK() body([[id: value( consumer('123'), producer(regex('[0-9]+')) @@ -1563,7 +1649,7 @@ World.'''""" urlPath '/api/tags' } response { - status 200 + status OK() body(["Java", "Java8", "Spring", "SpringBoot", "Stream"]) headers { header('Content-Type': 'application/json;charset=UTF-8') @@ -1600,7 +1686,7 @@ World.'''""" urlPath '/api/tags' } response { - status 200 + status OK() body(["Java", "Java8", "Spring", "SpringBoot", "Stream"]) headers { header('Content-Type': 'application/json;charset=UTF-8') @@ -1636,7 +1722,7 @@ World.'''""" urlPath '/api/categories' } response { - status 200 + status OK() body([["Programming", "Java"], ["Programming", "Java", "Spring", "Boot"]]) headers { header('Content-Type': 'application/json;charset=UTF-8') @@ -1670,7 +1756,7 @@ World.'''""" url '/test' } response { - status 200 + status OK() async() } } @@ -1704,7 +1790,7 @@ World.'''""" } } response { - status 200 + status OK() async() } } @@ -1734,7 +1820,7 @@ World.'''""" urlPath '/api/tags' } response { - status 200 + status OK() body('''{ "partners":[ { @@ -1770,7 +1856,7 @@ World.'''""" urlPath '/get' } response { - status 200 + status OK() body( code: 9, message: $(consumer('Wrong credentials'), producer(regex('^(?!\\s*$).+'))) ) } } @@ -1826,7 +1912,7 @@ World.'''""" ''' } response { - status 200 + status OK() } } // end::dsl_example[] @@ -1845,7 +1931,7 @@ World.'''""" } } response { - status 200 + status OK() body([ responseElement: $(producer(regex('[0-9]{7}'))) ]) @@ -1886,7 +1972,7 @@ World.'''""" urlPath '/get' } response { - status 200 + status OK() body([ fraudCheckStatus: "OK", rejectionReason : [ @@ -1918,7 +2004,7 @@ World.'''""" urlPath '/get' } response { - status 200 + status OK() body([ [ name: $(consumer("userName 1"), producer(execute('assertThatUserNameIsNotNull($it)'))) @@ -1948,7 +2034,7 @@ World.'''""" urlPath '/get' } response { - status 200 + status OK() body([ [ name: $(consumer("userName 1"), producer(execute('assertThatUserNameIsNotNull($it)'))) @@ -1981,7 +2067,7 @@ World.'''""" } } response { - status 200 + status OK() body([ fraudCheckStatus: "OK", rejectionReason : [ @@ -2013,7 +2099,7 @@ World.'''""" url '/get' } response { - status 200 + status OK() body(value(stub("HELLO FROM STUB"), server(regex(".*")))) } } @@ -2037,7 +2123,7 @@ World.'''""" url '/get' } response { - status 200 + status OK() body(value(stub("HELLO FROM STUB"), server(execute('foo($it)')))) } } @@ -2067,7 +2153,7 @@ World.'''""" } } response { - status 200 + status OK() body([ fraudCheckStatus: "OK", rejectionReason : [ @@ -2101,11 +2187,15 @@ World.'''""" 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()), @@ -2120,15 +2210,19 @@ World.'''""" } } response { - status 200 + 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()), @@ -2152,10 +2246,14 @@ World.'''""" 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("[\'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("[\'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])') @@ -2170,7 +2268,7 @@ World.'''""" SyntaxChecker.tryToCompile(methodBuilderName, blockBuilder.toString()) and: String jsonSample = '''\ -String json = "{\\"duck\\":\\"8\\",\\"alpha\\":\\"YAJEOWYGMFBEWPMEMAZI\\",\\"number\\":-2095030871,\\"aBoolean\\":true,\\"ip\\":\\"129.168.99.100\\",\\"hostname\\":\\"http://foo389886219.com\\",\\"email\\":\\"foo@bar1367573183.com\\",\\"url\\":\\"http://foo-597104692.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\\"}"; +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: @@ -2196,7 +2294,7 @@ DocumentContext parsedJson = JsonPath.parse(json); } } response { - status 200 + status OK() headers { contentType("application/vnd.fraud.v1+json") } @@ -2296,7 +2394,7 @@ DocumentContext parsedJson = JsonPath.parse(json); url '/foo' } response { - status 200 + status OK() headers { contentType(applicationJsonUtf8()) } @@ -2335,7 +2433,7 @@ DocumentContext parsedJson = JsonPath.parse(json); headers { header('Content-Type', 'application/json;charset=UTF-8') } } response { - status 200 + status OK() body( bar: $(producer(regex('some value \u0022with quote\u0022|bar'))) ) @@ -2367,7 +2465,7 @@ DocumentContext parsedJson = JsonPath.parse(json); url $(c("foo"), p(execute("executedMethod()"))) } response { - status 200 + status OK() } } MethodBodyBuilder builder = methodBuilder(contractDsl) @@ -2401,7 +2499,7 @@ DocumentContext parsedJson = JsonPath.parse(json); url '/api/v1/xxxx' } response { - status 200 + status OK() body([ status: '200', list: [], @@ -2437,7 +2535,7 @@ DocumentContext parsedJson = JsonPath.parse(json); body(12000) } response { - status 200 + status OK() body(12000) } } @@ -2479,7 +2577,7 @@ DocumentContext parsedJson = JsonPath.parse(json); body(foo: "bar", baz: 5) } response { - status 200 + status OK() headers { header(authorization(), "foo ${fromRequest().header(authorization())} bar") } @@ -2494,7 +2592,17 @@ DocumentContext parsedJson = JsonPath.parse(json); fullBody: fromRequest().body(), responseFoo: fromRequest().body('$.foo'), responseBaz: fromRequest().body('$.baz'), - responseBaz2: "Bla bla ${fromRequest().body('$.foo')} bla bla" + 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" ) } } @@ -2508,6 +2616,7 @@ DocumentContext parsedJson = JsonPath.parse(json); 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")''') @@ -2519,6 +2628,16 @@ DocumentContext parsedJson = JsonPath.parse(json); 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 @@ -2528,6 +2647,60 @@ DocumentContext parsedJson = JsonPath.parse(json); "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) @@ -2614,37 +2787,37 @@ DocumentContext parsedJson = JsonPath.parse(json); SyntaxChecker.tryToCompile("MockMvcSpockMethodRequestProcessingBodyBuilder", blockBuilder.toString()) } - @Issue("#628") - def "should execute method in response header [#methodBuilderName]"() { + @Issue('#554') + def "should create an assertion for an empty map or Object for [#methodBuilderName]"() { given: Contract contractDsl = Contract.make { request { method 'GET' - urlPath '/whatever' - headers { - header 'My-UUID': value(test(execute('property("my-uuid")')), stub('76c53386-ad9b-11e6-92dc-0370ae47c3b2')) - } + url '/api/v1/xxxx' } response { status 200 - headers { - header 'My-UUID': value(test(execute('property("my-uuid")')), stub('76c53386-ad9b-11e6-92dc-0370ae47c3b2')) - } + body([ + aMap : ["foo": "bar"], + anEmptyMap: [:] + ]) } } MethodBodyBuilder builder = methodBuilder(contractDsl) BlockBuilder blockBuilder = new BlockBuilder(" ") - when: + and: builder.appendTo(blockBuilder) String test = blockBuilder.toString() + when: + SyntaxChecker.tryToRun(methodBuilderName, test.join("\n")) then: - responseAssertion(test) + test.contains('''assertThatJson(parsedJson).field("['aMap']").field("['foo']").isEqualTo("bar")''') + test.contains('''assertThatJson(parsedJson).field("['anEmptyMap']").isEmpty()''') where: - methodBuilderName | methodBuilder | responseAssertion - "MockMvcSpockMethodBuilder" | { Contract dsl -> new MockMvcSpockMethodRequestProcessingBodyBuilder(dsl, properties) } | { String body -> body.contains("response.header('My-UUID') == property(\"my-uuid\")") } - "MockMvcJUnitMethodBuilder" | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl, properties) } | { String body -> body.contains('assertThat(response.header("My-UUID")).isEqualTo(property("my-uuid"));') } - "JaxRsClientSpockMethodRequestProcessingBodyBuilder" | { Contract dsl -> new JaxRsClientSpockMethodRequestProcessingBodyBuilder(dsl, properties) } | { String body -> body.contains("response.getHeaderString('My-UUID') == property(\"my-uuid\")") } - "JaxRsClientJUnitMethodBodyBuilder" | { Contract dsl -> new JaxRsClientJUnitMethodBodyBuilder(dsl, properties) } | { String body -> body.contains('assertThat(response.getHeaderString("My-UUID")).isEqualTo(property("my-uuid"));') } + 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) } } - } From 35719ae2befdd072180020c2e5b230d8ea9badf7 Mon Sep 17 00:00:00 2001 From: Olga Maciaszek-Sharma Date: Wed, 12 Sep 2018 14:13:39 +0200 Subject: [PATCH 6/7] Revert 077e18aa259e9ac0999d4435c056a3fca56a127f. --- .../MockMvcMethodBodyBuilderSpec.groovy | 291 ++++-------------- 1 file changed, 60 insertions(+), 231 deletions(-) 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 index 79a558a0a2..b67850555b 100644 --- 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 @@ -179,7 +179,7 @@ class MockMvcMethodBodyBuilderSpec extends Specification implements WireMockStub url "test" } response { - status OK() + status 200 body """{ "property1": "a", "property2": "b" @@ -212,7 +212,7 @@ class MockMvcMethodBodyBuilderSpec extends Specification implements WireMockStub url "test" } response { - status OK() + status 200 body """{ "property1": "true", "property2": null, @@ -247,7 +247,7 @@ class MockMvcMethodBodyBuilderSpec extends Specification implements WireMockStub url "test" } response { - status OK() + status 200 body( property1: 'a', property2: [ @@ -286,7 +286,7 @@ class MockMvcMethodBodyBuilderSpec extends Specification implements WireMockStub url "test" } response { - status OK() + status 200 body( property1: 'a', property2: [ @@ -327,7 +327,7 @@ class MockMvcMethodBodyBuilderSpec extends Specification implements WireMockStub ) } response { - status OK() + status 200 } } MethodBodyBuilder builder = methodBuilder(contractDsl) @@ -358,7 +358,7 @@ class MockMvcMethodBodyBuilderSpec extends Specification implements WireMockStub ) } response { - status OK() + status 200 } } MethodBodyBuilder builder = methodBuilder(contractDsl) @@ -386,7 +386,7 @@ class MockMvcMethodBodyBuilderSpec extends Specification implements WireMockStub url "test" } response { - status OK() + status 200 body( property: [ 14: 0.0, @@ -420,7 +420,7 @@ class MockMvcMethodBodyBuilderSpec extends Specification implements WireMockStub url "test" } response { - status OK() + status 200 body """[ { "property1": "a" @@ -455,7 +455,7 @@ class MockMvcMethodBodyBuilderSpec extends Specification implements WireMockStub url "test" } response { - status OK() + status 200 body """{ "property1": [ { "property2": "test1"}, @@ -489,7 +489,7 @@ class MockMvcMethodBodyBuilderSpec extends Specification implements WireMockStub url "test" } response { - status OK() + status 200 body '''\ { "property1": "a", @@ -523,7 +523,7 @@ class MockMvcMethodBodyBuilderSpec extends Specification implements WireMockStub url "test" } response { - status OK() + status 200 body( property1: "a", property2: value( @@ -561,7 +561,7 @@ class MockMvcMethodBodyBuilderSpec extends Specification implements WireMockStub url "test" } response { - status OK() + status 200 body("""{"property1":"a","property2":"${ value(consumer('123'), producer(regex('[0-9]{3}'))) }"}""") @@ -596,7 +596,7 @@ class MockMvcMethodBodyBuilderSpec extends Specification implements WireMockStub url "test" } response { - status OK() + status 200 body("""{"property":" ${ value(consumer('123'), producer(regex('\\d+'))) }"}""") @@ -642,7 +642,7 @@ class MockMvcMethodBodyBuilderSpec extends Specification implements WireMockStub } } response { - status OK() + status 200 body """ { "property1": "a", @@ -700,7 +700,7 @@ class MockMvcMethodBodyBuilderSpec extends Specification implements WireMockStub } } response { - status OK() + status 200 body """ { "property1": "a", @@ -773,7 +773,7 @@ class MockMvcMethodBodyBuilderSpec extends Specification implements WireMockStub url "test" } response { - status OK() + status 200 body "test" } } @@ -896,7 +896,7 @@ class MockMvcMethodBodyBuilderSpec extends Specification implements WireMockStub } response { - status OK() + status 200 body(errors: [ [property: "bank_account_number", message: "incorrect_format"] ]) @@ -1059,7 +1059,7 @@ class MockMvcMethodBodyBuilderSpec extends Specification implements WireMockStub } response { - status OK() + status 200 body("""{ "fraudCheckStatus": "OK", "rejectionReason": ${ @@ -1136,7 +1136,7 @@ class MockMvcMethodBodyBuilderSpec extends Specification implements WireMockStub ) } response { - status OK() + status 200 headers { contentType(applicationJson()) } @@ -1158,50 +1158,6 @@ class MockMvcMethodBodyBuilderSpec extends Specification implements WireMockStub "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"() { @@ -1223,7 +1179,7 @@ DocumentContext parsedJson = JsonPath.parse(json); ) } response { - status OK() + status 200 headers { contentType(applicationJson()) } @@ -1255,7 +1211,7 @@ DocumentContext parsedJson = JsonPath.parse(json); World.''') } response { - status OK() + status 200 } } MethodBodyBuilder builder = methodBuilder(contractDsl) @@ -1301,7 +1257,7 @@ World.'''""" ) } response { - status OK() + status 200 } } // end::multipartdsl[] @@ -1352,7 +1308,7 @@ World.'''""" ) } response { - status OK() + status 200 } } MethodBodyBuilder builder = methodBuilder(contractDsl) @@ -1378,48 +1334,6 @@ World.'''""" '.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: @@ -1439,7 +1353,7 @@ World.'''""" ) } response { - status OK() + status 200 } } MethodBodyBuilder builder = methodBuilder(contractDsl) @@ -1489,7 +1403,7 @@ World.'''""" ) } response { - status OK() + status 200 } } MethodBodyBuilder builder = methodBuilder(contractDsl) @@ -1515,7 +1429,8 @@ World.'''""" method "GET" urlPath('/auth/oauth/check_token') { queryParameters { - parameter 'token': value( + 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') ) @@ -1523,7 +1438,7 @@ World.'''""" } } response { - status OK() + status 200 body( authorities: [ value(consumer('ROLE_ADMIN'), producer(regex('^[a-zA-Z0-9_\\- ]+$'))) @@ -1550,7 +1465,8 @@ World.'''""" method "GET" urlPath('/auth/oauth/check_token') { queryParameters { - parameter 'token': value( + 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') ) @@ -1558,7 +1474,7 @@ World.'''""" } } response { - status OK() + status 200 body( authorities: [ value(consumer('ROLE_ADMIN'), producer(regex('^[a-zA-Z0-9_\\- ]+$'))) @@ -1585,7 +1501,7 @@ World.'''""" url '/fraudcheck' } response { - status OK() + status 200 body( fraudCheckStatus: "OK", rejectionReason: $(consumer(null), producer(execute('assertThatRejectionReasonIsNull($it)'))) @@ -1616,7 +1532,7 @@ World.'''""" urlPath '/foos' } response { - status OK() + status 200 body([[id: value( consumer('123'), producer(regex('[0-9]+')) @@ -1649,7 +1565,7 @@ World.'''""" urlPath '/api/tags' } response { - status OK() + status 200 body(["Java", "Java8", "Spring", "SpringBoot", "Stream"]) headers { header('Content-Type': 'application/json;charset=UTF-8') @@ -1686,7 +1602,7 @@ World.'''""" urlPath '/api/tags' } response { - status OK() + status 200 body(["Java", "Java8", "Spring", "SpringBoot", "Stream"]) headers { header('Content-Type': 'application/json;charset=UTF-8') @@ -1722,7 +1638,7 @@ World.'''""" urlPath '/api/categories' } response { - status OK() + status 200 body([["Programming", "Java"], ["Programming", "Java", "Spring", "Boot"]]) headers { header('Content-Type': 'application/json;charset=UTF-8') @@ -1756,7 +1672,7 @@ World.'''""" url '/test' } response { - status OK() + status 200 async() } } @@ -1790,7 +1706,7 @@ World.'''""" } } response { - status OK() + status 200 async() } } @@ -1820,7 +1736,7 @@ World.'''""" urlPath '/api/tags' } response { - status OK() + status 200 body('''{ "partners":[ { @@ -1856,7 +1772,7 @@ World.'''""" urlPath '/get' } response { - status OK() + status 200 body( code: 9, message: $(consumer('Wrong credentials'), producer(regex('^(?!\\s*$).+'))) ) } } @@ -1912,7 +1828,7 @@ World.'''""" ''' } response { - status OK() + status 200 } } // end::dsl_example[] @@ -1931,7 +1847,7 @@ World.'''""" } } response { - status OK() + status 200 body([ responseElement: $(producer(regex('[0-9]{7}'))) ]) @@ -1972,7 +1888,7 @@ World.'''""" urlPath '/get' } response { - status OK() + status 200 body([ fraudCheckStatus: "OK", rejectionReason : [ @@ -2004,7 +1920,7 @@ World.'''""" urlPath '/get' } response { - status OK() + status 200 body([ [ name: $(consumer("userName 1"), producer(execute('assertThatUserNameIsNotNull($it)'))) @@ -2034,7 +1950,7 @@ World.'''""" urlPath '/get' } response { - status OK() + status 200 body([ [ name: $(consumer("userName 1"), producer(execute('assertThatUserNameIsNotNull($it)'))) @@ -2067,7 +1983,7 @@ World.'''""" } } response { - status OK() + status 200 body([ fraudCheckStatus: "OK", rejectionReason : [ @@ -2099,7 +2015,7 @@ World.'''""" url '/get' } response { - status OK() + status 200 body(value(stub("HELLO FROM STUB"), server(regex(".*")))) } } @@ -2123,7 +2039,7 @@ World.'''""" url '/get' } response { - status OK() + status 200 body(value(stub("HELLO FROM STUB"), server(execute('foo($it)')))) } } @@ -2153,7 +2069,7 @@ World.'''""" } } response { - status OK() + status 200 body([ fraudCheckStatus: "OK", rejectionReason : [ @@ -2187,15 +2103,11 @@ World.'''""" 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()), @@ -2210,19 +2122,15 @@ World.'''""" } } response { - status OK() + status 200 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()), @@ -2246,14 +2154,10 @@ World.'''""" 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("[\'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("[\'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])') @@ -2268,7 +2172,7 @@ World.'''""" 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\\"}"; +String json = "{\\"duck\\":\\"8\\",\\"alpha\\":\\"YAJEOWYGMFBEWPMEMAZI\\",\\"number\\":-2095030871,\\"aBoolean\\":true,\\"ip\\":\\"129.168.99.100\\",\\"hostname\\":\\"http://foo389886219.com\\",\\"email\\":\\"foo@bar1367573183.com\\",\\"url\\":\\"http://foo-597104692.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: @@ -2294,7 +2198,7 @@ DocumentContext parsedJson = JsonPath.parse(json); } } response { - status OK() + status 200 headers { contentType("application/vnd.fraud.v1+json") } @@ -2394,7 +2298,7 @@ DocumentContext parsedJson = JsonPath.parse(json); url '/foo' } response { - status OK() + status 200 headers { contentType(applicationJsonUtf8()) } @@ -2433,7 +2337,7 @@ DocumentContext parsedJson = JsonPath.parse(json); headers { header('Content-Type', 'application/json;charset=UTF-8') } } response { - status OK() + status 200 body( bar: $(producer(regex('some value \u0022with quote\u0022|bar'))) ) @@ -2465,7 +2369,7 @@ DocumentContext parsedJson = JsonPath.parse(json); url $(c("foo"), p(execute("executedMethod()"))) } response { - status OK() + status 200 } } MethodBodyBuilder builder = methodBuilder(contractDsl) @@ -2499,7 +2403,7 @@ DocumentContext parsedJson = JsonPath.parse(json); url '/api/v1/xxxx' } response { - status OK() + status 200 body([ status: '200', list: [], @@ -2535,7 +2439,7 @@ DocumentContext parsedJson = JsonPath.parse(json); body(12000) } response { - status OK() + status 200 body(12000) } } @@ -2577,7 +2481,7 @@ DocumentContext parsedJson = JsonPath.parse(json); body(foo: "bar", baz: 5) } response { - status OK() + status 200 headers { header(authorization(), "foo ${fromRequest().header(authorization())} bar") } @@ -2592,17 +2496,7 @@ DocumentContext parsedJson = JsonPath.parse(json); 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" + responseBaz2: "Bla bla ${fromRequest().body('$.foo')} bla bla" ) } } @@ -2616,7 +2510,6 @@ DocumentContext parsedJson = JsonPath.parse(json); 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")''') @@ -2628,16 +2521,6 @@ DocumentContext parsedJson = JsonPath.parse(json); 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 @@ -2647,60 +2530,6 @@ DocumentContext parsedJson = JsonPath.parse(json); "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) From 1b36df5cafa56271f610e8f1c577783af11825b3 Mon Sep 17 00:00:00 2001 From: Olga Maciaszek-Sharma Date: Wed, 12 Sep 2018 14:14:09 +0200 Subject: [PATCH 7/7] Revert - resolve conflicts. --- .../MockMvcMethodBodyBuilderSpec.groovy | 34 ------------------- 1 file changed, 34 deletions(-) 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 index b67850555b..6daf734d96 100644 --- 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 @@ -2615,38 +2615,4 @@ DocumentContext parsedJson = JsonPath.parse(json); 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) } - } }