Add support for placeholder resolution in stub file names

E.g. document("{method-name}/{step}").

Fixes gh-84
This commit is contained in:
Dave Syer
2017-06-16 14:36:49 +01:00
parent 0905469866
commit 8cdad73158
3 changed files with 64 additions and 26 deletions

View File

@@ -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

View File

@@ -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;
@@ -27,11 +24,6 @@ import java.util.LinkedHashSet;
import java.util.Set;
import java.util.regex.Pattern;
import org.springframework.http.MediaType;
import org.springframework.restdocs.RestDocumentationContext;
import org.springframework.restdocs.operation.Operation;
import org.springframework.restdocs.snippet.Snippet;
import com.github.tomakehurst.wiremock.client.MappingBuilder;
import com.github.tomakehurst.wiremock.client.ResponseDefinitionBuilder;
import com.github.tomakehurst.wiremock.common.Json;
@@ -40,19 +32,29 @@ import com.github.tomakehurst.wiremock.http.HttpHeaders;
import com.github.tomakehurst.wiremock.matching.UrlPattern;
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;
import static com.github.tomakehurst.wiremock.client.WireMock.equalTo;
import static com.github.tomakehurst.wiremock.client.WireMock.equalToJson;
import static com.github.tomakehurst.wiremock.client.WireMock.get;
import static com.github.tomakehurst.wiremock.client.WireMock.head;
import static com.github.tomakehurst.wiremock.client.WireMock.matching;
import static com.github.tomakehurst.wiremock.client.WireMock.matchingJsonPath;
import static com.github.tomakehurst.wiremock.client.WireMock.patch;
import static com.github.tomakehurst.wiremock.client.WireMock.head;
import static com.github.tomakehurst.wiremock.client.WireMock.options;
import static com.github.tomakehurst.wiremock.client.WireMock.trace;
import static com.github.tomakehurst.wiremock.client.WireMock.patch;
import static com.github.tomakehurst.wiremock.client.WireMock.post;
import static com.github.tomakehurst.wiremock.client.WireMock.put;
import static com.github.tomakehurst.wiremock.client.WireMock.trace;
import static com.github.tomakehurst.wiremock.client.WireMock.urlEqualTo;
public class WireMockSnippet implements Snippet {
@@ -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));

View File

@@ -7,6 +7,9 @@ import java.nio.charset.Charset;
import java.nio.file.Files;
import java.util.Collection;
import com.github.tomakehurst.wiremock.matching.EqualToJsonPattern;
import com.github.tomakehurst.wiremock.stubbing.StubMapping;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
@@ -15,11 +18,13 @@ import org.junit.runner.RunWith;
import org.mockito.Answers;
import org.mockito.Mock;
import org.mockito.runners.MockitoJUnitRunner;
import org.springframework.cloud.contract.wiremock.WireMockStubMapping;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.restdocs.ManualRestDocumentation;
import org.springframework.restdocs.RestDocumentationContext;
import org.springframework.restdocs.operation.Operation;
import org.springframework.restdocs.operation.OperationRequest;
@@ -27,9 +32,6 @@ import org.springframework.restdocs.operation.OperationRequestPart;
import org.springframework.restdocs.operation.OperationResponse;
import org.springframework.restdocs.operation.Parameters;
import com.github.tomakehurst.wiremock.matching.EqualToJsonPattern;
import com.github.tomakehurst.wiremock.stubbing.StubMapping;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.BDDMockito.given;
import static org.mockito.Matchers.anyString;
@@ -49,9 +51,9 @@ public class WireMockSnippetTests {
@Before
public void setup() throws IOException {
this.outputFolder = this.tmp.newFolder();
RestDocumentationContext context = new RestDocumentationContext(this.getClass(),
"method", this.outputFolder);
given(this.operation.getName()).willReturn("foo");
ManualRestDocumentation restDocumentation = new ManualRestDocumentation(this.outputFolder.getAbsolutePath());
restDocumentation.beforeTest(this.getClass(), "method");
RestDocumentationContext context = restDocumentation.beforeOperation();
given(this.operation.getAttributes().get(anyString())).willReturn(null);
given(this.operation.getAttributes()
.get(RestDocumentationContext.class.getName())).willReturn(context);
@@ -62,6 +64,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);
@@ -74,9 +77,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());