diff --git a/spring-cloud-contract-verifier/src/main/java/org/springframework/cloud/contract/verifier/builder/GenericJsonBodyThen.java b/spring-cloud-contract-verifier/src/main/java/org/springframework/cloud/contract/verifier/builder/GenericJsonBodyThen.java index 669780a57d..435e0be37a 100644 --- a/spring-cloud-contract-verifier/src/main/java/org/springframework/cloud/contract/verifier/builder/GenericJsonBodyThen.java +++ b/spring-cloud-contract-verifier/src/main/java/org/springframework/cloud/contract/verifier/builder/GenericJsonBodyThen.java @@ -27,6 +27,7 @@ import org.apache.commons.text.StringEscapeUtils; import org.springframework.cloud.contract.spec.ContractTemplate; import org.springframework.cloud.contract.spec.internal.BodyMatchers; import org.springframework.cloud.contract.spec.internal.ExecutionProperty; +import org.springframework.cloud.contract.spec.internal.FromFileProperty; import org.springframework.cloud.contract.verifier.config.TestFramework; import org.springframework.cloud.contract.verifier.file.SingleContractMetadata; import org.springframework.cloud.contract.verifier.template.HandlebarsTemplateProcessor; @@ -195,6 +196,10 @@ class GenericJsonBodyThen implements Then { @Override public boolean accept(SingleContractMetadata metadata) { + Object responseBody = this.bodyParser.responseBody(metadata).getServerValue(); + if (responseBody instanceof FromFileProperty) { + return !((FromFileProperty) responseBody).isByte(); + } ContentType outputTestContentType = metadata.getOutputTestContentType(); return JSON == outputTestContentType || mostLikelyJson(outputTestContentType, metadata); } 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 5f43ff6fb1..9260686b86 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 @@ -1009,6 +1009,119 @@ public class FooTest { assertThatJson(parsedJson).field("['uid']").matches("[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}"); } +} +""" + } + + @Issue('#1701') + def "should generate output for message whose body is json and contains string that looks like json [#methodBuilderName]"() { + given: + Contract contractDsl = org.springframework.cloud.contract.spec.Contract.make { + name "foo" + description 'issue #650' + label 'trigger' + input { + triggeredBy('toString()') + } + outputMessage { + sentTo("foo") + headers { + messagingContentType(applicationJson()) + } + body(fileAsBytes('messageResponse.json')) + } + } + methodBuilder() + when: + String test = singleTestGenerator(contractDsl) + then: + !test.contains('cursor') + !test.contains('REGEXP>>') + test.trim() == expectedTest.trim() + where: + methodBuilderName | methodBuilder | expectedTest + "spock" | { properties.testFramework = TestFramework.SPOCK } | """\ +package com.example + +import com.jayway.jsonpath.DocumentContext +import com.jayway.jsonpath.JsonPath +import spock.lang.Specification +import javax.inject.Inject +import org.springframework.cloud.contract.verifier.messaging.internal.ContractVerifierObjectMapper +import org.springframework.cloud.contract.verifier.messaging.internal.ContractVerifierMessage +import org.springframework.cloud.contract.verifier.messaging.internal.ContractVerifierMessaging + +import static org.springframework.cloud.contract.verifier.assertion.SpringCloudContractAssertions.assertThat +import static org.springframework.cloud.contract.verifier.util.ContractVerifierUtil.* +import static com.toomuchcoding.jsonassert.JsonAssertion.assertThatJson +import static org.springframework.cloud.contract.verifier.messaging.util.ContractVerifierMessagingUtil.headers +import static org.springframework.cloud.contract.verifier.util.ContractVerifierUtil.fileToBytes + +@SuppressWarnings("rawtypes") +class FooSpec extends Specification { + @Inject ContractVerifierMessaging contractVerifierMessaging + @Inject ContractVerifierObjectMapper contractVerifierObjectMapper + + def validate_foo() throws Exception { + when: + toString() + + then: + ContractVerifierMessage response = contractVerifierMessaging.receive("foo", + contract(this, "foo.yml")) + response != null + + and: + response.getHeader("contentType") != null + response.getHeader("contentType").toString() == 'application/json' + + and: + response.getPayloadAsByteArray() == fileToBytes(this, "foo_response_messageResponse.json") + } + +} +""" + "junit" | { properties.testFramework = TestFramework.JUNIT } | """\ +package com.example; + +import com.jayway.jsonpath.DocumentContext; +import com.jayway.jsonpath.JsonPath; +import org.junit.Test; +import org.junit.Rule; +import javax.inject.Inject; +import org.springframework.cloud.contract.verifier.messaging.internal.ContractVerifierObjectMapper; +import org.springframework.cloud.contract.verifier.messaging.internal.ContractVerifierMessage; +import org.springframework.cloud.contract.verifier.messaging.internal.ContractVerifierMessaging; + +import static org.springframework.cloud.contract.verifier.assertion.SpringCloudContractAssertions.assertThat; +import static org.springframework.cloud.contract.verifier.util.ContractVerifierUtil.*; +import static com.toomuchcoding.jsonassert.JsonAssertion.assertThatJson; +import static org.springframework.cloud.contract.verifier.messaging.util.ContractVerifierMessagingUtil.headers; +import static org.springframework.cloud.contract.verifier.util.ContractVerifierUtil.fileToBytes; + +@SuppressWarnings("rawtypes") +public class FooTest { + @Inject ContractVerifierMessaging contractVerifierMessaging; + @Inject ContractVerifierObjectMapper contractVerifierObjectMapper; + + @Test + public void validate_foo() throws Exception { + // when: + toString(); + + // then: + ContractVerifierMessage response = contractVerifierMessaging.receive("foo", + contract(this, "foo.yml")); + assertThat(response).isNotNull(); + + // and: + assertThat(response.getHeader("contentType")).isNotNull(); + assertThat(response.getHeader("contentType").toString()).isEqualTo("application/json"); + + // and: + assertThat(response.getPayloadAsByteArray()).isEqualTo(fileToBytes(this, "foo_response_messageResponse.json")); + } + } """ } diff --git a/spring-cloud-contract-verifier/src/test/groovy/org/springframework/cloud/contract/verifier/builder/messageResponse.json b/spring-cloud-contract-verifier/src/test/groovy/org/springframework/cloud/contract/verifier/builder/messageResponse.json new file mode 100644 index 0000000000..f9504caa62 --- /dev/null +++ b/spring-cloud-contract-verifier/src/test/groovy/org/springframework/cloud/contract/verifier/builder/messageResponse.json @@ -0,0 +1,3 @@ +{ + "payload": "{\"propsA\":\"valueA\",\"propsB\":\"valueB\"}" +} diff --git a/spring-cloud-contract-verifier/src/test/resources/messageResponse.json b/spring-cloud-contract-verifier/src/test/resources/messageResponse.json new file mode 100644 index 0000000000..f9504caa62 --- /dev/null +++ b/spring-cloud-contract-verifier/src/test/resources/messageResponse.json @@ -0,0 +1,3 @@ +{ + "payload": "{\"propsA\":\"valueA\",\"propsB\":\"valueB\"}" +}