diff --git a/docs/src/main/asciidoc/spring-cloud-wiremock.adoc b/docs/src/main/asciidoc/spring-cloud-wiremock.adoc index 081920b18c..b0e5b51e0f 100644 --- a/docs/src/main/asciidoc/spring-cloud-wiremock.adoc +++ b/docs/src/main/asciidoc/spring-cloud-wiremock.adoc @@ -323,15 +323,13 @@ import org.springframework.cloud.contract.spec.Contract Contract.make { request { method 'POST' - url 'http://localhost:8080/foo' + url '/foo' body(''' {"foo": 23 } ''') headers { header('''Accept''', '''application/json''') header('''Content-Type''', '''application/json''') - header('''Host''', '''localhost:8080''') - header('''Content-Length''', '''12''') } } response { diff --git a/spring-cloud-contract-wiremock/src/main/java/org/springframework/cloud/contract/wiremock/restdocs/ContractDslSnippet.java b/spring-cloud-contract-wiremock/src/main/java/org/springframework/cloud/contract/wiremock/restdocs/ContractDslSnippet.java index 37073c5d18..59da24a28a 100644 --- a/spring-cloud-contract-wiremock/src/main/java/org/springframework/cloud/contract/wiremock/restdocs/ContractDslSnippet.java +++ b/spring-cloud-contract-wiremock/src/main/java/org/springframework/cloud/contract/wiremock/restdocs/ContractDslSnippet.java @@ -5,6 +5,8 @@ import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStreamWriter; import java.io.Writer; +import java.net.URI; +import java.util.Arrays; import java.util.HashMap; import java.util.HashSet; import java.util.Map; @@ -17,6 +19,7 @@ import org.springframework.restdocs.operation.OperationRequest; import org.springframework.restdocs.operation.OperationResponse; import org.springframework.restdocs.snippet.TemplatedSnippet; import org.springframework.restdocs.templates.TemplateEngine; +import org.springframework.util.StringUtils; /** * A {@link org.springframework.restdocs.snippet.Snippet} that documents the Spring Cloud Contract Groovy DSL. @@ -30,6 +33,7 @@ public class ContractDslSnippet extends TemplatedSnippet { private static final String SNIPPET_NAME = "dsl-contract"; private Map model = new HashMap<>(); + private Set bannedHeaders = new HashSet<>(Arrays.asList(HttpHeaders.HOST, HttpHeaders.CONTENT_LENGTH)); /** * Creates a new {@code ContractDslSnippet} with no additional attributes. @@ -53,7 +57,8 @@ public class ContractDslSnippet extends TemplatedSnippet { return this.model; } - @Override public void document(Operation operation) throws IOException { + @Override + public void document(Operation operation) throws IOException { TemplateEngine templateEngine = (TemplateEngine) operation.getAttributes().get(TemplateEngine.class.getName()); String renderedContract = templateEngine.compileTemplate("default-dsl-contract-only") .render(createModelForContract(operation)); @@ -90,12 +95,30 @@ public class ContractDslSnippet extends TemplatedSnippet { private void insertRequestModel(Operation operation, Map model) { OperationRequest request = operation.getRequest(); model.put("request_method", request.getMethod()); - model.put("request_url", request.getUri()); + model.put("request_url", prepareRequestUrl(request.getUri())); model.put("request_body_present", request.getContent().length > 0); model.put("request_body", request.getContentAsString()); - HttpHeaders headers = request.getHeaders(); + Map headers = request.getHeaders().toSingleValueMap(); + filterHeaders(headers); model.put("request_headers_present", !headers.isEmpty()); - model.put("request_headers", headers.toSingleValueMap().entrySet()); + model.put("request_headers", headers.entrySet()); + } + + private void filterHeaders(Map headers) { + for (String header : this.bannedHeaders) { + if (headers.containsKey(header)) { + headers.remove(header); + } + } + } + + private String prepareRequestUrl(URI uri) { + String path = uri.getRawPath(); + String query = uri.getRawQuery(); + if (StringUtils.hasText(query)) { + path = path + "?" + query; + } + return path; } private Map createModelForContract(Operation operation) { diff --git a/spring-cloud-contract-wiremock/src/test/java/org/springframework/cloud/contract/wiremock/restdocs/ContractDslSnippetTests.java b/spring-cloud-contract-wiremock/src/test/java/org/springframework/cloud/contract/wiremock/restdocs/ContractDslSnippetTests.java index f38b1d38dc..0006f6c5b5 100644 --- a/spring-cloud-contract-wiremock/src/test/java/org/springframework/cloud/contract/wiremock/restdocs/ContractDslSnippetTests.java +++ b/spring-cloud-contract-wiremock/src/test/java/org/springframework/cloud/contract/wiremock/restdocs/ContractDslSnippetTests.java @@ -5,6 +5,8 @@ import java.io.IOException; import java.net.URISyntaxException; import java.nio.charset.StandardCharsets; import java.nio.file.Files; +import java.util.HashSet; +import java.util.Set; import org.junit.Before; import org.junit.Rule; @@ -14,8 +16,10 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.cloud.contract.spec.Contract; +import org.springframework.cloud.contract.spec.internal.Header; import org.springframework.cloud.contract.verifier.util.ContractVerifierDslConverter; import org.springframework.context.annotation.Configuration; +import org.springframework.http.HttpHeaders; import org.springframework.http.MediaType; import org.springframework.restdocs.JUnitRestDocumentation; import org.springframework.test.context.junit4.SpringRunner; @@ -80,9 +84,12 @@ public class ContractDslSnippetTests { String contract = readFromFile(file("/contracts/index.groovy")); // try to parse the contract Contract parsedContract = ContractVerifierDslConverter.convert(contract); - then(parsedContract.getRequest().getHeaders().getEntries()).isNotEmpty(); + then(parsedContract.getRequest().getHeaders().getEntries()).isNotNull(); + then(headerNames(parsedContract.getRequest().getHeaders().getEntries())).doesNotContain + (HttpHeaders.HOST, HttpHeaders.CONTENT_LENGTH); then(parsedContract.getRequest().getMethod().getClientValue()).isNotNull(); then(parsedContract.getRequest().getUrl().getClientValue()).isNotNull(); + then(parsedContract.getRequest().getUrl().getClientValue().toString()).startsWith("/"); then(parsedContract.getRequest().getBody().getClientValue()).isNotNull(); then(parsedContract.getResponse().getStatus().getClientValue()).isNotNull(); then(parsedContract.getResponse().getHeaders().getEntries()).isNotEmpty(); @@ -101,9 +108,10 @@ public class ContractDslSnippetTests { String contract = readFromFile(file("/contracts/empty.groovy")); // try to parse the contract Contract parsedContract = ContractVerifierDslConverter.convert(contract); - then(parsedContract.getRequest().getHeaders().getEntries()).isNotEmpty(); + then(parsedContract.getRequest().getHeaders()).isNull(); then(parsedContract.getRequest().getMethod().getClientValue()).isNotNull(); then(parsedContract.getRequest().getUrl().getClientValue()).isNotNull(); + then(parsedContract.getRequest().getUrl().getClientValue().toString()).startsWith("/"); then(parsedContract.getRequest().getBody()).isNull(); then(parsedContract.getResponse().getStatus().getClientValue()).isNotNull(); then(parsedContract.getResponse().getHeaders()).isNull(); @@ -111,6 +119,14 @@ public class ContractDslSnippetTests { then(parsedContract.getResponse().getMatchers()).isNull(); } + private Set headerNames(Set
headers) { + Set names = new HashSet<>(); + for (Header header : headers) { + names.add(header.getName()); + } + return names; + } + private File file(String name) throws URISyntaxException { return new File(OUTPUT, name); }