diff --git a/spring-cloud-contract-verifier/src/main/groovy/org/springframework/cloud/contract/verifier/builder/JaxRsRequestMethodWhen.java b/spring-cloud-contract-verifier/src/main/groovy/org/springframework/cloud/contract/verifier/builder/JaxRsRequestMethodWhen.java index ec0ba3bd30..7e4f163440 100644 --- a/spring-cloud-contract-verifier/src/main/groovy/org/springframework/cloud/contract/verifier/builder/JaxRsRequestMethodWhen.java +++ b/spring-cloud-contract-verifier/src/main/groovy/org/springframework/cloud/contract/verifier/builder/JaxRsRequestMethodWhen.java @@ -18,7 +18,6 @@ package org.springframework.cloud.contract.verifier.builder; import org.springframework.cloud.contract.spec.internal.ExecutionProperty; import org.springframework.cloud.contract.spec.internal.FromFileProperty; -import org.springframework.cloud.contract.spec.internal.Header; import org.springframework.cloud.contract.spec.internal.Request; import org.springframework.cloud.contract.verifier.file.SingleContractMetadata; import org.springframework.cloud.contract.verifier.util.ContentType; @@ -46,9 +45,8 @@ class JaxRsRequestMethodWhen implements When, JaxRsBodyParser { ContentType type = metadata.getInputTestContentType(); String method = request.getMethod().getServerValue().toString().toLowerCase(); if (request.getBody() != null) { - String contentType = type.getMimeType(); - contentType = StringUtils.hasText(contentType) ? contentType - : getContentType(request); + String contentType = StringUtils.hasText(metadata.getDefinedInputTestContentType()) + ? metadata.getDefinedInputTestContentType() : type.getMimeType(); Object body = request.getBody().getServerValue(); String value; if (body instanceof ExecutionProperty) { @@ -73,13 +71,6 @@ class JaxRsRequestMethodWhen implements When, JaxRsBodyParser { } } - private String getContentType(Request request) { - Header contentType = request.getHeaders().getEntries().stream() - .filter(header -> "Content-Type".equalsIgnoreCase(header.getName())) - .findFirst().orElse(null); - return contentType != null ? contentType.getServerValue().toString() : ""; - } - @Override public boolean accept(SingleContractMetadata metadata) { return true; diff --git a/spring-cloud-contract-verifier/src/main/groovy/org/springframework/cloud/contract/verifier/file/ContractMetadata.groovy b/spring-cloud-contract-verifier/src/main/groovy/org/springframework/cloud/contract/verifier/file/ContractMetadata.groovy index c06b40b9e8..20eeb7a2c4 100644 --- a/spring-cloud-contract-verifier/src/main/groovy/org/springframework/cloud/contract/verifier/file/ContractMetadata.groovy +++ b/spring-cloud-contract-verifier/src/main/groovy/org/springframework/cloud/contract/verifier/file/ContractMetadata.groovy @@ -26,12 +26,12 @@ import org.apache.commons.logging.LogFactory import org.springframework.cloud.contract.spec.Contract import org.springframework.cloud.contract.spec.internal.DslProperty +import org.springframework.cloud.contract.spec.internal.Header import org.springframework.cloud.contract.spec.internal.Headers import org.springframework.cloud.contract.verifier.util.ContentType import org.springframework.cloud.contract.verifier.util.ContentUtils import org.springframework.cloud.contract.verifier.util.NamesUtil import org.springframework.util.Assert - /** * Contains metadata for a particular file with a DSL * @@ -103,12 +103,16 @@ class SingleContractMetadata { private final File stubsFile final Contract contract private final Collection allContracts + final String definedInputStubContentType final ContentType inputStubContentType final ContentType evaluatedInputStubContentType + final String definedOutputStubContentType final ContentType outputStubContentType final ContentType evaluatedOutputStubContentType + final String definedInputTestContentType final ContentType inputTestContentType final ContentType evaluatedInputTestContentType + final String definedOutputTestContentType final ContentType outputTestContentType final ContentType evaluatedOutputTestContentType private final boolean http @@ -121,12 +125,18 @@ class SingleContractMetadata { DslProperty inputBody = inputBody(currentContract) Headers outputHeaders = outputHeaders(currentContract) DslProperty outputBody = outputBody(currentContract) + Header inputContentType = contentTypeHeader(inputHeaders) + Header outputContentType = contentTypeHeader(outputHeaders) + this.definedInputTestContentType = inputContentType != null ? inputContentType.getServerValue() : "" this.evaluatedInputTestContentType = tryToEvaluateTestContentType(inputHeaders, inputBody) this.inputTestContentType = inputBody != null ? this.evaluatedInputTestContentType : ContentType.UNKNOWN + this.definedOutputTestContentType = outputContentType != null ? outputContentType.getServerValue() : "" this.evaluatedOutputTestContentType = tryToEvaluateTestContentType(outputHeaders, outputBody) this.outputTestContentType = outputBody != null ? this.evaluatedOutputTestContentType : ContentType.UNKNOWN + this.definedInputStubContentType = inputContentType != null ? inputContentType.getClientValue() : "" this.evaluatedInputStubContentType = tryToEvaluateStubContentType(inputHeaders, inputBody) this.inputStubContentType = inputBody != null ? this.evaluatedInputStubContentType : ContentType.UNKNOWN + this.definedOutputStubContentType = outputContentType != null ? outputContentType.getClientValue() : "" this.evaluatedOutputStubContentType = tryToEvaluateStubContentType(outputHeaders, outputBody) this.outputStubContentType = outputBody != null ? this.evaluatedOutputStubContentType : ContentType.UNKNOWN this.http = currentContract.request != null @@ -134,6 +144,12 @@ class SingleContractMetadata { this.stubsFile = contractMetadata.getPath() != null ? contractMetadata.getPath().toFile() : null } + private Header contentTypeHeader(Headers headers) { + return headers == null ? null : headers.getEntries().stream() + .filter({ header -> "Content-Type".equalsIgnoreCase(header.getName()) }) + .findFirst().orElse(null) + } + private ContentType tryToEvaluateStubContentType(Headers mainHeaders, DslProperty body) { ContentType contentType = ContentUtils.evaluateClientSideContentType(mainHeaders, body?.getClientValue()) if (contentType == ContentType.DEFINED || contentType == ContentType.UNKNOWN) { 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 bf32e5025f..62d111283d 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 @@ -1338,6 +1338,41 @@ public class FooTest { } } + @Issue('#1388') + @Unroll + def "should keep the custom content type that includes the +json suffix [#methodBuilderName]"() { + given: + Contract contractDsl = Contract.make { + request { + method("POST") + url("/ping") + headers { + header('Content-Type': 'application/my-content-type+json') + } + body($(test(value: "test"), stub(anyNonEmptyString()))) + } + response { + status 200 + } + } + methodBuilder() + when: + String test = singleTestGenerator(contractDsl) + then: + test.contains('"application/my-content-type+json")') + !test.contains('"application/json")') + and: + SyntaxChecker.tryToCompile(methodBuilderName, test) + where: + methodBuilderName | methodBuilder + "jaxrs-spock" | { + properties.testFramework = TestFramework.SPOCK; properties.testMode = TestMode.JAXRSCLIENT + } + "jaxrs" | { + properties.testFramework = TestFramework.JUNIT; properties.testMode = TestMode.JAXRSCLIENT + } + } + @Issue('#261') @Unroll def "should not produce any additional quotes for [#methodBuilderName]"() {