diff --git a/samples/standalone/restdocs/http-server/src/test/java/com/example/fraud/StubGeneratorTests.java b/samples/standalone/restdocs/http-server/src/test/java/com/example/fraud/StubGeneratorTests.java index 8e8a1462bf..5c5c2a853a 100644 --- a/samples/standalone/restdocs/http-server/src/test/java/com/example/fraud/StubGeneratorTests.java +++ b/samples/standalone/restdocs/http-server/src/test/java/com/example/fraud/StubGeneratorTests.java @@ -56,7 +56,7 @@ public class StubGeneratorTests { .andDo(verify().jsonPath("$.clientId") .jsonPath("$[?(@.loanAmount > 1000)]") .contentType(MediaType.valueOf("application/vnd.fraud.v1+json")) - .stub("markClientAsFraud")); + .stub("markClientAsFraud/{step}")); } @Test diff --git a/spring-cloud-contract-wiremock/src/main/java/org/springframework/cloud/contract/wiremock/restdocs/WireMockSnippet.java b/spring-cloud-contract-wiremock/src/main/java/org/springframework/cloud/contract/wiremock/restdocs/WireMockSnippet.java index 7bb2025162..2592456c9f 100644 --- a/spring-cloud-contract-wiremock/src/main/java/org/springframework/cloud/contract/wiremock/restdocs/WireMockSnippet.java +++ b/spring-cloud-contract-wiremock/src/main/java/org/springframework/cloud/contract/wiremock/restdocs/WireMockSnippet.java @@ -16,10 +16,7 @@ package org.springframework.cloud.contract.wiremock.restdocs; -import java.io.File; -import java.io.FileOutputStream; import java.io.IOException; -import java.io.OutputStreamWriter; import java.io.Writer; import java.util.Arrays; import java.util.HashSet; @@ -38,7 +35,12 @@ import com.github.tomakehurst.wiremock.stubbing.StubMapping; import org.springframework.http.MediaType; import org.springframework.restdocs.RestDocumentationContext; import org.springframework.restdocs.operation.Operation; +import org.springframework.restdocs.snippet.RestDocumentationContextPlaceholderResolverFactory; import org.springframework.restdocs.snippet.Snippet; +import org.springframework.restdocs.snippet.StandardWriterResolver; +import org.springframework.restdocs.snippet.WriterResolver; +import org.springframework.restdocs.templates.TemplateFormat; +import org.springframework.util.PropertyPlaceholderHelper; import static com.github.tomakehurst.wiremock.client.WireMock.aResponse; import static com.github.tomakehurst.wiremock.client.WireMock.delete; @@ -70,6 +72,22 @@ public class WireMockSnippet implements Snippet { private boolean hasJsonBodyRequestToMatch = false; + private final PropertyPlaceholderHelper propertyPlaceholderHelper = new PropertyPlaceholderHelper( + "{", "}"); + + private static final TemplateFormat TEMPLATE_FORMAT = new TemplateFormat() { + + @Override + public String getId() { + return "json"; + } + + @Override + public String getFileExtension() { + return "json"; + } + }; + @Override public void document(Operation operation) throws IOException { extractMatchers(operation); @@ -79,10 +97,12 @@ public class WireMockSnippet implements Snippet { String json = Json.write(this.stubMapping); RestDocumentationContext context = (RestDocumentationContext) operation .getAttributes().get(RestDocumentationContext.class.getName()); - File output = new File(context.getOutputDirectory(), - this.snippetName + "/" + operation.getName() + ".json"); - output.getParentFile().mkdirs(); - try (Writer writer = new OutputStreamWriter(new FileOutputStream(output))) { + RestDocumentationContextPlaceholderResolverFactory placeholders = new RestDocumentationContextPlaceholderResolverFactory(); + WriterResolver writerResolver = new StandardWriterResolver(placeholders, "UTF-8", + TEMPLATE_FORMAT); + String path = this.propertyPlaceholderHelper.replacePlaceholders(operation.getName(), + placeholders.create(context)); + try (Writer writer = writerResolver.resolve(this.snippetName, path, context)) { writer.append(json); } } @@ -120,8 +140,7 @@ public class WireMockSnippet implements Snippet { return requestHeaders(requestBuilder(operation), operation); } - private MappingBuilder requestHeaders(MappingBuilder request, - Operation operation) { + private MappingBuilder requestHeaders(MappingBuilder request, Operation operation) { org.springframework.http.HttpHeaders headers = operation.getRequest() .getHeaders(); // TODO: whitelist headers @@ -167,8 +186,7 @@ public class WireMockSnippet implements Snippet { } } - private MappingBuilder bodyPattern(MappingBuilder builder, - String content) { + private MappingBuilder bodyPattern(MappingBuilder builder, String content) { if (this.jsonPaths != null && !this.jsonPaths.isEmpty()) { for (String jsonPath : this.jsonPaths) { builder.withRequestBody(matchingJsonPath(jsonPath)); diff --git a/spring-cloud-contract-wiremock/src/test/java/org/springframework/cloud/contract/wiremock/restdocs/WireMockSnippetTests.java b/spring-cloud-contract-wiremock/src/test/java/org/springframework/cloud/contract/wiremock/restdocs/WireMockSnippetTests.java index 58f4494760..caa93a77d1 100644 --- a/spring-cloud-contract-wiremock/src/test/java/org/springframework/cloud/contract/wiremock/restdocs/WireMockSnippetTests.java +++ b/spring-cloud-contract-wiremock/src/test/java/org/springframework/cloud/contract/wiremock/restdocs/WireMockSnippetTests.java @@ -56,7 +56,6 @@ public class WireMockSnippetTests { ManualRestDocumentation restDocumentation = new ManualRestDocumentation(this.outputFolder.getAbsolutePath()); restDocumentation.beforeTest(this.getClass(), "method"); RestDocumentationContext context = restDocumentation.beforeOperation(); - given(this.operation.getName()).willReturn("foo"); given(this.operation.getAttributes().get(anyString())).willReturn(null); given(this.operation.getAttributes() .get(RestDocumentationContext.class.getName())).willReturn(context); @@ -67,6 +66,7 @@ public class WireMockSnippetTests { @Test public void should_maintain_the_response_status_when_generating_stub() throws Exception { + given(this.operation.getName()).willReturn("foo"); WireMockSnippet snippet = new WireMockSnippet(); snippet.document(this.operation); @@ -79,9 +79,26 @@ public class WireMockSnippetTests { .isEqualTo(HttpStatus.ACCEPTED.value()); } + @Test + public void should_use_placeholders_in_stub_file_name() + throws Exception { + given(this.operation.getName()).willReturn("{method-name}/{step}"); + WireMockSnippet snippet = new WireMockSnippet(); + + snippet.document(this.operation); + + File stub = new File(this.outputFolder, "stubs/method/1.json"); + assertThat(stub).exists(); + StubMapping stubMapping = WireMockStubMapping + .buildFrom(new String(Files.readAllBytes(stub.toPath()))); + assertThat(stubMapping.getResponse().getStatus()) + .isEqualTo(HttpStatus.ACCEPTED.value()); + } + @Test public void should_use_equal_to_json_pattern_for_body_when_request_content_type_is_json_when_generating_stub() throws Exception { + given(this.operation.getName()).willReturn("foo"); WireMockSnippet snippet = new WireMockSnippet(); given(this.operation.getRequest()).willReturn(requestPostWithJsonContentType());