Upgrade to Spring Java Format 0.0.38

Closes gh-890
This commit is contained in:
Andy Wilkinson
2023-05-11 17:51:45 +01:00
parent 24ad0a829f
commit e741790f02
142 changed files with 2994 additions and 2090 deletions

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2014-2019 the original author or authors.
* Copyright 2014-2023 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -81,8 +81,9 @@ public class RestDocumentationExtension implements BeforeEachCallback, AfterEach
private ManualRestDocumentation getDelegate(ExtensionContext context) {
Namespace namespace = Namespace.create(getClass(), context.getUniqueId());
return context.getStore(namespace).getOrComputeIfAbsent(ManualRestDocumentation.class,
this::createManualRestDocumentation, ManualRestDocumentation.class);
return context.getStore(namespace)
.getOrComputeIfAbsent(ManualRestDocumentation.class, this::createManualRestDocumentation,
ManualRestDocumentation.class);
}
private ManualRestDocumentation createManualRestDocumentation(Class<ManualRestDocumentation> key) {

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2014-2022 the original author or authors.
* Copyright 2014-2023 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -94,7 +94,7 @@ public class CurlRequestSnippet extends TemplatedSnippet {
HttpMethod method = request.getMethod();
return (method != HttpMethod.PUT && method != HttpMethod.POST && method != HttpMethod.PATCH)
|| (request.getContent().length > 0 && !MediaType.APPLICATION_FORM_URLENCODED
.isCompatibleWith(request.getHeaders().getContentType()));
.isCompatibleWith(request.getHeaders().getContentType()));
}
private String getOptions(Operation operation) {

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2014-2022 the original author or authors.
* Copyright 2014-2023 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -135,7 +135,7 @@ public class HttpieRequestSnippet extends TemplatedSnippet {
HttpMethod method = request.getMethod();
return (method != HttpMethod.PUT && method != HttpMethod.POST && method != HttpMethod.PATCH)
|| (request.getContent().length > 0 && !MediaType.APPLICATION_FORM_URLENCODED
.isCompatibleWith(request.getHeaders().getContentType()));
.isCompatibleWith(request.getHeaders().getContentType()));
}
private boolean includeParametersAsFormOptions(OperationRequest request) {

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2014-2020 the original author or authors.
* Copyright 2014-2023 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -110,7 +110,7 @@ public abstract class RestDocumentationConfigurer<S extends AbstractConfigurer,
TemplateEngine engineToUse = this.templateEngine;
if (engineToUse == null) {
SnippetConfiguration snippetConfiguration = (SnippetConfiguration) configuration
.get(SnippetConfiguration.class.getName());
.get(SnippetConfiguration.class.getName());
Map<String, Object> templateContext = new HashMap<>();
if (snippetConfiguration.getTemplateFormat().getId().equals(TemplateFormats.asciidoctor().getId())) {
templateContext.put("tableCellContent", new AsciidoctorTableCellContentLambda());
@@ -138,7 +138,7 @@ public abstract class RestDocumentationConfigurer<S extends AbstractConfigurer,
WriterResolver resolverToUse = this.writerResolver;
if (resolverToUse == null) {
SnippetConfiguration snippetConfiguration = (SnippetConfiguration) configuration
.get(SnippetConfiguration.class.getName());
.get(SnippetConfiguration.class.getName());
resolverToUse = new StandardWriterResolver(new RestDocumentationContextPlaceholderResolverFactory(),
snippetConfiguration.getEncoding(), snippetConfiguration.getTemplateFormat());
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2014-2022 the original author or authors.
* Copyright 2014-2023 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -97,7 +97,7 @@ public class HttpRequestSnippet extends TemplatedSnippet {
HttpMethod method = request.getMethod();
return (method != HttpMethod.PUT && method != HttpMethod.POST && method != HttpMethod.PATCH)
|| (request.getContent().length > 0 && !MediaType.APPLICATION_FORM_URLENCODED
.isCompatibleWith(request.getHeaders().getContentType()));
.isCompatibleWith(request.getHeaders().getContentType()));
}
private List<Map<String, String>> getHeaders(OperationRequest request) {
@@ -153,8 +153,10 @@ public class HttpRequestSnippet extends TemplatedSnippet {
private void writeParts(OperationRequest request, PrintWriter writer) {
writer.println();
Set<String> partNames = request.getParts().stream().map(OperationRequestPart::getName)
.collect(Collectors.toSet());
Set<String> partNames = request.getParts()
.stream()
.map(OperationRequestPart::getName)
.collect(Collectors.toSet());
for (Entry<String, List<String>> parameter : request.getParameters().entrySet()) {
if (!partNames.contains(parameter.getKey())) {
if (parameter.getValue().isEmpty()) {

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2014-2019 the original author or authors.
* Copyright 2014-2023 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -118,8 +118,10 @@ public class Link {
@Override
public String toString() {
return new ToStringCreator(this).append("rel", this.rel).append("href", this.href).append("title", this.title)
.toString();
return new ToStringCreator(this).append("rel", this.rel)
.append("href", this.href)
.append("title", this.title)
.toString();
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2014-2020 the original author or authors.
* Copyright 2014-2023 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -121,7 +121,8 @@ public class OperationRequestFactory {
private HttpHeaders augmentHeaders(HttpHeaders originalHeaders, URI uri, byte[] content) {
return new HttpHeadersHelper(originalHeaders).addIfAbsent(HttpHeaders.HOST, createHostHeader(uri))
.setContentLengthHeader(content).getHeaders();
.setContentLengthHeader(content)
.getHeaders();
}
private String createHostHeader(URI uri) {

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2014-2021 the original author or authors.
* Copyright 2014-2023 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -53,7 +53,7 @@ import org.springframework.http.MediaType;
public class PrettyPrintingContentModifier implements ContentModifier {
private static final List<PrettyPrinter> PRETTY_PRINTERS = Collections
.unmodifiableList(Arrays.asList(new JsonPrettyPrinter(), new XmlPrettyPrinter()));
.unmodifiableList(Arrays.asList(new JsonPrettyPrinter(), new XmlPrettyPrinter()));
@Override
public byte[] modifyContent(byte[] originalContent, MediaType contentType) {
@@ -142,7 +142,7 @@ public class PrettyPrintingContentModifier implements ContentModifier {
private static final class JsonPrettyPrinter implements PrettyPrinter {
private final ObjectMapper objectMapper = new ObjectMapper().configure(SerializationFeature.INDENT_OUTPUT, true)
.configure(DeserializationFeature.FAIL_ON_TRAILING_TOKENS, true);
.configure(DeserializationFeature.FAIL_ON_TRAILING_TOKENS, true);
@Override
public byte[] prettyPrint(byte[] original) throws IOException {

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2014-2022 the original author or authors.
* Copyright 2014-2023 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -169,7 +169,7 @@ public class UriModifyingOperationPreprocessor implements OperationPreprocessor
private static final class UriModifyingContentModifier implements ContentModifier {
private static final Pattern SCHEME_HOST_PORT_PATTERN = Pattern
.compile("(http[s]?)://([a-zA-Z0-9-\\.]+)(:[0-9]+)?");
.compile("(http[s]?)://([a-zA-Z0-9-\\.]+)(:[0-9]+)?");
private String scheme;

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2014-2021 the original author or authors.
* Copyright 2014-2023 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -44,7 +44,7 @@ public class FieldPathPayloadSubsectionExtractor
private static final ObjectMapper objectMapper = new ObjectMapper();
private static final ObjectMapper prettyPrintingOjectMapper = new ObjectMapper()
.enable(SerializationFeature.INDENT_OUTPUT);
.enable(SerializationFeature.INDENT_OUTPUT);
private final String fieldPath;
@@ -87,23 +87,26 @@ public class FieldPathPayloadSubsectionExtractor
throw new PayloadHandlingException(this.fieldPath + " does not identify a section of the payload");
}
Map<JsonFieldPath, FieldDescriptor> descriptorsByPath = descriptors.stream()
.collect(Collectors.toMap(
(descriptor) -> JsonFieldPath.compile(this.fieldPath + "." + descriptor.getPath()),
this::prependFieldPath));
.collect(Collectors.toMap(
(descriptor) -> JsonFieldPath.compile(this.fieldPath + "." + descriptor.getPath()),
this::prependFieldPath));
if (value instanceof List) {
List<?> extractedList = (List<?>) value;
if (extractedList.isEmpty()) {
throw new PayloadHandlingException(this.fieldPath + " identifies an empty section of the payload");
}
JsonContentHandler contentHandler = new JsonContentHandler(payload, descriptorsByPath.values());
Set<JsonFieldPath> uncommonPaths = JsonFieldPaths.from(extractedList).getUncommon().stream()
.map((path) -> JsonFieldPath
.compile((path.equals("")) ? this.fieldPath : this.fieldPath + "." + path))
.filter((path) -> {
FieldDescriptor descriptorForPath = descriptorsByPath.getOrDefault(path,
new FieldDescriptor(path.toString()));
return contentHandler.isMissing(descriptorForPath);
}).collect(Collectors.toSet());
Set<JsonFieldPath> uncommonPaths = JsonFieldPaths.from(extractedList)
.getUncommon()
.stream()
.map((path) -> JsonFieldPath
.compile((path.equals("")) ? this.fieldPath : this.fieldPath + "." + path))
.filter((path) -> {
FieldDescriptor descriptorForPath = descriptorsByPath.getOrDefault(path,
new FieldDescriptor(path.toString()));
return contentHandler.isMissing(descriptorForPath);
})
.collect(Collectors.toSet());
if (uncommonPaths.isEmpty()) {
value = extractedList.get(0);
}
@@ -111,8 +114,9 @@ public class FieldPathPayloadSubsectionExtractor
String message = this.fieldPath + " identifies multiple sections of "
+ "the payload and they do not have a common structure. The "
+ "following non-optional uncommon paths were found: ";
message += uncommonPaths.stream().map(JsonFieldPath::toString)
.collect(Collectors.toCollection(TreeSet::new));
message += uncommonPaths.stream()
.map(JsonFieldPath::toString)
.collect(Collectors.toCollection(TreeSet::new));
throw new PayloadHandlingException(message);
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2014-2019 the original author or authors.
* Copyright 2014-2023 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -149,7 +149,7 @@ class JsonContentHandler implements ContentHandler {
public Object resolveFieldType(FieldDescriptor fieldDescriptor) {
if (fieldDescriptor.getType() == null) {
return this.fieldTypesDiscoverer.discoverFieldTypes(fieldDescriptor.getPath(), readContent())
.coalesce(fieldDescriptor.isOptional());
.coalesce(fieldDescriptor.isOptional());
}
if (!(fieldDescriptor.getType() instanceof JsonFieldType)) {
return fieldDescriptor.getType();
@@ -157,8 +157,8 @@ class JsonContentHandler implements ContentHandler {
JsonFieldType descriptorFieldType = (JsonFieldType) fieldDescriptor.getType();
try {
JsonFieldType actualFieldType = this.fieldTypesDiscoverer
.discoverFieldTypes(fieldDescriptor.getPath(), readContent())
.coalesce(fieldDescriptor.isOptional());
.discoverFieldTypes(fieldDescriptor.getPath(), readContent())
.coalesce(fieldDescriptor.isOptional());
if (descriptorFieldType == JsonFieldType.VARIES || descriptorFieldType == actualFieldType
|| (fieldDescriptor.isOptional() && actualFieldType == JsonFieldType.NULL)
|| (isNestedBeneathMissingOptionalField(fieldDescriptor, readContent())

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2014-2019 the original author or authors.
* Copyright 2014-2023 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -31,7 +31,7 @@ import java.util.regex.Pattern;
final class JsonFieldPath {
private static final Pattern BRACKETS_AND_ARRAY_PATTERN = Pattern
.compile("\\[\'(.+?)\'\\]|\\[([0-9]+|\\*){0,1}\\]");
.compile("\\[\'(.+?)\'\\]|\\[([0-9]+|\\*){0,1}\\]");
private static final Pattern ARRAY_INDEX_PATTERN = Pattern.compile("\\[([0-9]+|\\*){0,1}\\]");

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2014-2019 the original author or authors.
* Copyright 2014-2023 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -163,7 +163,7 @@ final class JsonFieldProcessor {
@Override
public void foundMatch(Match match) {
this.matchType = this.matchType
.combinedWith((match.getValue() != null) ? MatchType.NON_NULL : MatchType.NULL);
.combinedWith((match.getValue() != null) ? MatchType.NON_NULL : MatchType.NULL);
}
@Override

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2014-2019 the original author or authors.
* Copyright 2014-2023 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -1507,8 +1507,9 @@ public abstract class PayloadDocumentation {
String prefixedPath = pathPrefix + descriptor.getPath();
FieldDescriptor prefixedDescriptor = (descriptor instanceof SubsectionDescriptor)
? new SubsectionDescriptor(prefixedPath) : new FieldDescriptor(prefixedPath);
prefixedDescriptor.description(descriptor.getDescription()).type(descriptor.getType())
.attributes(asArray(descriptor.getAttributes()));
prefixedDescriptor.description(descriptor.getDescription())
.type(descriptor.getType())
.attributes(asArray(descriptor.getAttributes()));
if (descriptor.isIgnored()) {
prefixedDescriptor.ignored();
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2014-2019 the original author or authors.
* Copyright 2014-2023 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -189,7 +189,7 @@ public class RequestFieldsSnippet extends AbstractFieldsSnippet {
List<FieldDescriptor> combinedDescriptors = new ArrayList<>();
combinedDescriptors.addAll(getFieldDescriptors());
combinedDescriptors
.addAll(PayloadDocumentation.applyPathPrefix(pathPrefix, Arrays.asList(additionalDescriptors)));
.addAll(PayloadDocumentation.applyPathPrefix(pathPrefix, Arrays.asList(additionalDescriptors)));
return new RequestFieldsSnippet(getSubsectionExtractor(), combinedDescriptors, getAttributes(),
isIgnoredUndocumentedFields());
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2014-2019 the original author or authors.
* Copyright 2014-2023 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -216,7 +216,7 @@ public class RequestPartFieldsSnippet extends AbstractFieldsSnippet {
List<FieldDescriptor> combinedDescriptors = new ArrayList<>();
combinedDescriptors.addAll(getFieldDescriptors());
combinedDescriptors
.addAll(PayloadDocumentation.applyPathPrefix(pathPrefix, Arrays.asList(additionalDescriptors)));
.addAll(PayloadDocumentation.applyPathPrefix(pathPrefix, Arrays.asList(additionalDescriptors)));
return new RequestPartFieldsSnippet(this.partName, combinedDescriptors, this.getAttributes());
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2014-2019 the original author or authors.
* Copyright 2014-2023 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -193,7 +193,7 @@ public class ResponseFieldsSnippet extends AbstractFieldsSnippet {
List<FieldDescriptor> combinedDescriptors = new ArrayList<>();
combinedDescriptors.addAll(getFieldDescriptors());
combinedDescriptors
.addAll(PayloadDocumentation.applyPathPrefix(pathPrefix, Arrays.asList(additionalDescriptors)));
.addAll(PayloadDocumentation.applyPathPrefix(pathPrefix, Arrays.asList(additionalDescriptors)));
return new ResponseFieldsSnippet(getSubsectionExtractor(), combinedDescriptors, this.getAttributes(),
isIgnoredUndocumentedFields());
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2014-2020 the original author or authors.
* Copyright 2014-2023 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -122,7 +122,7 @@ public class PathParametersSnippet extends AbstractParametersSnippet {
private String extractUrlTemplate(Operation operation) {
String urlTemplate = (String) operation.getAttributes()
.get(RestDocumentationGenerator.ATTRIBUTE_NAME_URL_TEMPLATE);
.get(RestDocumentationGenerator.ATTRIBUTE_NAME_URL_TEMPLATE);
Assert.notNull(urlTemplate, "urlTemplate not found. If you are using MockMvc did "
+ "you use RestDocumentationRequestBuilders to build the request?");
return urlTemplate;

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2014-2019 the original author or authors.
* Copyright 2014-2023 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -72,13 +72,13 @@ public abstract class TemplatedSnippet implements Snippet {
@Override
public void document(Operation operation) throws IOException {
RestDocumentationContext context = (RestDocumentationContext) operation.getAttributes()
.get(RestDocumentationContext.class.getName());
.get(RestDocumentationContext.class.getName());
WriterResolver writerResolver = (WriterResolver) operation.getAttributes().get(WriterResolver.class.getName());
try (Writer writer = writerResolver.resolve(operation.getName(), this.snippetName, context)) {
Map<String, Object> model = createModel(operation);
model.putAll(this.attributes);
TemplateEngine templateEngine = (TemplateEngine) operation.getAttributes()
.get(TemplateEngine.class.getName());
.get(TemplateEngine.class.getName());
writer.append(templateEngine.compileTemplate(this.templateName).render(model));
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2014-2019 the original author or authors.
* Copyright 2014-2023 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -67,7 +67,7 @@ public class RestDocumentationGeneratorTests {
private final Object response = new Object();
private final OperationRequest operationRequest = new OperationRequestFactory()
.create(URI.create("http://localhost:8080"), null, null, new HttpHeaders(), null, null);
.create(URI.create("http://localhost:8080"), null, null, new HttpHeaders(), null, null);
private final OperationResponse operationResponse = new OperationResponseFactory().create(0, null, null);
@@ -83,7 +83,7 @@ public class RestDocumentationGeneratorTests {
given(this.responseConverter.convert(this.response)).willReturn(this.operationResponse);
HashMap<String, Object> configuration = new HashMap<>();
new RestDocumentationGenerator<>("id", this.requestConverter, this.responseConverter, this.snippet)
.handle(this.request, this.response, configuration);
.handle(this.request, this.response, configuration);
verifySnippetInvocation(this.snippet, configuration);
}
@@ -97,7 +97,7 @@ public class RestDocumentationGeneratorTests {
configuration.put(RestDocumentationGenerator.ATTRIBUTE_NAME_DEFAULT_SNIPPETS,
Arrays.asList(defaultSnippet1, defaultSnippet2));
new RestDocumentationGenerator<>("id", this.requestConverter, this.responseConverter, this.snippet)
.handle(this.request, this.response, configuration);
.handle(this.request, this.response, configuration);
InOrder inOrder = Mockito.inOrder(defaultSnippet1, defaultSnippet2, this.snippet);
verifySnippetInvocation(inOrder, defaultSnippet1, configuration);
verifySnippetInvocation(inOrder, defaultSnippet2, configuration);
@@ -120,8 +120,8 @@ public class RestDocumentationGeneratorTests {
given(defaultPreprocessor1.preprocess(first)).willReturn(second);
given(defaultPreprocessor2.preprocess(second)).willReturn(third);
new RestDocumentationGenerator<>("id", this.requestConverter, this.responseConverter,
Preprocessors.preprocessRequest(this.requestPreprocessor), this.snippet).handle(this.request,
this.response, configuration);
Preprocessors.preprocessRequest(this.requestPreprocessor), this.snippet)
.handle(this.request, this.response, configuration);
verifySnippetInvocation(this.snippet, third, this.operationResponse, configuration, 1);
}
@@ -141,8 +141,8 @@ public class RestDocumentationGeneratorTests {
given(defaultPreprocessor1.preprocess(first)).willReturn(second);
given(defaultPreprocessor2.preprocess(second)).willReturn(third);
new RestDocumentationGenerator<>("id", this.requestConverter, this.responseConverter,
Preprocessors.preprocessResponse(this.responsePreprocessor), this.snippet).handle(this.request,
this.response, configuration);
Preprocessors.preprocessResponse(this.responsePreprocessor), this.snippet)
.handle(this.request, this.response, configuration);
verifySnippetInvocation(this.snippet, this.operationRequest, third, configuration, 1);
}
@@ -159,8 +159,8 @@ public class RestDocumentationGeneratorTests {
RestDocumentationGenerator<Object, Object> generator = new RestDocumentationGenerator<>("id",
this.requestConverter, this.responseConverter, requestPreprocessor, responsePreprocessor, this.snippet);
HashMap<String, Object> configuration = new HashMap<>();
generator.withSnippets(additionalSnippet1, additionalSnippet2).handle(this.request, this.response,
configuration);
generator.withSnippets(additionalSnippet1, additionalSnippet2)
.handle(this.request, this.response, configuration);
verifyNoMoreInteractions(this.snippet);
verifySnippetInvocation(additionalSnippet1, configuration);
verifySnippetInvocation(additionalSnippet2, configuration);

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2014-2019 the original author or authors.
* Copyright 2014-2023 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -51,7 +51,7 @@ public class ConcatenatingCommandFormatterTests {
@Test
public void formattingMultipleElements() {
assertThat(this.singleLineFormat.format(Arrays.asList("alpha", "bravo")))
.isEqualTo(String.format(" alpha bravo"));
.isEqualTo(String.format(" alpha bravo"));
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2014-2022 the original author or authors.
* Copyright 2014-2023 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -52,41 +52,41 @@ public class CurlRequestSnippetTests extends AbstractSnippetTests {
@Test
public void getRequest() throws IOException {
new CurlRequestSnippet(this.commandFormatter)
.document(this.operationBuilder.request("http://localhost/foo").build());
.document(this.operationBuilder.request("http://localhost/foo").build());
assertThat(this.generatedSnippets.curlRequest())
.is(codeBlock("bash").withContent("$ curl 'http://localhost/foo' -i -X GET"));
.is(codeBlock("bash").withContent("$ curl 'http://localhost/foo' -i -X GET"));
}
@Test
public void getRequestWithParameter() throws IOException {
new CurlRequestSnippet(this.commandFormatter)
.document(this.operationBuilder.request("http://localhost/foo").param("a", "alpha").build());
.document(this.operationBuilder.request("http://localhost/foo").param("a", "alpha").build());
assertThat(this.generatedSnippets.curlRequest())
.is(codeBlock("bash").withContent("$ curl 'http://localhost/foo?a=alpha' -i -X GET"));
.is(codeBlock("bash").withContent("$ curl 'http://localhost/foo?a=alpha' -i -X GET"));
}
@Test
public void nonGetRequest() throws IOException {
new CurlRequestSnippet(this.commandFormatter)
.document(this.operationBuilder.request("http://localhost/foo").method("POST").build());
.document(this.operationBuilder.request("http://localhost/foo").method("POST").build());
assertThat(this.generatedSnippets.curlRequest())
.is(codeBlock("bash").withContent("$ curl 'http://localhost/foo' -i -X POST"));
.is(codeBlock("bash").withContent("$ curl 'http://localhost/foo' -i -X POST"));
}
@Test
public void requestWithContent() throws IOException {
new CurlRequestSnippet(this.commandFormatter)
.document(this.operationBuilder.request("http://localhost/foo").content("content").build());
.document(this.operationBuilder.request("http://localhost/foo").content("content").build());
assertThat(this.generatedSnippets.curlRequest())
.is(codeBlock("bash").withContent("$ curl 'http://localhost/foo' -i -X GET -d 'content'"));
.is(codeBlock("bash").withContent("$ curl 'http://localhost/foo' -i -X GET -d 'content'"));
}
@Test
public void getRequestWithQueryString() throws IOException {
new CurlRequestSnippet(this.commandFormatter)
.document(this.operationBuilder.request("http://localhost/foo?param=value").build());
.document(this.operationBuilder.request("http://localhost/foo?param=value").build());
assertThat(this.generatedSnippets.curlRequest())
.is(codeBlock("bash").withContent("$ curl 'http://localhost/foo?param=value' -i -X GET"));
.is(codeBlock("bash").withContent("$ curl 'http://localhost/foo?param=value' -i -X GET"));
}
@Test
@@ -94,173 +94,203 @@ public class CurlRequestSnippetTests extends AbstractSnippetTests {
new CurlRequestSnippet(this.commandFormatter).document(
this.operationBuilder.request("http://localhost/foo?param=value").param("param", "value").build());
assertThat(this.generatedSnippets.curlRequest())
.is(codeBlock("bash").withContent("$ curl 'http://localhost/foo?param=value' -i -X GET"));
.is(codeBlock("bash").withContent("$ curl 'http://localhost/foo?param=value' -i -X GET"));
}
@Test
public void getRequestWithPartiallyOverlappingQueryStringAndParameters() throws IOException {
new CurlRequestSnippet(this.commandFormatter).document(this.operationBuilder
.request("http://localhost/foo?a=alpha").param("a", "alpha").param("b", "bravo").build());
new CurlRequestSnippet(this.commandFormatter)
.document(this.operationBuilder.request("http://localhost/foo?a=alpha")
.param("a", "alpha")
.param("b", "bravo")
.build());
assertThat(this.generatedSnippets.curlRequest())
.is(codeBlock("bash").withContent("$ curl 'http://localhost/foo?a=alpha&b=bravo' -i -X GET"));
.is(codeBlock("bash").withContent("$ curl 'http://localhost/foo?a=alpha&b=bravo' -i -X GET"));
}
@Test
public void getRequestWithDisjointQueryStringAndParameters() throws IOException {
new CurlRequestSnippet(this.commandFormatter)
.document(this.operationBuilder.request("http://localhost/foo?a=alpha").param("b", "bravo").build());
.document(this.operationBuilder.request("http://localhost/foo?a=alpha").param("b", "bravo").build());
assertThat(this.generatedSnippets.curlRequest())
.is(codeBlock("bash").withContent("$ curl 'http://localhost/foo?a=alpha&b=bravo' -i -X GET"));
.is(codeBlock("bash").withContent("$ curl 'http://localhost/foo?a=alpha&b=bravo' -i -X GET"));
}
@Test
public void getRequestWithQueryStringWithNoValue() throws IOException {
new CurlRequestSnippet(this.commandFormatter)
.document(this.operationBuilder.request("http://localhost/foo?param").build());
.document(this.operationBuilder.request("http://localhost/foo?param").build());
assertThat(this.generatedSnippets.curlRequest())
.is(codeBlock("bash").withContent("$ curl 'http://localhost/foo?param' -i -X GET"));
.is(codeBlock("bash").withContent("$ curl 'http://localhost/foo?param' -i -X GET"));
}
@Test
public void postRequestWithQueryString() throws IOException {
new CurlRequestSnippet(this.commandFormatter)
.document(this.operationBuilder.request("http://localhost/foo?param=value").method("POST").build());
.document(this.operationBuilder.request("http://localhost/foo?param=value").method("POST").build());
assertThat(this.generatedSnippets.curlRequest())
.is(codeBlock("bash").withContent("$ curl 'http://localhost/foo?param=value' -i -X POST"));
.is(codeBlock("bash").withContent("$ curl 'http://localhost/foo?param=value' -i -X POST"));
}
@Test
public void postRequestWithQueryStringWithNoValue() throws IOException {
new CurlRequestSnippet(this.commandFormatter)
.document(this.operationBuilder.request("http://localhost/foo?param").method("POST").build());
.document(this.operationBuilder.request("http://localhost/foo?param").method("POST").build());
assertThat(this.generatedSnippets.curlRequest())
.is(codeBlock("bash").withContent("$ curl 'http://localhost/foo?param' -i -X POST"));
.is(codeBlock("bash").withContent("$ curl 'http://localhost/foo?param' -i -X POST"));
}
@Test
public void postRequestWithOneParameter() throws IOException {
new CurlRequestSnippet(this.commandFormatter).document(
this.operationBuilder.request("http://localhost/foo").method("POST").param("k1", "v1").build());
new CurlRequestSnippet(this.commandFormatter)
.document(this.operationBuilder.request("http://localhost/foo").method("POST").param("k1", "v1").build());
assertThat(this.generatedSnippets.curlRequest())
.is(codeBlock("bash").withContent("$ curl 'http://localhost/foo' -i -X POST -d 'k1=v1'"));
.is(codeBlock("bash").withContent("$ curl 'http://localhost/foo' -i -X POST -d 'k1=v1'"));
}
@Test
public void postRequestWithOneParameterWithNoValue() throws IOException {
new CurlRequestSnippet(this.commandFormatter)
.document(this.operationBuilder.request("http://localhost/foo").method("POST").param("k1").build());
.document(this.operationBuilder.request("http://localhost/foo").method("POST").param("k1").build());
assertThat(this.generatedSnippets.curlRequest())
.is(codeBlock("bash").withContent("$ curl 'http://localhost/foo' -i -X POST -d 'k1='"));
.is(codeBlock("bash").withContent("$ curl 'http://localhost/foo' -i -X POST -d 'k1='"));
}
@Test
public void postRequestWithMultipleParameters() throws IOException {
new CurlRequestSnippet(this.commandFormatter).document(this.operationBuilder.request("http://localhost/foo")
.method("POST").param("k1", "v1", "v1-bis").param("k2", "v2").build());
.method("POST")
.param("k1", "v1", "v1-bis")
.param("k2", "v2")
.build());
assertThat(this.generatedSnippets.curlRequest()).is(codeBlock("bash")
.withContent("$ curl 'http://localhost/foo' -i -X POST" + " -d 'k1=v1&k1=v1-bis&k2=v2'"));
.withContent("$ curl 'http://localhost/foo' -i -X POST" + " -d 'k1=v1&k1=v1-bis&k2=v2'"));
}
@Test
public void postRequestWithUrlEncodedParameter() throws IOException {
new CurlRequestSnippet(this.commandFormatter).document(
this.operationBuilder.request("http://localhost/foo").method("POST").param("k1", "a&b").build());
new CurlRequestSnippet(this.commandFormatter)
.document(this.operationBuilder.request("http://localhost/foo").method("POST").param("k1", "a&b").build());
assertThat(this.generatedSnippets.curlRequest())
.is(codeBlock("bash").withContent("$ curl 'http://localhost/foo' -i -X POST -d 'k1=a%26b'"));
.is(codeBlock("bash").withContent("$ curl 'http://localhost/foo' -i -X POST -d 'k1=a%26b'"));
}
@Test
public void postRequestWithDisjointQueryStringAndParameter() throws IOException {
new CurlRequestSnippet(this.commandFormatter).document(this.operationBuilder
.request("http://localhost/foo?a=alpha").method("POST").param("b", "bravo").build());
new CurlRequestSnippet(this.commandFormatter)
.document(this.operationBuilder.request("http://localhost/foo?a=alpha")
.method("POST")
.param("b", "bravo")
.build());
assertThat(this.generatedSnippets.curlRequest())
.is(codeBlock("bash").withContent("$ curl 'http://localhost/foo?a=alpha' -i -X POST -d 'b=bravo'"));
.is(codeBlock("bash").withContent("$ curl 'http://localhost/foo?a=alpha' -i -X POST -d 'b=bravo'"));
}
@Test
public void postRequestWithTotallyOverlappingQueryStringAndParameters() throws IOException {
new CurlRequestSnippet(this.commandFormatter)
.document(this.operationBuilder.request("http://localhost/foo?a=alpha&b=bravo").method("POST")
.param("a", "alpha").param("b", "bravo").build());
.document(this.operationBuilder.request("http://localhost/foo?a=alpha&b=bravo")
.method("POST")
.param("a", "alpha")
.param("b", "bravo")
.build());
assertThat(this.generatedSnippets.curlRequest())
.is(codeBlock("bash").withContent("$ curl 'http://localhost/foo?a=alpha&b=bravo' -i -X POST"));
.is(codeBlock("bash").withContent("$ curl 'http://localhost/foo?a=alpha&b=bravo' -i -X POST"));
}
@Test
public void postRequestWithPartiallyOverlappingQueryStringAndParameters() throws IOException {
new CurlRequestSnippet(this.commandFormatter)
.document(this.operationBuilder.request("http://localhost/foo?a=alpha").method("POST")
.param("a", "alpha").param("b", "bravo").build());
.document(this.operationBuilder.request("http://localhost/foo?a=alpha")
.method("POST")
.param("a", "alpha")
.param("b", "bravo")
.build());
assertThat(this.generatedSnippets.curlRequest())
.is(codeBlock("bash").withContent("$ curl 'http://localhost/foo?a=alpha' -i -X POST -d 'b=bravo'"));
.is(codeBlock("bash").withContent("$ curl 'http://localhost/foo?a=alpha' -i -X POST -d 'b=bravo'"));
}
@Test
public void postRequestWithOverlappingParametersAndFormUrlEncodedBody() throws IOException {
new CurlRequestSnippet(this.commandFormatter).document(
this.operationBuilder.request("http://localhost/foo").method("POST").content("a=alpha&b=bravo")
.header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_FORM_URLENCODED_VALUE)
.param("a", "alpha").param("b", "bravo").build());
new CurlRequestSnippet(this.commandFormatter).document(this.operationBuilder.request("http://localhost/foo")
.method("POST")
.content("a=alpha&b=bravo")
.header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_FORM_URLENCODED_VALUE)
.param("a", "alpha")
.param("b", "bravo")
.build());
assertThat(this.generatedSnippets.curlRequest())
.is(codeBlock("bash").withContent("$ curl 'http://localhost/foo' -i -X POST "
+ "-H 'Content-Type: application/x-www-form-urlencoded' " + "-d 'a=alpha&b=bravo'"));
.is(codeBlock("bash").withContent("$ curl 'http://localhost/foo' -i -X POST "
+ "-H 'Content-Type: application/x-www-form-urlencoded' " + "-d 'a=alpha&b=bravo'"));
}
@Test
public void putRequestWithOneParameter() throws IOException {
new CurlRequestSnippet(this.commandFormatter).document(
this.operationBuilder.request("http://localhost/foo").method("PUT").param("k1", "v1").build());
new CurlRequestSnippet(this.commandFormatter)
.document(this.operationBuilder.request("http://localhost/foo").method("PUT").param("k1", "v1").build());
assertThat(this.generatedSnippets.curlRequest())
.is(codeBlock("bash").withContent("$ curl 'http://localhost/foo' -i -X PUT -d 'k1=v1'"));
.is(codeBlock("bash").withContent("$ curl 'http://localhost/foo' -i -X PUT -d 'k1=v1'"));
}
@Test
public void putRequestWithMultipleParameters() throws IOException {
new CurlRequestSnippet(this.commandFormatter).document(this.operationBuilder.request("http://localhost/foo")
.method("PUT").param("k1", "v1").param("k1", "v1-bis").param("k2", "v2").build());
.method("PUT")
.param("k1", "v1")
.param("k1", "v1-bis")
.param("k2", "v2")
.build());
assertThat(this.generatedSnippets.curlRequest()).is(codeBlock("bash")
.withContent("$ curl 'http://localhost/foo' -i -X PUT" + " -d 'k1=v1&k1=v1-bis&k2=v2'"));
.withContent("$ curl 'http://localhost/foo' -i -X PUT" + " -d 'k1=v1&k1=v1-bis&k2=v2'"));
}
@Test
public void putRequestWithUrlEncodedParameter() throws IOException {
new CurlRequestSnippet(this.commandFormatter).document(
this.operationBuilder.request("http://localhost/foo").method("PUT").param("k1", "a&b").build());
new CurlRequestSnippet(this.commandFormatter)
.document(this.operationBuilder.request("http://localhost/foo").method("PUT").param("k1", "a&b").build());
assertThat(this.generatedSnippets.curlRequest())
.is(codeBlock("bash").withContent("$ curl 'http://localhost/foo' -i -X PUT -d 'k1=a%26b'"));
.is(codeBlock("bash").withContent("$ curl 'http://localhost/foo' -i -X PUT -d 'k1=a%26b'"));
}
@Test
public void requestWithHeaders() throws IOException {
new CurlRequestSnippet(this.commandFormatter).document(this.operationBuilder.request("http://localhost/foo")
.header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE).header("a", "alpha").build());
.header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE)
.header("a", "alpha")
.build());
assertThat(this.generatedSnippets.curlRequest()).is(codeBlock("bash").withContent(
"$ curl 'http://localhost/foo' -i -X GET" + " -H 'Content-Type: application/json' -H 'a: alpha'"));
}
@Test
public void requestWithHeadersMultiline() throws IOException {
new CurlRequestSnippet(CliDocumentation.multiLineFormat()).document(this.operationBuilder
.request("http://localhost/foo").header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE)
.header("a", "alpha").build());
new CurlRequestSnippet(CliDocumentation.multiLineFormat())
.document(this.operationBuilder.request("http://localhost/foo")
.header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE)
.header("a", "alpha")
.build());
assertThat(this.generatedSnippets.curlRequest())
.is(codeBlock("bash").withContent(String.format("$ curl 'http://localhost/foo' -i -X GET \\%n"
+ " -H 'Content-Type: application/json' \\%n" + " -H 'a: alpha'")));
.is(codeBlock("bash").withContent(String.format("$ curl 'http://localhost/foo' -i -X GET \\%n"
+ " -H 'Content-Type: application/json' \\%n" + " -H 'a: alpha'")));
}
@Test
public void requestWithCookies() throws IOException {
new CurlRequestSnippet(this.commandFormatter).document(this.operationBuilder.request("http://localhost/foo")
.cookie("name1", "value1").cookie("name2", "value2").build());
.cookie("name1", "value1")
.cookie("name2", "value2")
.build());
assertThat(this.generatedSnippets.curlRequest()).is(codeBlock("bash")
.withContent("$ curl 'http://localhost/foo' -i -X GET" + " --cookie 'name1=value1;name2=value2'"));
.withContent("$ curl 'http://localhost/foo' -i -X GET" + " --cookie 'name1=value1;name2=value2'"));
}
@Test
public void multipartPostWithNoSubmittedFileName() throws IOException {
new CurlRequestSnippet(this.commandFormatter).document(this.operationBuilder.request("http://localhost/upload")
.method("POST").header(HttpHeaders.CONTENT_TYPE, MediaType.MULTIPART_FORM_DATA_VALUE)
.part("metadata", "{\"description\": \"foo\"}".getBytes()).build());
.method("POST")
.header(HttpHeaders.CONTENT_TYPE, MediaType.MULTIPART_FORM_DATA_VALUE)
.part("metadata", "{\"description\": \"foo\"}".getBytes())
.build());
String expectedContent = "$ curl 'http://localhost/upload' -i -X POST -H "
+ "'Content-Type: multipart/form-data' -F " + "'metadata={\"description\": \"foo\"}'";
assertThat(this.generatedSnippets.curlRequest()).is(codeBlock("bash").withContent(expectedContent));
@@ -269,9 +299,12 @@ public class CurlRequestSnippetTests extends AbstractSnippetTests {
@Test
public void multipartPostWithContentType() throws IOException {
new CurlRequestSnippet(this.commandFormatter).document(this.operationBuilder.request("http://localhost/upload")
.method("POST").header(HttpHeaders.CONTENT_TYPE, MediaType.MULTIPART_FORM_DATA_VALUE)
.part("image", new byte[0]).header(HttpHeaders.CONTENT_TYPE, MediaType.IMAGE_PNG_VALUE)
.submittedFileName("documents/images/example.png").build());
.method("POST")
.header(HttpHeaders.CONTENT_TYPE, MediaType.MULTIPART_FORM_DATA_VALUE)
.part("image", new byte[0])
.header(HttpHeaders.CONTENT_TYPE, MediaType.IMAGE_PNG_VALUE)
.submittedFileName("documents/images/example.png")
.build());
String expectedContent = "$ curl 'http://localhost/upload' -i -X POST -H "
+ "'Content-Type: multipart/form-data' -F " + "'image=@documents/images/example.png;type=image/png'";
assertThat(this.generatedSnippets.curlRequest()).is(codeBlock("bash").withContent(expectedContent));
@@ -280,8 +313,11 @@ public class CurlRequestSnippetTests extends AbstractSnippetTests {
@Test
public void multipartPost() throws IOException {
new CurlRequestSnippet(this.commandFormatter).document(this.operationBuilder.request("http://localhost/upload")
.method("POST").header(HttpHeaders.CONTENT_TYPE, MediaType.MULTIPART_FORM_DATA_VALUE)
.part("image", new byte[0]).submittedFileName("documents/images/example.png").build());
.method("POST")
.header(HttpHeaders.CONTENT_TYPE, MediaType.MULTIPART_FORM_DATA_VALUE)
.part("image", new byte[0])
.submittedFileName("documents/images/example.png")
.build());
String expectedContent = "$ curl 'http://localhost/upload' -i -X POST -H "
+ "'Content-Type: multipart/form-data' -F " + "'image=@documents/images/example.png'";
assertThat(this.generatedSnippets.curlRequest()).is(codeBlock("bash").withContent(expectedContent));
@@ -290,9 +326,14 @@ public class CurlRequestSnippetTests extends AbstractSnippetTests {
@Test
public void multipartPostWithParameters() throws IOException {
new CurlRequestSnippet(this.commandFormatter).document(this.operationBuilder.request("http://localhost/upload")
.method("POST").header(HttpHeaders.CONTENT_TYPE, MediaType.MULTIPART_FORM_DATA_VALUE)
.part("image", new byte[0]).submittedFileName("documents/images/example.png").and()
.param("a", "apple", "avocado").param("b", "banana").build());
.method("POST")
.header(HttpHeaders.CONTENT_TYPE, MediaType.MULTIPART_FORM_DATA_VALUE)
.part("image", new byte[0])
.submittedFileName("documents/images/example.png")
.and()
.param("a", "apple", "avocado")
.param("b", "banana")
.build());
String expectedContent = "$ curl 'http://localhost/upload' -i -X POST -H "
+ "'Content-Type: multipart/form-data' -F "
+ "'image=@documents/images/example.png' -F 'a=apple' -F 'a=avocado' " + "-F 'b=banana'";
@@ -302,9 +343,15 @@ public class CurlRequestSnippetTests extends AbstractSnippetTests {
@Test
public void multipartPostWithOverlappingPartsAndParameters() throws IOException {
new CurlRequestSnippet(this.commandFormatter).document(this.operationBuilder.request("http://localhost/upload")
.method("POST").header(HttpHeaders.CONTENT_TYPE, MediaType.MULTIPART_FORM_DATA_VALUE)
.part("image", new byte[0]).submittedFileName("documents/images/example.png").and()
.part("a", "apple".getBytes()).and().param("a", "apple").build());
.method("POST")
.header(HttpHeaders.CONTENT_TYPE, MediaType.MULTIPART_FORM_DATA_VALUE)
.part("image", new byte[0])
.submittedFileName("documents/images/example.png")
.and()
.part("a", "apple".getBytes())
.and()
.param("a", "apple")
.build());
String expectedContent = "$ curl 'http://localhost/upload' -i -X POST -H "
+ "'Content-Type: multipart/form-data' -F 'image=@documents/images/example.png' -F 'a=apple'";
assertThat(this.generatedSnippets.curlRequest()).is(codeBlock("bash").withContent(expectedContent));
@@ -313,44 +360,53 @@ public class CurlRequestSnippetTests extends AbstractSnippetTests {
@Test
public void basicAuthCredentialsAreSuppliedUsingUserOption() throws IOException {
new CurlRequestSnippet(this.commandFormatter).document(this.operationBuilder.request("http://localhost/foo")
.header(HttpHeaders.AUTHORIZATION, "Basic " + Base64Utils.encodeToString("user:secret".getBytes()))
.build());
.header(HttpHeaders.AUTHORIZATION, "Basic " + Base64Utils.encodeToString("user:secret".getBytes()))
.build());
assertThat(this.generatedSnippets.curlRequest())
.is(codeBlock("bash").withContent("$ curl 'http://localhost/foo' -i -u 'user:secret' -X GET"));
.is(codeBlock("bash").withContent("$ curl 'http://localhost/foo' -i -u 'user:secret' -X GET"));
}
@Test
public void customAttributes() throws IOException {
new CurlRequestSnippet(this.commandFormatter).document(this.operationBuilder.request("http://localhost/foo")
.header(HttpHeaders.HOST, "api.example.com")
.header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE).header("a", "alpha").build());
.header(HttpHeaders.HOST, "api.example.com")
.header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE)
.header("a", "alpha")
.build());
assertThat(this.generatedSnippets.curlRequest())
.is(codeBlock("bash").withContent("$ curl 'http://localhost/foo' -i -X GET -H 'Host: api.example.com'"
+ " -H 'Content-Type: application/json' -H 'a: alpha'"));
.is(codeBlock("bash").withContent("$ curl 'http://localhost/foo' -i -X GET -H 'Host: api.example.com'"
+ " -H 'Content-Type: application/json' -H 'a: alpha'"));
}
@Test
public void postWithContentAndParameters() throws IOException {
new CurlRequestSnippet(this.commandFormatter).document(this.operationBuilder.request("http://localhost/foo")
.param("a", "alpha").method("POST").param("b", "bravo").content("Some content").build());
.param("a", "alpha")
.method("POST")
.param("b", "bravo")
.content("Some content")
.build());
assertThat(this.generatedSnippets.curlRequest()).is(codeBlock("bash")
.withContent("$ curl 'http://localhost/foo?a=alpha&b=bravo' -i " + "-X POST -d 'Some content'"));
.withContent("$ curl 'http://localhost/foo?a=alpha&b=bravo' -i " + "-X POST -d 'Some content'"));
}
@Test
public void deleteWithParameters() throws IOException {
new CurlRequestSnippet(this.commandFormatter).document(this.operationBuilder.request("http://localhost/foo")
.method("DELETE").param("a", "alpha").param("b", "bravo").build());
.method("DELETE")
.param("a", "alpha")
.param("b", "bravo")
.build());
assertThat(this.generatedSnippets.curlRequest())
.is(codeBlock("bash").withContent("$ curl 'http://localhost/foo?a=alpha&b=bravo' -i " + "-X DELETE"));
.is(codeBlock("bash").withContent("$ curl 'http://localhost/foo?a=alpha&b=bravo' -i " + "-X DELETE"));
}
@Test
public void deleteWithQueryString() throws IOException {
new CurlRequestSnippet(this.commandFormatter).document(
this.operationBuilder.request("http://localhost/foo?a=alpha&b=bravo").method("DELETE").build());
new CurlRequestSnippet(this.commandFormatter)
.document(this.operationBuilder.request("http://localhost/foo?a=alpha&b=bravo").method("DELETE").build());
assertThat(this.generatedSnippets.curlRequest())
.is(codeBlock("bash").withContent("$ curl 'http://localhost/foo?a=alpha&b=bravo' -i " + "-X DELETE"));
.is(codeBlock("bash").withContent("$ curl 'http://localhost/foo?a=alpha&b=bravo' -i " + "-X DELETE"));
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2014-2022 the original author or authors.
* Copyright 2014-2023 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -53,41 +53,41 @@ public class HttpieRequestSnippetTests extends AbstractSnippetTests {
@Test
public void getRequest() throws IOException {
new HttpieRequestSnippet(this.commandFormatter)
.document(this.operationBuilder.request("http://localhost/foo").build());
.document(this.operationBuilder.request("http://localhost/foo").build());
assertThat(this.generatedSnippets.httpieRequest())
.is(codeBlock("bash").withContent("$ http GET 'http://localhost/foo'"));
.is(codeBlock("bash").withContent("$ http GET 'http://localhost/foo'"));
}
@Test
public void getRequestWithParameter() throws IOException {
new HttpieRequestSnippet(this.commandFormatter)
.document(this.operationBuilder.request("http://localhost/foo").param("a", "alpha").build());
.document(this.operationBuilder.request("http://localhost/foo").param("a", "alpha").build());
assertThat(this.generatedSnippets.httpieRequest())
.is(codeBlock("bash").withContent("$ http GET 'http://localhost/foo?a=alpha'"));
.is(codeBlock("bash").withContent("$ http GET 'http://localhost/foo?a=alpha'"));
}
@Test
public void nonGetRequest() throws IOException {
new HttpieRequestSnippet(this.commandFormatter)
.document(this.operationBuilder.request("http://localhost/foo").method("POST").build());
.document(this.operationBuilder.request("http://localhost/foo").method("POST").build());
assertThat(this.generatedSnippets.httpieRequest())
.is(codeBlock("bash").withContent("$ http POST 'http://localhost/foo'"));
.is(codeBlock("bash").withContent("$ http POST 'http://localhost/foo'"));
}
@Test
public void requestWithContent() throws IOException {
new HttpieRequestSnippet(this.commandFormatter)
.document(this.operationBuilder.request("http://localhost/foo").content("content").build());
.document(this.operationBuilder.request("http://localhost/foo").content("content").build());
assertThat(this.generatedSnippets.httpieRequest())
.is(codeBlock("bash").withContent("$ echo 'content' | http GET 'http://localhost/foo'"));
.is(codeBlock("bash").withContent("$ echo 'content' | http GET 'http://localhost/foo'"));
}
@Test
public void getRequestWithQueryString() throws IOException {
new HttpieRequestSnippet(this.commandFormatter)
.document(this.operationBuilder.request("http://localhost/foo?param=value").build());
.document(this.operationBuilder.request("http://localhost/foo?param=value").build());
assertThat(this.generatedSnippets.httpieRequest())
.is(codeBlock("bash").withContent("$ http GET 'http://localhost/foo?param=value'"));
.is(codeBlock("bash").withContent("$ http GET 'http://localhost/foo?param=value'"));
}
@Test
@@ -95,155 +95,181 @@ public class HttpieRequestSnippetTests extends AbstractSnippetTests {
new HttpieRequestSnippet(this.commandFormatter).document(
this.operationBuilder.request("http://localhost/foo?param=value").param("param", "value").build());
assertThat(this.generatedSnippets.httpieRequest())
.is(codeBlock("bash").withContent("$ http GET 'http://localhost/foo?param=value'"));
.is(codeBlock("bash").withContent("$ http GET 'http://localhost/foo?param=value'"));
}
@Test
public void getRequestWithPartiallyOverlappingQueryStringAndParameters() throws IOException {
new HttpieRequestSnippet(this.commandFormatter).document(this.operationBuilder
.request("http://localhost/foo?a=alpha").param("a", "alpha").param("b", "bravo").build());
new HttpieRequestSnippet(this.commandFormatter)
.document(this.operationBuilder.request("http://localhost/foo?a=alpha")
.param("a", "alpha")
.param("b", "bravo")
.build());
assertThat(this.generatedSnippets.httpieRequest())
.is(codeBlock("bash").withContent("$ http GET 'http://localhost/foo?a=alpha&b=bravo'"));
.is(codeBlock("bash").withContent("$ http GET 'http://localhost/foo?a=alpha&b=bravo'"));
}
@Test
public void getRequestWithDisjointQueryStringAndParameters() throws IOException {
new HttpieRequestSnippet(this.commandFormatter)
.document(this.operationBuilder.request("http://localhost/foo?a=alpha").param("b", "bravo").build());
.document(this.operationBuilder.request("http://localhost/foo?a=alpha").param("b", "bravo").build());
assertThat(this.generatedSnippets.httpieRequest())
.is(codeBlock("bash").withContent("$ http GET 'http://localhost/foo?a=alpha&b=bravo'"));
.is(codeBlock("bash").withContent("$ http GET 'http://localhost/foo?a=alpha&b=bravo'"));
}
@Test
public void getRequestWithQueryStringWithNoValue() throws IOException {
new HttpieRequestSnippet(this.commandFormatter)
.document(this.operationBuilder.request("http://localhost/foo?param").build());
.document(this.operationBuilder.request("http://localhost/foo?param").build());
assertThat(this.generatedSnippets.httpieRequest())
.is(codeBlock("bash").withContent("$ http GET 'http://localhost/foo?param'"));
.is(codeBlock("bash").withContent("$ http GET 'http://localhost/foo?param'"));
}
@Test
public void postRequestWithQueryString() throws IOException {
new HttpieRequestSnippet(this.commandFormatter)
.document(this.operationBuilder.request("http://localhost/foo?param=value").method("POST").build());
.document(this.operationBuilder.request("http://localhost/foo?param=value").method("POST").build());
assertThat(this.generatedSnippets.httpieRequest())
.is(codeBlock("bash").withContent("$ http POST 'http://localhost/foo?param=value'"));
.is(codeBlock("bash").withContent("$ http POST 'http://localhost/foo?param=value'"));
}
@Test
public void postRequestWithQueryStringWithNoValue() throws IOException {
new HttpieRequestSnippet(this.commandFormatter)
.document(this.operationBuilder.request("http://localhost/foo?param").method("POST").build());
.document(this.operationBuilder.request("http://localhost/foo?param").method("POST").build());
assertThat(this.generatedSnippets.httpieRequest())
.is(codeBlock("bash").withContent("$ http POST 'http://localhost/foo?param'"));
.is(codeBlock("bash").withContent("$ http POST 'http://localhost/foo?param'"));
}
@Test
public void postRequestWithOneParameter() throws IOException {
new HttpieRequestSnippet(this.commandFormatter).document(
this.operationBuilder.request("http://localhost/foo").method("POST").param("k1", "v1").build());
new HttpieRequestSnippet(this.commandFormatter)
.document(this.operationBuilder.request("http://localhost/foo").method("POST").param("k1", "v1").build());
assertThat(this.generatedSnippets.httpieRequest())
.is(codeBlock("bash").withContent("$ http --form POST 'http://localhost/foo' 'k1=v1'"));
.is(codeBlock("bash").withContent("$ http --form POST 'http://localhost/foo' 'k1=v1'"));
}
@Test
public void postRequestWithOneParameterWithNoValue() throws IOException {
new HttpieRequestSnippet(this.commandFormatter)
.document(this.operationBuilder.request("http://localhost/foo").method("POST").param("k1").build());
.document(this.operationBuilder.request("http://localhost/foo").method("POST").param("k1").build());
assertThat(this.generatedSnippets.httpieRequest())
.is(codeBlock("bash").withContent("$ http --form POST 'http://localhost/foo' 'k1='"));
.is(codeBlock("bash").withContent("$ http --form POST 'http://localhost/foo' 'k1='"));
}
@Test
public void postRequestWithMultipleParameters() throws IOException {
new HttpieRequestSnippet(this.commandFormatter).document(this.operationBuilder.request("http://localhost/foo")
.method("POST").param("k1", "v1", "v1-bis").param("k2", "v2").build());
.method("POST")
.param("k1", "v1", "v1-bis")
.param("k2", "v2")
.build());
assertThat(this.generatedSnippets.httpieRequest()).is(codeBlock("bash")
.withContent("$ http --form POST 'http://localhost/foo'" + " 'k1=v1' 'k1=v1-bis' 'k2=v2'"));
.withContent("$ http --form POST 'http://localhost/foo'" + " 'k1=v1' 'k1=v1-bis' 'k2=v2'"));
}
@Test
public void postRequestWithUrlEncodedParameter() throws IOException {
new HttpieRequestSnippet(this.commandFormatter).document(
this.operationBuilder.request("http://localhost/foo").method("POST").param("k1", "a&b").build());
new HttpieRequestSnippet(this.commandFormatter)
.document(this.operationBuilder.request("http://localhost/foo").method("POST").param("k1", "a&b").build());
assertThat(this.generatedSnippets.httpieRequest())
.is(codeBlock("bash").withContent("$ http --form POST 'http://localhost/foo' 'k1=a&b'"));
.is(codeBlock("bash").withContent("$ http --form POST 'http://localhost/foo' 'k1=a&b'"));
}
@Test
public void postRequestWithDisjointQueryStringAndParameter() throws IOException {
new HttpieRequestSnippet(this.commandFormatter).document(this.operationBuilder
.request("http://localhost/foo?a=alpha").method("POST").param("b", "bravo").build());
new HttpieRequestSnippet(this.commandFormatter)
.document(this.operationBuilder.request("http://localhost/foo?a=alpha")
.method("POST")
.param("b", "bravo")
.build());
assertThat(this.generatedSnippets.httpieRequest())
.is(codeBlock("bash").withContent("$ http --form POST 'http://localhost/foo?a=alpha' 'b=bravo'"));
.is(codeBlock("bash").withContent("$ http --form POST 'http://localhost/foo?a=alpha' 'b=bravo'"));
}
@Test
public void postRequestWithTotallyOverlappingQueryStringAndParameters() throws IOException {
new HttpieRequestSnippet(this.commandFormatter)
.document(this.operationBuilder.request("http://localhost/foo?a=alpha&b=bravo").method("POST")
.param("a", "alpha").param("b", "bravo").build());
.document(this.operationBuilder.request("http://localhost/foo?a=alpha&b=bravo")
.method("POST")
.param("a", "alpha")
.param("b", "bravo")
.build());
assertThat(this.generatedSnippets.httpieRequest())
.is(codeBlock("bash").withContent("$ http POST 'http://localhost/foo?a=alpha&b=bravo'"));
.is(codeBlock("bash").withContent("$ http POST 'http://localhost/foo?a=alpha&b=bravo'"));
}
@Test
public void postRequestWithPartiallyOverlappingQueryStringAndParameters() throws IOException {
new HttpieRequestSnippet(this.commandFormatter)
.document(this.operationBuilder.request("http://localhost/foo?a=alpha").method("POST")
.param("a", "alpha").param("b", "bravo").build());
.document(this.operationBuilder.request("http://localhost/foo?a=alpha")
.method("POST")
.param("a", "alpha")
.param("b", "bravo")
.build());
assertThat(this.generatedSnippets.httpieRequest())
.is(codeBlock("bash").withContent("$ http --form POST 'http://localhost/foo?a=alpha' 'b=bravo'"));
.is(codeBlock("bash").withContent("$ http --form POST 'http://localhost/foo?a=alpha' 'b=bravo'"));
}
@Test
public void postRequestWithOverlappingParametersAndFormUrlEncodedBody() throws IOException {
new HttpieRequestSnippet(this.commandFormatter).document(
this.operationBuilder.request("http://localhost/foo").method("POST").content("a=alpha&b=bravo")
.header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_FORM_URLENCODED_VALUE)
.param("a", "alpha").param("b", "bravo").build());
new HttpieRequestSnippet(this.commandFormatter).document(this.operationBuilder.request("http://localhost/foo")
.method("POST")
.content("a=alpha&b=bravo")
.header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_FORM_URLENCODED_VALUE)
.param("a", "alpha")
.param("b", "bravo")
.build());
assertThat(this.generatedSnippets.httpieRequest())
.is(codeBlock("bash").withContent("$ echo 'a=alpha&b=bravo' | http POST 'http://localhost/foo' "
+ "'Content-Type:application/x-www-form-urlencoded'"));
.is(codeBlock("bash").withContent("$ echo 'a=alpha&b=bravo' | http POST 'http://localhost/foo' "
+ "'Content-Type:application/x-www-form-urlencoded'"));
}
@Test
public void putRequestWithOneParameter() throws IOException {
new HttpieRequestSnippet(this.commandFormatter).document(
this.operationBuilder.request("http://localhost/foo").method("PUT").param("k1", "v1").build());
new HttpieRequestSnippet(this.commandFormatter)
.document(this.operationBuilder.request("http://localhost/foo").method("PUT").param("k1", "v1").build());
assertThat(this.generatedSnippets.httpieRequest())
.is(codeBlock("bash").withContent("$ http --form PUT 'http://localhost/foo' 'k1=v1'"));
.is(codeBlock("bash").withContent("$ http --form PUT 'http://localhost/foo' 'k1=v1'"));
}
@Test
public void putRequestWithMultipleParameters() throws IOException {
new HttpieRequestSnippet(this.commandFormatter).document(this.operationBuilder.request("http://localhost/foo")
.method("PUT").param("k1", "v1").param("k1", "v1-bis").param("k2", "v2").build());
.method("PUT")
.param("k1", "v1")
.param("k1", "v1-bis")
.param("k2", "v2")
.build());
assertThat(this.generatedSnippets.httpieRequest()).is(codeBlock("bash")
.withContent("$ http --form PUT 'http://localhost/foo'" + " 'k1=v1' 'k1=v1-bis' 'k2=v2'"));
.withContent("$ http --form PUT 'http://localhost/foo'" + " 'k1=v1' 'k1=v1-bis' 'k2=v2'"));
}
@Test
public void putRequestWithUrlEncodedParameter() throws IOException {
new HttpieRequestSnippet(this.commandFormatter).document(
this.operationBuilder.request("http://localhost/foo").method("PUT").param("k1", "a&b").build());
new HttpieRequestSnippet(this.commandFormatter)
.document(this.operationBuilder.request("http://localhost/foo").method("PUT").param("k1", "a&b").build());
assertThat(this.generatedSnippets.httpieRequest())
.is(codeBlock("bash").withContent("$ http --form PUT 'http://localhost/foo' 'k1=a&b'"));
.is(codeBlock("bash").withContent("$ http --form PUT 'http://localhost/foo' 'k1=a&b'"));
}
@Test
public void requestWithHeaders() throws IOException {
new HttpieRequestSnippet(this.commandFormatter).document(this.operationBuilder.request("http://localhost/foo")
.header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE).header("a", "alpha").build());
.header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE)
.header("a", "alpha")
.build());
assertThat(this.generatedSnippets.httpieRequest()).is(codeBlock("bash")
.withContent("$ http GET 'http://localhost/foo'" + " 'Content-Type:application/json' 'a:alpha'"));
.withContent("$ http GET 'http://localhost/foo'" + " 'Content-Type:application/json' 'a:alpha'"));
}
@Test
public void requestWithHeadersMultiline() throws IOException {
new HttpieRequestSnippet(CliDocumentation.multiLineFormat()).document(this.operationBuilder
.request("http://localhost/foo").header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE)
.header("a", "alpha").build());
new HttpieRequestSnippet(CliDocumentation.multiLineFormat())
.document(this.operationBuilder.request("http://localhost/foo")
.header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE)
.header("a", "alpha")
.build());
assertThat(this.generatedSnippets.httpieRequest()).is(codeBlock("bash").withContent(String.format(
"$ http GET 'http://localhost/foo' \\%n" + " 'Content-Type:application/json' \\%n 'a:alpha'")));
}
@@ -251,17 +277,21 @@ public class HttpieRequestSnippetTests extends AbstractSnippetTests {
@Test
public void requestWithCookies() throws IOException {
new HttpieRequestSnippet(this.commandFormatter).document(this.operationBuilder.request("http://localhost/foo")
.cookie("name1", "value1").cookie("name2", "value2").build());
.cookie("name1", "value1")
.cookie("name2", "value2")
.build());
assertThat(this.generatedSnippets.httpieRequest()).is(codeBlock("bash")
.withContent("$ http GET 'http://localhost/foo'" + " 'Cookie:name1=value1' 'Cookie:name2=value2'"));
.withContent("$ http GET 'http://localhost/foo'" + " 'Cookie:name1=value1' 'Cookie:name2=value2'"));
}
@Test
public void multipartPostWithNoSubmittedFileName() throws IOException {
new HttpieRequestSnippet(this.commandFormatter)
.document(this.operationBuilder.request("http://localhost/upload").method("POST")
.header(HttpHeaders.CONTENT_TYPE, MediaType.MULTIPART_FORM_DATA_VALUE)
.part("metadata", "{\"description\": \"foo\"}".getBytes()).build());
.document(this.operationBuilder.request("http://localhost/upload")
.method("POST")
.header(HttpHeaders.CONTENT_TYPE, MediaType.MULTIPART_FORM_DATA_VALUE)
.part("metadata", "{\"description\": \"foo\"}".getBytes())
.build());
String expectedContent = "$ http --multipart POST 'http://localhost/upload'"
+ " 'metadata'='{\"description\": \"foo\"}'";
assertThat(this.generatedSnippets.httpieRequest()).is(codeBlock("bash").withContent(expectedContent));
@@ -270,10 +300,13 @@ public class HttpieRequestSnippetTests extends AbstractSnippetTests {
@Test
public void multipartPostWithContentType() throws IOException {
new HttpieRequestSnippet(this.commandFormatter)
.document(this.operationBuilder.request("http://localhost/upload").method("POST")
.header(HttpHeaders.CONTENT_TYPE, MediaType.MULTIPART_FORM_DATA_VALUE)
.part("image", new byte[0]).header(HttpHeaders.CONTENT_TYPE, MediaType.IMAGE_PNG_VALUE)
.submittedFileName("documents/images/example.png").build());
.document(this.operationBuilder.request("http://localhost/upload")
.method("POST")
.header(HttpHeaders.CONTENT_TYPE, MediaType.MULTIPART_FORM_DATA_VALUE)
.part("image", new byte[0])
.header(HttpHeaders.CONTENT_TYPE, MediaType.IMAGE_PNG_VALUE)
.submittedFileName("documents/images/example.png")
.build());
// httpie does not yet support manually set content type by part
String expectedContent = "$ http --multipart POST 'http://localhost/upload'"
+ " 'image'@'documents/images/example.png'";
@@ -283,9 +316,12 @@ public class HttpieRequestSnippetTests extends AbstractSnippetTests {
@Test
public void multipartPost() throws IOException {
new HttpieRequestSnippet(this.commandFormatter)
.document(this.operationBuilder.request("http://localhost/upload").method("POST")
.header(HttpHeaders.CONTENT_TYPE, MediaType.MULTIPART_FORM_DATA_VALUE)
.part("image", new byte[0]).submittedFileName("documents/images/example.png").build());
.document(this.operationBuilder.request("http://localhost/upload")
.method("POST")
.header(HttpHeaders.CONTENT_TYPE, MediaType.MULTIPART_FORM_DATA_VALUE)
.part("image", new byte[0])
.submittedFileName("documents/images/example.png")
.build());
String expectedContent = "$ http --multipart POST 'http://localhost/upload'"
+ " 'image'@'documents/images/example.png'";
assertThat(this.generatedSnippets.httpieRequest()).is(codeBlock("bash").withContent(expectedContent));
@@ -294,10 +330,15 @@ public class HttpieRequestSnippetTests extends AbstractSnippetTests {
@Test
public void multipartPostWithParameters() throws IOException {
new HttpieRequestSnippet(this.commandFormatter)
.document(this.operationBuilder.request("http://localhost/upload").method("POST")
.header(HttpHeaders.CONTENT_TYPE, MediaType.MULTIPART_FORM_DATA_VALUE)
.part("image", new byte[0]).submittedFileName("documents/images/example.png").and()
.param("a", "apple", "avocado").param("b", "banana").build());
.document(this.operationBuilder.request("http://localhost/upload")
.method("POST")
.header(HttpHeaders.CONTENT_TYPE, MediaType.MULTIPART_FORM_DATA_VALUE)
.part("image", new byte[0])
.submittedFileName("documents/images/example.png")
.and()
.param("a", "apple", "avocado")
.param("b", "banana")
.build());
String expectedContent = "$ http --multipart POST 'http://localhost/upload'"
+ " 'image'@'documents/images/example.png' 'a=apple' 'a=avocado'" + " 'b=banana'";
assertThat(this.generatedSnippets.httpieRequest()).is(codeBlock("bash").withContent(expectedContent));
@@ -306,10 +347,16 @@ public class HttpieRequestSnippetTests extends AbstractSnippetTests {
@Test
public void multipartPostWithOverlappingPartsAndParameters() throws IOException {
new HttpieRequestSnippet(this.commandFormatter)
.document(this.operationBuilder.request("http://localhost/upload").method("POST")
.header(HttpHeaders.CONTENT_TYPE, MediaType.MULTIPART_FORM_DATA_VALUE)
.part("image", new byte[0]).submittedFileName("documents/images/example.png").and()
.part("a", "apple".getBytes()).and().param("a", "apple").build());
.document(this.operationBuilder.request("http://localhost/upload")
.method("POST")
.header(HttpHeaders.CONTENT_TYPE, MediaType.MULTIPART_FORM_DATA_VALUE)
.part("image", new byte[0])
.submittedFileName("documents/images/example.png")
.and()
.part("a", "apple".getBytes())
.and()
.param("a", "apple")
.build());
String expectedContent = "$ http --multipart POST 'http://localhost/upload'"
+ " 'image'@'documents/images/example.png' 'a'='apple'";
assertThat(this.generatedSnippets.httpieRequest()).is(codeBlock("bash").withContent(expectedContent));
@@ -318,44 +365,53 @@ public class HttpieRequestSnippetTests extends AbstractSnippetTests {
@Test
public void basicAuthCredentialsAreSuppliedUsingAuthOption() throws IOException {
new HttpieRequestSnippet(this.commandFormatter).document(this.operationBuilder.request("http://localhost/foo")
.header(HttpHeaders.AUTHORIZATION, "Basic " + Base64Utils.encodeToString("user:secret".getBytes()))
.build());
.header(HttpHeaders.AUTHORIZATION, "Basic " + Base64Utils.encodeToString("user:secret".getBytes()))
.build());
assertThat(this.generatedSnippets.httpieRequest())
.is(codeBlock("bash").withContent("$ http --auth 'user:secret' GET 'http://localhost/foo'"));
.is(codeBlock("bash").withContent("$ http --auth 'user:secret' GET 'http://localhost/foo'"));
}
@Test
public void customAttributes() throws IOException {
new HttpieRequestSnippet(this.commandFormatter).document(this.operationBuilder.request("http://localhost/foo")
.header(HttpHeaders.HOST, "api.example.com")
.header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE).header("a", "alpha").build());
.header(HttpHeaders.HOST, "api.example.com")
.header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE)
.header("a", "alpha")
.build());
assertThat(this.generatedSnippets.httpieRequest())
.is(codeBlock("bash").withContent("$ http GET 'http://localhost/foo' 'Host:api.example.com'"
+ " 'Content-Type:application/json' 'a:alpha'"));
.is(codeBlock("bash").withContent("$ http GET 'http://localhost/foo' 'Host:api.example.com'"
+ " 'Content-Type:application/json' 'a:alpha'"));
}
@Test
public void postWithContentAndParameters() throws IOException {
new HttpieRequestSnippet(this.commandFormatter).document(this.operationBuilder.request("http://localhost/foo")
.method("POST").param("a", "alpha").param("b", "bravo").content("Some content").build());
.method("POST")
.param("a", "alpha")
.param("b", "bravo")
.content("Some content")
.build());
assertThat(this.generatedSnippets.httpieRequest()).is(codeBlock("bash")
.withContent("$ echo 'Some content' | http POST " + "'http://localhost/foo?a=alpha&b=bravo'"));
.withContent("$ echo 'Some content' | http POST " + "'http://localhost/foo?a=alpha&b=bravo'"));
}
@Test
public void deleteWithParameters() throws IOException {
new HttpieRequestSnippet(this.commandFormatter).document(this.operationBuilder.request("http://localhost/foo")
.method("DELETE").param("a", "alpha").param("b", "bravo").build());
.method("DELETE")
.param("a", "alpha")
.param("b", "bravo")
.build());
assertThat(this.generatedSnippets.httpieRequest())
.is(codeBlock("bash").withContent("$ http DELETE 'http://localhost/foo?a=alpha&b=bravo'"));
.is(codeBlock("bash").withContent("$ http DELETE 'http://localhost/foo?a=alpha&b=bravo'"));
}
@Test
public void deleteWithQueryString() throws IOException {
new HttpieRequestSnippet(this.commandFormatter).document(
this.operationBuilder.request("http://localhost/foo?a=alpha&b=bravo").method("DELETE").build());
new HttpieRequestSnippet(this.commandFormatter)
.document(this.operationBuilder.request("http://localhost/foo?a=alpha&b=bravo").method("DELETE").build());
assertThat(this.generatedSnippets.httpieRequest())
.is(codeBlock("bash").withContent("$ http DELETE 'http://localhost/foo?a=alpha&b=bravo'"));
.is(codeBlock("bash").withContent("$ http DELETE 'http://localhost/foo?a=alpha&b=bravo'"));
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2014-2020 the original author or authors.
* Copyright 2014-2023 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -80,24 +80,24 @@ public class RestDocumentationConfigurerTests {
assertThat(configuration.get(WriterResolver.class.getName())).isInstanceOf(StandardWriterResolver.class);
assertThat(configuration).containsKey(RestDocumentationGenerator.ATTRIBUTE_NAME_DEFAULT_SNIPPETS);
assertThat(configuration.get(RestDocumentationGenerator.ATTRIBUTE_NAME_DEFAULT_SNIPPETS))
.isInstanceOf(List.class);
.isInstanceOf(List.class);
List<Snippet> defaultSnippets = (List<Snippet>) configuration
.get(RestDocumentationGenerator.ATTRIBUTE_NAME_DEFAULT_SNIPPETS);
assertThat(defaultSnippets).extracting("class").containsExactlyInAnyOrder(CurlRequestSnippet.class,
HttpieRequestSnippet.class, HttpRequestSnippet.class, HttpResponseSnippet.class,
RequestBodySnippet.class, ResponseBodySnippet.class);
.get(RestDocumentationGenerator.ATTRIBUTE_NAME_DEFAULT_SNIPPETS);
assertThat(defaultSnippets).extracting("class")
.containsExactlyInAnyOrder(CurlRequestSnippet.class, HttpieRequestSnippet.class, HttpRequestSnippet.class,
HttpResponseSnippet.class, RequestBodySnippet.class, ResponseBodySnippet.class);
assertThat(configuration).containsKey(SnippetConfiguration.class.getName());
assertThat(configuration.get(SnippetConfiguration.class.getName())).isInstanceOf(SnippetConfiguration.class);
SnippetConfiguration snippetConfiguration = (SnippetConfiguration) configuration
.get(SnippetConfiguration.class.getName());
.get(SnippetConfiguration.class.getName());
assertThat(snippetConfiguration.getEncoding()).isEqualTo("UTF-8");
assertThat(snippetConfiguration.getTemplateFormat().getId()).isEqualTo(TemplateFormats.asciidoctor().getId());
OperationRequestPreprocessor defaultOperationRequestPreprocessor = (OperationRequestPreprocessor) configuration
.get(RestDocumentationGenerator.ATTRIBUTE_NAME_DEFAULT_OPERATION_REQUEST_PREPROCESSOR);
.get(RestDocumentationGenerator.ATTRIBUTE_NAME_DEFAULT_OPERATION_REQUEST_PREPROCESSOR);
assertThat(defaultOperationRequestPreprocessor).isNull();
OperationResponsePreprocessor defaultOperationResponsePreprocessor = (OperationResponsePreprocessor) configuration
.get(RestDocumentationGenerator.ATTRIBUTE_NAME_DEFAULT_OPERATION_RESPONSE_PREPROCESSOR);
.get(RestDocumentationGenerator.ATTRIBUTE_NAME_DEFAULT_OPERATION_RESPONSE_PREPROCESSOR);
assertThat(defaultOperationResponsePreprocessor).isNull();
}
@@ -123,10 +123,10 @@ public class RestDocumentationConfigurerTests {
this.configurer.snippets().withDefaults(CliDocumentation.curlRequest()).apply(configuration, createContext());
assertThat(configuration).containsKey(RestDocumentationGenerator.ATTRIBUTE_NAME_DEFAULT_SNIPPETS);
assertThat(configuration.get(RestDocumentationGenerator.ATTRIBUTE_NAME_DEFAULT_SNIPPETS))
.isInstanceOf(List.class);
.isInstanceOf(List.class);
@SuppressWarnings("unchecked")
List<Snippet> defaultSnippets = (List<Snippet>) configuration
.get(RestDocumentationGenerator.ATTRIBUTE_NAME_DEFAULT_SNIPPETS);
.get(RestDocumentationGenerator.ATTRIBUTE_NAME_DEFAULT_SNIPPETS);
assertThat(defaultSnippets).hasSize(1);
assertThat(defaultSnippets).hasOnlyElementsOfType(CurlRequestSnippet.class);
}
@@ -139,12 +139,12 @@ public class RestDocumentationConfigurerTests {
this.configurer.snippets().withAdditionalDefaults(snippet).apply(configuration, createContext());
assertThat(configuration).containsKey(RestDocumentationGenerator.ATTRIBUTE_NAME_DEFAULT_SNIPPETS);
assertThat(configuration.get(RestDocumentationGenerator.ATTRIBUTE_NAME_DEFAULT_SNIPPETS))
.isInstanceOf(List.class);
.isInstanceOf(List.class);
List<Snippet> defaultSnippets = (List<Snippet>) configuration
.get(RestDocumentationGenerator.ATTRIBUTE_NAME_DEFAULT_SNIPPETS);
assertThat(defaultSnippets).extracting("class").containsExactlyInAnyOrder(CurlRequestSnippet.class,
HttpieRequestSnippet.class, HttpRequestSnippet.class, HttpResponseSnippet.class,
RequestBodySnippet.class, ResponseBodySnippet.class, snippet.getClass());
.get(RestDocumentationGenerator.ATTRIBUTE_NAME_DEFAULT_SNIPPETS);
assertThat(defaultSnippets).extracting("class")
.containsExactlyInAnyOrder(CurlRequestSnippet.class, HttpieRequestSnippet.class, HttpRequestSnippet.class,
HttpResponseSnippet.class, RequestBodySnippet.class, ResponseBodySnippet.class, snippet.getClass());
}
@Test
@@ -155,7 +155,7 @@ public class RestDocumentationConfigurerTests {
assertThat(configuration).containsKey(SnippetConfiguration.class.getName());
assertThat(configuration.get(SnippetConfiguration.class.getName())).isInstanceOf(SnippetConfiguration.class);
SnippetConfiguration snippetConfiguration = (SnippetConfiguration) configuration
.get(SnippetConfiguration.class.getName());
.get(SnippetConfiguration.class.getName());
assertThat(snippetConfiguration.getEncoding()).isEqualTo(StandardCharsets.ISO_8859_1.displayName());
assertThat(configuration.get(TemplateEngine.class.getName())).hasFieldOrPropertyWithValue("templateEncoding",
StandardCharsets.ISO_8859_1);
@@ -168,7 +168,7 @@ public class RestDocumentationConfigurerTests {
assertThat(configuration).containsKey(SnippetConfiguration.class.getName());
assertThat(configuration.get(SnippetConfiguration.class.getName())).isInstanceOf(SnippetConfiguration.class);
SnippetConfiguration snippetConfiguration = (SnippetConfiguration) configuration
.get(SnippetConfiguration.class.getName());
.get(SnippetConfiguration.class.getName());
assertThat(snippetConfiguration.getTemplateFormat().getId()).isEqualTo(TemplateFormats.markdown().getId());
}
@@ -202,10 +202,10 @@ public class RestDocumentationConfigurerTests {
public void customDefaultOperationRequestPreprocessor() {
Map<String, Object> configuration = new HashMap<>();
this.configurer.operationPreprocessors()
.withRequestDefaults(Preprocessors.prettyPrint(), Preprocessors.removeHeaders("Foo"))
.apply(configuration, createContext());
.withRequestDefaults(Preprocessors.prettyPrint(), Preprocessors.removeHeaders("Foo"))
.apply(configuration, createContext());
OperationRequestPreprocessor preprocessor = (OperationRequestPreprocessor) configuration
.get(RestDocumentationGenerator.ATTRIBUTE_NAME_DEFAULT_OPERATION_REQUEST_PREPROCESSOR);
.get(RestDocumentationGenerator.ATTRIBUTE_NAME_DEFAULT_OPERATION_REQUEST_PREPROCESSOR);
HttpHeaders headers = new HttpHeaders();
headers.add("Foo", "value");
OperationRequest request = new OperationRequestFactory().create(URI.create("http://localhost:8080"),
@@ -217,10 +217,10 @@ public class RestDocumentationConfigurerTests {
public void customDefaultOperationResponsePreprocessor() {
Map<String, Object> configuration = new HashMap<>();
this.configurer.operationPreprocessors()
.withResponseDefaults(Preprocessors.prettyPrint(), Preprocessors.removeHeaders("Foo"))
.apply(configuration, createContext());
.withResponseDefaults(Preprocessors.prettyPrint(), Preprocessors.removeHeaders("Foo"))
.apply(configuration, createContext());
OperationResponsePreprocessor preprocessor = (OperationResponsePreprocessor) configuration
.get(RestDocumentationGenerator.ATTRIBUTE_NAME_DEFAULT_OPERATION_RESPONSE_PREPROCESSOR);
.get(RestDocumentationGenerator.ATTRIBUTE_NAME_DEFAULT_OPERATION_RESPONSE_PREPROCESSOR);
HttpHeaders headers = new HttpHeaders();
headers.add("Foo", "value");
OperationResponse response = new OperationResponseFactory().create(HttpStatus.OK.value(), headers, null);

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2014-2019 the original author or authors.
* Copyright 2014-2023 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -45,7 +45,7 @@ public class ConstraintDescriptionsTests {
Constraint constraint1 = new Constraint("constraint1", Collections.<String, Object>emptyMap());
Constraint constraint2 = new Constraint("constraint2", Collections.<String, Object>emptyMap());
given(this.constraintResolver.resolveForProperty("foo", Constrained.class))
.willReturn(Arrays.asList(constraint1, constraint2));
.willReturn(Arrays.asList(constraint1, constraint2));
given(this.constraintDescriptionResolver.resolveDescription(constraint1)).willReturn("Bravo");
given(this.constraintDescriptionResolver.resolveDescription(constraint2)).willReturn("Alpha");
assertThat(this.constraintDescriptions.descriptionsForProperty("foo")).containsExactly("Alpha", "Bravo");
@@ -54,7 +54,7 @@ public class ConstraintDescriptionsTests {
@Test
public void emptyListOfDescriptionsWhenThereAreNoConstraints() {
given(this.constraintResolver.resolveForProperty("foo", Constrained.class))
.willReturn(Collections.<Constraint>emptyList());
.willReturn(Collections.<Constraint>emptyList());
assertThat(this.constraintDescriptions.descriptionsForProperty("foo").size()).isEqualTo(0);
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2014-2019 the original author or authors.
* Copyright 2014-2023 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -89,13 +89,13 @@ public class ResourceBundleConstraintDescriptionResolverTests {
@Test
public void defaultMessageCodePointLength() {
assertThat(constraintDescriptionForField("codePointLength"))
.isEqualTo("Code point length must be between 2 and 5 inclusive");
.isEqualTo("Code point length must be between 2 and 5 inclusive");
}
@Test
public void defaultMessageCurrency() {
assertThat(constraintDescriptionForField("currency"))
.isEqualTo("Must be in an accepted currency unit (GBP, USD)");
.isEqualTo("Must be in an accepted currency unit (GBP, USD)");
}
@Test
@@ -111,7 +111,7 @@ public class ResourceBundleConstraintDescriptionResolverTests {
@Test
public void defaultMessageDigits() {
assertThat(constraintDescriptionForField("digits"))
.isEqualTo("Must have at most 2 integral digits and 5 fractional digits");
.isEqualTo("Must have at most 2 integral digits and 5 fractional digits");
}
@Test
@@ -157,7 +157,7 @@ public class ResourceBundleConstraintDescriptionResolverTests {
@Test
public void defaultMessagePattern() {
assertThat(constraintDescriptionForField("pattern"))
.isEqualTo("Must match the regular expression `[A-Z][a-z]+`");
.isEqualTo("Must match the regular expression `[A-Z][a-z]+`");
}
@Test
@@ -168,7 +168,7 @@ public class ResourceBundleConstraintDescriptionResolverTests {
@Test
public void defaultMessageCreditCardNumber() {
assertThat(constraintDescriptionForField("creditCardNumber"))
.isEqualTo("Must be a well-formed credit card number");
.isEqualTo("Must be a well-formed credit card number");
}
@Test
@@ -184,7 +184,7 @@ public class ResourceBundleConstraintDescriptionResolverTests {
@Test
public void defaultMessageEmailHibernateValidator() {
assertThat(constraintDescriptionForField("emailHibernateValidator"))
.isEqualTo("Must be a well-formed email address");
.isEqualTo("Must be a well-formed email address");
}
@Test
@@ -195,7 +195,7 @@ public class ResourceBundleConstraintDescriptionResolverTests {
@Test
public void defaultMessageLuhnCheck() {
assertThat(constraintDescriptionForField("luhnCheck"))
.isEqualTo("Must pass the Luhn Modulo 10 checksum algorithm");
.isEqualTo("Must pass the Luhn Modulo 10 checksum algorithm");
}
@Test
@@ -279,8 +279,8 @@ public class ResourceBundleConstraintDescriptionResolverTests {
});
try {
String description = new ResourceBundleConstraintDescriptionResolver().resolveDescription(
new Constraint(NotNull.class.getName(), Collections.<String, Object>emptyMap()));
String description = new ResourceBundleConstraintDescriptionResolver()
.resolveDescription(new Constraint(NotNull.class.getName(), Collections.<String, Object>emptyMap()));
assertThat(description).isEqualTo("Should not be null");
}
@@ -300,7 +300,7 @@ public class ResourceBundleConstraintDescriptionResolverTests {
};
String description = new ResourceBundleConstraintDescriptionResolver(bundle)
.resolveDescription(new Constraint(NotNull.class.getName(), Collections.<String, Object>emptyMap()));
.resolveDescription(new Constraint(NotNull.class.getName(), Collections.<String, Object>emptyMap()));
assertThat(description).isEqualTo("Not null");
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2014-2022 the original author or authors.
* Copyright 2014-2023 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -42,17 +42,17 @@ public class RequestHeadersSnippetFailureTests {
@Test
public void missingRequestHeader() {
assertThatExceptionOfType(SnippetException.class)
.isThrownBy(() -> new RequestHeadersSnippet(Arrays.asList(headerWithName("Accept").description("one")))
.document(this.operationBuilder.request("http://localhost").build()))
.withMessage("Headers with the following names were not found in the request: [Accept]");
.isThrownBy(() -> new RequestHeadersSnippet(Arrays.asList(headerWithName("Accept").description("one")))
.document(this.operationBuilder.request("http://localhost").build()))
.withMessage("Headers with the following names were not found in the request: [Accept]");
}
@Test
public void undocumentedRequestHeaderAndMissingRequestHeader() {
assertThatExceptionOfType(SnippetException.class)
.isThrownBy(() -> new RequestHeadersSnippet(Arrays.asList(headerWithName("Accept").description("one")))
.document(this.operationBuilder.request("http://localhost").header("X-Test", "test").build()))
.withMessageEndingWith("Headers with the following names were not found in the request: [Accept]");
.isThrownBy(() -> new RequestHeadersSnippet(Arrays.asList(headerWithName("Accept").description("one")))
.document(this.operationBuilder.request("http://localhost").header("X-Test", "test").build()))
.withMessageEndingWith("Headers with the following names were not found in the request: [Accept]");
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2014-2019 the original author or authors.
* Copyright 2014-2023 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -53,42 +53,54 @@ public class RequestHeadersSnippetTests extends AbstractSnippetTests {
headerWithName("Accept").description("two"), headerWithName("Accept-Encoding").description("three"),
headerWithName("Accept-Language").description("four"),
headerWithName("Cache-Control").description("five"), headerWithName("Connection").description("six")))
.document(this.operationBuilder.request("http://localhost").header("X-Test", "test")
.header("Accept", "*/*").header("Accept-Encoding", "gzip, deflate")
.header("Accept-Language", "en-US,en;q=0.5").header("Cache-Control", "max-age=0")
.header("Connection", "keep-alive").build());
assertThat(this.generatedSnippets.requestHeaders()).is(tableWithHeader("Name", "Description")
.row("`X-Test`", "one").row("`Accept`", "two").row("`Accept-Encoding`", "three")
.row("`Accept-Language`", "four").row("`Cache-Control`", "five").row("`Connection`", "six"));
.document(this.operationBuilder.request("http://localhost")
.header("X-Test", "test")
.header("Accept", "*/*")
.header("Accept-Encoding", "gzip, deflate")
.header("Accept-Language", "en-US,en;q=0.5")
.header("Cache-Control", "max-age=0")
.header("Connection", "keep-alive")
.build());
assertThat(this.generatedSnippets.requestHeaders())
.is(tableWithHeader("Name", "Description").row("`X-Test`", "one")
.row("`Accept`", "two")
.row("`Accept-Encoding`", "three")
.row("`Accept-Language`", "four")
.row("`Cache-Control`", "five")
.row("`Connection`", "six"));
}
@Test
public void caseInsensitiveRequestHeaders() throws IOException {
new RequestHeadersSnippet(Arrays.asList(headerWithName("X-Test").description("one")))
.document(this.operationBuilder.request("/").header("X-test", "test").build());
.document(this.operationBuilder.request("/").header("X-test", "test").build());
assertThat(this.generatedSnippets.requestHeaders())
.is(tableWithHeader("Name", "Description").row("`X-Test`", "one"));
.is(tableWithHeader("Name", "Description").row("`X-Test`", "one"));
}
@Test
public void undocumentedRequestHeader() throws IOException {
new RequestHeadersSnippet(Arrays.asList(headerWithName("X-Test").description("one")))
.document(this.operationBuilder.request("http://localhost").header("X-Test", "test")
.header("Accept", "*/*").build());
.document(this.operationBuilder.request("http://localhost")
.header("X-Test", "test")
.header("Accept", "*/*")
.build());
assertThat(this.generatedSnippets.requestHeaders())
.is(tableWithHeader("Name", "Description").row("`X-Test`", "one"));
.is(tableWithHeader("Name", "Description").row("`X-Test`", "one"));
}
@Test
public void requestHeadersWithCustomAttributes() throws IOException {
TemplateResourceResolver resolver = mock(TemplateResourceResolver.class);
given(resolver.resolveTemplateResource("request-headers"))
.willReturn(snippetResource("request-headers-with-title"));
.willReturn(snippetResource("request-headers-with-title"));
new RequestHeadersSnippet(Arrays.asList(headerWithName("X-Test").description("one")),
attributes(key("title").value("Custom title")))
.document(this.operationBuilder
.attribute(TemplateEngine.class.getName(), new MustacheTemplateEngine(resolver))
.request("http://localhost").header("X-Test", "test").build());
.document(this.operationBuilder
.attribute(TemplateEngine.class.getName(), new MustacheTemplateEngine(resolver))
.request("http://localhost")
.header("X-Test", "test")
.build());
assertThat(this.generatedSnippets.requestHeaders()).contains("Custom title");
}
@@ -96,42 +108,54 @@ public class RequestHeadersSnippetTests extends AbstractSnippetTests {
public void requestHeadersWithCustomDescriptorAttributes() throws IOException {
TemplateResourceResolver resolver = mock(TemplateResourceResolver.class);
given(resolver.resolveTemplateResource("request-headers"))
.willReturn(snippetResource("request-headers-with-extra-column"));
.willReturn(snippetResource("request-headers-with-extra-column"));
new RequestHeadersSnippet(
Arrays.asList(headerWithName("X-Test").description("one").attributes(key("foo").value("alpha")),
headerWithName("Accept-Encoding").description("two").attributes(key("foo").value("bravo")),
headerWithName("Accept").description("three").attributes(key("foo").value("charlie"))))
.document(this.operationBuilder
.attribute(TemplateEngine.class.getName(), new MustacheTemplateEngine(resolver))
.request("http://localhost").header("X-Test", "test")
.header("Accept-Encoding", "gzip, deflate").header("Accept", "*/*").build());
.document(this.operationBuilder
.attribute(TemplateEngine.class.getName(), new MustacheTemplateEngine(resolver))
.request("http://localhost")
.header("X-Test", "test")
.header("Accept-Encoding", "gzip, deflate")
.header("Accept", "*/*")
.build());
assertThat(this.generatedSnippets.requestHeaders()).is(//
tableWithHeader("Name", "Description", "Foo").row("X-Test", "one", "alpha")
.row("Accept-Encoding", "two", "bravo").row("Accept", "three", "charlie"));
.row("Accept-Encoding", "two", "bravo")
.row("Accept", "three", "charlie"));
}
@Test
public void additionalDescriptors() throws IOException {
HeaderDocumentation.requestHeaders(headerWithName("X-Test").description("one"),
headerWithName("Accept").description("two"), headerWithName("Accept-Encoding").description("three"),
headerWithName("Accept-Language").description("four"))
.and(headerWithName("Cache-Control").description("five"),
headerWithName("Connection").description("six"))
.document(this.operationBuilder.request("http://localhost").header("X-Test", "test")
.header("Accept", "*/*").header("Accept-Encoding", "gzip, deflate")
.header("Accept-Language", "en-US,en;q=0.5").header("Cache-Control", "max-age=0")
.header("Connection", "keep-alive").build());
assertThat(this.generatedSnippets.requestHeaders()).is(tableWithHeader("Name", "Description")
.row("`X-Test`", "one").row("`Accept`", "two").row("`Accept-Encoding`", "three")
.row("`Accept-Language`", "four").row("`Cache-Control`", "five").row("`Connection`", "six"));
HeaderDocumentation
.requestHeaders(headerWithName("X-Test").description("one"), headerWithName("Accept").description("two"),
headerWithName("Accept-Encoding").description("three"),
headerWithName("Accept-Language").description("four"))
.and(headerWithName("Cache-Control").description("five"), headerWithName("Connection").description("six"))
.document(this.operationBuilder.request("http://localhost")
.header("X-Test", "test")
.header("Accept", "*/*")
.header("Accept-Encoding", "gzip, deflate")
.header("Accept-Language", "en-US,en;q=0.5")
.header("Cache-Control", "max-age=0")
.header("Connection", "keep-alive")
.build());
assertThat(this.generatedSnippets.requestHeaders())
.is(tableWithHeader("Name", "Description").row("`X-Test`", "one")
.row("`Accept`", "two")
.row("`Accept-Encoding`", "three")
.row("`Accept-Language`", "four")
.row("`Cache-Control`", "five")
.row("`Connection`", "six"));
}
@Test
public void tableCellContentIsEscapedWhenNecessary() throws IOException {
new RequestHeadersSnippet(Arrays.asList(headerWithName("Foo|Bar").description("one|two")))
.document(this.operationBuilder.request("http://localhost").header("Foo|Bar", "baz").build());
.document(this.operationBuilder.request("http://localhost").header("Foo|Bar", "baz").build());
assertThat(this.generatedSnippets.requestHeaders()).is(tableWithHeader("Name", "Description")
.row(escapeIfNecessary("`Foo|Bar`"), escapeIfNecessary("one|two")));
.row(escapeIfNecessary("`Foo|Bar`"), escapeIfNecessary("one|two")));
}
private String escapeIfNecessary(String input) {

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2014-2022 the original author or authors.
* Copyright 2014-2023 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -41,19 +41,20 @@ public class ResponseHeadersSnippetFailureTests {
@Test
public void missingResponseHeader() {
assertThatExceptionOfType(SnippetException.class).isThrownBy(
() -> new ResponseHeadersSnippet(Arrays.asList(headerWithName("Content-Type").description("one")))
assertThatExceptionOfType(SnippetException.class)
.isThrownBy(
() -> new ResponseHeadersSnippet(Arrays.asList(headerWithName("Content-Type").description("one")))
.document(this.operationBuilder.response().build()))
.withMessage("Headers with the following names were not found" + " in the response: [Content-Type]");
.withMessage("Headers with the following names were not found" + " in the response: [Content-Type]");
}
@Test
public void undocumentedResponseHeaderAndMissingResponseHeader() {
assertThatExceptionOfType(SnippetException.class).isThrownBy(
() -> new ResponseHeadersSnippet(Arrays.asList(headerWithName("Content-Type").description("one")))
assertThatExceptionOfType(SnippetException.class)
.isThrownBy(
() -> new ResponseHeadersSnippet(Arrays.asList(headerWithName("Content-Type").description("one")))
.document(this.operationBuilder.response().header("X-Test", "test").build()))
.withMessageEndingWith(
"Headers with the following names were not found in the response: [Content-Type]");
.withMessageEndingWith("Headers with the following names were not found in the response: [Content-Type]");
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2014-2019 the original author or authors.
* Copyright 2014-2023 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -52,40 +52,49 @@ public class ResponseHeadersSnippetTests extends AbstractSnippetTests {
new ResponseHeadersSnippet(Arrays.asList(headerWithName("X-Test").description("one"),
headerWithName("Content-Type").description("two"), headerWithName("Etag").description("three"),
headerWithName("Cache-Control").description("five"), headerWithName("Vary").description("six")))
.document(this.operationBuilder.response().header("X-Test", "test")
.header("Content-Type", "application/json").header("Etag", "lskjadldj3ii32l2ij23")
.header("Cache-Control", "max-age=0").header("Vary", "User-Agent").build());
.document(this.operationBuilder.response()
.header("X-Test", "test")
.header("Content-Type", "application/json")
.header("Etag", "lskjadldj3ii32l2ij23")
.header("Cache-Control", "max-age=0")
.header("Vary", "User-Agent")
.build());
assertThat(this.generatedSnippets.responseHeaders())
.is(tableWithHeader("Name", "Description").row("`X-Test`", "one").row("`Content-Type`", "two")
.row("`Etag`", "three").row("`Cache-Control`", "five").row("`Vary`", "six"));
.is(tableWithHeader("Name", "Description").row("`X-Test`", "one")
.row("`Content-Type`", "two")
.row("`Etag`", "three")
.row("`Cache-Control`", "five")
.row("`Vary`", "six"));
}
@Test
public void caseInsensitiveResponseHeaders() throws IOException {
new ResponseHeadersSnippet(Arrays.asList(headerWithName("X-Test").description("one")))
.document(this.operationBuilder.response().header("X-test", "test").build());
.document(this.operationBuilder.response().header("X-test", "test").build());
assertThat(this.generatedSnippets.responseHeaders())
.is(tableWithHeader("Name", "Description").row("`X-Test`", "one"));
.is(tableWithHeader("Name", "Description").row("`X-Test`", "one"));
}
@Test
public void undocumentedResponseHeader() throws IOException {
new ResponseHeadersSnippet(Arrays.asList(headerWithName("X-Test").description("one"))).document(
this.operationBuilder.response().header("X-Test", "test").header("Content-Type", "*/*").build());
new ResponseHeadersSnippet(Arrays.asList(headerWithName("X-Test").description("one")))
.document(this.operationBuilder.response().header("X-Test", "test").header("Content-Type", "*/*").build());
assertThat(this.generatedSnippets.responseHeaders())
.is(tableWithHeader("Name", "Description").row("`X-Test`", "one"));
.is(tableWithHeader("Name", "Description").row("`X-Test`", "one"));
}
@Test
public void responseHeadersWithCustomAttributes() throws IOException {
TemplateResourceResolver resolver = mock(TemplateResourceResolver.class);
given(resolver.resolveTemplateResource("response-headers"))
.willReturn(snippetResource("response-headers-with-title"));
.willReturn(snippetResource("response-headers-with-title"));
new ResponseHeadersSnippet(Arrays.asList(headerWithName("X-Test").description("one")),
attributes(key("title").value("Custom title")))
.document(this.operationBuilder
.attribute(TemplateEngine.class.getName(), new MustacheTemplateEngine(resolver))
.response().header("X-Test", "test").build());
.document(this.operationBuilder
.attribute(TemplateEngine.class.getName(), new MustacheTemplateEngine(resolver))
.response()
.header("X-Test", "test")
.build());
assertThat(this.generatedSnippets.responseHeaders()).contains("Custom title");
}
@@ -93,39 +102,51 @@ public class ResponseHeadersSnippetTests extends AbstractSnippetTests {
public void responseHeadersWithCustomDescriptorAttributes() throws IOException {
TemplateResourceResolver resolver = mock(TemplateResourceResolver.class);
given(resolver.resolveTemplateResource("response-headers"))
.willReturn(snippetResource("response-headers-with-extra-column"));
.willReturn(snippetResource("response-headers-with-extra-column"));
new ResponseHeadersSnippet(
Arrays.asList(headerWithName("X-Test").description("one").attributes(key("foo").value("alpha")),
headerWithName("Content-Type").description("two").attributes(key("foo").value("bravo")),
headerWithName("Etag").description("three").attributes(key("foo").value("charlie"))))
.document(this.operationBuilder
.attribute(TemplateEngine.class.getName(), new MustacheTemplateEngine(resolver))
.response().header("X-Test", "test").header("Content-Type", "application/json")
.header("Etag", "lskjadldj3ii32l2ij23").build());
assertThat(this.generatedSnippets.responseHeaders()).is(tableWithHeader("Name", "Description", "Foo")
.row("X-Test", "one", "alpha").row("Content-Type", "two", "bravo").row("Etag", "three", "charlie"));
.document(this.operationBuilder
.attribute(TemplateEngine.class.getName(), new MustacheTemplateEngine(resolver))
.response()
.header("X-Test", "test")
.header("Content-Type", "application/json")
.header("Etag", "lskjadldj3ii32l2ij23")
.build());
assertThat(this.generatedSnippets.responseHeaders())
.is(tableWithHeader("Name", "Description", "Foo").row("X-Test", "one", "alpha")
.row("Content-Type", "two", "bravo")
.row("Etag", "three", "charlie"));
}
@Test
public void additionalDescriptors() throws IOException {
HeaderDocumentation
.responseHeaders(headerWithName("X-Test").description("one"),
headerWithName("Content-Type").description("two"), headerWithName("Etag").description("three"))
.and(headerWithName("Cache-Control").description("five"), headerWithName("Vary").description("six"))
.document(this.operationBuilder.response().header("X-Test", "test")
.header("Content-Type", "application/json").header("Etag", "lskjadldj3ii32l2ij23")
.header("Cache-Control", "max-age=0").header("Vary", "User-Agent").build());
.responseHeaders(headerWithName("X-Test").description("one"),
headerWithName("Content-Type").description("two"), headerWithName("Etag").description("three"))
.and(headerWithName("Cache-Control").description("five"), headerWithName("Vary").description("six"))
.document(this.operationBuilder.response()
.header("X-Test", "test")
.header("Content-Type", "application/json")
.header("Etag", "lskjadldj3ii32l2ij23")
.header("Cache-Control", "max-age=0")
.header("Vary", "User-Agent")
.build());
assertThat(this.generatedSnippets.responseHeaders())
.is(tableWithHeader("Name", "Description").row("`X-Test`", "one").row("`Content-Type`", "two")
.row("`Etag`", "three").row("`Cache-Control`", "five").row("`Vary`", "six"));
.is(tableWithHeader("Name", "Description").row("`X-Test`", "one")
.row("`Content-Type`", "two")
.row("`Etag`", "three")
.row("`Cache-Control`", "five")
.row("`Vary`", "six"));
}
@Test
public void tableCellContentIsEscapedWhenNecessary() throws IOException {
new ResponseHeadersSnippet(Arrays.asList(headerWithName("Foo|Bar").description("one|two")))
.document(this.operationBuilder.response().header("Foo|Bar", "baz").build());
.document(this.operationBuilder.response().header("Foo|Bar", "baz").build());
assertThat(this.generatedSnippets.responseHeaders()).is(tableWithHeader("Name", "Description")
.row(escapeIfNecessary("`Foo|Bar`"), escapeIfNecessary("one|two")));
.row(escapeIfNecessary("`Foo|Bar`"), escapeIfNecessary("one|two")));
}
private String escapeIfNecessary(String input) {

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2014-2022 the original author or authors.
* Copyright 2014-2023 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -52,270 +52,345 @@ public class HttpRequestSnippetTests extends AbstractSnippetTests {
@Test
public void getRequest() throws IOException {
new HttpRequestSnippet()
.document(this.operationBuilder.request("http://localhost/foo").header("Alpha", "a").build());
.document(this.operationBuilder.request("http://localhost/foo").header("Alpha", "a").build());
assertThat(this.generatedSnippets.httpRequest())
.is(httpRequest(RequestMethod.GET, "/foo").header("Alpha", "a").header(HttpHeaders.HOST, "localhost"));
.is(httpRequest(RequestMethod.GET, "/foo").header("Alpha", "a").header(HttpHeaders.HOST, "localhost"));
}
@Test
public void getRequestWithParameters() throws IOException {
new HttpRequestSnippet().document(
this.operationBuilder.request("http://localhost/foo").header("Alpha", "a").param("b", "bravo").build());
assertThat(this.generatedSnippets.httpRequest()).is(httpRequest(RequestMethod.GET, "/foo?b=bravo")
.header("Alpha", "a").header(HttpHeaders.HOST, "localhost"));
assertThat(this.generatedSnippets.httpRequest())
.is(httpRequest(RequestMethod.GET, "/foo?b=bravo").header("Alpha", "a")
.header(HttpHeaders.HOST, "localhost"));
}
@Test
public void getRequestWithPort() throws IOException {
new HttpRequestSnippet()
.document(this.operationBuilder.request("http://localhost:8080/foo").header("Alpha", "a").build());
assertThat(this.generatedSnippets.httpRequest()).is(
httpRequest(RequestMethod.GET, "/foo").header("Alpha", "a").header(HttpHeaders.HOST, "localhost:8080"));
.document(this.operationBuilder.request("http://localhost:8080/foo").header("Alpha", "a").build());
assertThat(this.generatedSnippets.httpRequest())
.is(httpRequest(RequestMethod.GET, "/foo").header("Alpha", "a").header(HttpHeaders.HOST, "localhost:8080"));
}
@Test
public void getRequestWithCookies() throws IOException {
new HttpRequestSnippet().document(this.operationBuilder.request("http://localhost/foo")
.cookie("name1", "value1").cookie("name2", "value2").build());
.cookie("name1", "value1")
.cookie("name2", "value2")
.build());
assertThat(this.generatedSnippets.httpRequest())
.is(httpRequest(RequestMethod.GET, "/foo").header(HttpHeaders.HOST, "localhost")
.header(HttpHeaders.COOKIE, "name1=value1").header(HttpHeaders.COOKIE, "name2=value2"));
.is(httpRequest(RequestMethod.GET, "/foo").header(HttpHeaders.HOST, "localhost")
.header(HttpHeaders.COOKIE, "name1=value1")
.header(HttpHeaders.COOKIE, "name2=value2"));
}
@Test
public void getRequestWithQueryString() throws IOException {
new HttpRequestSnippet().document(this.operationBuilder.request("http://localhost/foo?bar=baz").build());
assertThat(this.generatedSnippets.httpRequest())
.is(httpRequest(RequestMethod.GET, "/foo?bar=baz").header(HttpHeaders.HOST, "localhost"));
.is(httpRequest(RequestMethod.GET, "/foo?bar=baz").header(HttpHeaders.HOST, "localhost"));
}
@Test
public void getRequestWithQueryStringWithNoValue() throws IOException {
new HttpRequestSnippet().document(this.operationBuilder.request("http://localhost/foo?bar").build());
assertThat(this.generatedSnippets.httpRequest())
.is(httpRequest(RequestMethod.GET, "/foo?bar").header(HttpHeaders.HOST, "localhost"));
.is(httpRequest(RequestMethod.GET, "/foo?bar").header(HttpHeaders.HOST, "localhost"));
}
@Test
public void getWithPartiallyOverlappingQueryStringAndParameters() throws IOException {
new HttpRequestSnippet().document(this.operationBuilder.request("http://localhost/foo?a=alpha")
.param("a", "alpha").param("b", "bravo").build());
.param("a", "alpha")
.param("b", "bravo")
.build());
assertThat(this.generatedSnippets.httpRequest())
.is(httpRequest(RequestMethod.GET, "/foo?a=alpha&b=bravo").header(HttpHeaders.HOST, "localhost"));
.is(httpRequest(RequestMethod.GET, "/foo?a=alpha&b=bravo").header(HttpHeaders.HOST, "localhost"));
}
@Test
public void getWithTotallyOverlappingQueryStringAndParameters() throws IOException {
new HttpRequestSnippet().document(this.operationBuilder.request("http://localhost/foo?a=alpha&b=bravo")
.param("a", "alpha").param("b", "bravo").build());
.param("a", "alpha")
.param("b", "bravo")
.build());
assertThat(this.generatedSnippets.httpRequest())
.is(httpRequest(RequestMethod.GET, "/foo?a=alpha&b=bravo").header(HttpHeaders.HOST, "localhost"));
.is(httpRequest(RequestMethod.GET, "/foo?a=alpha&b=bravo").header(HttpHeaders.HOST, "localhost"));
}
@Test
public void postRequestWithContent() throws IOException {
String content = "Hello, world";
new HttpRequestSnippet().document(
this.operationBuilder.request("http://localhost/foo").method("POST").content(content).build());
new HttpRequestSnippet()
.document(this.operationBuilder.request("http://localhost/foo").method("POST").content(content).build());
assertThat(this.generatedSnippets.httpRequest())
.is(httpRequest(RequestMethod.POST, "/foo").header(HttpHeaders.HOST, "localhost").content(content)
.header(HttpHeaders.CONTENT_LENGTH, content.getBytes().length));
.is(httpRequest(RequestMethod.POST, "/foo").header(HttpHeaders.HOST, "localhost")
.content(content)
.header(HttpHeaders.CONTENT_LENGTH, content.getBytes().length));
}
@Test
public void postRequestWithContentAndParameters() throws IOException {
String content = "Hello, world";
new HttpRequestSnippet().document(this.operationBuilder.request("http://localhost/foo").method("POST")
.param("a", "alpha").content(content).build());
new HttpRequestSnippet().document(this.operationBuilder.request("http://localhost/foo")
.method("POST")
.param("a", "alpha")
.content(content)
.build());
assertThat(this.generatedSnippets.httpRequest())
.is(httpRequest(RequestMethod.POST, "/foo?a=alpha").header(HttpHeaders.HOST, "localhost")
.content(content).header(HttpHeaders.CONTENT_LENGTH, content.getBytes().length));
.is(httpRequest(RequestMethod.POST, "/foo?a=alpha").header(HttpHeaders.HOST, "localhost")
.content(content)
.header(HttpHeaders.CONTENT_LENGTH, content.getBytes().length));
}
@Test
public void postRequestWithContentAndDisjointQueryStringAndParameters() throws IOException {
String content = "Hello, world";
new HttpRequestSnippet().document(this.operationBuilder.request("http://localhost/foo?b=bravo").method("POST")
.param("a", "alpha").content(content).build());
new HttpRequestSnippet().document(this.operationBuilder.request("http://localhost/foo?b=bravo")
.method("POST")
.param("a", "alpha")
.content(content)
.build());
assertThat(this.generatedSnippets.httpRequest())
.is(httpRequest(RequestMethod.POST, "/foo?b=bravo&a=alpha").header(HttpHeaders.HOST, "localhost")
.content(content).header(HttpHeaders.CONTENT_LENGTH, content.getBytes().length));
.is(httpRequest(RequestMethod.POST, "/foo?b=bravo&a=alpha").header(HttpHeaders.HOST, "localhost")
.content(content)
.header(HttpHeaders.CONTENT_LENGTH, content.getBytes().length));
}
@Test
public void postRequestWithContentAndPartiallyOverlappingQueryStringAndParameters() throws IOException {
String content = "Hello, world";
new HttpRequestSnippet().document(this.operationBuilder.request("http://localhost/foo?b=bravo").method("POST")
.param("a", "alpha").param("b", "bravo").content(content).build());
new HttpRequestSnippet().document(this.operationBuilder.request("http://localhost/foo?b=bravo")
.method("POST")
.param("a", "alpha")
.param("b", "bravo")
.content(content)
.build());
assertThat(this.generatedSnippets.httpRequest())
.is(httpRequest(RequestMethod.POST, "/foo?b=bravo&a=alpha").header(HttpHeaders.HOST, "localhost")
.content(content).header(HttpHeaders.CONTENT_LENGTH, content.getBytes().length));
.is(httpRequest(RequestMethod.POST, "/foo?b=bravo&a=alpha").header(HttpHeaders.HOST, "localhost")
.content(content)
.header(HttpHeaders.CONTENT_LENGTH, content.getBytes().length));
}
@Test
public void postRequestWithContentAndTotallyOverlappingQueryStringAndParameters() throws IOException {
String content = "Hello, world";
new HttpRequestSnippet().document(this.operationBuilder.request("http://localhost/foo?b=bravo&a=alpha")
.method("POST").param("a", "alpha").param("b", "bravo").content(content).build());
.method("POST")
.param("a", "alpha")
.param("b", "bravo")
.content(content)
.build());
assertThat(this.generatedSnippets.httpRequest())
.is(httpRequest(RequestMethod.POST, "/foo?b=bravo&a=alpha").header(HttpHeaders.HOST, "localhost")
.content(content).header(HttpHeaders.CONTENT_LENGTH, content.getBytes().length));
.is(httpRequest(RequestMethod.POST, "/foo?b=bravo&a=alpha").header(HttpHeaders.HOST, "localhost")
.content(content)
.header(HttpHeaders.CONTENT_LENGTH, content.getBytes().length));
}
@Test
public void postRequestWithOverlappingParametersAndFormUrlEncodedBody() throws IOException {
String content = "a=alpha&b=bravo";
new HttpRequestSnippet().document(
this.operationBuilder.request("http://localhost/foo").method("POST").content("a=alpha&b=bravo")
.header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_FORM_URLENCODED_VALUE)
.param("a", "alpha").param("b", "bravo").build());
new HttpRequestSnippet().document(this.operationBuilder.request("http://localhost/foo")
.method("POST")
.content("a=alpha&b=bravo")
.header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_FORM_URLENCODED_VALUE)
.param("a", "alpha")
.param("b", "bravo")
.build());
assertThat(this.generatedSnippets.httpRequest()).is(httpRequest(RequestMethod.POST, "/foo")
.header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_FORM_URLENCODED_VALUE)
.header(HttpHeaders.HOST, "localhost").content(content)
.header(HttpHeaders.CONTENT_LENGTH, content.getBytes().length));
.header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_FORM_URLENCODED_VALUE)
.header(HttpHeaders.HOST, "localhost")
.content(content)
.header(HttpHeaders.CONTENT_LENGTH, content.getBytes().length));
}
@Test
public void postRequestWithCharset() throws IOException {
String japaneseContent = "\u30b3\u30f3\u30c6\u30f3\u30c4";
byte[] contentBytes = japaneseContent.getBytes("UTF-8");
new HttpRequestSnippet().document(this.operationBuilder.request("http://localhost/foo").method("POST")
.header("Content-Type", "text/plain;charset=UTF-8").content(contentBytes).build());
assertThat(this.generatedSnippets.httpRequest()).is(httpRequest(RequestMethod.POST, "/foo")
.header("Content-Type", "text/plain;charset=UTF-8").header(HttpHeaders.HOST, "localhost")
.header(HttpHeaders.CONTENT_LENGTH, contentBytes.length).content(japaneseContent));
new HttpRequestSnippet().document(this.operationBuilder.request("http://localhost/foo")
.method("POST")
.header("Content-Type", "text/plain;charset=UTF-8")
.content(contentBytes)
.build());
assertThat(this.generatedSnippets.httpRequest())
.is(httpRequest(RequestMethod.POST, "/foo").header("Content-Type", "text/plain;charset=UTF-8")
.header(HttpHeaders.HOST, "localhost")
.header(HttpHeaders.CONTENT_LENGTH, contentBytes.length)
.content(japaneseContent));
}
@Test
public void postRequestWithParameter() throws IOException {
new HttpRequestSnippet().document(this.operationBuilder.request("http://localhost/foo").method("POST")
.param("b&r", "baz").param("a", "alpha").build());
new HttpRequestSnippet().document(this.operationBuilder.request("http://localhost/foo")
.method("POST")
.param("b&r", "baz")
.param("a", "alpha")
.build());
assertThat(this.generatedSnippets.httpRequest())
.is(httpRequest(RequestMethod.POST, "/foo").header(HttpHeaders.HOST, "localhost")
.header("Content-Type", "application/x-www-form-urlencoded").content("b%26r=baz&a=alpha"));
.is(httpRequest(RequestMethod.POST, "/foo").header(HttpHeaders.HOST, "localhost")
.header("Content-Type", "application/x-www-form-urlencoded")
.content("b%26r=baz&a=alpha"));
}
@Test
public void postRequestWithParameterWithNoValue() throws IOException {
new HttpRequestSnippet()
.document(this.operationBuilder.request("http://localhost/foo").method("POST").param("bar").build());
.document(this.operationBuilder.request("http://localhost/foo").method("POST").param("bar").build());
assertThat(this.generatedSnippets.httpRequest())
.is(httpRequest(RequestMethod.POST, "/foo").header(HttpHeaders.HOST, "localhost")
.header("Content-Type", "application/x-www-form-urlencoded").content("bar="));
.is(httpRequest(RequestMethod.POST, "/foo").header(HttpHeaders.HOST, "localhost")
.header("Content-Type", "application/x-www-form-urlencoded")
.content("bar="));
}
@Test
public void putRequestWithContent() throws IOException {
String content = "Hello, world";
new HttpRequestSnippet()
.document(this.operationBuilder.request("http://localhost/foo").method("PUT").content(content).build());
.document(this.operationBuilder.request("http://localhost/foo").method("PUT").content(content).build());
assertThat(this.generatedSnippets.httpRequest())
.is(httpRequest(RequestMethod.PUT, "/foo").header(HttpHeaders.HOST, "localhost").content(content)
.header(HttpHeaders.CONTENT_LENGTH, content.getBytes().length));
.is(httpRequest(RequestMethod.PUT, "/foo").header(HttpHeaders.HOST, "localhost")
.content(content)
.header(HttpHeaders.CONTENT_LENGTH, content.getBytes().length));
}
@Test
public void putRequestWithParameter() throws IOException {
new HttpRequestSnippet().document(this.operationBuilder.request("http://localhost/foo").method("PUT")
.param("b&r", "baz").param("a", "alpha").build());
new HttpRequestSnippet().document(this.operationBuilder.request("http://localhost/foo")
.method("PUT")
.param("b&r", "baz")
.param("a", "alpha")
.build());
assertThat(this.generatedSnippets.httpRequest())
.is(httpRequest(RequestMethod.PUT, "/foo").header(HttpHeaders.HOST, "localhost")
.header("Content-Type", "application/x-www-form-urlencoded").content("b%26r=baz&a=alpha"));
.is(httpRequest(RequestMethod.PUT, "/foo").header(HttpHeaders.HOST, "localhost")
.header("Content-Type", "application/x-www-form-urlencoded")
.content("b%26r=baz&a=alpha"));
}
@Test
public void putRequestWithTotallyOverlappingQueryStringAndParameters() throws IOException {
new HttpRequestSnippet().document(this.operationBuilder.request("http://localhost/foo?a=alpha&b=bravo")
.method("PUT").param("a", "alpha").param("b", "bravo").build());
.method("PUT")
.param("a", "alpha")
.param("b", "bravo")
.build());
assertThat(this.generatedSnippets.httpRequest())
.is(httpRequest(RequestMethod.PUT, "/foo?a=alpha&b=bravo").header(HttpHeaders.HOST, "localhost"));
.is(httpRequest(RequestMethod.PUT, "/foo?a=alpha&b=bravo").header(HttpHeaders.HOST, "localhost"));
}
@Test
public void multipartPost() throws IOException {
new HttpRequestSnippet().document(this.operationBuilder.request("http://localhost/upload").method("POST")
.header(HttpHeaders.CONTENT_TYPE, MediaType.MULTIPART_FORM_DATA_VALUE)
.part("image", "<< data >>".getBytes()).build());
new HttpRequestSnippet().document(this.operationBuilder.request("http://localhost/upload")
.method("POST")
.header(HttpHeaders.CONTENT_TYPE, MediaType.MULTIPART_FORM_DATA_VALUE)
.part("image", "<< data >>".getBytes())
.build());
String expectedContent = createPart(
String.format("Content-Disposition: " + "form-data; " + "name=image%n%n<< data >>"));
assertThat(this.generatedSnippets.httpRequest()).is(httpRequest(RequestMethod.POST, "/upload")
.header("Content-Type", "multipart/form-data; boundary=" + BOUNDARY)
.header(HttpHeaders.HOST, "localhost").content(expectedContent));
.header("Content-Type", "multipart/form-data; boundary=" + BOUNDARY)
.header(HttpHeaders.HOST, "localhost")
.content(expectedContent));
}
@Test
public void multipartPostWithFilename() throws IOException {
new HttpRequestSnippet().document(this.operationBuilder.request("http://localhost/upload").method("POST")
.header(HttpHeaders.CONTENT_TYPE, MediaType.MULTIPART_FORM_DATA_VALUE)
.part("image", "<< data >>".getBytes()).submittedFileName("image.png").build());
new HttpRequestSnippet().document(this.operationBuilder.request("http://localhost/upload")
.method("POST")
.header(HttpHeaders.CONTENT_TYPE, MediaType.MULTIPART_FORM_DATA_VALUE)
.part("image", "<< data >>".getBytes())
.submittedFileName("image.png")
.build());
String expectedContent = createPart(String
.format("Content-Disposition: " + "form-data; " + "name=image; filename=image.png%n%n<< data >>"));
.format("Content-Disposition: " + "form-data; " + "name=image; filename=image.png%n%n<< data >>"));
assertThat(this.generatedSnippets.httpRequest()).is(httpRequest(RequestMethod.POST, "/upload")
.header("Content-Type", "multipart/form-data; boundary=" + BOUNDARY)
.header(HttpHeaders.HOST, "localhost").content(expectedContent));
.header("Content-Type", "multipart/form-data; boundary=" + BOUNDARY)
.header(HttpHeaders.HOST, "localhost")
.content(expectedContent));
}
@Test
public void multipartPostWithParameters() throws IOException {
new HttpRequestSnippet().document(this.operationBuilder.request("http://localhost/upload").method("POST")
.header(HttpHeaders.CONTENT_TYPE, MediaType.MULTIPART_FORM_DATA_VALUE).param("a", "apple", "avocado")
.param("b", "banana").part("image", "<< data >>".getBytes()).build());
new HttpRequestSnippet().document(this.operationBuilder.request("http://localhost/upload")
.method("POST")
.header(HttpHeaders.CONTENT_TYPE, MediaType.MULTIPART_FORM_DATA_VALUE)
.param("a", "apple", "avocado")
.param("b", "banana")
.part("image", "<< data >>".getBytes())
.build());
String param1Part = createPart(String.format("Content-Disposition: form-data; " + "name=a%n%napple"), false);
String param2Part = createPart(String.format("Content-Disposition: form-data; " + "name=a%n%navocado"), false);
String param3Part = createPart(String.format("Content-Disposition: form-data; " + "name=b%n%nbanana"), false);
String filePart = createPart(String.format("Content-Disposition: form-data; " + "name=image%n%n<< data >>"));
String expectedContent = param1Part + param2Part + param3Part + filePart;
assertThat(this.generatedSnippets.httpRequest()).is(httpRequest(RequestMethod.POST, "/upload")
.header("Content-Type", "multipart/form-data; boundary=" + BOUNDARY)
.header(HttpHeaders.HOST, "localhost").content(expectedContent));
.header("Content-Type", "multipart/form-data; boundary=" + BOUNDARY)
.header(HttpHeaders.HOST, "localhost")
.content(expectedContent));
}
@Test
public void multipartPostWithOverlappingPartsAndParameters() throws IOException {
new HttpRequestSnippet().document(this.operationBuilder.request("http://localhost/upload").method("POST")
.header(HttpHeaders.CONTENT_TYPE, MediaType.MULTIPART_FORM_DATA_VALUE).param("a", "apple")
.part("a", "apple".getBytes()).and().part("image", "<< data >>".getBytes()).build());
new HttpRequestSnippet().document(this.operationBuilder.request("http://localhost/upload")
.method("POST")
.header(HttpHeaders.CONTENT_TYPE, MediaType.MULTIPART_FORM_DATA_VALUE)
.param("a", "apple")
.part("a", "apple".getBytes())
.and()
.part("image", "<< data >>".getBytes())
.build());
String paramPart = createPart(String.format("Content-Disposition: form-data; " + "name=a%n%napple"), false);
String filePart = createPart(String.format("Content-Disposition: form-data; " + "name=image%n%n<< data >>"));
String expectedContent = paramPart + filePart;
assertThat(this.generatedSnippets.httpRequest()).is(httpRequest(RequestMethod.POST, "/upload")
.header("Content-Type", "multipart/form-data; boundary=" + BOUNDARY)
.header(HttpHeaders.HOST, "localhost").content(expectedContent));
.header("Content-Type", "multipart/form-data; boundary=" + BOUNDARY)
.header(HttpHeaders.HOST, "localhost")
.content(expectedContent));
}
@Test
public void multipartPostWithParameterWithNoValue() throws IOException {
new HttpRequestSnippet().document(this.operationBuilder.request("http://localhost/upload").method("POST")
.header(HttpHeaders.CONTENT_TYPE, MediaType.MULTIPART_FORM_DATA_VALUE).param("a")
.part("image", "<< data >>".getBytes()).build());
new HttpRequestSnippet().document(this.operationBuilder.request("http://localhost/upload")
.method("POST")
.header(HttpHeaders.CONTENT_TYPE, MediaType.MULTIPART_FORM_DATA_VALUE)
.param("a")
.part("image", "<< data >>".getBytes())
.build());
String paramPart = createPart(String.format("Content-Disposition: form-data; " + "name=a%n"), false);
String filePart = createPart(String.format("Content-Disposition: form-data; " + "name=image%n%n<< data >>"));
String expectedContent = paramPart + filePart;
assertThat(this.generatedSnippets.httpRequest()).is(httpRequest(RequestMethod.POST, "/upload")
.header("Content-Type", "multipart/form-data; boundary=" + BOUNDARY)
.header(HttpHeaders.HOST, "localhost").content(expectedContent));
.header("Content-Type", "multipart/form-data; boundary=" + BOUNDARY)
.header(HttpHeaders.HOST, "localhost")
.content(expectedContent));
}
@Test
public void multipartPostWithContentType() throws IOException {
new HttpRequestSnippet().document(this.operationBuilder.request("http://localhost/upload").method("POST")
.header(HttpHeaders.CONTENT_TYPE, MediaType.MULTIPART_FORM_DATA_VALUE)
.part("image", "<< data >>".getBytes()).header(HttpHeaders.CONTENT_TYPE, MediaType.IMAGE_PNG_VALUE)
.build());
new HttpRequestSnippet().document(this.operationBuilder.request("http://localhost/upload")
.method("POST")
.header(HttpHeaders.CONTENT_TYPE, MediaType.MULTIPART_FORM_DATA_VALUE)
.part("image", "<< data >>".getBytes())
.header(HttpHeaders.CONTENT_TYPE, MediaType.IMAGE_PNG_VALUE)
.build());
String expectedContent = createPart(String
.format("Content-Disposition: form-data; name=image%nContent-Type: " + "image/png%n%n<< data >>"));
.format("Content-Disposition: form-data; name=image%nContent-Type: " + "image/png%n%n<< data >>"));
assertThat(this.generatedSnippets.httpRequest()).is(httpRequest(RequestMethod.POST, "/upload")
.header("Content-Type", "multipart/form-data; boundary=" + BOUNDARY)
.header(HttpHeaders.HOST, "localhost").content(expectedContent));
.header("Content-Type", "multipart/form-data; boundary=" + BOUNDARY)
.header(HttpHeaders.HOST, "localhost")
.content(expectedContent));
}
@Test
public void getRequestWithCustomHost() throws IOException {
new HttpRequestSnippet().document(this.operationBuilder.request("http://localhost/foo")
.header(HttpHeaders.HOST, "api.example.com").build());
.header(HttpHeaders.HOST, "api.example.com")
.build());
assertThat(this.generatedSnippets.httpRequest())
.is(httpRequest(RequestMethod.GET, "/foo").header(HttpHeaders.HOST, "api.example.com"));
.is(httpRequest(RequestMethod.GET, "/foo").header(HttpHeaders.HOST, "api.example.com"));
}
@Test
@@ -324,24 +399,28 @@ public class HttpRequestSnippetTests extends AbstractSnippetTests {
given(resolver.resolveTemplateResource("http-request")).willReturn(snippetResource("http-request-with-title"));
new HttpRequestSnippet(attributes(key("title").value("Title for the request"))).document(
this.operationBuilder.attribute(TemplateEngine.class.getName(), new MustacheTemplateEngine(resolver))
.request("http://localhost/foo").build());
.request("http://localhost/foo")
.build());
assertThat(this.generatedSnippets.httpRequest()).contains("Title for the request");
}
@Test
public void deleteWithParameters() throws IOException {
new HttpRequestSnippet().document(this.operationBuilder.request("http://localhost/foo").method("DELETE")
.param("a", "alpha").param("b", "bravo").build());
new HttpRequestSnippet().document(this.operationBuilder.request("http://localhost/foo")
.method("DELETE")
.param("a", "alpha")
.param("b", "bravo")
.build());
assertThat(this.generatedSnippets.httpRequest())
.is(httpRequest(RequestMethod.DELETE, "/foo?a=alpha&b=bravo").header("Host", "localhost"));
.is(httpRequest(RequestMethod.DELETE, "/foo?a=alpha&b=bravo").header("Host", "localhost"));
}
@Test
public void deleteWithQueryString() throws IOException {
new HttpRequestSnippet().document(
this.operationBuilder.request("http://localhost/foo?a=alpha&b=bravo").method("DELETE").build());
new HttpRequestSnippet()
.document(this.operationBuilder.request("http://localhost/foo?a=alpha&b=bravo").method("DELETE").build());
assertThat(this.generatedSnippets.httpRequest())
.is(httpRequest(RequestMethod.DELETE, "/foo?a=alpha&b=bravo").header("Host", "localhost"));
.is(httpRequest(RequestMethod.DELETE, "/foo?a=alpha&b=bravo").header("Host", "localhost"));
}
private String createPart(String content) {

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2014-2019 the original author or authors.
* Copyright 2014-2023 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -56,16 +56,18 @@ public class HttpResponseSnippetTests extends AbstractSnippetTests {
@Test
public void nonOkResponse() throws IOException {
new HttpResponseSnippet()
.document(this.operationBuilder.response().status(HttpStatus.BAD_REQUEST.value()).build());
.document(this.operationBuilder.response().status(HttpStatus.BAD_REQUEST.value()).build());
assertThat(this.generatedSnippets.httpResponse()).is(httpResponse(HttpStatus.BAD_REQUEST));
}
@Test
public void responseWithHeaders() throws IOException {
new HttpResponseSnippet().document(this.operationBuilder.response()
.header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE).header("a", "alpha").build());
.header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE)
.header("a", "alpha")
.build());
assertThat(this.generatedSnippets.httpResponse())
.is(httpResponse(HttpStatus.OK).header("Content-Type", "application/json").header("a", "alpha"));
.is(httpResponse(HttpStatus.OK).header("Content-Type", "application/json").header("a", "alpha"));
}
@Test
@@ -73,7 +75,7 @@ public class HttpResponseSnippetTests extends AbstractSnippetTests {
String content = "content";
new HttpResponseSnippet().document(this.operationBuilder.response().content(content).build());
assertThat(this.generatedSnippets.httpResponse()).is(httpResponse(HttpStatus.OK).content(content)
.header(HttpHeaders.CONTENT_LENGTH, content.getBytes().length));
.header(HttpHeaders.CONTENT_LENGTH, content.getBytes().length));
}
@Test
@@ -81,19 +83,23 @@ public class HttpResponseSnippetTests extends AbstractSnippetTests {
String japaneseContent = "\u30b3\u30f3\u30c6\u30f3\u30c4";
byte[] contentBytes = japaneseContent.getBytes("UTF-8");
new HttpResponseSnippet().document(this.operationBuilder.response()
.header("Content-Type", "text/plain;charset=UTF-8").content(contentBytes).build());
.header("Content-Type", "text/plain;charset=UTF-8")
.content(contentBytes)
.build());
assertThat(this.generatedSnippets.httpResponse())
.is(httpResponse(HttpStatus.OK).header("Content-Type", "text/plain;charset=UTF-8")
.content(japaneseContent).header(HttpHeaders.CONTENT_LENGTH, contentBytes.length));
.is(httpResponse(HttpStatus.OK).header("Content-Type", "text/plain;charset=UTF-8")
.content(japaneseContent)
.header(HttpHeaders.CONTENT_LENGTH, contentBytes.length));
}
@Test
public void responseWithCustomSnippetAttributes() throws IOException {
TemplateResourceResolver resolver = mock(TemplateResourceResolver.class);
given(resolver.resolveTemplateResource("http-response"))
.willReturn(snippetResource("http-response-with-title"));
new HttpResponseSnippet(attributes(key("title").value("Title for the response"))).document(this.operationBuilder
.attribute(TemplateEngine.class.getName(), new MustacheTemplateEngine(resolver)).build());
.willReturn(snippetResource("http-response-with-title"));
new HttpResponseSnippet(attributes(key("title").value("Title for the response"))).document(
this.operationBuilder.attribute(TemplateEngine.class.getName(), new MustacheTemplateEngine(resolver))
.build());
assertThat(this.generatedSnippets.httpResponse()).contains("Title for the response");
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2014-2019 the original author or authors.
* Copyright 2014-2023 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -49,7 +49,7 @@ public class ContentTypeLinkExtractorTests {
public void extractionFailsWithNullContentType() throws IOException {
this.thrown.expect(IllegalStateException.class);
new ContentTypeLinkExtractor()
.extractLinks(this.responseFactory.create(HttpStatus.OK.value(), new HttpHeaders(), null));
.extractLinks(this.responseFactory.create(HttpStatus.OK.value(), new HttpHeaders(), null));
}
@Test

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2014-2019 the original author or authors.
* Copyright 2014-2023 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -73,7 +73,7 @@ public class LinkExtractorsPayloadTests {
@Test
public void multipleLinksWithDifferentRels() throws IOException {
Map<String, List<Link>> links = this.linkExtractor
.extractLinks(createResponse("multiple-links-different-rels"));
.extractLinks(createResponse("multiple-links-different-rels"));
assertLinks(Arrays.asList(new Link("alpha", "https://alpha.example.com", "Alpha"),
new Link("bravo", "https://bravo.example.com")), links);
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2014-2022 the original author or authors.
* Copyright 2014-2023 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -42,37 +42,39 @@ public class LinksSnippetFailureTests {
@Test
public void undocumentedLink() {
assertThatExceptionOfType(SnippetException.class)
.isThrownBy(() -> new LinksSnippet(new StubLinkExtractor().withLinks(new Link("foo", "bar")),
Collections.<LinkDescriptor>emptyList()).document(this.operationBuilder.build()))
.withMessage("Links with the following relations were not documented: [foo]");
.isThrownBy(() -> new LinksSnippet(new StubLinkExtractor().withLinks(new Link("foo", "bar")),
Collections.<LinkDescriptor>emptyList())
.document(this.operationBuilder.build()))
.withMessage("Links with the following relations were not documented: [foo]");
}
@Test
public void missingLink() {
assertThatExceptionOfType(SnippetException.class)
.isThrownBy(() -> new LinksSnippet(new StubLinkExtractor(),
Arrays.asList(new LinkDescriptor("foo").description("bar")))
.document(this.operationBuilder.build()))
.withMessage("Links with the following relations were not found in the response: [foo]");
.isThrownBy(() -> new LinksSnippet(new StubLinkExtractor(),
Arrays.asList(new LinkDescriptor("foo").description("bar")))
.document(this.operationBuilder.build()))
.withMessage("Links with the following relations were not found in the response: [foo]");
}
@Test
public void undocumentedLinkAndMissingLink() {
assertThatExceptionOfType(SnippetException.class)
.isThrownBy(() -> new LinksSnippet(new StubLinkExtractor().withLinks(new Link("a", "alpha")),
Arrays.asList(new LinkDescriptor("foo").description("bar")))
.document(this.operationBuilder.build()))
.withMessage("Links with the following relations were not documented: [a]. Links with the following"
+ " relations were not found in the response: [foo]");
.isThrownBy(() -> new LinksSnippet(new StubLinkExtractor().withLinks(new Link("a", "alpha")),
Arrays.asList(new LinkDescriptor("foo").description("bar")))
.document(this.operationBuilder.build()))
.withMessage("Links with the following relations were not documented: [a]. Links with the following"
+ " relations were not found in the response: [foo]");
}
@Test
public void linkWithNoDescription() {
assertThatExceptionOfType(SnippetException.class)
.isThrownBy(() -> new LinksSnippet(new StubLinkExtractor().withLinks(new Link("foo", "bar")),
Arrays.asList(new LinkDescriptor("foo"))).document(this.operationBuilder.build()))
.withMessage("No description was provided for the link with rel 'foo' and no title was available"
+ " from the link in the payload");
.isThrownBy(() -> new LinksSnippet(new StubLinkExtractor().withLinks(new Link("foo", "bar")),
Arrays.asList(new LinkDescriptor("foo")))
.document(this.operationBuilder.build()))
.withMessage("No description was provided for the link with rel 'foo' and no title was available"
+ " from the link in the payload");
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2014-2019 the original author or authors.
* Copyright 2014-2023 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -49,7 +49,7 @@ public class LinksSnippetTests extends AbstractSnippetTests {
public void ignoredLink() throws IOException {
new LinksSnippet(new StubLinkExtractor().withLinks(new Link("a", "alpha"), new Link("b", "bravo")),
Arrays.asList(new LinkDescriptor("a").ignored(), new LinkDescriptor("b").description("Link b")))
.document(this.operationBuilder.build());
.document(this.operationBuilder.build());
assertThat(this.generatedSnippets.links()).is(tableWithHeader("Relation", "Description").row("`b`", "Link b"));
}
@@ -57,7 +57,7 @@ public class LinksSnippetTests extends AbstractSnippetTests {
public void allUndocumentedLinksCanBeIgnored() throws IOException {
new LinksSnippet(new StubLinkExtractor().withLinks(new Link("a", "alpha"), new Link("b", "bravo")),
Arrays.asList(new LinkDescriptor("b").description("Link b")), true)
.document(this.operationBuilder.build());
.document(this.operationBuilder.build());
assertThat(this.generatedSnippets.links()).is(tableWithHeader("Relation", "Description").row("`b`", "Link b"));
}
@@ -65,7 +65,7 @@ public class LinksSnippetTests extends AbstractSnippetTests {
public void presentOptionalLink() throws IOException {
new LinksSnippet(new StubLinkExtractor().withLinks(new Link("foo", "blah")),
Arrays.asList(new LinkDescriptor("foo").description("bar").optional()))
.document(this.operationBuilder.build());
.document(this.operationBuilder.build());
assertThat(this.generatedSnippets.links()).is(tableWithHeader("Relation", "Description").row("`foo`", "bar"));
}
@@ -73,7 +73,7 @@ public class LinksSnippetTests extends AbstractSnippetTests {
public void missingOptionalLink() throws IOException {
new LinksSnippet(new StubLinkExtractor(),
Arrays.asList(new LinkDescriptor("foo").description("bar").optional()))
.document(this.operationBuilder.build());
.document(this.operationBuilder.build());
assertThat(this.generatedSnippets.links()).is(tableWithHeader("Relation", "Description").row("`foo`", "bar"));
}
@@ -81,9 +81,9 @@ public class LinksSnippetTests extends AbstractSnippetTests {
public void documentedLinks() throws IOException {
new LinksSnippet(new StubLinkExtractor().withLinks(new Link("a", "alpha"), new Link("b", "bravo")),
Arrays.asList(new LinkDescriptor("a").description("one"), new LinkDescriptor("b").description("two")))
.document(this.operationBuilder.build());
.document(this.operationBuilder.build());
assertThat(this.generatedSnippets.links())
.is(tableWithHeader("Relation", "Description").row("`a`", "one").row("`b`", "two"));
.is(tableWithHeader("Relation", "Description").row("`a`", "one").row("`b`", "two"));
}
@Test
@@ -91,9 +91,9 @@ public class LinksSnippetTests extends AbstractSnippetTests {
new LinksSnippet(
new StubLinkExtractor().withLinks(new Link("a", "alpha", "Link a"), new Link("b", "bravo", "Link b")),
Arrays.asList(new LinkDescriptor("a").description("one"), new LinkDescriptor("b")))
.document(this.operationBuilder.build());
.document(this.operationBuilder.build());
assertThat(this.generatedSnippets.links())
.is(tableWithHeader("Relation", "Description").row("`a`", "one").row("`b`", "Link b"));
.is(tableWithHeader("Relation", "Description").row("`a`", "one").row("`b`", "Link b"));
}
@Test
@@ -103,9 +103,9 @@ public class LinksSnippetTests extends AbstractSnippetTests {
new LinksSnippet(new StubLinkExtractor().withLinks(new Link("a", "alpha"), new Link("b", "bravo")),
Arrays.asList(new LinkDescriptor("a").description("one"), new LinkDescriptor("b").description("two")),
attributes(key("title").value("Title for the links")))
.document(this.operationBuilder
.attribute(TemplateEngine.class.getName(), new MustacheTemplateEngine(resolver))
.build());
.document(this.operationBuilder
.attribute(TemplateEngine.class.getName(), new MustacheTemplateEngine(resolver))
.build());
assertThat(this.generatedSnippets.links()).contains("Title for the links");
}
@@ -116,30 +116,31 @@ public class LinksSnippetTests extends AbstractSnippetTests {
new LinksSnippet(new StubLinkExtractor().withLinks(new Link("a", "alpha"), new Link("b", "bravo")),
Arrays.asList(new LinkDescriptor("a").description("one").attributes(key("foo").value("alpha")),
new LinkDescriptor("b").description("two").attributes(key("foo").value("bravo"))))
.document(this.operationBuilder
.attribute(TemplateEngine.class.getName(), new MustacheTemplateEngine(resolver))
.build());
assertThat(this.generatedSnippets.links()).is(
tableWithHeader("Relation", "Description", "Foo").row("a", "one", "alpha").row("b", "two", "bravo"));
.document(this.operationBuilder
.attribute(TemplateEngine.class.getName(), new MustacheTemplateEngine(resolver))
.build());
assertThat(this.generatedSnippets.links())
.is(tableWithHeader("Relation", "Description", "Foo").row("a", "one", "alpha").row("b", "two", "bravo"));
}
@Test
public void additionalDescriptors() throws IOException {
HypermediaDocumentation
.links(new StubLinkExtractor().withLinks(new Link("a", "alpha"), new Link("b", "bravo")),
new LinkDescriptor("a").description("one"))
.and(new LinkDescriptor("b").description("two")).document(this.operationBuilder.build());
.links(new StubLinkExtractor().withLinks(new Link("a", "alpha"), new Link("b", "bravo")),
new LinkDescriptor("a").description("one"))
.and(new LinkDescriptor("b").description("two"))
.document(this.operationBuilder.build());
assertThat(this.generatedSnippets.links())
.is(tableWithHeader("Relation", "Description").row("`a`", "one").row("`b`", "two"));
.is(tableWithHeader("Relation", "Description").row("`a`", "one").row("`b`", "two"));
}
@Test
public void tableCellContentIsEscapedWhenNecessary() throws IOException {
new LinksSnippet(new StubLinkExtractor().withLinks(new Link("Foo|Bar", "foo")),
Arrays.asList(new LinkDescriptor("Foo|Bar").description("one|two")))
.document(this.operationBuilder.build());
.document(this.operationBuilder.build());
assertThat(this.generatedSnippets.links()).is(tableWithHeader("Relation", "Description")
.row(escapeIfNecessary("`Foo|Bar`"), escapeIfNecessary("one|two")));
.row(escapeIfNecessary("`Foo|Bar`"), escapeIfNecessary("one|two")));
}
private String escapeIfNecessary(String input) {

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2014-2019 the original author or authors.
* Copyright 2014-2023 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -72,8 +72,8 @@ public class QueryStringParserTests {
@Test
public void malformedParameter() {
assertThatIllegalArgumentException()
.isThrownBy(() -> this.queryStringParser.parse(URI.create("http://localhost?a=apple=avocado")))
.withMessage("The parameter 'a=apple=avocado' is malformed");
.isThrownBy(() -> this.queryStringParser.parse(URI.create("http://localhost?a=apple=avocado")))
.withMessage("The parameter 'a=apple=avocado' is malformed");
}
@Test

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2014-2019 the original author or authors.
* Copyright 2014-2023 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -48,7 +48,8 @@ public class DelegatingOperationRequestPreprocessorTests {
given(preprocessor3.preprocess(preprocessedRequest2)).willReturn(preprocessedRequest3);
OperationRequest result = new DelegatingOperationRequestPreprocessor(
Arrays.asList(preprocessor1, preprocessor2, preprocessor3)).preprocess(originalRequest);
Arrays.asList(preprocessor1, preprocessor2, preprocessor3))
.preprocess(originalRequest);
assertThat(result).isSameAs(preprocessedRequest3);
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2014-2019 the original author or authors.
* Copyright 2014-2023 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -48,7 +48,8 @@ public class DelegatingOperationResponsePreprocessorTests {
given(preprocessor3.preprocess(preprocessedResponse2)).willReturn(preprocessedResponse3);
OperationResponse result = new DelegatingOperationResponsePreprocessor(
Arrays.asList(preprocessor1, preprocessor2, preprocessor3)).preprocess(originalResponse);
Arrays.asList(preprocessor1, preprocessor2, preprocessor3))
.preprocess(originalResponse);
assertThat(result).isSameAs(preprocessedResponse3);
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2014-2019 the original author or authors.
* Copyright 2014-2023 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -49,32 +49,32 @@ public class LinkMaskingContentModifierTests {
@Test
public void halLinksAreMasked() throws Exception {
assertThat(this.contentModifier.modifyContent(halPayloadWithLinks(this.links), null))
.isEqualTo(halPayloadWithLinks(this.maskedLinks));
.isEqualTo(halPayloadWithLinks(this.maskedLinks));
}
@Test
public void formattedHalLinksAreMasked() throws Exception {
assertThat(this.contentModifier.modifyContent(formattedHalPayloadWithLinks(this.links), null))
.isEqualTo(formattedHalPayloadWithLinks(this.maskedLinks));
.isEqualTo(formattedHalPayloadWithLinks(this.maskedLinks));
}
@Test
public void atomLinksAreMasked() throws Exception {
assertThat(this.contentModifier.modifyContent(atomPayloadWithLinks(this.links), null))
.isEqualTo(atomPayloadWithLinks(this.maskedLinks));
.isEqualTo(atomPayloadWithLinks(this.maskedLinks));
}
@Test
public void formattedAtomLinksAreMasked() throws Exception {
assertThat(this.contentModifier.modifyContent(formattedAtomPayloadWithLinks(this.links), null))
.isEqualTo(formattedAtomPayloadWithLinks(this.maskedLinks));
.isEqualTo(formattedAtomPayloadWithLinks(this.maskedLinks));
}
@Test
public void maskCanBeCustomized() throws Exception {
assertThat(
new LinkMaskingContentModifier("custom").modifyContent(formattedAtomPayloadWithLinks(this.links), null))
.isEqualTo(formattedAtomPayloadWithLinks(new Link("a", "custom"), new Link("b", "custom")));
.isEqualTo(formattedAtomPayloadWithLinks(new Link("a", "custom"), new Link("b", "custom")));
}
@Test
@@ -82,7 +82,7 @@ public class LinkMaskingContentModifierTests {
String ellipsis = "\u2026";
assertThat(
new LinkMaskingContentModifier(ellipsis).modifyContent(formattedHalPayloadWithLinks(this.links), null))
.isEqualTo(formattedHalPayloadWithLinks(new Link("a", ellipsis), new Link("b", ellipsis)));
.isEqualTo(formattedHalPayloadWithLinks(new Link("a", ellipsis), new Link("b", ellipsis)));
}
private byte[] atomPayloadWithLinks(Link... links) throws JsonProcessingException {
@@ -91,7 +91,7 @@ public class LinkMaskingContentModifierTests {
private byte[] formattedAtomPayloadWithLinks(Link... links) throws JsonProcessingException {
return new ObjectMapper().configure(SerializationFeature.INDENT_OUTPUT, true)
.writeValueAsBytes(createAtomPayload(links));
.writeValueAsBytes(createAtomPayload(links));
}
private AtomPayload createAtomPayload(Link... links) {
@@ -106,7 +106,7 @@ public class LinkMaskingContentModifierTests {
private byte[] formattedHalPayloadWithLinks(Link... links) throws JsonProcessingException {
return new ObjectMapper().configure(SerializationFeature.INDENT_OUTPUT, true)
.writeValueAsBytes(createHalPayload(links));
.writeValueAsBytes(createHalPayload(links));
}
private HalPayload createHalPayload(Link... links) {

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2014-2020 the original author or authors.
* Copyright 2014-2023 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -61,7 +61,7 @@ public class ParametersModifyingOperationPreprocessorTests {
public void setNewParameter() {
Parameters parameters = new Parameters();
OperationRequest request = this.preprocessor.set("a", "alpha", "avocado")
.preprocess(createGetRequest(parameters));
.preprocess(createGetRequest(parameters));
assertThat(request.getParameters()).containsEntry("a", Arrays.asList("alpha", "avocado"));
assertThat(request.getUri()).isEqualTo(URI.create("http://localhost:8080?a=alpha&a=avocado"));
}
@@ -71,7 +71,7 @@ public class ParametersModifyingOperationPreprocessorTests {
Parameters parameters = new Parameters();
parameters.add("a", "apple");
OperationRequest request = this.preprocessor.set("a", "alpha", "avocado")
.preprocess(createGetRequest(parameters));
.preprocess(createGetRequest(parameters));
assertThat(request.getParameters()).containsEntry("a", Arrays.asList("alpha", "avocado"));
assertThat(request.getUri()).isEqualTo(URI.create("http://localhost:8080?a=alpha&a=avocado"));
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2014-2022 the original author or authors.
* Copyright 2014-2023 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -40,7 +40,7 @@ public class PatternReplacingContentModifierTests {
PatternReplacingContentModifier contentModifier = new PatternReplacingContentModifier(pattern, "<<uuid>>");
assertThat(
contentModifier.modifyContent("{\"id\" : \"CA761232-ED42-11CE-BACD-00AA0057B223\"}".getBytes(), null))
.isEqualTo("{\"id\" : \"<<uuid>>\"}".getBytes());
.isEqualTo("{\"id\" : \"<<uuid>>\"}".getBytes());
}
@Test
@@ -49,7 +49,7 @@ public class PatternReplacingContentModifierTests {
Pattern.CASE_INSENSITIVE);
PatternReplacingContentModifier contentModifier = new PatternReplacingContentModifier(pattern, "<<uuid>>");
assertThat(contentModifier.modifyContent("{\"id\" : \"CA76-ED42-11CE-BACD\"}".getBytes(), null))
.isEqualTo("{\"id\" : \"CA76-ED42-11CE-BACD\"}".getBytes());
.isEqualTo("{\"id\" : \"CA76-ED42-11CE-BACD\"}".getBytes());
}
@Test
@@ -59,7 +59,7 @@ public class PatternReplacingContentModifierTests {
PatternReplacingContentModifier contentModifier = new PatternReplacingContentModifier(pattern, "<<number>>");
assertThat(contentModifier.modifyContent((japaneseContent + " 123").getBytes(),
new MediaType("text", "plain", Charset.forName("UTF-8"))))
.isEqualTo((japaneseContent + " <<number>>").getBytes());
.isEqualTo((japaneseContent + " <<number>>").getBytes());
}
@Test
@@ -69,7 +69,7 @@ public class PatternReplacingContentModifierTests {
PatternReplacingContentModifier contentModifier = new PatternReplacingContentModifier(pattern, "<<number>>",
StandardCharsets.UTF_8);
assertThat(contentModifier.modifyContent((japaneseContent + " 123").getBytes(), new MediaType("text", "plain")))
.isEqualTo((japaneseContent + " <<number>>").getBytes());
.isEqualTo((japaneseContent + " <<number>>").getBytes());
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2014-2022 the original author or authors.
* Copyright 2014-2023 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -41,15 +41,17 @@ public class PrettyPrintingContentModifierTests {
@Test
public void prettyPrintJson() {
assertThat(new PrettyPrintingContentModifier().modifyContent("{\"a\":5}".getBytes(), null))
.isEqualTo(String.format("{%n \"a\" : 5%n}").getBytes());
.isEqualTo(String.format("{%n \"a\" : 5%n}").getBytes());
}
@Test
public void prettyPrintXml() {
assertThat(new PrettyPrintingContentModifier()
.modifyContent("<one a=\"alpha\"><two b=\"bravo\"/></one>".getBytes(), null))
.isEqualTo(String.format("<?xml version=\"1.0\" encoding=\"UTF-8\"?>%n"
+ "<one a=\"alpha\">%n <two b=\"bravo\"/>%n</one>%n").getBytes());
.modifyContent("<one a=\"alpha\"><two b=\"bravo\"/></one>".getBytes(), null))
.isEqualTo(String
.format("<?xml version=\"1.0\" encoding=\"UTF-8\"?>%n"
+ "<one a=\"alpha\">%n <two b=\"bravo\"/>%n</one>%n")
.getBytes());
}
@Test
@@ -61,7 +63,7 @@ public class PrettyPrintingContentModifierTests {
public void nonJsonAndNonXmlContentIsHandledGracefully() {
String content = "abcdefg";
assertThat(new PrettyPrintingContentModifier().modifyContent(content.getBytes(), null))
.isEqualTo(content.getBytes());
.isEqualTo(content.getBytes());
assertThat(this.outputCapture).isEmpty();
}
@@ -69,7 +71,7 @@ public class PrettyPrintingContentModifierTests {
public void nonJsonContentThatInitiallyLooksLikeJsonIsHandledGracefully() {
String content = "\"abc\",\"def\"";
assertThat(new PrettyPrintingContentModifier().modifyContent(content.getBytes(), null))
.isEqualTo(content.getBytes());
.isEqualTo(content.getBytes());
assertThat(this.outputCapture).isEmpty();
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2014-2022 the original author or authors.
* Copyright 2014-2023 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -69,7 +69,7 @@ public class UriModifyingOperationPreprocessorTests {
public void requestUriPortCanBeModified() {
this.preprocessor.port(23456);
OperationRequest processed = this.preprocessor
.preprocess(createRequestWithUri("https://api.example.com:12345"));
.preprocess(createRequestWithUri("https://api.example.com:12345"));
assertThat(processed.getUri()).isEqualTo(URI.create("https://api.example.com:23456"));
assertThat(processed.getHeaders().getFirst(HttpHeaders.HOST)).isEqualTo("api.example.com:23456");
}
@@ -78,7 +78,7 @@ public class UriModifyingOperationPreprocessorTests {
public void requestUriPortCanBeRemoved() {
this.preprocessor.removePort();
OperationRequest processed = this.preprocessor
.preprocess(createRequestWithUri("https://api.example.com:12345"));
.preprocess(createRequestWithUri("https://api.example.com:12345"));
assertThat(processed.getUri()).isEqualTo(URI.create("https://api.example.com"));
assertThat(processed.getHeaders().getFirst(HttpHeaders.HOST)).isEqualTo("api.example.com");
}
@@ -87,7 +87,7 @@ public class UriModifyingOperationPreprocessorTests {
public void requestUriPathIsPreserved() {
this.preprocessor.removePort();
OperationRequest processed = this.preprocessor
.preprocess(createRequestWithUri("https://api.example.com:12345/foo/bar"));
.preprocess(createRequestWithUri("https://api.example.com:12345/foo/bar"));
assertThat(processed.getUri()).isEqualTo(URI.create("https://api.example.com/foo/bar"));
}
@@ -95,7 +95,7 @@ public class UriModifyingOperationPreprocessorTests {
public void requestUriQueryIsPreserved() {
this.preprocessor.removePort();
OperationRequest processed = this.preprocessor
.preprocess(createRequestWithUri("https://api.example.com:12345?foo=bar"));
.preprocess(createRequestWithUri("https://api.example.com:12345?foo=bar"));
assertThat(processed.getUri()).isEqualTo(URI.create("https://api.example.com?foo=bar"));
}
@@ -103,7 +103,7 @@ public class UriModifyingOperationPreprocessorTests {
public void requestUriAnchorIsPreserved() {
this.preprocessor.removePort();
OperationRequest processed = this.preprocessor
.preprocess(createRequestWithUri("https://api.example.com:12345#foo"));
.preprocess(createRequestWithUri("https://api.example.com:12345#foo"));
assertThat(processed.getUri()).isEqualTo(URI.create("https://api.example.com#foo"));
}
@@ -113,7 +113,7 @@ public class UriModifyingOperationPreprocessorTests {
OperationRequest processed = this.preprocessor.preprocess(createRequestWithContent(
"The uri 'https://localhost:12345' should be used. foo:bar will be unaffected"));
assertThat(new String(processed.getContent()))
.isEqualTo("The uri 'https://localhost:12345' should be used. foo:bar will be unaffected");
.isEqualTo("The uri 'https://localhost:12345' should be used. foo:bar will be unaffected");
}
@Test
@@ -122,7 +122,7 @@ public class UriModifyingOperationPreprocessorTests {
OperationRequest processed = this.preprocessor.preprocess(createRequestWithContent(
"The uri 'https://localhost:12345' should be used. foo:bar will be unaffected"));
assertThat(new String(processed.getContent()))
.isEqualTo("The uri 'https://api.example.com:12345' should be used. foo:bar will be unaffected");
.isEqualTo("The uri 'https://api.example.com:12345' should be used. foo:bar will be unaffected");
}
@Test
@@ -131,7 +131,7 @@ public class UriModifyingOperationPreprocessorTests {
OperationRequest processed = this.preprocessor.preprocess(
createRequestWithContent("The uri 'https://localhost' should be used. foo:bar will be unaffected"));
assertThat(new String(processed.getContent()))
.isEqualTo("The uri 'https://api.example.com' should be used. foo:bar will be unaffected");
.isEqualTo("The uri 'https://api.example.com' should be used. foo:bar will be unaffected");
}
@Test
@@ -140,7 +140,7 @@ public class UriModifyingOperationPreprocessorTests {
OperationRequest processed = this.preprocessor.preprocess(
createRequestWithContent("The uri 'http://localhost' should be used. foo:bar will be unaffected"));
assertThat(new String(processed.getContent()))
.isEqualTo("The uri 'http://localhost:23456' should be used. foo:bar will be unaffected");
.isEqualTo("The uri 'http://localhost:23456' should be used. foo:bar will be unaffected");
}
@Test
@@ -149,7 +149,7 @@ public class UriModifyingOperationPreprocessorTests {
OperationRequest processed = this.preprocessor.preprocess(createRequestWithContent(
"The uri 'http://localhost:12345' should be used. foo:bar will be unaffected"));
assertThat(new String(processed.getContent()))
.isEqualTo("The uri 'http://localhost:23456' should be used. foo:bar will be unaffected");
.isEqualTo("The uri 'http://localhost:23456' should be used. foo:bar will be unaffected");
}
@Test
@@ -158,7 +158,7 @@ public class UriModifyingOperationPreprocessorTests {
OperationRequest processed = this.preprocessor.preprocess(createRequestWithContent(
"The uri 'http://localhost:12345' should be used. foo:bar will be unaffected"));
assertThat(new String(processed.getContent()))
.isEqualTo("The uri 'http://localhost' should be used. foo:bar will be unaffected");
.isEqualTo("The uri 'http://localhost' should be used. foo:bar will be unaffected");
}
@Test
@@ -167,14 +167,14 @@ public class UriModifyingOperationPreprocessorTests {
OperationRequest processed = this.preprocessor.preprocess(createRequestWithContent(
"Use 'http://localhost:12345' or 'https://localhost:23456' to access the service"));
assertThat(new String(processed.getContent()))
.isEqualTo("Use 'http://localhost' or 'https://localhost' to access the service");
.isEqualTo("Use 'http://localhost' or 'https://localhost' to access the service");
}
@Test
public void requestContentUriPathIsPreserved() {
this.preprocessor.removePort();
OperationRequest processed = this.preprocessor
.preprocess(createRequestWithContent("The uri 'http://localhost:12345/foo/bar' should be used"));
.preprocess(createRequestWithContent("The uri 'http://localhost:12345/foo/bar' should be used"));
assertThat(new String(processed.getContent())).isEqualTo("The uri 'http://localhost/foo/bar' should be used");
}
@@ -182,7 +182,7 @@ public class UriModifyingOperationPreprocessorTests {
public void requestContentUriQueryIsPreserved() {
this.preprocessor.removePort();
OperationRequest processed = this.preprocessor
.preprocess(createRequestWithContent("The uri 'http://localhost:12345?foo=bar' should be used"));
.preprocess(createRequestWithContent("The uri 'http://localhost:12345?foo=bar' should be used"));
assertThat(new String(processed.getContent())).isEqualTo("The uri 'http://localhost?foo=bar' should be used");
}
@@ -190,7 +190,7 @@ public class UriModifyingOperationPreprocessorTests {
public void requestContentUriAnchorIsPreserved() {
this.preprocessor.removePort();
OperationRequest processed = this.preprocessor
.preprocess(createRequestWithContent("The uri 'http://localhost:12345#foo' should be used"));
.preprocess(createRequestWithContent("The uri 'http://localhost:12345#foo' should be used"));
assertThat(new String(processed.getContent())).isEqualTo("The uri 'http://localhost#foo' should be used");
}
@@ -198,7 +198,7 @@ public class UriModifyingOperationPreprocessorTests {
public void responseContentUriSchemeCanBeModified() {
this.preprocessor.scheme("https");
OperationResponse processed = this.preprocessor
.preprocess(createResponseWithContent("The uri 'http://localhost:12345' should be used"));
.preprocess(createResponseWithContent("The uri 'http://localhost:12345' should be used"));
assertThat(new String(processed.getContent())).isEqualTo("The uri 'https://localhost:12345' should be used");
}
@@ -206,16 +206,16 @@ public class UriModifyingOperationPreprocessorTests {
public void responseContentUriHostCanBeModified() {
this.preprocessor.host("api.example.com");
OperationResponse processed = this.preprocessor
.preprocess(createResponseWithContent("The uri 'https://localhost:12345' should be used"));
.preprocess(createResponseWithContent("The uri 'https://localhost:12345' should be used"));
assertThat(new String(processed.getContent()))
.isEqualTo("The uri 'https://api.example.com:12345' should be used");
.isEqualTo("The uri 'https://api.example.com:12345' should be used");
}
@Test
public void responseContentUriPortCanBeModified() {
this.preprocessor.port(23456);
OperationResponse processed = this.preprocessor
.preprocess(createResponseWithContent("The uri 'http://localhost:12345' should be used"));
.preprocess(createResponseWithContent("The uri 'http://localhost:12345' should be used"));
assertThat(new String(processed.getContent())).isEqualTo("The uri 'http://localhost:23456' should be used");
}
@@ -223,7 +223,7 @@ public class UriModifyingOperationPreprocessorTests {
public void responseContentUriPortCanBeRemoved() {
this.preprocessor.removePort();
OperationResponse processed = this.preprocessor
.preprocess(createResponseWithContent("The uri 'http://localhost:12345' should be used"));
.preprocess(createResponseWithContent("The uri 'http://localhost:12345' should be used"));
assertThat(new String(processed.getContent())).isEqualTo("The uri 'http://localhost' should be used");
}
@@ -233,14 +233,14 @@ public class UriModifyingOperationPreprocessorTests {
OperationResponse processed = this.preprocessor.preprocess(createResponseWithContent(
"Use 'http://localhost:12345' or 'https://localhost:23456' to access the service"));
assertThat(new String(processed.getContent()))
.isEqualTo("Use 'http://localhost' or 'https://localhost' to access the service");
.isEqualTo("Use 'http://localhost' or 'https://localhost' to access the service");
}
@Test
public void responseContentUriPathIsPreserved() {
this.preprocessor.removePort();
OperationResponse processed = this.preprocessor
.preprocess(createResponseWithContent("The uri 'http://localhost:12345/foo/bar' should be used"));
.preprocess(createResponseWithContent("The uri 'http://localhost:12345/foo/bar' should be used"));
assertThat(new String(processed.getContent())).isEqualTo("The uri 'http://localhost/foo/bar' should be used");
}
@@ -248,7 +248,7 @@ public class UriModifyingOperationPreprocessorTests {
public void responseContentUriQueryIsPreserved() {
this.preprocessor.removePort();
OperationResponse processed = this.preprocessor
.preprocess(createResponseWithContent("The uri 'http://localhost:12345?foo=bar' should be used"));
.preprocess(createResponseWithContent("The uri 'http://localhost:12345?foo=bar' should be used"));
assertThat(new String(processed.getContent())).isEqualTo("The uri 'http://localhost?foo=bar' should be used");
}
@@ -256,14 +256,14 @@ public class UriModifyingOperationPreprocessorTests {
public void responseContentUriAnchorIsPreserved() {
this.preprocessor.removePort();
OperationResponse processed = this.preprocessor
.preprocess(createResponseWithContent("The uri 'http://localhost:12345#foo' should be used"));
.preprocess(createResponseWithContent("The uri 'http://localhost:12345#foo' should be used"));
assertThat(new String(processed.getContent())).isEqualTo("The uri 'http://localhost#foo' should be used");
}
@Test
public void urisInRequestHeadersCanBeModified() {
OperationRequest processed = this.preprocessor.host("api.example.com")
.preprocess(createRequestWithHeader("Foo", "https://locahost:12345"));
.preprocess(createRequestWithHeader("Foo", "https://locahost:12345"));
assertThat(processed.getHeaders().getFirst("Foo")).isEqualTo("https://api.example.com:12345");
assertThat(processed.getHeaders().getFirst("Host")).isEqualTo("api.example.com");
}
@@ -271,31 +271,31 @@ public class UriModifyingOperationPreprocessorTests {
@Test
public void urisInResponseHeadersCanBeModified() {
OperationResponse processed = this.preprocessor.host("api.example.com")
.preprocess(createResponseWithHeader("Foo", "https://locahost:12345"));
.preprocess(createResponseWithHeader("Foo", "https://locahost:12345"));
assertThat(processed.getHeaders().getFirst("Foo")).isEqualTo("https://api.example.com:12345");
}
@Test
public void urisInRequestPartHeadersCanBeModified() {
OperationRequest processed = this.preprocessor.host("api.example.com")
.preprocess(createRequestWithPartWithHeader("Foo", "https://locahost:12345"));
.preprocess(createRequestWithPartWithHeader("Foo", "https://locahost:12345"));
assertThat(processed.getParts().iterator().next().getHeaders().getFirst("Foo"))
.isEqualTo("https://api.example.com:12345");
.isEqualTo("https://api.example.com:12345");
}
@Test
public void urisInRequestPartContentCanBeModified() {
OperationRequest processed = this.preprocessor.host("api.example.com")
.preprocess(createRequestWithPartWithContent("The uri 'https://localhost:12345' should be used"));
.preprocess(createRequestWithPartWithContent("The uri 'https://localhost:12345' should be used"));
assertThat(new String(processed.getParts().iterator().next().getContent()))
.isEqualTo("The uri 'https://api.example.com:12345' should be used");
.isEqualTo("The uri 'https://api.example.com:12345' should be used");
}
@Test
public void modifiedUriDoesNotGetDoubleEncoded() {
this.preprocessor.scheme("https");
OperationRequest processed = this.preprocessor
.preprocess(createRequestWithUri("http://localhost:12345?foo=%7B%7D"));
.preprocess(createRequestWithUri("http://localhost:12345?foo=%7B%7D"));
assertThat(processed.getUri()).isEqualTo(URI.create("https://localhost:12345?foo=%7B%7D"));
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2014-2021 the original author or authors.
* Copyright 2014-2023 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -53,14 +53,17 @@ public class AsciidoctorRequestFieldsSnippetTests {
public void requestFieldsWithListDescription() throws IOException {
TemplateResourceResolver resolver = mock(TemplateResourceResolver.class);
given(resolver.resolveTemplateResource("request-fields"))
.willReturn(snippetResource("request-fields-with-list-description"));
.willReturn(snippetResource("request-fields-with-list-description"));
new RequestFieldsSnippet(Arrays.asList(fieldWithPath("a").description(Arrays.asList("one", "two")))).document(
this.operationBuilder.attribute(TemplateEngine.class.getName(), new MustacheTemplateEngine(resolver))
.request("http://localhost").content("{\"a\": \"foo\"}").build());
.request("http://localhost")
.content("{\"a\": \"foo\"}")
.build());
assertThat(this.generatedSnippets.requestFields())
.is(SnippetConditions.tableWithHeader(TemplateFormats.asciidoctor(), "Path", "Type", "Description")
//
.row("a", "String", String.format(" - one%n - two")).configuration("[cols=\"1,1,1a\"]"));
.is(SnippetConditions.tableWithHeader(TemplateFormats.asciidoctor(), "Path", "Type", "Description")
//
.row("a", "String", String.format(" - one%n - two"))
.configuration("[cols=\"1,1,1a\"]"));
}
private FileSystemResource snippetResource(String name) {

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2014-2022 the original author or authors.
* Copyright 2014-2023 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -48,7 +48,7 @@ public class FieldPathPayloadSubsectionExtractorTests {
@SuppressWarnings("unchecked")
public void extractMapSubsectionOfJsonMap() throws JsonParseException, JsonMappingException, IOException {
byte[] extractedPayload = new FieldPathPayloadSubsectionExtractor("a.b")
.extractSubsection("{\"a\":{\"b\":{\"c\":5}}}".getBytes(), MediaType.APPLICATION_JSON);
.extractSubsection("{\"a\":{\"b\":{\"c\":5}}}".getBytes(), MediaType.APPLICATION_JSON);
Map<String, Object> extracted = new ObjectMapper().readValue(extractedPayload, Map.class);
assertThat(extracted.size()).isEqualTo(1);
assertThat(extracted.get("c")).isEqualTo(5);
@@ -59,7 +59,7 @@ public class FieldPathPayloadSubsectionExtractorTests {
public void extractSingleElementArraySubsectionOfJsonMap()
throws JsonParseException, JsonMappingException, IOException {
byte[] extractedPayload = new FieldPathPayloadSubsectionExtractor("a.[]")
.extractSubsection("{\"a\":[{\"b\":5}]}".getBytes(), MediaType.APPLICATION_JSON);
.extractSubsection("{\"a\":[{\"b\":5}]}".getBytes(), MediaType.APPLICATION_JSON);
Map<String, Object> extracted = new ObjectMapper().readValue(extractedPayload, Map.class);
assertThat(extracted.size()).isEqualTo(1);
assertThat(extracted).containsOnlyKeys("b");
@@ -70,7 +70,7 @@ public class FieldPathPayloadSubsectionExtractorTests {
public void extractMultiElementArraySubsectionOfJsonMap()
throws JsonParseException, JsonMappingException, IOException {
byte[] extractedPayload = new FieldPathPayloadSubsectionExtractor("a")
.extractSubsection("{\"a\":[{\"b\":5},{\"b\":4}]}".getBytes(), MediaType.APPLICATION_JSON);
.extractSubsection("{\"a\":[{\"b\":5},{\"b\":4}]}".getBytes(), MediaType.APPLICATION_JSON);
Map<String, Object> extracted = new ObjectMapper().readValue(extractedPayload, Map.class);
assertThat(extracted.size()).isEqualTo(1);
assertThat(extracted).containsOnlyKeys("b");
@@ -81,7 +81,7 @@ public class FieldPathPayloadSubsectionExtractorTests {
public void extractMapSubsectionFromSingleElementArrayInAJsonMap()
throws JsonParseException, JsonMappingException, IOException {
byte[] extractedPayload = new FieldPathPayloadSubsectionExtractor("a.[].b")
.extractSubsection("{\"a\":[{\"b\":{\"c\":5}}]}".getBytes(), MediaType.APPLICATION_JSON);
.extractSubsection("{\"a\":[{\"b\":{\"c\":5}}]}".getBytes(), MediaType.APPLICATION_JSON);
Map<String, Object> extracted = new ObjectMapper().readValue(extractedPayload, Map.class);
assertThat(extracted.size()).isEqualTo(1);
assertThat(extracted.get("c")).isEqualTo(5);
@@ -91,8 +91,8 @@ public class FieldPathPayloadSubsectionExtractorTests {
@SuppressWarnings("unchecked")
public void extractMapSubsectionWithCommonStructureFromMultiElementArrayInAJsonMap()
throws JsonParseException, JsonMappingException, IOException {
byte[] extractedPayload = new FieldPathPayloadSubsectionExtractor("a.[].b").extractSubsection(
"{\"a\":[{\"b\":{\"c\":5}},{\"b\":{\"c\":6}}]}".getBytes(), MediaType.APPLICATION_JSON);
byte[] extractedPayload = new FieldPathPayloadSubsectionExtractor("a.[].b")
.extractSubsection("{\"a\":[{\"b\":{\"c\":5}},{\"b\":{\"c\":6}}]}".getBytes(), MediaType.APPLICATION_JSON);
Map<String, Object> extracted = new ObjectMapper().readValue(extractedPayload, Map.class);
assertThat(extracted.size()).isEqualTo(1);
assertThat(extracted).containsOnlyKeys("c");
@@ -152,11 +152,11 @@ public class FieldPathPayloadSubsectionExtractorTests {
throws JsonParseException, JsonMappingException, JsonProcessingException, IOException {
ObjectMapper objectMapper = new ObjectMapper().enable(SerializationFeature.INDENT_OUTPUT);
byte[] prettyPrintedPayload = objectMapper
.writeValueAsBytes(objectMapper.readValue("{\"a\": { \"b\": { \"c\": 1 }}}", Object.class));
.writeValueAsBytes(objectMapper.readValue("{\"a\": { \"b\": { \"c\": 1 }}}", Object.class));
byte[] extractedSubsection = new FieldPathPayloadSubsectionExtractor("a.b")
.extractSubsection(prettyPrintedPayload, MediaType.APPLICATION_JSON);
.extractSubsection(prettyPrintedPayload, MediaType.APPLICATION_JSON);
byte[] prettyPrintedSubsection = objectMapper
.writeValueAsBytes(objectMapper.readValue("{\"c\": 1 }", Object.class));
.writeValueAsBytes(objectMapper.readValue("{\"c\": 1 }", Object.class));
assertThat(new String(extractedSubsection)).isEqualTo(new String(prettyPrintedSubsection));
}
@@ -165,7 +165,7 @@ public class FieldPathPayloadSubsectionExtractorTests {
throws JsonParseException, JsonMappingException, JsonProcessingException, IOException {
ObjectMapper objectMapper = new ObjectMapper();
byte[] payload = objectMapper
.writeValueAsBytes(objectMapper.readValue("{\"a\": { \"b\": { \"c\": 1 }}}", Object.class));
.writeValueAsBytes(objectMapper.readValue("{\"a\": { \"b\": { \"c\": 1 }}}", Object.class));
byte[] extractedSubsection = new FieldPathPayloadSubsectionExtractor("a.b").extractSubsection(payload,
MediaType.APPLICATION_JSON);
byte[] subsection = objectMapper.writeValueAsBytes(objectMapper.readValue("{\"c\": 1 }", Object.class));
@@ -175,17 +175,17 @@ public class FieldPathPayloadSubsectionExtractorTests {
@Test
public void extractNonExistentSubsection() {
assertThatThrownBy(() -> new FieldPathPayloadSubsectionExtractor("a.c")
.extractSubsection("{\"a\":{\"b\":{\"c\":5}}}".getBytes(), MediaType.APPLICATION_JSON))
.isInstanceOf(PayloadHandlingException.class)
.hasMessage("a.c does not identify a section of the payload");
.extractSubsection("{\"a\":{\"b\":{\"c\":5}}}".getBytes(), MediaType.APPLICATION_JSON))
.isInstanceOf(PayloadHandlingException.class)
.hasMessage("a.c does not identify a section of the payload");
}
@Test
public void extractEmptyArraySubsection() {
assertThatThrownBy(() -> new FieldPathPayloadSubsectionExtractor("a")
.extractSubsection("{\"a\":[]}}".getBytes(), MediaType.APPLICATION_JSON))
.isInstanceOf(PayloadHandlingException.class)
.hasMessage("a identifies an empty section of the payload");
.extractSubsection("{\"a\":[]}}".getBytes(), MediaType.APPLICATION_JSON))
.isInstanceOf(PayloadHandlingException.class)
.hasMessage("a identifies an empty section of the payload");
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2014-2019 the original author or authors.
* Copyright 2014-2023 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -40,14 +40,14 @@ public class FieldTypeResolverTests {
@Deprecated
public void whenForContentCalledWithJsonContentThenReturnsJsonFieldTypeResolver() {
assertThat(FieldTypeResolver.forContent("{\"field\": \"value\"}".getBytes(), MediaType.APPLICATION_JSON))
.isInstanceOf(JsonContentHandler.class);
.isInstanceOf(JsonContentHandler.class);
}
@Test
@Deprecated
public void whenForContentCalledWithXmlContentThenReturnsXmlContentHandler() {
assertThat(FieldTypeResolver.forContent("<a><b>5</b></a>".getBytes(), MediaType.APPLICATION_XML))
.isInstanceOf(XmlContentHandler.class);
.isInstanceOf(XmlContentHandler.class);
}
@Test
@@ -60,13 +60,15 @@ public class FieldTypeResolverTests {
@Test
public void whenForContentWithDescriptorsCalledWithJsonContentThenReturnsJsonFieldTypeResolver() {
assertThat(FieldTypeResolver.forContentWithDescriptors("{\"field\": \"value\"}".getBytes(),
MediaType.APPLICATION_JSON, Collections.emptyList())).isInstanceOf(JsonContentHandler.class);
MediaType.APPLICATION_JSON, Collections.emptyList()))
.isInstanceOf(JsonContentHandler.class);
}
@Test
public void whenForContentWithDescriptorsCalledWithXmlContentThenReturnsXmlContentHandler() {
assertThat(FieldTypeResolver.forContentWithDescriptors("<a><b>5</b></a>".getBytes(), MediaType.APPLICATION_XML,
Collections.emptyList())).isInstanceOf(XmlContentHandler.class);
Collections.emptyList()))
.isInstanceOf(XmlContentHandler.class);
}
@Test

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2014-2022 the original author or authors.
* Copyright 2014-2023 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -49,7 +49,7 @@ public class JsonContentHandlerTests {
this.thrown.expect(FieldTypesDoNotMatchException.class);
FieldDescriptor descriptor = new FieldDescriptor("a[].id").type(JsonFieldType.STRING);
new JsonContentHandler("{\"a\":[{\"id\":1},{\"id\":null}]}".getBytes(), Arrays.asList(descriptor))
.resolveFieldType(descriptor);
.resolveFieldType(descriptor);
}
@Test
@@ -57,14 +57,15 @@ public class JsonContentHandlerTests {
this.thrown.expect(FieldTypesDoNotMatchException.class);
FieldDescriptor descriptor = new FieldDescriptor("a.[].id").type(JsonFieldType.STRING);
new JsonContentHandler("{\"a\":[{\"id\":null},{\"id\":1}]}".getBytes(), Arrays.asList(descriptor))
.resolveFieldType(descriptor);
.resolveFieldType(descriptor);
}
@Test
public void typeForOptionalFieldWithNumberAndThenNullValueIsNumber() {
FieldDescriptor descriptor = new FieldDescriptor("a[].id").optional();
Object fieldType = new JsonContentHandler("{\"a\":[{\"id\":1},{\"id\":null}]}\"".getBytes(),
Arrays.asList(descriptor)).resolveFieldType(descriptor);
Arrays.asList(descriptor))
.resolveFieldType(descriptor);
assertThat((JsonFieldType) fieldType).isEqualTo(JsonFieldType.NUMBER);
}
@@ -72,7 +73,8 @@ public class JsonContentHandlerTests {
public void typeForOptionalFieldWithNullAndThenNumberIsNumber() {
FieldDescriptor descriptor = new FieldDescriptor("a[].id").optional();
Object fieldType = new JsonContentHandler("{\"a\":[{\"id\":null},{\"id\":1}]}".getBytes(),
Arrays.asList(descriptor)).resolveFieldType(descriptor);
Arrays.asList(descriptor))
.resolveFieldType(descriptor);
assertThat((JsonFieldType) fieldType).isEqualTo(JsonFieldType.NUMBER);
}
@@ -80,7 +82,8 @@ public class JsonContentHandlerTests {
public void typeForFieldWithNumberAndThenNullValueIsVaries() {
FieldDescriptor descriptor = new FieldDescriptor("a[].id");
Object fieldType = new JsonContentHandler("{\"a\":[{\"id\":1},{\"id\":null}]}\"".getBytes(),
Arrays.asList(descriptor)).resolveFieldType(descriptor);
Arrays.asList(descriptor))
.resolveFieldType(descriptor);
assertThat((JsonFieldType) fieldType).isEqualTo(JsonFieldType.VARIES);
}
@@ -88,7 +91,8 @@ public class JsonContentHandlerTests {
public void typeForFieldWithNullAndThenNumberIsVaries() {
FieldDescriptor descriptor = new FieldDescriptor("a[].id");
Object fieldType = new JsonContentHandler("{\"a\":[{\"id\":null},{\"id\":1}]}".getBytes(),
Arrays.asList(descriptor)).resolveFieldType(descriptor);
Arrays.asList(descriptor))
.resolveFieldType(descriptor);
assertThat((JsonFieldType) fieldType).isEqualTo(JsonFieldType.VARIES);
}
@@ -96,7 +100,7 @@ public class JsonContentHandlerTests {
public void typeForOptionalFieldWithNullValueCanBeProvidedExplicitly() {
FieldDescriptor descriptor = new FieldDescriptor("a").type(JsonFieldType.STRING).optional();
Object fieldType = new JsonContentHandler("{\"a\": null}".getBytes(), Arrays.asList(descriptor))
.resolveFieldType(descriptor);
.resolveFieldType(descriptor);
assertThat((JsonFieldType) fieldType).isEqualTo(JsonFieldType.STRING);
}
@@ -105,7 +109,8 @@ public class JsonContentHandlerTests {
FieldDescriptor descriptor = new FieldDescriptor("a.[].b.c").type(JsonFieldType.NUMBER);
FieldDescriptor ancestor = new FieldDescriptor("a.[].b").optional();
Object fieldType = new JsonContentHandler("{\"a\":[ { \"d\": 4}, {\"b\":{\"c\":5}, \"d\": 4}]}".getBytes(),
Arrays.asList(descriptor, ancestor)).resolveFieldType(descriptor);
Arrays.asList(descriptor, ancestor))
.resolveFieldType(descriptor);
assertThat((JsonFieldType) fieldType).isEqualTo(JsonFieldType.NUMBER);
}
@@ -120,7 +125,8 @@ public class JsonContentHandlerTests {
List<FieldDescriptor> descriptors = Arrays.asList(new FieldDescriptor("a"), new FieldDescriptor("b"),
new FieldDescriptor("c"));
List<FieldDescriptor> missingFields = new JsonContentHandler("{\"a\": \"alpha\", \"b\":\"bravo\"}".getBytes(),
descriptors).findMissingFields();
descriptors)
.findMissingFields();
assertThat(missingFields.size()).isEqualTo(1);
assertThat(missingFields.get(0).getPath()).isEqualTo("c");
}
@@ -130,7 +136,8 @@ public class JsonContentHandlerTests {
List<FieldDescriptor> descriptors = Arrays.asList(new FieldDescriptor("a"), new FieldDescriptor("b"),
new FieldDescriptor("c").optional());
List<FieldDescriptor> missingFields = new JsonContentHandler("{\"a\": \"alpha\", \"b\":\"bravo\"}".getBytes(),
descriptors).findMissingFields();
descriptors)
.findMissingFields();
assertThat(missingFields.size()).isEqualTo(0);
}
@@ -139,7 +146,8 @@ public class JsonContentHandlerTests {
List<FieldDescriptor> descriptors = Arrays.asList(new FieldDescriptor("a").optional(), new FieldDescriptor("b"),
new FieldDescriptor("a.c"));
List<FieldDescriptor> missingFields = new JsonContentHandler("{\"a\":\"alpha\",\"b\":\"bravo\"}".getBytes(),
descriptors).findMissingFields();
descriptors)
.findMissingFields();
assertThat(missingFields.size()).isEqualTo(1);
assertThat(missingFields.get(0).getPath()).isEqualTo("a.c");
}
@@ -149,7 +157,7 @@ public class JsonContentHandlerTests {
List<FieldDescriptor> descriptors = Arrays.asList(new FieldDescriptor("a").optional(), new FieldDescriptor("b"),
new FieldDescriptor("a.c"));
List<FieldDescriptor> missingFields = new JsonContentHandler("{\"b\":\"bravo\"}".getBytes(), descriptors)
.findMissingFields();
.findMissingFields();
assertThat(missingFields.size()).isEqualTo(0);
}
@@ -158,7 +166,7 @@ public class JsonContentHandlerTests {
List<FieldDescriptor> descriptors = Arrays.asList(new FieldDescriptor("outer"),
new FieldDescriptor("outer[]").optional(), new FieldDescriptor("outer[].inner"));
List<FieldDescriptor> missingFields = new JsonContentHandler("{\"outer\":[]}".getBytes(), descriptors)
.findMissingFields();
.findMissingFields();
assertThat(missingFields.size()).isEqualTo(0);
}
@@ -168,7 +176,7 @@ public class JsonContentHandlerTests {
new FieldDescriptor("a.[].c.d"));
List<FieldDescriptor> missingFields = new JsonContentHandler(
"{\"a\":[ {\"b\": \"bravo\"}, {\"b\": \"bravo\", \"c\": { \"d\": \"delta\"}}]}".getBytes(), descriptors)
.findMissingFields();
.findMissingFields();
assertThat(missingFields.size()).isEqualTo(0);
}
@@ -177,7 +185,7 @@ public class JsonContentHandlerTests {
List<FieldDescriptor> descriptors = Arrays.asList(new FieldDescriptor("a.[].b").optional(),
new FieldDescriptor("a.[].b.[]").optional(), new FieldDescriptor("a.[].b.[].c"));
List<FieldDescriptor> missingFields = new JsonContentHandler("{\"a\":[{\"b\":[]}]}".getBytes(), descriptors)
.findMissingFields();
.findMissingFields();
assertThat(missingFields.size()).isEqualTo(0);
}
@@ -186,7 +194,7 @@ public class JsonContentHandlerTests {
List<FieldDescriptor> descriptors = Arrays.asList(new FieldDescriptor("a.[].b").optional(),
new FieldDescriptor("a.[].b.[]").optional(), new FieldDescriptor("a.[].b.[].c"));
List<FieldDescriptor> missingFields = new JsonContentHandler("{\"a\":[{\"b\":[{}]}]}".getBytes(), descriptors)
.findMissingFields();
.findMissingFields();
assertThat(missingFields.size()).isEqualTo(1);
assertThat(missingFields.get(0).getPath()).isEqualTo("a.[].b.[].c");
}
@@ -196,7 +204,7 @@ public class JsonContentHandlerTests {
List<FieldDescriptor> descriptors = Arrays.asList(new FieldDescriptor("a").optional(),
new FieldDescriptor("a.b"));
List<FieldDescriptor> missingFields = new JsonContentHandler("{\"a\":null}".getBytes(), descriptors)
.findMissingFields();
.findMissingFields();
assertThat(missingFields.size()).isEqualTo(0);
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2014-2021 the original author or authors.
* Copyright 2014-2023 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -37,7 +37,8 @@ public class JsonFieldPathsTests {
public void noUncommonPathsForSingleItem() {
assertThat(
JsonFieldPaths.from(Arrays.asList(json("{\"a\": 1, \"b\": [ { \"c\": 2}, {\"c\": 3}, {\"c\": null}]}")))
.getUncommon()).isEmpty();
.getUncommon())
.isEmpty();
}
@Test
@@ -49,54 +50,52 @@ public class JsonFieldPathsTests {
@Test
public void noUncommonPathsForMultipleMatchingItemsWithDifferentScalarValues() {
assertThat(JsonFieldPaths.from(Arrays.asList(json("{\"a\": 1, \"b\": [ { \"c\": 2}, {\"c\": 3} ]}"),
json("{\"a\": 4, \"b\": [ { \"c\": 5}, {\"c\": 6} ]}"))).getUncommon()).isEmpty();
json("{\"a\": 4, \"b\": [ { \"c\": 5}, {\"c\": 6} ]}")))
.getUncommon()).isEmpty();
}
@Test
public void missingEntryInMapIsIdentifiedAsUncommon() {
assertThat(
JsonFieldPaths.from(Arrays.asList(json("{\"a\": 1}"), json("{\"a\": 1}"), json("{\"a\": 1, \"b\": 2}")))
.getUncommon()).containsExactly("b");
.getUncommon())
.containsExactly("b");
}
@Test
public void missingEntryInNestedMapIsIdentifiedAsUncommon() {
assertThat(
JsonFieldPaths
.from(Arrays.asList(json("{\"a\": 1, \"b\": {\"c\": 1}}"),
json("{\"a\": 1, \"b\": {\"c\": 1}}"), json("{\"a\": 1, \"b\": {\"c\": 1, \"d\": 2}}")))
.getUncommon()).containsExactly("b.d");
assertThat(JsonFieldPaths.from(Arrays.asList(json("{\"a\": 1, \"b\": {\"c\": 1}}"),
json("{\"a\": 1, \"b\": {\"c\": 1}}"), json("{\"a\": 1, \"b\": {\"c\": 1, \"d\": 2}}")))
.getUncommon()).containsExactly("b.d");
}
@Test
public void missingEntriesInNestedMapAreIdentifiedAsUncommon() {
assertThat(
JsonFieldPaths
.from(Arrays.asList(json("{\"a\": 1, \"b\": {\"c\": 1}}"),
json("{\"a\": 1, \"b\": {\"c\": 1}}"), json("{\"a\": 1, \"b\": {\"d\": 2}}")))
.getUncommon()).containsExactly("b.c", "b.d");
assertThat(JsonFieldPaths.from(Arrays.asList(json("{\"a\": 1, \"b\": {\"c\": 1}}"),
json("{\"a\": 1, \"b\": {\"c\": 1}}"), json("{\"a\": 1, \"b\": {\"d\": 2}}")))
.getUncommon()).containsExactly("b.c", "b.d");
}
@Test
public void absentItemFromFieldExtractionCausesAllPresentFieldsToBeIdentifiedAsUncommon() {
assertThat(
JsonFieldPaths
.from(Arrays.asList(ExtractedField.ABSENT, json("{\"a\": 1, \"b\": {\"c\": 1}}"),
json("{\"a\": 1, \"b\": {\"c\": 1}}"), json("{\"a\": 1, \"b\": {\"d\": 2}}")))
.getUncommon()).containsExactly("", "a", "b", "b.c", "b.d");
assertThat(JsonFieldPaths
.from(Arrays.asList(ExtractedField.ABSENT, json("{\"a\": 1, \"b\": {\"c\": 1}}"),
json("{\"a\": 1, \"b\": {\"c\": 1}}"), json("{\"a\": 1, \"b\": {\"d\": 2}}")))
.getUncommon()).containsExactly("", "a", "b", "b.c", "b.d");
}
@Test
public void missingEntryBeneathArrayIsIdentifiedAsUncommon() {
assertThat(JsonFieldPaths
.from(Arrays.asList(json("[{\"b\": 1}]"), json("[{\"b\": 1}]"), json("[{\"b\": 1, \"c\": 2}]")))
.getUncommon()).containsExactly("[].c");
.from(Arrays.asList(json("[{\"b\": 1}]"), json("[{\"b\": 1}]"), json("[{\"b\": 1, \"c\": 2}]")))
.getUncommon()).containsExactly("[].c");
}
@Test
public void missingEntryBeneathNestedArrayIsIdentifiedAsUncommon() {
assertThat(JsonFieldPaths.from(Arrays.asList(json("{\"a\": [{\"b\": 1}]}"), json("{\"a\": [{\"b\": 1}]}"),
json("{\"a\": [{\"b\": 1, \"c\": 2}]}"))).getUncommon()).containsExactly("a.[].c");
json("{\"a\": [{\"b\": 1, \"c\": 2}]}")))
.getUncommon()).containsExactly("a.[].c");
}
private Object json(String json) {

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2014-2022 the original author or authors.
* Copyright 2014-2023 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -105,7 +105,7 @@ public class JsonFieldProcessorTests {
List<Map<String, Object>> alpha = Arrays.asList(entry, new HashMap<String, Object>());
payload.put("a", alpha);
assertThat(this.fieldProcessor.extract("a[].b", payload).getValue())
.isEqualTo(Arrays.asList("bravo", ExtractedField.ABSENT));
.isEqualTo(Arrays.asList("bravo", ExtractedField.ABSENT));
}
@Test
@@ -129,7 +129,7 @@ public class JsonFieldProcessorTests {
List<List<Map<String, String>>> alpha = Arrays.asList(Arrays.asList(entry1, entry2), Arrays.asList(entry3));
payload.put("a", alpha);
assertThat(this.fieldProcessor.extract("a[][]", payload).getValue())
.isEqualTo(Arrays.asList(Arrays.asList(entry1, entry2), Arrays.asList(entry3)));
.isEqualTo(Arrays.asList(Arrays.asList(entry1, entry2), Arrays.asList(entry3)));
}
@Test
@@ -152,13 +152,13 @@ public class JsonFieldProcessorTests {
List<List<Map<String, Object>>> alpha = Arrays.asList(Arrays.asList(entry1, entry2), Arrays.asList(entry3));
payload.put("a", alpha);
assertThat(this.fieldProcessor.extract("a[][].ids", payload).getValue())
.isEqualTo(Arrays.asList(Arrays.asList(1, 2), Arrays.asList(3), Arrays.asList(4)));
.isEqualTo(Arrays.asList(Arrays.asList(1, 2), Arrays.asList(3), Arrays.asList(4)));
}
@Test
public void nonExistentTopLevelField() {
assertThat(this.fieldProcessor.extract("a", Collections.emptyMap()).getValue())
.isEqualTo(ExtractedField.ABSENT);
.isEqualTo(ExtractedField.ABSENT);
}
@Test
@@ -204,7 +204,7 @@ public class JsonFieldProcessorTests {
alpha.put("b", Arrays.asList(new HashMap<String, Object>()));
payload.put("a", alpha);
assertThat(this.fieldProcessor.extract("a.b[].id", payload).getValue())
.isEqualTo(Arrays.asList(ExtractedField.ABSENT));
.isEqualTo(Arrays.asList(ExtractedField.ABSENT));
}
@Test

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2014-2019 the original author or authors.
* Copyright 2014-2023 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -60,7 +60,7 @@ public class JsonFieldTypesDiscovererTests {
@Test
public void specificFieldOfObjectInArrayNestedBeneathAnArray() throws IOException {
assertThat(discoverFieldTypes("a[].b[].c", "{\"a\": [{\"b\": [ {\"c\": 5}, {\"c\": 5}]}]}"))
.containsExactly(JsonFieldType.NUMBER);
.containsExactly(JsonFieldType.NUMBER);
}
@Test
@@ -96,49 +96,49 @@ public class JsonFieldTypesDiscovererTests {
@Test
public void multipleFieldsWithSameType() throws IOException {
assertThat(discoverFieldTypes("a[].id", "{\"a\":[{\"id\":1},{\"id\":2}]}"))
.containsExactly(JsonFieldType.NUMBER);
.containsExactly(JsonFieldType.NUMBER);
}
@Test
public void multipleFieldsWithDifferentTypes() throws IOException {
assertThat(discoverFieldTypes("a[].id", "{\"a\":[{\"id\":1},{\"id\":true}]}"))
.containsExactlyInAnyOrder(JsonFieldType.NUMBER, JsonFieldType.BOOLEAN);
.containsExactlyInAnyOrder(JsonFieldType.NUMBER, JsonFieldType.BOOLEAN);
}
@Test
public void multipleFieldsWithDifferentTypesAndSometimesAbsent() throws IOException {
assertThat(discoverFieldTypes("a[].id", "{\"a\":[{\"id\":1},{\"id\":true}, {}]}"))
.containsExactlyInAnyOrder(JsonFieldType.NUMBER, JsonFieldType.BOOLEAN, JsonFieldType.NULL);
.containsExactlyInAnyOrder(JsonFieldType.NUMBER, JsonFieldType.BOOLEAN, JsonFieldType.NULL);
}
@Test
public void multipleFieldsWhenSometimesAbsent() throws IOException {
assertThat(discoverFieldTypes("a[].id", "{\"a\":[{\"id\":1},{\"id\":2}, {}]}"))
.containsExactlyInAnyOrder(JsonFieldType.NUMBER, JsonFieldType.NULL);
.containsExactlyInAnyOrder(JsonFieldType.NUMBER, JsonFieldType.NULL);
}
@Test
public void multipleFieldsWhenSometimesNull() throws IOException {
assertThat(discoverFieldTypes("a[].id", "{\"a\":[{\"id\":1},{\"id\":2}, {\"id\":null}]}"))
.containsExactlyInAnyOrder(JsonFieldType.NUMBER, JsonFieldType.NULL);
.containsExactlyInAnyOrder(JsonFieldType.NUMBER, JsonFieldType.NULL);
}
@Test
public void multipleFieldsWithDifferentTypesAndSometimesNull() throws IOException {
assertThat(discoverFieldTypes("a[].id", "{\"a\":[{\"id\":1},{\"id\":true}, {\"id\":null}]}"))
.containsExactlyInAnyOrder(JsonFieldType.NUMBER, JsonFieldType.BOOLEAN, JsonFieldType.NULL);
.containsExactlyInAnyOrder(JsonFieldType.NUMBER, JsonFieldType.BOOLEAN, JsonFieldType.NULL);
}
@Test
public void multipleFieldsWhenEitherNullOrAbsent() throws IOException {
assertThat(discoverFieldTypes("a[].id", "{\"a\":[{},{\"id\":null}]}"))
.containsExactlyInAnyOrder(JsonFieldType.NULL);
.containsExactlyInAnyOrder(JsonFieldType.NULL);
}
@Test
public void multipleFieldsThatAreAllNull() throws IOException {
assertThat(discoverFieldTypes("a[].id", "{\"a\":[{\"id\":null},{\"id\":null}]}"))
.containsExactlyInAnyOrder(JsonFieldType.NULL);
.containsExactlyInAnyOrder(JsonFieldType.NULL);
}
@Test
@@ -158,25 +158,25 @@ public class JsonFieldTypesDiscovererTests {
@Test
public void leafWildcardWithCommonType() throws IOException {
assertThat(discoverFieldTypes("a.*", "{\"a\": {\"b\": 5, \"c\": 6}}"))
.containsExactlyInAnyOrder(JsonFieldType.NUMBER);
.containsExactlyInAnyOrder(JsonFieldType.NUMBER);
}
@Test
public void leafWildcardWithVaryingType() throws IOException {
assertThat(discoverFieldTypes("a.*", "{\"a\": {\"b\": 5, \"c\": \"six\"}}"))
.containsExactlyInAnyOrder(JsonFieldType.NUMBER, JsonFieldType.STRING);
.containsExactlyInAnyOrder(JsonFieldType.NUMBER, JsonFieldType.STRING);
}
@Test
public void intermediateWildcardWithCommonType() throws IOException {
assertThat(discoverFieldTypes("a.*.d", "{\"a\": {\"b\": {\"d\": 4}, \"c\": {\"d\": 5}}}}"))
.containsExactlyInAnyOrder(JsonFieldType.NUMBER);
.containsExactlyInAnyOrder(JsonFieldType.NUMBER);
}
@Test
public void intermediateWildcardWithVaryingType() throws IOException {
assertThat(discoverFieldTypes("a.*.d", "{\"a\": {\"b\": {\"d\": 4}, \"c\": {\"d\": \"four\"}}}}"))
.containsExactlyInAnyOrder(JsonFieldType.NUMBER, JsonFieldType.STRING);
.containsExactlyInAnyOrder(JsonFieldType.NUMBER, JsonFieldType.STRING);
}
private JsonFieldTypes discoverFieldTypes(String value) throws IOException {

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2014-2019 the original author or authors.
* Copyright 2014-2023 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -42,19 +42,19 @@ public class JsonFieldTypesTests {
@Test
public void multipleTypesCoalescesToVaries() {
assertThat(new JsonFieldTypes(EnumSet.of(JsonFieldType.ARRAY, JsonFieldType.NUMBER)).coalesce(false))
.isEqualTo(JsonFieldType.VARIES);
.isEqualTo(JsonFieldType.VARIES);
}
@Test
public void nullAndNonNullTypesCoalescesToVaries() {
assertThat(new JsonFieldTypes(EnumSet.of(JsonFieldType.ARRAY, JsonFieldType.NULL)).coalesce(false))
.isEqualTo(JsonFieldType.VARIES);
.isEqualTo(JsonFieldType.VARIES);
}
@Test
public void nullAndNonNullTypesCoalescesToNonNullTypeWhenOptional() {
assertThat(new JsonFieldTypes(EnumSet.of(JsonFieldType.ARRAY, JsonFieldType.NULL)).coalesce(true))
.isEqualTo(JsonFieldType.ARRAY);
.isEqualTo(JsonFieldType.ARRAY);
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2014-2019 the original author or authors.
* Copyright 2014-2023 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -47,38 +47,41 @@ public class RequestBodyPartSnippetTests extends AbstractSnippetTests {
@Test
public void requestPartWithBody() throws IOException {
requestPartBody("one").document(
this.operationBuilder.request("http://localhost").part("one", "some content".getBytes()).build());
requestPartBody("one")
.document(this.operationBuilder.request("http://localhost").part("one", "some content".getBytes()).build());
assertThat(this.generatedSnippets.snippet("request-part-one-body"))
.is(codeBlock(null, "nowrap").withContent("some content"));
.is(codeBlock(null, "nowrap").withContent("some content"));
}
@Test
public void requestPartWithNoBody() throws IOException {
requestPartBody("one")
.document(this.operationBuilder.request("http://localhost").part("one", new byte[0]).build());
.document(this.operationBuilder.request("http://localhost").part("one", new byte[0]).build());
assertThat(this.generatedSnippets.snippet("request-part-one-body"))
.is(codeBlock(null, "nowrap").withContent(""));
.is(codeBlock(null, "nowrap").withContent(""));
}
@Test
public void subsectionOfRequestPartBody() throws IOException {
requestPartBody("one", beneathPath("a.b")).document(this.operationBuilder.request("http://localhost")
.part("one", "{\"a\":{\"b\":{\"c\":5}}}".getBytes()).build());
.part("one", "{\"a\":{\"b\":{\"c\":5}}}".getBytes())
.build());
assertThat(this.generatedSnippets.snippet("request-part-one-body-beneath-a.b"))
.is(codeBlock(null, "nowrap").withContent("{\"c\":5}"));
.is(codeBlock(null, "nowrap").withContent("{\"c\":5}"));
}
@Test
public void customSnippetAttributes() throws IOException {
TemplateResourceResolver resolver = mock(TemplateResourceResolver.class);
given(resolver.resolveTemplateResource("request-part-body"))
.willReturn(snippetResource("request-part-body-with-language"));
.willReturn(snippetResource("request-part-body-with-language"));
requestPartBody("one", attributes(key("language").value("json"))).document(
this.operationBuilder.attribute(TemplateEngine.class.getName(), new MustacheTemplateEngine(resolver))
.request("http://localhost").part("one", "{\"a\":\"alpha\"}".getBytes()).build());
.request("http://localhost")
.part("one", "{\"a\":\"alpha\"}".getBytes())
.build());
assertThat(this.generatedSnippets.snippet("request-part-one-body"))
.is(codeBlock("json", "nowrap").withContent("{\"a\":\"alpha\"}"));
.is(codeBlock("json", "nowrap").withContent("{\"a\":\"alpha\"}"));
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2014-2019 the original author or authors.
* Copyright 2014-2023 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -49,7 +49,7 @@ public class RequestBodySnippetTests extends AbstractSnippetTests {
public void requestWithBody() throws IOException {
requestBody().document(this.operationBuilder.request("http://localhost").content("some content").build());
assertThat(this.generatedSnippets.snippet("request-body"))
.is(codeBlock(null, "nowrap").withContent("some content"));
.is(codeBlock(null, "nowrap").withContent("some content"));
}
@Test
@@ -60,22 +60,24 @@ public class RequestBodySnippetTests extends AbstractSnippetTests {
@Test
public void subsectionOfRequestBody() throws IOException {
requestBody(beneathPath("a.b")).document(
this.operationBuilder.request("http://localhost").content("{\"a\":{\"b\":{\"c\":5}}}").build());
requestBody(beneathPath("a.b"))
.document(this.operationBuilder.request("http://localhost").content("{\"a\":{\"b\":{\"c\":5}}}").build());
assertThat(this.generatedSnippets.snippet("request-body-beneath-a.b"))
.is(codeBlock(null, "nowrap").withContent("{\"c\":5}"));
.is(codeBlock(null, "nowrap").withContent("{\"c\":5}"));
}
@Test
public void customSnippetAttributes() throws IOException {
TemplateResourceResolver resolver = mock(TemplateResourceResolver.class);
given(resolver.resolveTemplateResource("request-body"))
.willReturn(snippetResource("request-body-with-language"));
.willReturn(snippetResource("request-body-with-language"));
requestBody(attributes(key("language").value("json"))).document(
this.operationBuilder.attribute(TemplateEngine.class.getName(), new MustacheTemplateEngine(resolver))
.request("http://localhost").content("{\"a\":\"alpha\"}").build());
.request("http://localhost")
.content("{\"a\":\"alpha\"}")
.build());
assertThat(this.generatedSnippets.snippet("request-body"))
.is(codeBlock("json", "nowrap").withContent("{\"a\":\"alpha\"}"));
.is(codeBlock("json", "nowrap").withContent("{\"a\":\"alpha\"}"));
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2014-2022 the original author or authors.
* Copyright 2014-2023 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -45,142 +45,152 @@ public class RequestFieldsSnippetFailureTests {
@Test
public void undocumentedRequestField() {
assertThatExceptionOfType(SnippetException.class)
.isThrownBy(() -> new RequestFieldsSnippet(Collections.<FieldDescriptor>emptyList())
.document(this.operationBuilder.request("http://localhost").content("{\"a\": 5}").build()))
.withMessageStartingWith("The following parts of the payload were not documented:");
.isThrownBy(() -> new RequestFieldsSnippet(Collections.<FieldDescriptor>emptyList())
.document(this.operationBuilder.request("http://localhost").content("{\"a\": 5}").build()))
.withMessageStartingWith("The following parts of the payload were not documented:");
}
@Test
public void missingRequestField() {
assertThatExceptionOfType(SnippetException.class)
.isThrownBy(() -> new RequestFieldsSnippet(Arrays.asList(fieldWithPath("a.b").description("one")))
.document(this.operationBuilder.request("http://localhost").content("{}").build()))
.withMessage("Fields with the following paths were not found in the payload: [a.b]");
.isThrownBy(() -> new RequestFieldsSnippet(Arrays.asList(fieldWithPath("a.b").description("one")))
.document(this.operationBuilder.request("http://localhost").content("{}").build()))
.withMessage("Fields with the following paths were not found in the payload: [a.b]");
}
@Test
public void missingOptionalRequestFieldWithNoTypeProvided() {
assertThatExceptionOfType(FieldTypeRequiredException.class).isThrownBy(
() -> new RequestFieldsSnippet(Arrays.asList(fieldWithPath("a.b").description("one").optional()))
.document(this.operationBuilder.request("http://localhost").content("{ }").build()));
.document(this.operationBuilder.request("http://localhost").content("{ }").build()));
}
@Test
public void undocumentedRequestFieldAndMissingRequestField() {
assertThatExceptionOfType(SnippetException.class).isThrownBy(
() -> new RequestFieldsSnippet(Arrays.asList(fieldWithPath("a.b").description("one"))).document(
this.operationBuilder.request("http://localhost").content("{ \"a\": { \"c\": 5 }}").build()))
.withMessageStartingWith("The following parts of the payload were not documented:")
.withMessageEndingWith("Fields with the following paths were not found in the payload: [a.b]");
assertThatExceptionOfType(SnippetException.class)
.isThrownBy(() -> new RequestFieldsSnippet(Arrays.asList(fieldWithPath("a.b").description("one")))
.document(this.operationBuilder.request("http://localhost").content("{ \"a\": { \"c\": 5 }}").build()))
.withMessageStartingWith("The following parts of the payload were not documented:")
.withMessageEndingWith("Fields with the following paths were not found in the payload: [a.b]");
}
@Test
public void attemptToDocumentFieldsWithNoRequestBody() {
assertThatExceptionOfType(SnippetException.class)
.isThrownBy(() -> new RequestFieldsSnippet(Arrays.asList(fieldWithPath("a").description("one")))
.document(this.operationBuilder.request("http://localhost").build()))
.withMessage("Cannot document request fields as the request body is empty");
.isThrownBy(() -> new RequestFieldsSnippet(Arrays.asList(fieldWithPath("a").description("one")))
.document(this.operationBuilder.request("http://localhost").build()))
.withMessage("Cannot document request fields as the request body is empty");
}
@Test
public void fieldWithExplicitTypeThatDoesNotMatchThePayload() {
assertThatExceptionOfType(FieldTypesDoNotMatchException.class)
.isThrownBy(() -> new RequestFieldsSnippet(
Arrays.asList(fieldWithPath("a").description("one").type(JsonFieldType.OBJECT))).document(
this.operationBuilder.request("http://localhost").content("{ \"a\": 5 }").build()))
.withMessage("The documented type of the field 'a' is Object but the actual type is Number");
.isThrownBy(() -> new RequestFieldsSnippet(
Arrays.asList(fieldWithPath("a").description("one").type(JsonFieldType.OBJECT)))
.document(this.operationBuilder.request("http://localhost").content("{ \"a\": 5 }").build()))
.withMessage("The documented type of the field 'a' is Object but the actual type is Number");
}
@Test
public void fieldWithExplicitSpecificTypeThatActuallyVaries() {
assertThatExceptionOfType(FieldTypesDoNotMatchException.class)
.isThrownBy(() -> new RequestFieldsSnippet(
Arrays.asList(fieldWithPath("[].a").description("one").type(JsonFieldType.OBJECT)))
.document(this.operationBuilder.request("http://localhost")
.content("[{ \"a\": 5 },{ \"a\": \"b\" }]").build()))
.withMessage("The documented type of the field '[].a' is Object but the actual type is Varies");
.isThrownBy(() -> new RequestFieldsSnippet(
Arrays.asList(fieldWithPath("[].a").description("one").type(JsonFieldType.OBJECT)))
.document(this.operationBuilder.request("http://localhost")
.content("[{ \"a\": 5 },{ \"a\": \"b\" }]")
.build()))
.withMessage("The documented type of the field '[].a' is Object but the actual type is Varies");
}
@Test
public void undocumentedXmlRequestField() {
assertThatExceptionOfType(SnippetException.class)
.isThrownBy(() -> new RequestFieldsSnippet(Collections.<FieldDescriptor>emptyList())
.document(this.operationBuilder.request("http://localhost").content("<a><b>5</b></a>")
.header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_XML_VALUE).build()))
.withMessageStartingWith("The following parts of the payload were not documented:");
.isThrownBy(() -> new RequestFieldsSnippet(Collections.<FieldDescriptor>emptyList())
.document(this.operationBuilder.request("http://localhost")
.content("<a><b>5</b></a>")
.header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_XML_VALUE)
.build()))
.withMessageStartingWith("The following parts of the payload were not documented:");
}
@Test
public void xmlDescendentsAreNotDocumentedByFieldDescriptor() {
assertThatExceptionOfType(SnippetException.class)
.isThrownBy(
() -> new RequestFieldsSnippet(Arrays.asList(fieldWithPath("a").type("a").description("one")))
.document(this.operationBuilder.request("http://localhost").content("<a><b>5</b></a>")
.header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_XML_VALUE).build()))
.withMessageStartingWith("The following parts of the payload were not documented:");
.isThrownBy(() -> new RequestFieldsSnippet(Arrays.asList(fieldWithPath("a").type("a").description("one")))
.document(this.operationBuilder.request("http://localhost")
.content("<a><b>5</b></a>")
.header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_XML_VALUE)
.build()))
.withMessageStartingWith("The following parts of the payload were not documented:");
}
@Test
public void xmlRequestFieldWithNoType() {
assertThatExceptionOfType(FieldTypeRequiredException.class)
.isThrownBy(() -> new RequestFieldsSnippet(Arrays.asList(fieldWithPath("a").description("one")))
.document(this.operationBuilder.request("http://localhost").content("<a>5</a>")
.header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_XML_VALUE).build()));
.isThrownBy(() -> new RequestFieldsSnippet(Arrays.asList(fieldWithPath("a").description("one")))
.document(this.operationBuilder.request("http://localhost")
.content("<a>5</a>")
.header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_XML_VALUE)
.build()));
}
@Test
public void missingXmlRequestField() {
assertThatExceptionOfType(SnippetException.class)
.isThrownBy(() -> new RequestFieldsSnippet(
Arrays.asList(fieldWithPath("a/b").description("one"), fieldWithPath("a").description("one")))
.document(this.operationBuilder.request("http://localhost").content("<a></a>")
.header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_XML_VALUE).build()))
.withMessage("Fields with the following paths were not found in the payload: [a/b]");
.isThrownBy(() -> new RequestFieldsSnippet(
Arrays.asList(fieldWithPath("a/b").description("one"), fieldWithPath("a").description("one")))
.document(this.operationBuilder.request("http://localhost")
.content("<a></a>")
.header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_XML_VALUE)
.build()))
.withMessage("Fields with the following paths were not found in the payload: [a/b]");
}
@Test
public void undocumentedXmlRequestFieldAndMissingXmlRequestField() {
assertThatExceptionOfType(SnippetException.class)
.isThrownBy(() -> new RequestFieldsSnippet(Arrays.asList(fieldWithPath("a/b").description("one")))
.document(this.operationBuilder.request("http://localhost").content("<a><c>5</c></a>")
.header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_XML_VALUE).build()))
.withMessageStartingWith("The following parts of the payload were not documented:")
.withMessageEndingWith("Fields with the following paths were not found in the payload: [a/b]");
.isThrownBy(() -> new RequestFieldsSnippet(Arrays.asList(fieldWithPath("a/b").description("one")))
.document(this.operationBuilder.request("http://localhost")
.content("<a><c>5</c></a>")
.header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_XML_VALUE)
.build()))
.withMessageStartingWith("The following parts of the payload were not documented:")
.withMessageEndingWith("Fields with the following paths were not found in the payload: [a/b]");
}
@Test
public void unsupportedContent() {
assertThatExceptionOfType(PayloadHandlingException.class)
.isThrownBy(() -> new RequestFieldsSnippet(Collections.<FieldDescriptor>emptyList())
.document(this.operationBuilder.request("http://localhost").content("Some plain text")
.header(HttpHeaders.CONTENT_TYPE, MediaType.TEXT_PLAIN_VALUE).build()))
.withMessage("Cannot handle text/plain content as it could not be parsed as JSON or XML");
.isThrownBy(() -> new RequestFieldsSnippet(Collections.<FieldDescriptor>emptyList())
.document(this.operationBuilder.request("http://localhost")
.content("Some plain text")
.header(HttpHeaders.CONTENT_TYPE, MediaType.TEXT_PLAIN_VALUE)
.build()))
.withMessage("Cannot handle text/plain content as it could not be parsed as JSON or XML");
}
@Test
public void nonOptionalFieldBeneathArrayThatIsSometimesNull() {
assertThatExceptionOfType(SnippetException.class)
.isThrownBy(() -> new RequestFieldsSnippet(
Arrays.asList(fieldWithPath("a[].b").description("one").type(JsonFieldType.NUMBER),
fieldWithPath("a[].c").description("two").type(JsonFieldType.NUMBER)))
.document(this.operationBuilder.request("http://localhost")
.content("{\"a\":[{\"b\": 1,\"c\": 2}, " + "{\"b\": null, \"c\": 2},"
+ " {\"b\": 1,\"c\": 2}]}")
.build()))
.withMessageStartingWith("Fields with the following paths were not found in the payload: [a[].b]");
.isThrownBy(() -> new RequestFieldsSnippet(
Arrays.asList(fieldWithPath("a[].b").description("one").type(JsonFieldType.NUMBER),
fieldWithPath("a[].c").description("two").type(JsonFieldType.NUMBER)))
.document(this.operationBuilder.request("http://localhost")
.content("{\"a\":[{\"b\": 1,\"c\": 2}, " + "{\"b\": null, \"c\": 2}," + " {\"b\": 1,\"c\": 2}]}")
.build()))
.withMessageStartingWith("Fields with the following paths were not found in the payload: [a[].b]");
}
@Test
public void nonOptionalFieldBeneathArrayThatIsSometimesAbsent() {
assertThatExceptionOfType(SnippetException.class)
.isThrownBy(() -> new RequestFieldsSnippet(
Arrays.asList(fieldWithPath("a[].b").description("one").type(JsonFieldType.NUMBER),
fieldWithPath("a[].c").description("two").type(JsonFieldType.NUMBER)))
.document(this.operationBuilder.request("http://localhost")
.content("{\"a\":[{\"b\": 1,\"c\": 2}, "
+ "{\"c\": 2}, {\"b\": 1,\"c\": 2}]}")
.build()))
.withMessageStartingWith("Fields with the following paths were not found in the payload: [a[].b]");
.isThrownBy(() -> new RequestFieldsSnippet(
Arrays.asList(fieldWithPath("a[].b").description("one").type(JsonFieldType.NUMBER),
fieldWithPath("a[].c").description("two").type(JsonFieldType.NUMBER)))
.document(this.operationBuilder.request("http://localhost")
.content("{\"a\":[{\"b\": 1,\"c\": 2}, " + "{\"c\": 2}, {\"b\": 1,\"c\": 2}]}")
.build()))
.withMessageStartingWith("Fields with the following paths were not found in the payload: [a[].b]");
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2014-2019 the original author or authors.
* Copyright 2014-2023 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -55,127 +55,141 @@ public class RequestFieldsSnippetTests extends AbstractSnippetTests {
public void mapRequestWithFields() throws IOException {
new RequestFieldsSnippet(Arrays.asList(fieldWithPath("a.b").description("one"),
fieldWithPath("a.c").description("two"), fieldWithPath("a").description("three")))
.document(this.operationBuilder.request("http://localhost")
.content("{\"a\": {\"b\": 5, \"c\": \"charlie\"}}").build());
assertThat(this.generatedSnippets.requestFields()).is(tableWithHeader("Path", "Type", "Description")
.row("`a.b`", "`Number`", "one").row("`a.c`", "`String`", "two").row("`a`", "`Object`", "three"));
.document(this.operationBuilder.request("http://localhost")
.content("{\"a\": {\"b\": 5, \"c\": \"charlie\"}}")
.build());
assertThat(this.generatedSnippets.requestFields())
.is(tableWithHeader("Path", "Type", "Description").row("`a.b`", "`Number`", "one")
.row("`a.c`", "`String`", "two")
.row("`a`", "`Object`", "three"));
}
@Test
public void mapRequestWithNullField() throws IOException {
new RequestFieldsSnippet(Arrays.asList(fieldWithPath("a.b").description("one")))
.document(this.operationBuilder.request("http://localhost").content("{\"a\": {\"b\": null}}").build());
.document(this.operationBuilder.request("http://localhost").content("{\"a\": {\"b\": null}}").build());
assertThat(this.generatedSnippets.requestFields())
.is(tableWithHeader("Path", "Type", "Description").row("`a.b`", "`Null`", "one"));
.is(tableWithHeader("Path", "Type", "Description").row("`a.b`", "`Null`", "one"));
}
@Test
public void entireSubsectionsCanBeDocumented() throws IOException {
new RequestFieldsSnippet(Arrays.asList(subsectionWithPath("a").description("one")))
.document(this.operationBuilder.request("http://localhost")
.content("{\"a\": {\"b\": 5, \"c\": \"charlie\"}}").build());
.document(this.operationBuilder.request("http://localhost")
.content("{\"a\": {\"b\": 5, \"c\": \"charlie\"}}")
.build());
assertThat(this.generatedSnippets.requestFields())
.is(tableWithHeader("Path", "Type", "Description").row("`a`", "`Object`", "one"));
.is(tableWithHeader("Path", "Type", "Description").row("`a`", "`Object`", "one"));
}
@Test
public void subsectionOfMapRequest() throws IOException {
requestFields(beneathPath("a"), fieldWithPath("b").description("one"), fieldWithPath("c").description("two"))
.document(this.operationBuilder.request("http://localhost")
.content("{\"a\": {\"b\": 5, \"c\": \"charlie\"}}").build());
.document(this.operationBuilder.request("http://localhost")
.content("{\"a\": {\"b\": 5, \"c\": \"charlie\"}}")
.build());
assertThat(this.generatedSnippets.snippet("request-fields-beneath-a"))
.is(tableWithHeader("Path", "Type", "Description").row("`b`", "`Number`", "one").row("`c`", "`String`",
"two"));
.is(tableWithHeader("Path", "Type", "Description").row("`b`", "`Number`", "one")
.row("`c`", "`String`", "two"));
}
@Test
public void subsectionOfMapRequestWithCommonPrefix() throws IOException {
requestFields(beneathPath("a")).andWithPrefix("b.", fieldWithPath("c").description("two"))
.document(this.operationBuilder.request("http://localhost")
.content("{\"a\": {\"b\": {\"c\": \"charlie\"}}}").build());
.document(this.operationBuilder.request("http://localhost")
.content("{\"a\": {\"b\": {\"c\": \"charlie\"}}}")
.build());
assertThat(this.generatedSnippets.snippet("request-fields-beneath-a"))
.is(tableWithHeader("Path", "Type", "Description").row("`b.c`", "`String`", "two"));
.is(tableWithHeader("Path", "Type", "Description").row("`b.c`", "`String`", "two"));
}
@Test
public void arrayRequestWithFields() throws IOException {
new RequestFieldsSnippet(Arrays.asList(fieldWithPath("[]").description("one"),
fieldWithPath("[]a.b").description("two"), fieldWithPath("[]a.c").description("three"),
fieldWithPath("[]a").description("four"))).document(this.operationBuilder.request("http://localhost")
.content("[{\"a\": {\"b\": 5, \"c\":\"charlie\"}}," + "{\"a\": {\"b\": 4, \"c\":\"chalk\"}}]")
.build());
assertThat(this.generatedSnippets.requestFields()).is(tableWithHeader("Path", "Type", "Description")
.row("`[]`", "`Array`", "one").row("`[]a.b`", "`Number`", "two").row("`[]a.c`", "`String`", "three")
new RequestFieldsSnippet(
Arrays.asList(fieldWithPath("[]").description("one"), fieldWithPath("[]a.b").description("two"),
fieldWithPath("[]a.c").description("three"), fieldWithPath("[]a").description("four")))
.document(this.operationBuilder.request("http://localhost")
.content("[{\"a\": {\"b\": 5, \"c\":\"charlie\"}}," + "{\"a\": {\"b\": 4, \"c\":\"chalk\"}}]")
.build());
assertThat(this.generatedSnippets.requestFields())
.is(tableWithHeader("Path", "Type", "Description").row("`[]`", "`Array`", "one")
.row("`[]a.b`", "`Number`", "two")
.row("`[]a.c`", "`String`", "three")
.row("`[]a`", "`Object`", "four"));
}
@Test
public void arrayRequestWithAlwaysNullField() throws IOException {
new RequestFieldsSnippet(Arrays.asList(fieldWithPath("[]a.b").description("one")))
.document(this.operationBuilder.request("http://localhost")
.content("[{\"a\": {\"b\": null}}," + "{\"a\": {\"b\": null}}]").build());
.document(this.operationBuilder.request("http://localhost")
.content("[{\"a\": {\"b\": null}}," + "{\"a\": {\"b\": null}}]")
.build());
assertThat(this.generatedSnippets.requestFields())
.is(tableWithHeader("Path", "Type", "Description").row("`[]a.b`", "`Null`", "one"));
.is(tableWithHeader("Path", "Type", "Description").row("`[]a.b`", "`Null`", "one"));
}
@Test
public void subsectionOfArrayRequest() throws IOException {
requestFields(beneathPath("[].a"), fieldWithPath("b").description("one"), fieldWithPath("c").description("two"))
.document(this.operationBuilder.request("http://localhost")
.content("[{\"a\": {\"b\": 5, \"c\": \"charlie\"}}]").build());
.document(this.operationBuilder.request("http://localhost")
.content("[{\"a\": {\"b\": 5, \"c\": \"charlie\"}}]")
.build());
assertThat(this.generatedSnippets.snippet("request-fields-beneath-[].a"))
.is(tableWithHeader("Path", "Type", "Description").row("`b`", "`Number`", "one").row("`c`", "`String`",
"two"));
.is(tableWithHeader("Path", "Type", "Description").row("`b`", "`Number`", "one")
.row("`c`", "`String`", "two"));
}
@Test
public void ignoredRequestField() throws IOException {
new RequestFieldsSnippet(Arrays.asList(fieldWithPath("a").ignored(), fieldWithPath("b").description("Field b")))
.document(this.operationBuilder.request("http://localhost").content("{\"a\": 5, \"b\": 4}").build());
.document(this.operationBuilder.request("http://localhost").content("{\"a\": 5, \"b\": 4}").build());
assertThat(this.generatedSnippets.requestFields())
.is(tableWithHeader("Path", "Type", "Description").row("`b`", "`Number`", "Field b"));
.is(tableWithHeader("Path", "Type", "Description").row("`b`", "`Number`", "Field b"));
}
@Test
public void entireSubsectionCanBeIgnored() throws IOException {
new RequestFieldsSnippet(
Arrays.asList(subsectionWithPath("a").ignored(), fieldWithPath("c").description("Field c")))
.document(this.operationBuilder.request("http://localhost")
.content("{\"a\": {\"b\": 5}, \"c\": 4}").build());
.document(
this.operationBuilder.request("http://localhost").content("{\"a\": {\"b\": 5}, \"c\": 4}").build());
assertThat(this.generatedSnippets.requestFields())
.is(tableWithHeader("Path", "Type", "Description").row("`c`", "`Number`", "Field c"));
.is(tableWithHeader("Path", "Type", "Description").row("`c`", "`Number`", "Field c"));
}
@Test
public void allUndocumentedRequestFieldsCanBeIgnored() throws IOException {
new RequestFieldsSnippet(Arrays.asList(fieldWithPath("b").description("Field b")), true)
.document(this.operationBuilder.request("http://localhost").content("{\"a\": 5, \"b\": 4}").build());
.document(this.operationBuilder.request("http://localhost").content("{\"a\": 5, \"b\": 4}").build());
assertThat(this.generatedSnippets.requestFields())
.is(tableWithHeader("Path", "Type", "Description").row("`b`", "`Number`", "Field b"));
.is(tableWithHeader("Path", "Type", "Description").row("`b`", "`Number`", "Field b"));
}
@Test
public void allUndocumentedFieldsContinueToBeIgnoredAfterAddingDescriptors() throws IOException {
new RequestFieldsSnippet(Arrays.asList(fieldWithPath("b").description("Field b")), true)
.andWithPrefix("c.", fieldWithPath("d").description("Field d")).document(this.operationBuilder
.request("http://localhost").content("{\"a\":5,\"b\":4,\"c\":{\"d\": 3}}").build());
assertThat(this.generatedSnippets.requestFields()).is(tableWithHeader("Path", "Type", "Description")
.row("`b`", "`Number`", "Field b").row("`c.d`", "`Number`", "Field d"));
.andWithPrefix("c.", fieldWithPath("d").description("Field d"))
.document(this.operationBuilder.request("http://localhost")
.content("{\"a\":5,\"b\":4,\"c\":{\"d\": 3}}")
.build());
assertThat(this.generatedSnippets.requestFields())
.is(tableWithHeader("Path", "Type", "Description").row("`b`", "`Number`", "Field b")
.row("`c.d`", "`Number`", "Field d"));
}
@Test
public void missingOptionalRequestField() throws IOException {
new RequestFieldsSnippet(
Arrays.asList(fieldWithPath("a.b").description("one").type(JsonFieldType.STRING).optional()))
.document(this.operationBuilder.request("http://localhost").content("{}").build());
.document(this.operationBuilder.request("http://localhost").content("{}").build());
assertThat(this.generatedSnippets.requestFields())
.is(tableWithHeader("Path", "Type", "Description").row("`a.b`", "`String`", "one"));
.is(tableWithHeader("Path", "Type", "Description").row("`a.b`", "`String`", "one"));
}
@Test
public void missingIgnoredOptionalRequestFieldDoesNotRequireAType() throws IOException {
new RequestFieldsSnippet(Arrays.asList(fieldWithPath("a.b").description("one").ignored().optional()))
.document(this.operationBuilder.request("http://localhost").content("{}").build());
.document(this.operationBuilder.request("http://localhost").content("{}").build());
assertThat(this.generatedSnippets.requestFields()).is(tableWithHeader("Path", "Type", "Description"));
}
@@ -183,22 +197,24 @@ public class RequestFieldsSnippetTests extends AbstractSnippetTests {
public void presentOptionalRequestField() throws IOException {
new RequestFieldsSnippet(
Arrays.asList(fieldWithPath("a.b").description("one").type(JsonFieldType.STRING).optional()))
.document(this.operationBuilder.request("http://localhost")
.content("{\"a\": { \"b\": \"bravo\"}}").build());
.document(
this.operationBuilder.request("http://localhost").content("{\"a\": { \"b\": \"bravo\"}}").build());
assertThat(this.generatedSnippets.requestFields())
.is(tableWithHeader("Path", "Type", "Description").row("`a.b`", "`String`", "one"));
.is(tableWithHeader("Path", "Type", "Description").row("`a.b`", "`String`", "one"));
}
@Test
public void requestFieldsWithCustomAttributes() throws IOException {
TemplateResourceResolver resolver = mock(TemplateResourceResolver.class);
given(resolver.resolveTemplateResource("request-fields"))
.willReturn(snippetResource("request-fields-with-title"));
.willReturn(snippetResource("request-fields-with-title"));
new RequestFieldsSnippet(Arrays.asList(fieldWithPath("a").description("one")),
attributes(key("title").value("Custom title")))
.document(this.operationBuilder
.attribute(TemplateEngine.class.getName(), new MustacheTemplateEngine(resolver))
.request("http://localhost").content("{\"a\": \"foo\"}").build());
.document(this.operationBuilder
.attribute(TemplateEngine.class.getName(), new MustacheTemplateEngine(resolver))
.request("http://localhost")
.content("{\"a\": \"foo\"}")
.build());
assertThat(this.generatedSnippets.requestFields()).contains("Custom title");
}
@@ -206,34 +222,36 @@ public class RequestFieldsSnippetTests extends AbstractSnippetTests {
public void requestFieldsWithCustomDescriptorAttributes() throws IOException {
TemplateResourceResolver resolver = mock(TemplateResourceResolver.class);
given(resolver.resolveTemplateResource("request-fields"))
.willReturn(snippetResource("request-fields-with-extra-column"));
.willReturn(snippetResource("request-fields-with-extra-column"));
new RequestFieldsSnippet(
Arrays.asList(fieldWithPath("a.b").description("one").attributes(key("foo").value("alpha")),
fieldWithPath("a.c").description("two").attributes(key("foo").value("bravo")),
fieldWithPath("a").description("three").attributes(key("foo").value("charlie"))))
.document(this.operationBuilder
.attribute(TemplateEngine.class.getName(), new MustacheTemplateEngine(resolver))
.request("http://localhost").content("{\"a\": {\"b\": 5, \"c\": \"charlie\"}}")
.build());
.document(this.operationBuilder
.attribute(TemplateEngine.class.getName(), new MustacheTemplateEngine(resolver))
.request("http://localhost")
.content("{\"a\": {\"b\": 5, \"c\": \"charlie\"}}")
.build());
assertThat(this.generatedSnippets.requestFields())
.is(tableWithHeader("Path", "Type", "Description", "Foo").row("a.b", "Number", "one", "alpha")
.row("a.c", "String", "two", "bravo").row("a", "Object", "three", "charlie"));
.is(tableWithHeader("Path", "Type", "Description", "Foo").row("a.b", "Number", "one", "alpha")
.row("a.c", "String", "two", "bravo")
.row("a", "Object", "three", "charlie"));
}
@Test
public void fieldWithExplictExactlyMatchingType() throws IOException {
new RequestFieldsSnippet(Arrays.asList(fieldWithPath("a").description("one").type(JsonFieldType.NUMBER)))
.document(this.operationBuilder.request("http://localhost").content("{\"a\": 5 }").build());
.document(this.operationBuilder.request("http://localhost").content("{\"a\": 5 }").build());
assertThat(this.generatedSnippets.requestFields())
.is(tableWithHeader("Path", "Type", "Description").row("`a`", "`Number`", "one"));
.is(tableWithHeader("Path", "Type", "Description").row("`a`", "`Number`", "one"));
}
@Test
public void fieldWithExplictVariesType() throws IOException {
new RequestFieldsSnippet(Arrays.asList(fieldWithPath("a").description("one").type(JsonFieldType.VARIES)))
.document(this.operationBuilder.request("http://localhost").content("{\"a\": 5 }").build());
.document(this.operationBuilder.request("http://localhost").content("{\"a\": 5 }").build());
assertThat(this.generatedSnippets.requestFields())
.is(tableWithHeader("Path", "Type", "Description").row("`a`", "`Varies`", "one"));
.is(tableWithHeader("Path", "Type", "Description").row("`a`", "`Varies`", "one"));
}
@Test
@@ -254,71 +272,85 @@ public class RequestFieldsSnippetTests extends AbstractSnippetTests {
private void xmlRequestFields(MediaType contentType) throws IOException {
new RequestFieldsSnippet(Arrays.asList(fieldWithPath("a/b").description("one").type("b"),
fieldWithPath("a/c").description("two").type("c"), fieldWithPath("a").description("three").type("a")))
.document(this.operationBuilder.request("http://localhost")
.content("<a><b>5</b><c>charlie</c></a>")
.header(HttpHeaders.CONTENT_TYPE, contentType.toString()).build());
assertThat(this.generatedSnippets.requestFields()).is(tableWithHeader("Path", "Type", "Description")
.row("`a/b`", "`b`", "one").row("`a/c`", "`c`", "two").row("`a`", "`a`", "three"));
.document(this.operationBuilder.request("http://localhost")
.content("<a><b>5</b><c>charlie</c></a>")
.header(HttpHeaders.CONTENT_TYPE, contentType.toString())
.build());
assertThat(this.generatedSnippets.requestFields())
.is(tableWithHeader("Path", "Type", "Description").row("`a/b`", "`b`", "one")
.row("`a/c`", "`c`", "two")
.row("`a`", "`a`", "three"));
}
@Test
public void entireSubsectionOfXmlPayloadCanBeDocumented() throws IOException {
new RequestFieldsSnippet(Arrays.asList(subsectionWithPath("a").description("one").type("a")))
.document(this.operationBuilder.request("http://localhost").content("<a><b>5</b><c>charlie</c></a>")
.header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_XML_VALUE).build());
.document(this.operationBuilder.request("http://localhost")
.content("<a><b>5</b><c>charlie</c></a>")
.header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_XML_VALUE)
.build());
assertThat(this.generatedSnippets.requestFields())
.is(tableWithHeader("Path", "Type", "Description").row("`a`", "`a`", "one"));
.is(tableWithHeader("Path", "Type", "Description").row("`a`", "`a`", "one"));
}
@Test
public void additionalDescriptors() throws IOException {
PayloadDocumentation
.requestFields(fieldWithPath("a.b").description("one"), fieldWithPath("a.c").description("two"))
.and(fieldWithPath("a").description("three")).document(this.operationBuilder.request("http://localhost")
.content("{\"a\": {\"b\": 5, \"c\": \"charlie\"}}").build());
assertThat(this.generatedSnippets.requestFields()).is(tableWithHeader("Path", "Type", "Description")
.row("`a.b`", "`Number`", "one").row("`a.c`", "`String`", "two").row("`a`", "`Object`", "three"));
.requestFields(fieldWithPath("a.b").description("one"), fieldWithPath("a.c").description("two"))
.and(fieldWithPath("a").description("three"))
.document(this.operationBuilder.request("http://localhost")
.content("{\"a\": {\"b\": 5, \"c\": \"charlie\"}}")
.build());
assertThat(this.generatedSnippets.requestFields())
.is(tableWithHeader("Path", "Type", "Description").row("`a.b`", "`Number`", "one")
.row("`a.c`", "`String`", "two")
.row("`a`", "`Object`", "three"));
}
@Test
public void prefixedAdditionalDescriptors() throws IOException {
PayloadDocumentation.requestFields(fieldWithPath("a").description("one"))
.andWithPrefix("a.", fieldWithPath("b").description("two"), fieldWithPath("c").description("three"))
.document(this.operationBuilder.request("http://localhost")
.content("{\"a\": {\"b\": 5, \"c\": \"charlie\"}}").build());
assertThat(this.generatedSnippets.requestFields()).is(tableWithHeader("Path", "Type", "Description")
.row("`a`", "`Object`", "one").row("`a.b`", "`Number`", "two").row("`a.c`", "`String`", "three"));
.andWithPrefix("a.", fieldWithPath("b").description("two"), fieldWithPath("c").description("three"))
.document(this.operationBuilder.request("http://localhost")
.content("{\"a\": {\"b\": 5, \"c\": \"charlie\"}}")
.build());
assertThat(this.generatedSnippets.requestFields())
.is(tableWithHeader("Path", "Type", "Description").row("`a`", "`Object`", "one")
.row("`a.b`", "`Number`", "two")
.row("`a.c`", "`String`", "three"));
}
@Test
public void requestWithFieldsWithEscapedContent() throws IOException {
new RequestFieldsSnippet(Arrays.asList(fieldWithPath("Foo|Bar").type("one|two").description("three|four")))
.document(this.operationBuilder.request("http://localhost").content("{\"Foo|Bar\": 5}").build());
.document(this.operationBuilder.request("http://localhost").content("{\"Foo|Bar\": 5}").build());
assertThat(this.generatedSnippets.requestFields()).is(tableWithHeader("Path", "Type", "Description")
.row(escapeIfNecessary("`Foo|Bar`"), escapeIfNecessary("`one|two`"), escapeIfNecessary("three|four")));
.row(escapeIfNecessary("`Foo|Bar`"), escapeIfNecessary("`one|two`"), escapeIfNecessary("three|four")));
}
@Test
public void mapRequestWithVaryingKeysMatchedUsingWildcard() throws IOException {
new RequestFieldsSnippet(Arrays.asList(fieldWithPath("things.*.size").description("one"),
fieldWithPath("things.*.type").description("two")))
.document(this.operationBuilder.request("http://localhost")
.content("{\"things\": {\"12abf\": {\"type\":" + "\"Whale\", \"size\": \"HUGE\"},"
+ "\"gzM33\" : {\"type\": \"Screw\"," + "\"size\": \"SMALL\"}}}")
.build());
assertThat(this.generatedSnippets.requestFields()).is(tableWithHeader("Path", "Type", "Description")
.row("`things.*.size`", "`String`", "one").row("`things.*.type`", "`String`", "two"));
.document(this.operationBuilder.request("http://localhost")
.content("{\"things\": {\"12abf\": {\"type\":" + "\"Whale\", \"size\": \"HUGE\"},"
+ "\"gzM33\" : {\"type\": \"Screw\"," + "\"size\": \"SMALL\"}}}")
.build());
assertThat(this.generatedSnippets.requestFields())
.is(tableWithHeader("Path", "Type", "Description").row("`things.*.size`", "`String`", "one")
.row("`things.*.type`", "`String`", "two"));
}
@Test
public void requestWithArrayContainingFieldThatIsSometimesNull() throws IOException {
new RequestFieldsSnippet(
Arrays.asList(fieldWithPath("assets[].name").description("one").type(JsonFieldType.STRING).optional()))
.document(this.operationBuilder.request("http://localhost").content("{\"assets\": ["
+ "{\"name\": \"sample1\"}, " + "{\"name\": null}, " + "{\"name\": \"sample2\"}]}")
.build());
.document(this.operationBuilder.request("http://localhost")
.content("{\"assets\": [" + "{\"name\": \"sample1\"}, " + "{\"name\": null}, "
+ "{\"name\": \"sample2\"}]}")
.build());
assertThat(this.generatedSnippets.requestFields())
.is(tableWithHeader("Path", "Type", "Description").row("`assets[].name`", "`String`", "one"));
.is(tableWithHeader("Path", "Type", "Description").row("`assets[].name`", "`String`", "one"));
}
@Test
@@ -326,21 +358,22 @@ public class RequestFieldsSnippetTests extends AbstractSnippetTests {
new RequestFieldsSnippet(
Arrays.asList(fieldWithPath("a[].b").description("one").type(JsonFieldType.NUMBER).optional(),
fieldWithPath("a[].c").description("two").type(JsonFieldType.NUMBER)))
.document(this.operationBuilder.request("http://localhost")
.content("{\"a\":[{\"b\": 1,\"c\": 2}, " + "{\"c\": 2}, {\"b\": 1,\"c\": 2}]}")
.build());
assertThat(this.generatedSnippets.requestFields()).is(tableWithHeader("Path", "Type", "Description")
.row("`a[].b`", "`Number`", "one").row("`a[].c`", "`Number`", "two"));
.document(this.operationBuilder.request("http://localhost")
.content("{\"a\":[{\"b\": 1,\"c\": 2}, " + "{\"c\": 2}, {\"b\": 1,\"c\": 2}]}")
.build());
assertThat(this.generatedSnippets.requestFields())
.is(tableWithHeader("Path", "Type", "Description").row("`a[].b`", "`Number`", "one")
.row("`a[].c`", "`Number`", "two"));
}
@Test
public void typeDeterminationDoesNotSetTypeOnDescriptor() throws IOException {
FieldDescriptor descriptor = fieldWithPath("a.b").description("one");
new RequestFieldsSnippet(Arrays.asList(descriptor))
.document(this.operationBuilder.request("http://localhost").content("{\"a\": {\"b\": 5}}").build());
.document(this.operationBuilder.request("http://localhost").content("{\"a\": {\"b\": 5}}").build());
assertThat(descriptor.getType()).isNull();
assertThat(this.generatedSnippets.requestFields())
.is(tableWithHeader("Path", "Type", "Description").row("`a.b`", "`Number`", "one"));
.is(tableWithHeader("Path", "Type", "Description").row("`a.b`", "`Number`", "one"));
}
private String escapeIfNecessary(String input) {

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2014-2022 the original author or authors.
* Copyright 2014-2023 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -44,29 +44,27 @@ public class RequestPartFieldsSnippetFailureTests {
@Test
public void undocumentedRequestPartField() {
assertThatExceptionOfType(SnippetException.class)
.isThrownBy(() -> new RequestPartFieldsSnippet("part", Collections.<FieldDescriptor>emptyList())
.document(this.operationBuilder.request("http://localhost")
.part("part", "{\"a\": 5}".getBytes()).build()))
.withMessageStartingWith("The following parts of the payload were not documented:");
.isThrownBy(() -> new RequestPartFieldsSnippet("part", Collections.<FieldDescriptor>emptyList()).document(
this.operationBuilder.request("http://localhost").part("part", "{\"a\": 5}".getBytes()).build()))
.withMessageStartingWith("The following parts of the payload were not documented:");
}
@Test
public void missingRequestPartField() {
assertThatExceptionOfType(SnippetException.class)
.isThrownBy(
() -> new RequestPartFieldsSnippet("part", Arrays.asList(fieldWithPath("b").description("one")))
.document(this.operationBuilder.request("http://localhost")
.part("part", "{\"a\": 5}".getBytes()).build()))
.withMessageStartingWith("The following parts of the payload were not documented:");
assertThatExceptionOfType(SnippetException.class).isThrownBy(() -> new RequestPartFieldsSnippet("part",
Arrays.asList(fieldWithPath("b").description("one")))
.document(this.operationBuilder.request("http://localhost").part("part", "{\"a\": 5}".getBytes()).build()))
.withMessageStartingWith("The following parts of the payload were not documented:");
}
@Test
public void missingRequestPart() {
assertThatExceptionOfType(SnippetException.class).isThrownBy(
() -> new RequestPartFieldsSnippet("another", Arrays.asList(fieldWithPath("a.b").description("one")))
.document(this.operationBuilder.request("http://localhost")
.part("part", "{\"a\": {\"b\": 5}}".getBytes()).build()))
.withMessage("A request part named 'another' was not found in the request");
.document(this.operationBuilder.request("http://localhost")
.part("part", "{\"a\": {\"b\": 5}}".getBytes())
.build()))
.withMessage("A request part named 'another' was not found in the request");
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2014-2019 the original author or authors.
* Copyright 2014-2023 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -47,27 +47,34 @@ public class RequestPartFieldsSnippetTests extends AbstractSnippetTests {
new RequestPartFieldsSnippet("one",
Arrays.asList(fieldWithPath("a.b").description("one"), fieldWithPath("a.c").description("two"),
fieldWithPath("a").description("three")))
.document(this.operationBuilder.request("http://localhost")
.part("one", "{\"a\": {\"b\": 5, \"c\": \"charlie\"}}".getBytes()).build());
assertThat(this.generatedSnippets.requestPartFields("one")).is(tableWithHeader("Path", "Type", "Description")
.row("`a.b`", "`Number`", "one").row("`a.c`", "`String`", "two").row("`a`", "`Object`", "three"));
.document(this.operationBuilder.request("http://localhost")
.part("one", "{\"a\": {\"b\": 5, \"c\": \"charlie\"}}".getBytes())
.build());
assertThat(this.generatedSnippets.requestPartFields("one"))
.is(tableWithHeader("Path", "Type", "Description").row("`a.b`", "`Number`", "one")
.row("`a.c`", "`String`", "two")
.row("`a`", "`Object`", "three"));
}
@Test
public void mapRequestPartSubsectionFields() throws IOException {
new RequestPartFieldsSnippet("one", beneathPath("a"),
Arrays.asList(fieldWithPath("b").description("one"), fieldWithPath("c").description("two")))
.document(this.operationBuilder.request("http://localhost")
.part("one", "{\"a\": {\"b\": 5, \"c\": \"charlie\"}}".getBytes()).build());
.document(this.operationBuilder.request("http://localhost")
.part("one", "{\"a\": {\"b\": 5, \"c\": \"charlie\"}}".getBytes())
.build());
assertThat(this.generatedSnippets.snippet("request-part-one-fields-beneath-a"))
.is(tableWithHeader("Path", "Type", "Description").row("`b`", "`Number`", "one").row("`c`", "`String`",
"two"));
.is(tableWithHeader("Path", "Type", "Description").row("`b`", "`Number`", "one")
.row("`c`", "`String`", "two"));
}
@Test
public void multipleRequestParts() throws IOException {
Operation operation = this.operationBuilder.request("http://localhost").part("one", "{}".getBytes()).and()
.part("two", "{}".getBytes()).build();
Operation operation = this.operationBuilder.request("http://localhost")
.part("one", "{}".getBytes())
.and()
.part("two", "{}".getBytes())
.build();
new RequestPartFieldsSnippet("one", Collections.<FieldDescriptor>emptyList()).document(operation);
new RequestPartFieldsSnippet("two", Collections.<FieldDescriptor>emptyList()).document(operation);
assertThat(this.generatedSnippets.requestPartFields("one")).isNotNull();
@@ -77,31 +84,38 @@ public class RequestPartFieldsSnippetTests extends AbstractSnippetTests {
@Test
public void allUndocumentedRequestPartFieldsCanBeIgnored() throws IOException {
new RequestPartFieldsSnippet("one", Arrays.asList(fieldWithPath("b").description("Field b")), true)
.document(this.operationBuilder.request("http://localhost")
.part("one", "{\"a\": 5, \"b\": 4}".getBytes()).build());
.document(this.operationBuilder.request("http://localhost")
.part("one", "{\"a\": 5, \"b\": 4}".getBytes())
.build());
assertThat(this.generatedSnippets.requestPartFields("one"))
.is(tableWithHeader("Path", "Type", "Description").row("`b`", "`Number`", "Field b"));
.is(tableWithHeader("Path", "Type", "Description").row("`b`", "`Number`", "Field b"));
}
@Test
public void additionalDescriptors() throws IOException {
PayloadDocumentation
.requestPartFields("one", fieldWithPath("a.b").description("one"),
fieldWithPath("a.c").description("two"))
.and(fieldWithPath("a").description("three")).document(this.operationBuilder.request("http://localhost")
.part("one", "{\"a\": {\"b\": 5, \"c\": \"charlie\"}}".getBytes()).build());
assertThat(this.generatedSnippets.requestPartFields("one")).is(tableWithHeader("Path", "Type", "Description")
.row("`a.b`", "`Number`", "one").row("`a.c`", "`String`", "two").row("`a`", "`Object`", "three"));
.requestPartFields("one", fieldWithPath("a.b").description("one"), fieldWithPath("a.c").description("two"))
.and(fieldWithPath("a").description("three"))
.document(this.operationBuilder.request("http://localhost")
.part("one", "{\"a\": {\"b\": 5, \"c\": \"charlie\"}}".getBytes())
.build());
assertThat(this.generatedSnippets.requestPartFields("one"))
.is(tableWithHeader("Path", "Type", "Description").row("`a.b`", "`Number`", "one")
.row("`a.c`", "`String`", "two")
.row("`a`", "`Object`", "three"));
}
@Test
public void prefixedAdditionalDescriptors() throws IOException {
PayloadDocumentation.requestPartFields("one", fieldWithPath("a").description("one"))
.andWithPrefix("a.", fieldWithPath("b").description("two"), fieldWithPath("c").description("three"))
.document(this.operationBuilder.request("http://localhost")
.part("one", "{\"a\": {\"b\": 5, \"c\": \"charlie\"}}".getBytes()).build());
assertThat(this.generatedSnippets.requestPartFields("one")).is(tableWithHeader("Path", "Type", "Description")
.row("`a`", "`Object`", "one").row("`a.b`", "`Number`", "two").row("`a.c`", "`String`", "three"));
.andWithPrefix("a.", fieldWithPath("b").description("two"), fieldWithPath("c").description("three"))
.document(this.operationBuilder.request("http://localhost")
.part("one", "{\"a\": {\"b\": 5, \"c\": \"charlie\"}}".getBytes())
.build());
assertThat(this.generatedSnippets.requestPartFields("one"))
.is(tableWithHeader("Path", "Type", "Description").row("`a`", "`Object`", "one")
.row("`a.b`", "`Number`", "two")
.row("`a.c`", "`String`", "three"));
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2014-2019 the original author or authors.
* Copyright 2014-2023 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -49,7 +49,7 @@ public class ResponseBodySnippetTests extends AbstractSnippetTests {
public void responseWithBody() throws IOException {
new ResponseBodySnippet().document(this.operationBuilder.response().content("some content").build());
assertThat(this.generatedSnippets.snippet("response-body"))
.is(codeBlock(null, "nowrap").withContent("some content"));
.is(codeBlock(null, "nowrap").withContent("some content"));
}
@Test
@@ -61,21 +61,23 @@ public class ResponseBodySnippetTests extends AbstractSnippetTests {
@Test
public void subsectionOfResponseBody() throws IOException {
responseBody(beneathPath("a.b"))
.document(this.operationBuilder.response().content("{\"a\":{\"b\":{\"c\":5}}}").build());
.document(this.operationBuilder.response().content("{\"a\":{\"b\":{\"c\":5}}}").build());
assertThat(this.generatedSnippets.snippet("response-body-beneath-a.b"))
.is(codeBlock(null, "nowrap").withContent("{\"c\":5}"));
.is(codeBlock(null, "nowrap").withContent("{\"c\":5}"));
}
@Test
public void customSnippetAttributes() throws IOException {
TemplateResourceResolver resolver = mock(TemplateResourceResolver.class);
given(resolver.resolveTemplateResource("response-body"))
.willReturn(snippetResource("response-body-with-language"));
.willReturn(snippetResource("response-body-with-language"));
new ResponseBodySnippet(attributes(key("language").value("json"))).document(
this.operationBuilder.attribute(TemplateEngine.class.getName(), new MustacheTemplateEngine(resolver))
.response().content("{\"a\":\"alpha\"}").build());
.response()
.content("{\"a\":\"alpha\"}")
.build());
assertThat(this.generatedSnippets.snippet("response-body"))
.is(codeBlock("json", "nowrap").withContent("{\"a\":\"alpha\"}"));
.is(codeBlock("json", "nowrap").withContent("{\"a\":\"alpha\"}"));
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2014-2022 the original author or authors.
* Copyright 2014-2023 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -45,122 +45,131 @@ public class ResponseFieldsSnippetFailureTests {
@Test
public void attemptToDocumentFieldsWithNoResponseBody() {
assertThatExceptionOfType(SnippetException.class)
.isThrownBy(() -> new ResponseFieldsSnippet(Arrays.asList(fieldWithPath("a").description("one")))
.document(this.operationBuilder.build()))
.withMessage("Cannot document response fields as the response body is empty");
.isThrownBy(() -> new ResponseFieldsSnippet(Arrays.asList(fieldWithPath("a").description("one")))
.document(this.operationBuilder.build()))
.withMessage("Cannot document response fields as the response body is empty");
}
@Test
public void fieldWithExplicitTypeThatDoesNotMatchThePayload() {
assertThatExceptionOfType(FieldTypesDoNotMatchException.class)
.isThrownBy(() -> new ResponseFieldsSnippet(
Arrays.asList(fieldWithPath("a").description("one").type(JsonFieldType.OBJECT)))
.document(this.operationBuilder.response().content("{ \"a\": 5 }}").build()))
.withMessage("The documented type of the field 'a' is Object but the actual type is Number");
.isThrownBy(() -> new ResponseFieldsSnippet(
Arrays.asList(fieldWithPath("a").description("one").type(JsonFieldType.OBJECT)))
.document(this.operationBuilder.response().content("{ \"a\": 5 }}").build()))
.withMessage("The documented type of the field 'a' is Object but the actual type is Number");
}
@Test
public void fieldWithExplicitSpecificTypeThatActuallyVaries() {
assertThatExceptionOfType(FieldTypesDoNotMatchException.class)
.isThrownBy(() -> new ResponseFieldsSnippet(
Arrays.asList(fieldWithPath("[].a").description("one").type(JsonFieldType.OBJECT))).document(
this.operationBuilder.response().content("[{ \"a\": 5 },{ \"a\": \"b\" }]").build()))
.withMessage("The documented type of the field '[].a' is Object but the actual type is Varies");
.isThrownBy(() -> new ResponseFieldsSnippet(
Arrays.asList(fieldWithPath("[].a").description("one").type(JsonFieldType.OBJECT)))
.document(this.operationBuilder.response().content("[{ \"a\": 5 },{ \"a\": \"b\" }]").build()))
.withMessage("The documented type of the field '[].a' is Object but the actual type is Varies");
}
@Test
public void undocumentedXmlResponseField() {
assertThatExceptionOfType(SnippetException.class)
.isThrownBy(() -> new ResponseFieldsSnippet(Collections.<FieldDescriptor>emptyList())
.document(this.operationBuilder.response().content("<a><b>5</b></a>")
.header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_XML_VALUE).build()))
.withMessageStartingWith("The following parts of the payload were not documented:");
.isThrownBy(() -> new ResponseFieldsSnippet(Collections.<FieldDescriptor>emptyList())
.document(this.operationBuilder.response()
.content("<a><b>5</b></a>")
.header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_XML_VALUE)
.build()))
.withMessageStartingWith("The following parts of the payload were not documented:");
}
@Test
public void missingXmlAttribute() {
assertThatExceptionOfType(SnippetException.class)
.isThrownBy(
() -> new ResponseFieldsSnippet(Arrays.asList(fieldWithPath("a").description("one").type("b"),
fieldWithPath("a/@id").description("two").type("c")))
.document(
this.operationBuilder.response().content("<a>foo</a>")
.header(HttpHeaders.CONTENT_TYPE,
MediaType.APPLICATION_XML_VALUE)
.build()))
.withMessage("Fields with the following paths were not found in the payload: [a/@id]");
.isThrownBy(() -> new ResponseFieldsSnippet(Arrays.asList(fieldWithPath("a").description("one").type("b"),
fieldWithPath("a/@id").description("two").type("c")))
.document(this.operationBuilder.response()
.content("<a>foo</a>")
.header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_XML_VALUE)
.build()))
.withMessage("Fields with the following paths were not found in the payload: [a/@id]");
}
@Test
public void documentedXmlAttributesAreRemoved() {
assertThatExceptionOfType(SnippetException.class).isThrownBy(
() -> new ResponseFieldsSnippet(Arrays.asList(fieldWithPath("a/@id").description("one").type("a")))
.document(this.operationBuilder.response().content("<a id=\"foo\">bar</a>")
.header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_XML_VALUE).build()))
.withMessage(String.format("The following parts of the payload were not documented:%n<a>bar</a>%n"));
assertThatExceptionOfType(SnippetException.class)
.isThrownBy(
() -> new ResponseFieldsSnippet(Arrays.asList(fieldWithPath("a/@id").description("one").type("a")))
.document(this.operationBuilder.response()
.content("<a id=\"foo\">bar</a>")
.header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_XML_VALUE)
.build()))
.withMessage(String.format("The following parts of the payload were not documented:%n<a>bar</a>%n"));
}
@Test
public void xmlResponseFieldWithNoType() {
assertThatExceptionOfType(FieldTypeRequiredException.class)
.isThrownBy(() -> new ResponseFieldsSnippet(Arrays.asList(fieldWithPath("a").description("one")))
.document(this.operationBuilder.response().content("<a>5</a>")
.header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_XML_VALUE).build()));
.isThrownBy(() -> new ResponseFieldsSnippet(Arrays.asList(fieldWithPath("a").description("one")))
.document(this.operationBuilder.response()
.content("<a>5</a>")
.header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_XML_VALUE)
.build()));
}
@Test
public void missingXmlResponseField() {
assertThatExceptionOfType(SnippetException.class)
.isThrownBy(() -> new ResponseFieldsSnippet(
Arrays.asList(fieldWithPath("a/b").description("one"), fieldWithPath("a").description("one")))
.document(this.operationBuilder.response().content("<a></a>")
.header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_XML_VALUE).build()))
.withMessage("Fields with the following paths were not found in the payload: [a/b]");
.isThrownBy(() -> new ResponseFieldsSnippet(
Arrays.asList(fieldWithPath("a/b").description("one"), fieldWithPath("a").description("one")))
.document(this.operationBuilder.response()
.content("<a></a>")
.header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_XML_VALUE)
.build()))
.withMessage("Fields with the following paths were not found in the payload: [a/b]");
}
@Test
public void undocumentedXmlResponseFieldAndMissingXmlResponseField() {
assertThatExceptionOfType(SnippetException.class)
.isThrownBy(() -> new ResponseFieldsSnippet(Arrays.asList(fieldWithPath("a/b").description("one")))
.document(this.operationBuilder.response().content("<a><c>5</c></a>")
.header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_XML_VALUE).build()))
.withMessageStartingWith("The following parts of the payload were not documented:")
.withMessageEndingWith("Fields with the following paths were not found in the payload: [a/b]");
.isThrownBy(() -> new ResponseFieldsSnippet(Arrays.asList(fieldWithPath("a/b").description("one")))
.document(this.operationBuilder.response()
.content("<a><c>5</c></a>")
.header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_XML_VALUE)
.build()))
.withMessageStartingWith("The following parts of the payload were not documented:")
.withMessageEndingWith("Fields with the following paths were not found in the payload: [a/b]");
}
@Test
public void unsupportedContent() {
assertThatExceptionOfType(PayloadHandlingException.class)
.isThrownBy(() -> new ResponseFieldsSnippet(Collections.<FieldDescriptor>emptyList())
.document(this.operationBuilder.response().content("Some plain text")
.header(HttpHeaders.CONTENT_TYPE, MediaType.TEXT_PLAIN_VALUE).build()))
.withMessage("Cannot handle text/plain content as it could not be parsed as JSON or XML");
.isThrownBy(() -> new ResponseFieldsSnippet(Collections.<FieldDescriptor>emptyList())
.document(this.operationBuilder.response()
.content("Some plain text")
.header(HttpHeaders.CONTENT_TYPE, MediaType.TEXT_PLAIN_VALUE)
.build()))
.withMessage("Cannot handle text/plain content as it could not be parsed as JSON or XML");
}
@Test
public void nonOptionalFieldBeneathArrayThatIsSometimesNull() {
assertThatExceptionOfType(SnippetException.class)
.isThrownBy(() -> new ResponseFieldsSnippet(
Arrays.asList(fieldWithPath("a[].b").description("one").type(JsonFieldType.NUMBER),
fieldWithPath("a[].c").description("two").type(JsonFieldType.NUMBER)))
.document(this.operationBuilder.response()
.content("{\"a\":[{\"b\": 1,\"c\": 2}, " + "{\"b\": null, \"c\": 2},"
+ " {\"b\": 1,\"c\": 2}]}")
.build()))
.withMessageStartingWith("Fields with the following paths were not found in the payload: [a[].b]");
.isThrownBy(() -> new ResponseFieldsSnippet(
Arrays.asList(fieldWithPath("a[].b").description("one").type(JsonFieldType.NUMBER),
fieldWithPath("a[].c").description("two").type(JsonFieldType.NUMBER)))
.document(this.operationBuilder.response()
.content("{\"a\":[{\"b\": 1,\"c\": 2}, " + "{\"b\": null, \"c\": 2}," + " {\"b\": 1,\"c\": 2}]}")
.build()))
.withMessageStartingWith("Fields with the following paths were not found in the payload: [a[].b]");
}
@Test
public void nonOptionalFieldBeneathArrayThatIsSometimesAbsent() {
assertThatExceptionOfType(SnippetException.class)
.isThrownBy(() -> new ResponseFieldsSnippet(
Arrays.asList(fieldWithPath("a[].b").description("one").type(JsonFieldType.NUMBER),
fieldWithPath("a[].c").description("two").type(JsonFieldType.NUMBER)))
.document(this.operationBuilder.response()
.content("{\"a\":[{\"b\": 1,\"c\": 2}, "
+ "{\"c\": 2}, {\"b\": 1,\"c\": 2}]}")
.build()))
.withMessageStartingWith("Fields with the following paths were not found in the payload: [a[].b]");
.isThrownBy(() -> new ResponseFieldsSnippet(
Arrays.asList(fieldWithPath("a[].b").description("one").type(JsonFieldType.NUMBER),
fieldWithPath("a[].c").description("two").type(JsonFieldType.NUMBER)))
.document(this.operationBuilder.response()
.content("{\"a\":[{\"b\": 1,\"c\": 2}, " + "{\"c\": 2}, {\"b\": 1,\"c\": 2}]}")
.build()))
.withMessageStartingWith("Fields with the following paths were not found in the payload: [a[].b]");
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2014-2019 the original author or authors.
* Copyright 2014-2023 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -55,116 +55,126 @@ public class ResponseFieldsSnippetTests extends AbstractSnippetTests {
new ResponseFieldsSnippet(Arrays.asList(fieldWithPath("id").description("one"),
fieldWithPath("date").description("two"), fieldWithPath("assets").description("three"),
fieldWithPath("assets[]").description("four"), fieldWithPath("assets[].id").description("five"),
fieldWithPath("assets[].name").description("six"))).document(
this.operationBuilder.response().content("{\"id\": 67,\"date\": \"2015-01-20\",\"assets\":"
+ " [{\"id\":356,\"name\": \"sample\"}]}").build());
assertThat(this.generatedSnippets.responseFields()).is(tableWithHeader("Path", "Type", "Description")
.row("`id`", "`Number`", "one").row("`date`", "`String`", "two").row("`assets`", "`Array`", "three")
.row("`assets[]`", "`Array`", "four").row("`assets[].id`", "`Number`", "five")
fieldWithPath("assets[].name").description("six")))
.document(this.operationBuilder.response()
.content("{\"id\": 67,\"date\": \"2015-01-20\",\"assets\":" + " [{\"id\":356,\"name\": \"sample\"}]}")
.build());
assertThat(this.generatedSnippets.responseFields())
.is(tableWithHeader("Path", "Type", "Description").row("`id`", "`Number`", "one")
.row("`date`", "`String`", "two")
.row("`assets`", "`Array`", "three")
.row("`assets[]`", "`Array`", "four")
.row("`assets[].id`", "`Number`", "five")
.row("`assets[].name`", "`String`", "six"));
}
@Test
public void mapResponseWithNullField() throws IOException {
new ResponseFieldsSnippet(Arrays.asList(fieldWithPath("a.b").description("one")))
.document(this.operationBuilder.response().content("{\"a\": {\"b\": null}}").build());
.document(this.operationBuilder.response().content("{\"a\": {\"b\": null}}").build());
assertThat(this.generatedSnippets.responseFields())
.is(tableWithHeader("Path", "Type", "Description").row("`a.b`", "`Null`", "one"));
.is(tableWithHeader("Path", "Type", "Description").row("`a.b`", "`Null`", "one"));
}
@Test
public void subsectionOfMapResponse() throws IOException {
responseFields(beneathPath("a"), fieldWithPath("b").description("one"), fieldWithPath("c").description("two"))
.document(this.operationBuilder.response().content("{\"a\": {\"b\": 5, \"c\": \"charlie\"}}").build());
.document(this.operationBuilder.response().content("{\"a\": {\"b\": 5, \"c\": \"charlie\"}}").build());
assertThat(this.generatedSnippets.snippet("response-fields-beneath-a"))
.is(tableWithHeader("Path", "Type", "Description").row("`b`", "`Number`", "one").row("`c`", "`String`",
"two"));
.is(tableWithHeader("Path", "Type", "Description").row("`b`", "`Number`", "one")
.row("`c`", "`String`", "two"));
}
@Test
public void subsectionOfMapResponseBeneathAnArray() throws IOException {
responseFields(beneathPath("a.b.[]"), fieldWithPath("c").description("one"),
fieldWithPath("d.[].e").description("two"))
.document(this.operationBuilder.response().content(
"{\"a\": {\"b\": [{\"c\": 1, \"d\": [{\"e\": 5}]}, {\"c\": 3, \"d\": [{\"e\": 4}]}]}}")
.build());
.document(this.operationBuilder.response()
.content("{\"a\": {\"b\": [{\"c\": 1, \"d\": [{\"e\": 5}]}, {\"c\": 3, \"d\": [{\"e\": 4}]}]}}")
.build());
assertThat(this.generatedSnippets.snippet("response-fields-beneath-a.b.[]"))
.is(tableWithHeader("Path", "Type", "Description").row("`c`", "`Number`", "one").row("`d.[].e`",
"`Number`", "two"));
.is(tableWithHeader("Path", "Type", "Description").row("`c`", "`Number`", "one")
.row("`d.[].e`", "`Number`", "two"));
}
@Test
public void subsectionOfMapResponseWithCommonsPrefix() throws IOException {
responseFields(beneathPath("a")).andWithPrefix("b.", fieldWithPath("c").description("two"))
.document(this.operationBuilder.response().content("{\"a\": {\"b\": {\"c\": \"charlie\"}}}").build());
.document(this.operationBuilder.response().content("{\"a\": {\"b\": {\"c\": \"charlie\"}}}").build());
assertThat(this.generatedSnippets.snippet("response-fields-beneath-a"))
.is(tableWithHeader("Path", "Type", "Description").row("`b.c`", "`String`", "two"));
.is(tableWithHeader("Path", "Type", "Description").row("`b.c`", "`String`", "two"));
}
@Test
public void arrayResponseWithFields() throws IOException {
new ResponseFieldsSnippet(Arrays.asList(fieldWithPath("[]a.b").description("one"),
fieldWithPath("[]a.c").description("two"), fieldWithPath("[]a").description("three")))
.document(this.operationBuilder.response().content(
"[{\"a\": {\"b\": 5, \"c\":\"charlie\"}}," + "{\"a\": {\"b\": 4, \"c\":\"chalk\"}}]")
.build());
assertThat(this.generatedSnippets.responseFields()).is(tableWithHeader("Path", "Type", "Description")
.row("`[]a.b`", "`Number`", "one").row("`[]a.c`", "`String`", "two").row("`[]a`", "`Object`", "three"));
.document(this.operationBuilder.response()
.content("[{\"a\": {\"b\": 5, \"c\":\"charlie\"}}," + "{\"a\": {\"b\": 4, \"c\":\"chalk\"}}]")
.build());
assertThat(this.generatedSnippets.responseFields())
.is(tableWithHeader("Path", "Type", "Description").row("`[]a.b`", "`Number`", "one")
.row("`[]a.c`", "`String`", "two")
.row("`[]a`", "`Object`", "three"));
}
@Test
public void arrayResponseWithAlwaysNullField() throws IOException {
new ResponseFieldsSnippet(Arrays.asList(fieldWithPath("[]a.b").description("one")))
.document(this.operationBuilder.response()
.content("[{\"a\": {\"b\": null}}," + "{\"a\": {\"b\": null}}]").build());
.document(this.operationBuilder.response()
.content("[{\"a\": {\"b\": null}}," + "{\"a\": {\"b\": null}}]")
.build());
assertThat(this.generatedSnippets.responseFields())
.is(tableWithHeader("Path", "Type", "Description").row("`[]a.b`", "`Null`", "one"));
.is(tableWithHeader("Path", "Type", "Description").row("`[]a.b`", "`Null`", "one"));
}
@Test
public void arrayResponse() throws IOException {
new ResponseFieldsSnippet(Arrays.asList(fieldWithPath("[]").description("one")))
.document(this.operationBuilder.response().content("[\"a\", \"b\", \"c\"]").build());
.document(this.operationBuilder.response().content("[\"a\", \"b\", \"c\"]").build());
assertThat(this.generatedSnippets.responseFields())
.is(tableWithHeader("Path", "Type", "Description").row("`[]`", "`Array`", "one"));
.is(tableWithHeader("Path", "Type", "Description").row("`[]`", "`Array`", "one"));
}
@Test
public void ignoredResponseField() throws IOException {
new ResponseFieldsSnippet(
Arrays.asList(fieldWithPath("a").ignored(), fieldWithPath("b").description("Field b")))
.document(this.operationBuilder.response().content("{\"a\": 5, \"b\": 4}").build());
.document(this.operationBuilder.response().content("{\"a\": 5, \"b\": 4}").build());
assertThat(this.generatedSnippets.responseFields())
.is(tableWithHeader("Path", "Type", "Description").row("`b`", "`Number`", "Field b"));
.is(tableWithHeader("Path", "Type", "Description").row("`b`", "`Number`", "Field b"));
}
@Test
public void allUndocumentedFieldsCanBeIgnored() throws IOException {
new ResponseFieldsSnippet(Arrays.asList(fieldWithPath("b").description("Field b")), true)
.document(this.operationBuilder.response().content("{\"a\": 5, \"b\": 4}").build());
.document(this.operationBuilder.response().content("{\"a\": 5, \"b\": 4}").build());
assertThat(this.generatedSnippets.responseFields())
.is(tableWithHeader("Path", "Type", "Description").row("`b`", "`Number`", "Field b"));
.is(tableWithHeader("Path", "Type", "Description").row("`b`", "`Number`", "Field b"));
}
@Test
public void allUndocumentedFieldsContinueToBeIgnoredAfterAddingDescriptors() throws IOException {
new ResponseFieldsSnippet(Arrays.asList(fieldWithPath("b").description("Field b")), true)
.andWithPrefix("c.", fieldWithPath("d").description("Field d"))
.document(this.operationBuilder.response().content("{\"a\":5,\"b\":4,\"c\":{\"d\": 3}}").build());
assertThat(this.generatedSnippets.responseFields()).is(tableWithHeader("Path", "Type", "Description")
.row("`b`", "`Number`", "Field b").row("`c.d`", "`Number`", "Field d"));
.andWithPrefix("c.", fieldWithPath("d").description("Field d"))
.document(this.operationBuilder.response().content("{\"a\":5,\"b\":4,\"c\":{\"d\": 3}}").build());
assertThat(this.generatedSnippets.responseFields())
.is(tableWithHeader("Path", "Type", "Description").row("`b`", "`Number`", "Field b")
.row("`c.d`", "`Number`", "Field d"));
}
@Test
public void responseFieldsWithCustomAttributes() throws IOException {
TemplateResourceResolver resolver = mock(TemplateResourceResolver.class);
given(resolver.resolveTemplateResource("response-fields"))
.willReturn(snippetResource("response-fields-with-title"));
.willReturn(snippetResource("response-fields-with-title"));
new ResponseFieldsSnippet(Arrays.asList(fieldWithPath("a").description("one")),
attributes(key("title").value("Custom title")))
.document(this.operationBuilder
.attribute(TemplateEngine.class.getName(), new MustacheTemplateEngine(resolver))
.response().content("{\"a\": \"foo\"}").build());
.document(this.operationBuilder
.attribute(TemplateEngine.class.getName(), new MustacheTemplateEngine(resolver))
.response()
.content("{\"a\": \"foo\"}")
.build());
assertThat(this.generatedSnippets.responseFields()).contains("Custom title");
}
@@ -172,15 +182,15 @@ public class ResponseFieldsSnippetTests extends AbstractSnippetTests {
public void missingOptionalResponseField() throws IOException {
new ResponseFieldsSnippet(
Arrays.asList(fieldWithPath("a.b").description("one").type(JsonFieldType.STRING).optional()))
.document(this.operationBuilder.response().content("{}").build());
.document(this.operationBuilder.response().content("{}").build());
assertThat(this.generatedSnippets.responseFields())
.is(tableWithHeader("Path", "Type", "Description").row("`a.b`", "`String`", "one"));
.is(tableWithHeader("Path", "Type", "Description").row("`a.b`", "`String`", "one"));
}
@Test
public void missingIgnoredOptionalResponseFieldDoesNotRequireAType() throws IOException {
new ResponseFieldsSnippet(Arrays.asList(fieldWithPath("a.b").description("one").ignored().optional()))
.document(this.operationBuilder.response().content("{}").build());
.document(this.operationBuilder.response().content("{}").build());
assertThat(this.generatedSnippets.responseFields()).is(tableWithHeader("Path", "Type", "Description"));
}
@@ -188,42 +198,45 @@ public class ResponseFieldsSnippetTests extends AbstractSnippetTests {
public void presentOptionalResponseField() throws IOException {
new ResponseFieldsSnippet(
Arrays.asList(fieldWithPath("a.b").description("one").type(JsonFieldType.STRING).optional()))
.document(this.operationBuilder.response().content("{\"a\": { \"b\": \"bravo\"}}").build());
.document(this.operationBuilder.response().content("{\"a\": { \"b\": \"bravo\"}}").build());
assertThat(this.generatedSnippets.responseFields())
.is(tableWithHeader("Path", "Type", "Description").row("`a.b`", "`String`", "one"));
.is(tableWithHeader("Path", "Type", "Description").row("`a.b`", "`String`", "one"));
}
@Test
public void responseFieldsWithCustomDescriptorAttributes() throws IOException {
TemplateResourceResolver resolver = mock(TemplateResourceResolver.class);
given(resolver.resolveTemplateResource("response-fields"))
.willReturn(snippetResource("response-fields-with-extra-column"));
.willReturn(snippetResource("response-fields-with-extra-column"));
new ResponseFieldsSnippet(
Arrays.asList(fieldWithPath("a.b").description("one").attributes(key("foo").value("alpha")),
fieldWithPath("a.c").description("two").attributes(key("foo").value("bravo")),
fieldWithPath("a").description("three").attributes(key("foo").value("charlie"))))
.document(this.operationBuilder
.attribute(TemplateEngine.class.getName(), new MustacheTemplateEngine(resolver))
.response().content("{\"a\": {\"b\": 5, \"c\": \"charlie\"}}").build());
.document(this.operationBuilder
.attribute(TemplateEngine.class.getName(), new MustacheTemplateEngine(resolver))
.response()
.content("{\"a\": {\"b\": 5, \"c\": \"charlie\"}}")
.build());
assertThat(this.generatedSnippets.responseFields())
.is(tableWithHeader("Path", "Type", "Description", "Foo").row("a.b", "Number", "one", "alpha")
.row("a.c", "String", "two", "bravo").row("a", "Object", "three", "charlie"));
.is(tableWithHeader("Path", "Type", "Description", "Foo").row("a.b", "Number", "one", "alpha")
.row("a.c", "String", "two", "bravo")
.row("a", "Object", "three", "charlie"));
}
@Test
public void fieldWithExplictExactlyMatchingType() throws IOException {
new ResponseFieldsSnippet(Arrays.asList(fieldWithPath("a").description("one").type(JsonFieldType.NUMBER)))
.document(this.operationBuilder.response().content("{\"a\": 5 }").build());
.document(this.operationBuilder.response().content("{\"a\": 5 }").build());
assertThat(this.generatedSnippets.responseFields())
.is(tableWithHeader("Path", "Type", "Description").row("`a`", "`Number`", "one"));
.is(tableWithHeader("Path", "Type", "Description").row("`a`", "`Number`", "one"));
}
@Test
public void fieldWithExplictVariesType() throws IOException {
new ResponseFieldsSnippet(Arrays.asList(fieldWithPath("a").description("one").type(JsonFieldType.VARIES)))
.document(this.operationBuilder.response().content("{\"a\": 5 }").build());
.document(this.operationBuilder.response().content("{\"a\": 5 }").build());
assertThat(this.generatedSnippets.responseFields())
.is(tableWithHeader("Path", "Type", "Description").row("`a`", "`Varies`", "one"));
.is(tableWithHeader("Path", "Type", "Description").row("`a`", "`Varies`", "one"));
}
@Test
@@ -244,95 +257,112 @@ public class ResponseFieldsSnippetTests extends AbstractSnippetTests {
private void xmlResponseFields(MediaType contentType) throws IOException {
new ResponseFieldsSnippet(Arrays.asList(fieldWithPath("a/b").description("one").type("b"),
fieldWithPath("a/c").description("two").type("c"), fieldWithPath("a").description("three").type("a")))
.document(this.operationBuilder.response().content("<a><b>5</b><c>charlie</c></a>")
.header(HttpHeaders.CONTENT_TYPE, contentType.toString()).build());
assertThat(this.generatedSnippets.responseFields()).is(tableWithHeader("Path", "Type", "Description")
.row("`a/b`", "`b`", "one").row("`a/c`", "`c`", "two").row("`a`", "`a`", "three"));
.document(this.operationBuilder.response()
.content("<a><b>5</b><c>charlie</c></a>")
.header(HttpHeaders.CONTENT_TYPE, contentType.toString())
.build());
assertThat(this.generatedSnippets.responseFields())
.is(tableWithHeader("Path", "Type", "Description").row("`a/b`", "`b`", "one")
.row("`a/c`", "`c`", "two")
.row("`a`", "`a`", "three"));
}
@Test
public void xmlAttribute() throws IOException {
new ResponseFieldsSnippet(Arrays.asList(fieldWithPath("a").description("one").type("b"),
fieldWithPath("a/@id").description("two").type("c")))
.document(this.operationBuilder.response().content("<a id=\"1\">foo</a>")
.header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_XML_VALUE).build());
assertThat(this.generatedSnippets.responseFields()).is(
tableWithHeader("Path", "Type", "Description").row("`a`", "`b`", "one").row("`a/@id`", "`c`", "two"));
.document(this.operationBuilder.response()
.content("<a id=\"1\">foo</a>")
.header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_XML_VALUE)
.build());
assertThat(this.generatedSnippets.responseFields())
.is(tableWithHeader("Path", "Type", "Description").row("`a`", "`b`", "one").row("`a/@id`", "`c`", "two"));
}
@Test
public void missingOptionalXmlAttribute() throws IOException {
new ResponseFieldsSnippet(Arrays.asList(fieldWithPath("a").description("one").type("b"),
fieldWithPath("a/@id").description("two").type("c").optional()))
.document(this.operationBuilder.response().content("<a>foo</a>")
.header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_XML_VALUE).build());
assertThat(this.generatedSnippets.responseFields()).is(
tableWithHeader("Path", "Type", "Description").row("`a`", "`b`", "one").row("`a/@id`", "`c`", "two"));
.document(this.operationBuilder.response()
.content("<a>foo</a>")
.header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_XML_VALUE)
.build());
assertThat(this.generatedSnippets.responseFields())
.is(tableWithHeader("Path", "Type", "Description").row("`a`", "`b`", "one").row("`a/@id`", "`c`", "two"));
}
@Test
public void undocumentedAttributeDoesNotCauseFailure() throws IOException {
new ResponseFieldsSnippet(Arrays.asList(fieldWithPath("a").description("one").type("a")))
.document(this.operationBuilder.response().content("<a id=\"foo\">bar</a>")
.header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_XML_VALUE).build());
.document(this.operationBuilder.response()
.content("<a id=\"foo\">bar</a>")
.header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_XML_VALUE)
.build());
assertThat(this.generatedSnippets.responseFields())
.is(tableWithHeader("Path", "Type", "Description").row("`a`", "`a`", "one"));
.is(tableWithHeader("Path", "Type", "Description").row("`a`", "`a`", "one"));
}
@Test
public void additionalDescriptors() throws IOException {
PayloadDocumentation
.responseFields(fieldWithPath("id").description("one"), fieldWithPath("date").description("two"),
fieldWithPath("assets").description("three"))
.and(fieldWithPath("assets[]").description("four"), fieldWithPath("assets[].id").description("five"),
fieldWithPath("assets[].name").description("six"))
.document(this.operationBuilder.response().content(
"{\"id\": 67,\"date\": \"2015-01-20\",\"assets\":" + " [{\"id\":356,\"name\": \"sample\"}]}")
.build());
assertThat(this.generatedSnippets.responseFields()).is(tableWithHeader("Path", "Type", "Description")
.row("`id`", "`Number`", "one").row("`date`", "`String`", "two").row("`assets`", "`Array`", "three")
.row("`assets[]`", "`Array`", "four").row("`assets[].id`", "`Number`", "five")
.responseFields(fieldWithPath("id").description("one"), fieldWithPath("date").description("two"),
fieldWithPath("assets").description("three"))
.and(fieldWithPath("assets[]").description("four"), fieldWithPath("assets[].id").description("five"),
fieldWithPath("assets[].name").description("six"))
.document(this.operationBuilder.response()
.content("{\"id\": 67,\"date\": \"2015-01-20\",\"assets\":" + " [{\"id\":356,\"name\": \"sample\"}]}")
.build());
assertThat(this.generatedSnippets.responseFields())
.is(tableWithHeader("Path", "Type", "Description").row("`id`", "`Number`", "one")
.row("`date`", "`String`", "two")
.row("`assets`", "`Array`", "three")
.row("`assets[]`", "`Array`", "four")
.row("`assets[].id`", "`Number`", "five")
.row("`assets[].name`", "`String`", "six"));
}
@Test
public void prefixedAdditionalDescriptors() throws IOException {
PayloadDocumentation.responseFields(fieldWithPath("a").description("one"))
.andWithPrefix("a.", fieldWithPath("b").description("two"), fieldWithPath("c").description("three"))
.document(this.operationBuilder.response().content("{\"a\": {\"b\": 5, \"c\": \"charlie\"}}").build());
assertThat(this.generatedSnippets.responseFields()).is(tableWithHeader("Path", "Type", "Description")
.row("`a`", "`Object`", "one").row("`a.b`", "`Number`", "two").row("`a.c`", "`String`", "three"));
.andWithPrefix("a.", fieldWithPath("b").description("two"), fieldWithPath("c").description("three"))
.document(this.operationBuilder.response().content("{\"a\": {\"b\": 5, \"c\": \"charlie\"}}").build());
assertThat(this.generatedSnippets.responseFields())
.is(tableWithHeader("Path", "Type", "Description").row("`a`", "`Object`", "one")
.row("`a.b`", "`Number`", "two")
.row("`a.c`", "`String`", "three"));
}
@Test
public void responseWithFieldsWithEscapedContent() throws IOException {
new ResponseFieldsSnippet(Arrays.asList(fieldWithPath("Foo|Bar").type("one|two").description("three|four")))
.document(this.operationBuilder.response().content("{\"Foo|Bar\": 5}").build());
.document(this.operationBuilder.response().content("{\"Foo|Bar\": 5}").build());
assertThat(this.generatedSnippets.responseFields()).is(tableWithHeader("Path", "Type", "Description")
.row(escapeIfNecessary("`Foo|Bar`"), escapeIfNecessary("`one|two`"), escapeIfNecessary("three|four")));
.row(escapeIfNecessary("`Foo|Bar`"), escapeIfNecessary("`one|two`"), escapeIfNecessary("three|four")));
}
@Test
public void mapResponseWithVaryingKeysMatchedUsingWildcard() throws IOException {
new ResponseFieldsSnippet(Arrays.asList(fieldWithPath("things.*.size").description("one"),
fieldWithPath("things.*.type").description("two")))
.document(this.operationBuilder.response()
.content("{\"things\": {\"12abf\": {\"type\":" + "\"Whale\", \"size\": \"HUGE\"},"
+ "\"gzM33\" : {\"type\": \"Screw\"," + "\"size\": \"SMALL\"}}}")
.build());
assertThat(this.generatedSnippets.responseFields()).is(tableWithHeader("Path", "Type", "Description")
.row("`things.*.size`", "`String`", "one").row("`things.*.type`", "`String`", "two"));
.document(this.operationBuilder.response()
.content("{\"things\": {\"12abf\": {\"type\":" + "\"Whale\", \"size\": \"HUGE\"},"
+ "\"gzM33\" : {\"type\": \"Screw\"," + "\"size\": \"SMALL\"}}}")
.build());
assertThat(this.generatedSnippets.responseFields())
.is(tableWithHeader("Path", "Type", "Description").row("`things.*.size`", "`String`", "one")
.row("`things.*.type`", "`String`", "two"));
}
@Test
public void responseWithArrayContainingFieldThatIsSometimesNull() throws IOException {
new ResponseFieldsSnippet(
Arrays.asList(fieldWithPath("assets[].name").description("one").type(JsonFieldType.STRING).optional()))
.document(
this.operationBuilder.response().content("{\"assets\": [" + "{\"name\": \"sample1\"}, "
+ "{\"name\": null}, " + "{\"name\": \"sample2\"}]}").build());
.document(this.operationBuilder.response()
.content("{\"assets\": [" + "{\"name\": \"sample1\"}, " + "{\"name\": null}, "
+ "{\"name\": \"sample2\"}]}")
.build());
assertThat(this.generatedSnippets.responseFields())
.is(tableWithHeader("Path", "Type", "Description").row("`assets[].name`", "`String`", "one"));
.is(tableWithHeader("Path", "Type", "Description").row("`assets[].name`", "`String`", "one"));
}
@Test
@@ -340,21 +370,22 @@ public class ResponseFieldsSnippetTests extends AbstractSnippetTests {
new ResponseFieldsSnippet(
Arrays.asList(fieldWithPath("a[].b").description("one").type(JsonFieldType.NUMBER).optional(),
fieldWithPath("a[].c").description("two").type(JsonFieldType.NUMBER)))
.document(this.operationBuilder.response()
.content("{\"a\":[{\"b\": 1,\"c\": 2}, " + "{\"c\": 2}, {\"b\": 1,\"c\": 2}]}")
.build());
assertThat(this.generatedSnippets.responseFields()).is(tableWithHeader("Path", "Type", "Description")
.row("`a[].b`", "`Number`", "one").row("`a[].c`", "`Number`", "two"));
.document(this.operationBuilder.response()
.content("{\"a\":[{\"b\": 1,\"c\": 2}, " + "{\"c\": 2}, {\"b\": 1,\"c\": 2}]}")
.build());
assertThat(this.generatedSnippets.responseFields())
.is(tableWithHeader("Path", "Type", "Description").row("`a[].b`", "`Number`", "one")
.row("`a[].c`", "`Number`", "two"));
}
@Test
public void typeDeterminationDoesNotSetTypeOnDescriptor() throws IOException {
FieldDescriptor descriptor = fieldWithPath("id").description("one");
new ResponseFieldsSnippet(Arrays.asList(descriptor))
.document(this.operationBuilder.response().content("{\"id\": 67}").build());
.document(this.operationBuilder.response().content("{\"id\": 67}").build());
assertThat(descriptor.getType()).isNull();
assertThat(this.generatedSnippets.responseFields())
.is(tableWithHeader("Path", "Type", "Description").row("`id`", "`Number`", "one"));
.is(tableWithHeader("Path", "Type", "Description").row("`id`", "`Number`", "one"));
}
private String escapeIfNecessary(String input) {

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2014-2022 the original author or authors.
* Copyright 2014-2023 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -44,30 +44,30 @@ public class PathParametersSnippetFailureTests {
@Test
public void undocumentedPathParameter() {
assertThatExceptionOfType(SnippetException.class)
.isThrownBy(() -> new PathParametersSnippet(Collections.<ParameterDescriptor>emptyList())
.document(this.operationBuilder
.attribute(RestDocumentationGenerator.ATTRIBUTE_NAME_URL_TEMPLATE, "/{a}/").build()))
.withMessage("Path parameters with the following names were not documented: [a]");
.isThrownBy(() -> new PathParametersSnippet(Collections.<ParameterDescriptor>emptyList()).document(
this.operationBuilder.attribute(RestDocumentationGenerator.ATTRIBUTE_NAME_URL_TEMPLATE, "/{a}/")
.build()))
.withMessage("Path parameters with the following names were not documented: [a]");
}
@Test
public void missingPathParameter() {
assertThatExceptionOfType(SnippetException.class)
.isThrownBy(() -> new PathParametersSnippet(Arrays.asList(parameterWithName("a").description("one")))
.document(this.operationBuilder
.attribute(RestDocumentationGenerator.ATTRIBUTE_NAME_URL_TEMPLATE, "/").build()))
.withMessage("Path parameters with the following names were not found in the request: [a]");
.isThrownBy(() -> new PathParametersSnippet(Arrays.asList(parameterWithName("a").description("one")))
.document(this.operationBuilder.attribute(RestDocumentationGenerator.ATTRIBUTE_NAME_URL_TEMPLATE, "/")
.build()))
.withMessage("Path parameters with the following names were not found in the request: [a]");
}
@Test
public void undocumentedAndMissingPathParameters() {
assertThatExceptionOfType(SnippetException.class)
.isThrownBy(() -> new PathParametersSnippet(Arrays.asList(parameterWithName("a").description("one")))
.document(this.operationBuilder
.attribute(RestDocumentationGenerator.ATTRIBUTE_NAME_URL_TEMPLATE, "/{b}").build()))
.withMessage(
"Path parameters with the following names were not documented: [b]. Path parameters with the"
+ " following names were not found in the request: [a]");
.isThrownBy(() -> new PathParametersSnippet(Arrays.asList(parameterWithName("a").description("one")))
.document(
this.operationBuilder.attribute(RestDocumentationGenerator.ATTRIBUTE_NAME_URL_TEMPLATE, "/{b}")
.build()))
.withMessage("Path parameters with the following names were not documented: [b]. Path parameters with the"
+ " following names were not found in the request: [a]");
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2014-2020 the original author or authors.
* Copyright 2014-2023 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -51,86 +51,88 @@ public class PathParametersSnippetTests extends AbstractSnippetTests {
public void pathParameters() throws IOException {
new PathParametersSnippet(
Arrays.asList(parameterWithName("a").description("one"), parameterWithName("b").description("two")))
.document(this.operationBuilder
.attribute(RestDocumentationGenerator.ATTRIBUTE_NAME_URL_TEMPLATE, "/{a}/{b}").build());
assertThat(this.generatedSnippets.pathParameters()).is(
tableWithTitleAndHeader(getTitle(), "Parameter", "Description").row("`a`", "one").row("`b`", "two"));
.document(
this.operationBuilder.attribute(RestDocumentationGenerator.ATTRIBUTE_NAME_URL_TEMPLATE, "/{a}/{b}")
.build());
assertThat(this.generatedSnippets.pathParameters())
.is(tableWithTitleAndHeader(getTitle(), "Parameter", "Description").row("`a`", "one").row("`b`", "two"));
}
@Test
public void ignoredPathParameter() throws IOException {
new PathParametersSnippet(
Arrays.asList(parameterWithName("a").ignored(), parameterWithName("b").description("two")))
.document(this.operationBuilder
.attribute(RestDocumentationGenerator.ATTRIBUTE_NAME_URL_TEMPLATE, "/{a}/{b}").build());
.document(
this.operationBuilder.attribute(RestDocumentationGenerator.ATTRIBUTE_NAME_URL_TEMPLATE, "/{a}/{b}")
.build());
assertThat(this.generatedSnippets.pathParameters())
.is(tableWithTitleAndHeader(getTitle(), "Parameter", "Description").row("`b`", "two"));
.is(tableWithTitleAndHeader(getTitle(), "Parameter", "Description").row("`b`", "two"));
}
@Test
public void allUndocumentedPathParametersCanBeIgnored() throws IOException {
new PathParametersSnippet(Arrays.asList(parameterWithName("b").description("two")), true)
.document(this.operationBuilder
.attribute(RestDocumentationGenerator.ATTRIBUTE_NAME_URL_TEMPLATE, "/{a}/{b}").build());
new PathParametersSnippet(Arrays.asList(parameterWithName("b").description("two")), true).document(
this.operationBuilder.attribute(RestDocumentationGenerator.ATTRIBUTE_NAME_URL_TEMPLATE, "/{a}/{b}")
.build());
assertThat(this.generatedSnippets.pathParameters())
.is(tableWithTitleAndHeader(getTitle(), "Parameter", "Description").row("`b`", "two"));
.is(tableWithTitleAndHeader(getTitle(), "Parameter", "Description").row("`b`", "two"));
}
@Test
public void missingOptionalPathParameter() throws IOException {
new PathParametersSnippet(Arrays.asList(parameterWithName("a").description("one"),
parameterWithName("b").description("two").optional()))
.document(this.operationBuilder
.attribute(RestDocumentationGenerator.ATTRIBUTE_NAME_URL_TEMPLATE, "/{a}").build());
.document(this.operationBuilder.attribute(RestDocumentationGenerator.ATTRIBUTE_NAME_URL_TEMPLATE, "/{a}")
.build());
assertThat(this.generatedSnippets.pathParameters())
.is(tableWithTitleAndHeader(getTitle("/{a}"), "Parameter", "Description").row("`a`", "one").row("`b`",
"two"));
.is(tableWithTitleAndHeader(getTitle("/{a}"), "Parameter", "Description").row("`a`", "one")
.row("`b`", "two"));
}
@Test
public void presentOptionalPathParameter() throws IOException {
new PathParametersSnippet(Arrays.asList(parameterWithName("a").description("one").optional()))
.document(this.operationBuilder
.attribute(RestDocumentationGenerator.ATTRIBUTE_NAME_URL_TEMPLATE, "/{a}").build());
.document(this.operationBuilder.attribute(RestDocumentationGenerator.ATTRIBUTE_NAME_URL_TEMPLATE, "/{a}")
.build());
assertThat(this.generatedSnippets.pathParameters())
.is(tableWithTitleAndHeader(getTitle("/{a}"), "Parameter", "Description").row("`a`", "one"));
.is(tableWithTitleAndHeader(getTitle("/{a}"), "Parameter", "Description").row("`a`", "one"));
}
@Test
public void pathParametersWithQueryString() throws IOException {
new PathParametersSnippet(
Arrays.asList(parameterWithName("a").description("one"), parameterWithName("b").description("two")))
.document(this.operationBuilder
.attribute(RestDocumentationGenerator.ATTRIBUTE_NAME_URL_TEMPLATE, "/{a}/{b}?foo=bar")
.build());
assertThat(this.generatedSnippets.pathParameters()).is(
tableWithTitleAndHeader(getTitle(), "Parameter", "Description").row("`a`", "one").row("`b`", "two"));
.document(this.operationBuilder
.attribute(RestDocumentationGenerator.ATTRIBUTE_NAME_URL_TEMPLATE, "/{a}/{b}?foo=bar")
.build());
assertThat(this.generatedSnippets.pathParameters())
.is(tableWithTitleAndHeader(getTitle(), "Parameter", "Description").row("`a`", "one").row("`b`", "two"));
}
@Test
public void pathParametersWithQueryStringWithParameters() throws IOException {
new PathParametersSnippet(
Arrays.asList(parameterWithName("a").description("one"), parameterWithName("b").description("two")))
.document(this.operationBuilder
.attribute(RestDocumentationGenerator.ATTRIBUTE_NAME_URL_TEMPLATE, "/{a}/{b}?foo={c}")
.build());
assertThat(this.generatedSnippets.pathParameters()).is(
tableWithTitleAndHeader(getTitle(), "Parameter", "Description").row("`a`", "one").row("`b`", "two"));
.document(this.operationBuilder
.attribute(RestDocumentationGenerator.ATTRIBUTE_NAME_URL_TEMPLATE, "/{a}/{b}?foo={c}")
.build());
assertThat(this.generatedSnippets.pathParameters())
.is(tableWithTitleAndHeader(getTitle(), "Parameter", "Description").row("`a`", "one").row("`b`", "two"));
}
@Test
public void pathParametersWithCustomAttributes() throws IOException {
TemplateResourceResolver resolver = mock(TemplateResourceResolver.class);
given(resolver.resolveTemplateResource("path-parameters"))
.willReturn(snippetResource("path-parameters-with-title"));
.willReturn(snippetResource("path-parameters-with-title"));
new PathParametersSnippet(
Arrays.asList(parameterWithName("a").description("one").attributes(key("foo").value("alpha")),
parameterWithName("b").description("two").attributes(key("foo").value("bravo"))),
attributes(key("title").value("The title")))
.document(this.operationBuilder
.attribute(RestDocumentationGenerator.ATTRIBUTE_NAME_URL_TEMPLATE, "/{a}/{b}")
.attribute(TemplateEngine.class.getName(), new MustacheTemplateEngine(resolver))
.build());
.document(
this.operationBuilder.attribute(RestDocumentationGenerator.ATTRIBUTE_NAME_URL_TEMPLATE, "/{a}/{b}")
.attribute(TemplateEngine.class.getName(), new MustacheTemplateEngine(resolver))
.build());
assertThat(this.generatedSnippets.pathParameters()).contains("The title");
}
@@ -138,45 +140,50 @@ public class PathParametersSnippetTests extends AbstractSnippetTests {
public void pathParametersWithCustomDescriptorAttributes() throws IOException {
TemplateResourceResolver resolver = mock(TemplateResourceResolver.class);
given(resolver.resolveTemplateResource("path-parameters"))
.willReturn(snippetResource("path-parameters-with-extra-column"));
.willReturn(snippetResource("path-parameters-with-extra-column"));
new PathParametersSnippet(
Arrays.asList(parameterWithName("a").description("one").attributes(key("foo").value("alpha")),
parameterWithName("b").description("two").attributes(key("foo").value("bravo"))))
.document(this.operationBuilder
.attribute(RestDocumentationGenerator.ATTRIBUTE_NAME_URL_TEMPLATE, "/{a}/{b}")
.attribute(TemplateEngine.class.getName(), new MustacheTemplateEngine(resolver))
.build());
assertThat(this.generatedSnippets.pathParameters()).is(
tableWithHeader("Parameter", "Description", "Foo").row("a", "one", "alpha").row("b", "two", "bravo"));
.document(
this.operationBuilder.attribute(RestDocumentationGenerator.ATTRIBUTE_NAME_URL_TEMPLATE, "/{a}/{b}")
.attribute(TemplateEngine.class.getName(), new MustacheTemplateEngine(resolver))
.build());
assertThat(this.generatedSnippets.pathParameters())
.is(tableWithHeader("Parameter", "Description", "Foo").row("a", "one", "alpha").row("b", "two", "bravo"));
}
@Test
public void additionalDescriptors() throws IOException {
RequestDocumentation.pathParameters(parameterWithName("a").description("one"))
.and(parameterWithName("b").description("two")).document(this.operationBuilder
.attribute(RestDocumentationGenerator.ATTRIBUTE_NAME_URL_TEMPLATE, "/{a}/{b}").build());
assertThat(this.generatedSnippets.pathParameters()).is(
tableWithTitleAndHeader(getTitle(), "Parameter", "Description").row("`a`", "one").row("`b`", "two"));
.and(parameterWithName("b").description("two"))
.document(
this.operationBuilder.attribute(RestDocumentationGenerator.ATTRIBUTE_NAME_URL_TEMPLATE, "/{a}/{b}")
.build());
assertThat(this.generatedSnippets.pathParameters())
.is(tableWithTitleAndHeader(getTitle(), "Parameter", "Description").row("`a`", "one").row("`b`", "two"));
}
@Test
public void additionalDescriptorsWithRelaxedRequestParameters() throws IOException {
RequestDocumentation.relaxedPathParameters(parameterWithName("a").description("one"))
.and(parameterWithName("b").description("two")).document(this.operationBuilder
.attribute(RestDocumentationGenerator.ATTRIBUTE_NAME_URL_TEMPLATE, "/{a}/{b}/{c}").build());
.and(parameterWithName("b").description("two"))
.document(this.operationBuilder
.attribute(RestDocumentationGenerator.ATTRIBUTE_NAME_URL_TEMPLATE, "/{a}/{b}/{c}")
.build());
assertThat(this.generatedSnippets.pathParameters())
.is(tableWithTitleAndHeader(getTitle("/{a}/{b}/{c}"), "Parameter", "Description").row("`a`", "one")
.row("`b`", "two"));
.is(tableWithTitleAndHeader(getTitle("/{a}/{b}/{c}"), "Parameter", "Description").row("`a`", "one")
.row("`b`", "two"));
}
@Test
public void pathParametersWithEscapedContent() throws IOException {
RequestDocumentation.pathParameters(parameterWithName("Foo|Bar").description("one|two"))
.document(this.operationBuilder
.attribute(RestDocumentationGenerator.ATTRIBUTE_NAME_URL_TEMPLATE, "{Foo|Bar}").build());
.document(
this.operationBuilder.attribute(RestDocumentationGenerator.ATTRIBUTE_NAME_URL_TEMPLATE, "{Foo|Bar}")
.build());
assertThat(this.generatedSnippets.pathParameters())
.is(tableWithTitleAndHeader(getTitle("{Foo|Bar}"), "Parameter", "Description")
.row(escapeIfNecessary("`Foo|Bar`"), escapeIfNecessary("one|two")));
.is(tableWithTitleAndHeader(getTitle("{Foo|Bar}"), "Parameter", "Description")
.row(escapeIfNecessary("`Foo|Bar`"), escapeIfNecessary("one|two")));
}
private String escapeIfNecessary(String input) {

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2014-2022 the original author or authors.
* Copyright 2014-2023 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -43,26 +43,26 @@ public class RequestParametersSnippetFailureTests {
@Test
public void undocumentedParameter() {
assertThatExceptionOfType(SnippetException.class)
.isThrownBy(() -> new RequestParametersSnippet(Collections.<ParameterDescriptor>emptyList())
.document(this.operationBuilder.request("http://localhost").param("a", "alpha").build()))
.withMessage("Request parameters with the following names were not documented: [a]");
.isThrownBy(() -> new RequestParametersSnippet(Collections.<ParameterDescriptor>emptyList())
.document(this.operationBuilder.request("http://localhost").param("a", "alpha").build()))
.withMessage("Request parameters with the following names were not documented: [a]");
}
@Test
public void missingParameter() {
assertThatExceptionOfType(SnippetException.class)
.isThrownBy(() -> new RequestParametersSnippet(Arrays.asList(parameterWithName("a").description("one")))
.document(this.operationBuilder.request("http://localhost").build()))
.withMessage("Request parameters with the following names were not found in the request: [a]");
.isThrownBy(() -> new RequestParametersSnippet(Arrays.asList(parameterWithName("a").description("one")))
.document(this.operationBuilder.request("http://localhost").build()))
.withMessage("Request parameters with the following names were not found in the request: [a]");
}
@Test
public void undocumentedAndMissingParameters() {
assertThatExceptionOfType(SnippetException.class)
.isThrownBy(() -> new RequestParametersSnippet(Arrays.asList(parameterWithName("a").description("one")))
.document(this.operationBuilder.request("http://localhost").param("b", "bravo").build()))
.withMessage("Request parameters with the following names were not documented: [b]. Request parameters"
+ " with the following names were not found in the request: [a]");
.isThrownBy(() -> new RequestParametersSnippet(Arrays.asList(parameterWithName("a").description("one")))
.document(this.operationBuilder.request("http://localhost").param("b", "bravo").build()))
.withMessage("Request parameters with the following names were not documented: [b]. Request parameters"
+ " with the following names were not found in the request: [a]");
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2014-2020 the original author or authors.
* Copyright 2014-2023 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -50,28 +50,28 @@ public class RequestParametersSnippetTests extends AbstractSnippetTests {
public void requestParameters() throws IOException {
new RequestParametersSnippet(
Arrays.asList(parameterWithName("a").description("one"), parameterWithName("b").description("two")))
.document(this.operationBuilder.request("http://localhost").param("a", "bravo")
.param("b", "bravo").build());
.document(
this.operationBuilder.request("http://localhost").param("a", "bravo").param("b", "bravo").build());
assertThat(this.generatedSnippets.requestParameters())
.is(tableWithHeader("Parameter", "Description").row("`a`", "one").row("`b`", "two"));
.is(tableWithHeader("Parameter", "Description").row("`a`", "one").row("`b`", "two"));
}
@Test
public void requestParameterWithNoValue() throws IOException {
new RequestParametersSnippet(Arrays.asList(parameterWithName("a").description("one")))
.document(this.operationBuilder.request("http://localhost").param("a").build());
.document(this.operationBuilder.request("http://localhost").param("a").build());
assertThat(this.generatedSnippets.requestParameters())
.is(tableWithHeader("Parameter", "Description").row("`a`", "one"));
.is(tableWithHeader("Parameter", "Description").row("`a`", "one"));
}
@Test
public void ignoredRequestParameter() throws IOException {
new RequestParametersSnippet(
Arrays.asList(parameterWithName("a").ignored(), parameterWithName("b").description("two")))
.document(this.operationBuilder.request("http://localhost").param("a", "bravo")
.param("b", "bravo").build());
.document(
this.operationBuilder.request("http://localhost").param("a", "bravo").param("b", "bravo").build());
assertThat(this.generatedSnippets.requestParameters())
.is(tableWithHeader("Parameter", "Description").row("`b`", "two"));
.is(tableWithHeader("Parameter", "Description").row("`b`", "two"));
}
@Test
@@ -79,38 +79,41 @@ public class RequestParametersSnippetTests extends AbstractSnippetTests {
new RequestParametersSnippet(Arrays.asList(parameterWithName("b").description("two")), true).document(
this.operationBuilder.request("http://localhost").param("a", "bravo").param("b", "bravo").build());
assertThat(this.generatedSnippets.requestParameters())
.is(tableWithHeader("Parameter", "Description").row("`b`", "two"));
.is(tableWithHeader("Parameter", "Description").row("`b`", "two"));
}
@Test
public void missingOptionalRequestParameter() throws IOException {
new RequestParametersSnippet(Arrays.asList(parameterWithName("a").description("one").optional(),
parameterWithName("b").description("two")))
.document(this.operationBuilder.request("http://localhost").param("b", "bravo").build());
.document(this.operationBuilder.request("http://localhost").param("b", "bravo").build());
assertThat(this.generatedSnippets.requestParameters())
.is(tableWithHeader("Parameter", "Description").row("`a`", "one").row("`b`", "two"));
.is(tableWithHeader("Parameter", "Description").row("`a`", "one").row("`b`", "two"));
}
@Test
public void presentOptionalRequestParameter() throws IOException {
new RequestParametersSnippet(Arrays.asList(parameterWithName("a").description("one").optional()))
.document(this.operationBuilder.request("http://localhost").param("a", "one").build());
.document(this.operationBuilder.request("http://localhost").param("a", "one").build());
assertThat(this.generatedSnippets.requestParameters())
.is(tableWithHeader("Parameter", "Description").row("`a`", "one"));
.is(tableWithHeader("Parameter", "Description").row("`a`", "one"));
}
@Test
public void requestParametersWithCustomAttributes() throws IOException {
TemplateResourceResolver resolver = mock(TemplateResourceResolver.class);
given(resolver.resolveTemplateResource("request-parameters"))
.willReturn(snippetResource("request-parameters-with-title"));
.willReturn(snippetResource("request-parameters-with-title"));
new RequestParametersSnippet(
Arrays.asList(parameterWithName("a").description("one").attributes(key("foo").value("alpha")),
parameterWithName("b").description("two").attributes(key("foo").value("bravo"))),
attributes(key("title").value("The title")))
.document(this.operationBuilder
.attribute(TemplateEngine.class.getName(), new MustacheTemplateEngine(resolver))
.request("http://localhost").param("a", "alpha").param("b", "bravo").build());
.document(this.operationBuilder
.attribute(TemplateEngine.class.getName(), new MustacheTemplateEngine(resolver))
.request("http://localhost")
.param("a", "alpha")
.param("b", "bravo")
.build());
assertThat(this.generatedSnippets.requestParameters()).contains("The title");
}
@@ -118,57 +121,67 @@ public class RequestParametersSnippetTests extends AbstractSnippetTests {
public void requestParametersWithCustomDescriptorAttributes() throws IOException {
TemplateResourceResolver resolver = mock(TemplateResourceResolver.class);
given(resolver.resolveTemplateResource("request-parameters"))
.willReturn(snippetResource("request-parameters-with-extra-column"));
.willReturn(snippetResource("request-parameters-with-extra-column"));
new RequestParametersSnippet(
Arrays.asList(parameterWithName("a").description("one").attributes(key("foo").value("alpha")),
parameterWithName("b").description("two").attributes(key("foo").value("bravo"))))
.document(this.operationBuilder
.attribute(TemplateEngine.class.getName(), new MustacheTemplateEngine(resolver))
.request("http://localhost").param("a", "alpha").param("b", "bravo").build());
assertThat(this.generatedSnippets.requestParameters()).is(
tableWithHeader("Parameter", "Description", "Foo").row("a", "one", "alpha").row("b", "two", "bravo"));
.document(this.operationBuilder
.attribute(TemplateEngine.class.getName(), new MustacheTemplateEngine(resolver))
.request("http://localhost")
.param("a", "alpha")
.param("b", "bravo")
.build());
assertThat(this.generatedSnippets.requestParameters())
.is(tableWithHeader("Parameter", "Description", "Foo").row("a", "one", "alpha").row("b", "two", "bravo"));
}
@Test
public void requestParametersWithOptionalColumn() throws IOException {
TemplateResourceResolver resolver = mock(TemplateResourceResolver.class);
given(resolver.resolveTemplateResource("request-parameters"))
.willReturn(snippetResource("request-parameters-with-optional-column"));
.willReturn(snippetResource("request-parameters-with-optional-column"));
new RequestParametersSnippet(Arrays.asList(parameterWithName("a").description("one").optional(),
parameterWithName("b").description("two")))
.document(this.operationBuilder
.attribute(TemplateEngine.class.getName(), new MustacheTemplateEngine(resolver))
.request("http://localhost").param("a", "alpha").param("b", "bravo").build());
.document(this.operationBuilder
.attribute(TemplateEngine.class.getName(), new MustacheTemplateEngine(resolver))
.request("http://localhost")
.param("a", "alpha")
.param("b", "bravo")
.build());
assertThat(this.generatedSnippets.requestParameters())
.is(tableWithHeader("Parameter", "Optional", "Description").row("a", "true", "one").row("b", "false",
"two"));
.is(tableWithHeader("Parameter", "Optional", "Description").row("a", "true", "one")
.row("b", "false", "two"));
}
@Test
public void additionalDescriptors() throws IOException {
RequestDocumentation.requestParameters(parameterWithName("a").description("one"))
.and(parameterWithName("b").description("two")).document(this.operationBuilder
.request("http://localhost").param("a", "bravo").param("b", "bravo").build());
.and(parameterWithName("b").description("two"))
.document(
this.operationBuilder.request("http://localhost").param("a", "bravo").param("b", "bravo").build());
assertThat(this.generatedSnippets.requestParameters())
.is(tableWithHeader("Parameter", "Description").row("`a`", "one").row("`b`", "two"));
.is(tableWithHeader("Parameter", "Description").row("`a`", "one").row("`b`", "two"));
}
@Test
public void additionalDescriptorsWithRelaxedRequestParameters() throws IOException {
RequestDocumentation.relaxedRequestParameters(parameterWithName("a").description("one"))
.and(parameterWithName("b").description("two"))
.document(this.operationBuilder.request("http://localhost").param("a", "bravo").param("b", "bravo")
.param("c", "undocumented").build());
.and(parameterWithName("b").description("two"))
.document(this.operationBuilder.request("http://localhost")
.param("a", "bravo")
.param("b", "bravo")
.param("c", "undocumented")
.build());
assertThat(this.generatedSnippets.requestParameters())
.is(tableWithHeader("Parameter", "Description").row("`a`", "one").row("`b`", "two"));
.is(tableWithHeader("Parameter", "Description").row("`a`", "one").row("`b`", "two"));
}
@Test
public void requestParametersWithEscapedContent() throws IOException {
RequestDocumentation.requestParameters(parameterWithName("Foo|Bar").description("one|two"))
.document(this.operationBuilder.request("http://localhost").param("Foo|Bar", "baz").build());
.document(this.operationBuilder.request("http://localhost").param("Foo|Bar", "baz").build());
assertThat(this.generatedSnippets.requestParameters()).is(tableWithHeader("Parameter", "Description")
.row(escapeIfNecessary("`Foo|Bar`"), escapeIfNecessary("one|two")));
.row(escapeIfNecessary("`Foo|Bar`"), escapeIfNecessary("one|two")));
}
private String escapeIfNecessary(String input) {

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2014-2022 the original author or authors.
* Copyright 2014-2023 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -43,26 +43,26 @@ public class RequestPartsSnippetFailureTests {
@Test
public void undocumentedPart() {
assertThatExceptionOfType(SnippetException.class)
.isThrownBy(() -> new RequestPartsSnippet(Collections.<RequestPartDescriptor>emptyList()).document(
this.operationBuilder.request("http://localhost").part("a", "alpha".getBytes()).build()))
.withMessage("Request parts with the following names were not documented: [a]");
.isThrownBy(() -> new RequestPartsSnippet(Collections.<RequestPartDescriptor>emptyList())
.document(this.operationBuilder.request("http://localhost").part("a", "alpha".getBytes()).build()))
.withMessage("Request parts with the following names were not documented: [a]");
}
@Test
public void missingPart() {
assertThatExceptionOfType(SnippetException.class)
.isThrownBy(() -> new RequestPartsSnippet(Arrays.asList(partWithName("a").description("one")))
.document(this.operationBuilder.request("http://localhost").build()))
.withMessage("Request parts with the following names were not found in the request: [a]");
.isThrownBy(() -> new RequestPartsSnippet(Arrays.asList(partWithName("a").description("one")))
.document(this.operationBuilder.request("http://localhost").build()))
.withMessage("Request parts with the following names were not found in the request: [a]");
}
@Test
public void undocumentedAndMissingParts() {
assertThatExceptionOfType(SnippetException.class)
.isThrownBy(() -> new RequestPartsSnippet(Arrays.asList(partWithName("a").description("one"))).document(
this.operationBuilder.request("http://localhost").part("b", "bravo".getBytes()).build()))
.withMessage("Request parts with the following names were not documented: [b]. Request parts with the"
+ " following names were not found in the request: [a]");
.isThrownBy(() -> new RequestPartsSnippet(Arrays.asList(partWithName("a").description("one")))
.document(this.operationBuilder.request("http://localhost").part("b", "bravo".getBytes()).build()))
.withMessage("Request parts with the following names were not documented: [b]. Request parts with the"
+ " following names were not found in the request: [a]");
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2014-2019 the original author or authors.
* Copyright 2014-2023 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -50,25 +50,34 @@ public class RequestPartsSnippetTests extends AbstractSnippetTests {
public void requestParts() throws IOException {
new RequestPartsSnippet(
Arrays.asList(partWithName("a").description("one"), partWithName("b").description("two")))
.document(this.operationBuilder.request("http://localhost").part("a", "bravo".getBytes()).and()
.part("b", "bravo".getBytes()).build());
.document(this.operationBuilder.request("http://localhost")
.part("a", "bravo".getBytes())
.and()
.part("b", "bravo".getBytes())
.build());
assertThat(this.generatedSnippets.requestParts())
.is(tableWithHeader("Part", "Description").row("`a`", "one").row("`b`", "two"));
.is(tableWithHeader("Part", "Description").row("`a`", "one").row("`b`", "two"));
}
@Test
public void ignoredRequestPart() throws IOException {
new RequestPartsSnippet(Arrays.asList(partWithName("a").ignored(), partWithName("b").description("two")))
.document(this.operationBuilder.request("http://localhost").part("a", "bravo".getBytes()).and()
.part("b", "bravo".getBytes()).build());
.document(this.operationBuilder.request("http://localhost")
.part("a", "bravo".getBytes())
.and()
.part("b", "bravo".getBytes())
.build());
assertThat(this.generatedSnippets.requestParts()).is(tableWithHeader("Part", "Description").row("`b`", "two"));
}
@Test
public void allUndocumentedRequestPartsCanBeIgnored() throws IOException {
new RequestPartsSnippet(Arrays.asList(partWithName("b").description("two")), true)
.document(this.operationBuilder.request("http://localhost").part("a", "bravo".getBytes()).and()
.part("b", "bravo".getBytes()).build());
.document(this.operationBuilder.request("http://localhost")
.part("a", "bravo".getBytes())
.and()
.part("b", "bravo".getBytes())
.build());
assertThat(this.generatedSnippets.requestParts()).is(tableWithHeader("Part", "Description").row("`b`", "two"));
}
@@ -76,16 +85,15 @@ public class RequestPartsSnippetTests extends AbstractSnippetTests {
public void missingOptionalRequestPart() throws IOException {
new RequestPartsSnippet(
Arrays.asList(partWithName("a").description("one").optional(), partWithName("b").description("two")))
.document(this.operationBuilder.request("http://localhost").part("b", "bravo".getBytes())
.build());
.document(this.operationBuilder.request("http://localhost").part("b", "bravo".getBytes()).build());
assertThat(this.generatedSnippets.requestParts())
.is(tableWithHeader("Part", "Description").row("`a`", "one").row("`b`", "two"));
.is(tableWithHeader("Part", "Description").row("`a`", "one").row("`b`", "two"));
}
@Test
public void presentOptionalRequestPart() throws IOException {
new RequestPartsSnippet(Arrays.asList(partWithName("a").description("one").optional()))
.document(this.operationBuilder.request("http://localhost").part("a", "one".getBytes()).build());
.document(this.operationBuilder.request("http://localhost").part("a", "one".getBytes()).build());
assertThat(this.generatedSnippets.requestParts()).is(tableWithHeader("Part", "Description").row("`a`", "one"));
}
@@ -93,15 +101,18 @@ public class RequestPartsSnippetTests extends AbstractSnippetTests {
public void requestPartsWithCustomAttributes() throws IOException {
TemplateResourceResolver resolver = mock(TemplateResourceResolver.class);
given(resolver.resolveTemplateResource("request-parts"))
.willReturn(snippetResource("request-parts-with-title"));
.willReturn(snippetResource("request-parts-with-title"));
new RequestPartsSnippet(
Arrays.asList(partWithName("a").description("one").attributes(key("foo").value("alpha")),
partWithName("b").description("two").attributes(key("foo").value("bravo"))),
attributes(key("title").value("The title")))
.document(this.operationBuilder
.attribute(TemplateEngine.class.getName(), new MustacheTemplateEngine(resolver))
.request("http://localhost").part("a", "alpha".getBytes()).and()
.part("b", "bravo".getBytes()).build());
.document(this.operationBuilder
.attribute(TemplateEngine.class.getName(), new MustacheTemplateEngine(resolver))
.request("http://localhost")
.part("a", "alpha".getBytes())
.and()
.part("b", "bravo".getBytes())
.build());
assertThat(this.generatedSnippets.requestParts()).contains("The title");
}
@@ -109,48 +120,58 @@ public class RequestPartsSnippetTests extends AbstractSnippetTests {
public void requestPartsWithCustomDescriptorAttributes() throws IOException {
TemplateResourceResolver resolver = mock(TemplateResourceResolver.class);
given(resolver.resolveTemplateResource("request-parts"))
.willReturn(snippetResource("request-parts-with-extra-column"));
.willReturn(snippetResource("request-parts-with-extra-column"));
new RequestPartsSnippet(
Arrays.asList(partWithName("a").description("one").attributes(key("foo").value("alpha")),
partWithName("b").description("two").attributes(key("foo").value("bravo"))))
.document(this.operationBuilder
.attribute(TemplateEngine.class.getName(), new MustacheTemplateEngine(resolver))
.request("http://localhost").part("a", "alpha".getBytes()).and()
.part("b", "bravo".getBytes()).build());
.document(this.operationBuilder
.attribute(TemplateEngine.class.getName(), new MustacheTemplateEngine(resolver))
.request("http://localhost")
.part("a", "alpha".getBytes())
.and()
.part("b", "bravo".getBytes())
.build());
assertThat(this.generatedSnippets.requestParts())
.is(tableWithHeader("Part", "Description", "Foo").row("a", "one", "alpha").row("b", "two", "bravo"));
.is(tableWithHeader("Part", "Description", "Foo").row("a", "one", "alpha").row("b", "two", "bravo"));
}
@Test
public void requestPartsWithOptionalColumn() throws IOException {
TemplateResourceResolver resolver = mock(TemplateResourceResolver.class);
given(resolver.resolveTemplateResource("request-parts"))
.willReturn(snippetResource("request-parts-with-optional-column"));
.willReturn(snippetResource("request-parts-with-optional-column"));
new RequestPartsSnippet(
Arrays.asList(partWithName("a").description("one").optional(), partWithName("b").description("two")))
.document(this.operationBuilder
.attribute(TemplateEngine.class.getName(), new MustacheTemplateEngine(resolver))
.request("http://localhost").part("a", "alpha".getBytes()).and()
.part("b", "bravo".getBytes()).build());
assertThat(this.generatedSnippets.requestParts()).is(
tableWithHeader("Part", "Optional", "Description").row("a", "true", "one").row("b", "false", "two"));
.document(this.operationBuilder
.attribute(TemplateEngine.class.getName(), new MustacheTemplateEngine(resolver))
.request("http://localhost")
.part("a", "alpha".getBytes())
.and()
.part("b", "bravo".getBytes())
.build());
assertThat(this.generatedSnippets.requestParts())
.is(tableWithHeader("Part", "Optional", "Description").row("a", "true", "one").row("b", "false", "two"));
}
@Test
public void additionalDescriptors() throws IOException {
RequestDocumentation.requestParts(partWithName("a").description("one"))
.and(partWithName("b").description("two")).document(this.operationBuilder.request("http://localhost")
.part("a", "bravo".getBytes()).and().part("b", "bravo".getBytes()).build());
.and(partWithName("b").description("two"))
.document(this.operationBuilder.request("http://localhost")
.part("a", "bravo".getBytes())
.and()
.part("b", "bravo".getBytes())
.build());
assertThat(this.generatedSnippets.requestParts())
.is(tableWithHeader("Part", "Description").row("`a`", "one").row("`b`", "two"));
.is(tableWithHeader("Part", "Description").row("`a`", "one").row("`b`", "two"));
}
@Test
public void requestPartsWithEscapedContent() throws IOException {
RequestDocumentation.requestParts(partWithName("Foo|Bar").description("one|two"))
.document(this.operationBuilder.request("http://localhost").part("Foo|Bar", "baz".getBytes()).build());
.document(this.operationBuilder.request("http://localhost").part("Foo|Bar", "baz".getBytes()).build());
assertThat(this.generatedSnippets.requestParts()).is(tableWithHeader("Part", "Description")
.row(escapeIfNecessary("`Foo|Bar`"), escapeIfNecessary("one|two")));
.row(escapeIfNecessary("`Foo|Bar`"), escapeIfNecessary("one|two")));
}
private String escapeIfNecessary(String input) {

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2014-2022 the original author or authors.
* Copyright 2014-2023 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -35,73 +35,73 @@ public class RestDocumentationContextPlaceholderResolverTests {
@Test
public void kebabCaseMethodName() {
assertThat(createResolver("dashSeparatedMethodName").resolvePlaceholder("method-name"))
.isEqualTo("dash-separated-method-name");
.isEqualTo("dash-separated-method-name");
}
@Test
public void kebabCaseMethodNameWithUpperCaseOpeningSection() {
assertThat(createResolver("URIDashSeparatedMethodName").resolvePlaceholder("method-name"))
.isEqualTo("uri-dash-separated-method-name");
.isEqualTo("uri-dash-separated-method-name");
}
@Test
public void kebabCaseMethodNameWithUpperCaseMidSection() {
assertThat(createResolver("dashSeparatedMethodNameWithURIInIt").resolvePlaceholder("method-name"))
.isEqualTo("dash-separated-method-name-with-uri-in-it");
.isEqualTo("dash-separated-method-name-with-uri-in-it");
}
@Test
public void kebabCaseMethodNameWithUpperCaseEndSection() {
assertThat(createResolver("dashSeparatedMethodNameWithURI").resolvePlaceholder("method-name"))
.isEqualTo("dash-separated-method-name-with-uri");
.isEqualTo("dash-separated-method-name-with-uri");
}
@Test
public void snakeCaseMethodName() {
assertThat(createResolver("underscoreSeparatedMethodName").resolvePlaceholder("method_name"))
.isEqualTo("underscore_separated_method_name");
.isEqualTo("underscore_separated_method_name");
}
@Test
public void snakeCaseMethodNameWithUpperCaseOpeningSection() {
assertThat(createResolver("URIUnderscoreSeparatedMethodName").resolvePlaceholder("method_name"))
.isEqualTo("uri_underscore_separated_method_name");
.isEqualTo("uri_underscore_separated_method_name");
}
@Test
public void snakeCaseMethodNameWithUpperCaseMidSection() {
assertThat(createResolver("underscoreSeparatedMethodNameWithURIInIt").resolvePlaceholder("method_name"))
.isEqualTo("underscore_separated_method_name_with_uri_in_it");
.isEqualTo("underscore_separated_method_name_with_uri_in_it");
}
@Test
public void snakeCaseMethodNameWithUpperCaseEndSection() {
assertThat(createResolver("underscoreSeparatedMethodNameWithURI").resolvePlaceholder("method_name"))
.isEqualTo("underscore_separated_method_name_with_uri");
.isEqualTo("underscore_separated_method_name_with_uri");
}
@Test
public void camelCaseMethodName() {
assertThat(createResolver("camelCaseMethodName").resolvePlaceholder("methodName"))
.isEqualTo("camelCaseMethodName");
.isEqualTo("camelCaseMethodName");
}
@Test
public void kebabCaseClassName() {
assertThat(createResolver().resolvePlaceholder("class-name"))
.isEqualTo("rest-documentation-context-placeholder-resolver-tests");
.isEqualTo("rest-documentation-context-placeholder-resolver-tests");
}
@Test
public void snakeCaseClassName() {
assertThat(createResolver().resolvePlaceholder("class_name"))
.isEqualTo("rest_documentation_context_placeholder_resolver_tests");
.isEqualTo("rest_documentation_context_placeholder_resolver_tests");
}
@Test
public void camelCaseClassName() {
assertThat(createResolver().resolvePlaceholder("ClassName"))
.isEqualTo("RestDocumentationContextPlaceholderResolverTests");
.isEqualTo("RestDocumentationContextPlaceholderResolverTests");
}
@Test

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2014-2019 the original author or authors.
* Copyright 2014-2023 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -54,14 +54,14 @@ public class StandardWriterResolverTests {
public void absoluteInput() {
String absolutePath = new File("foo").getAbsolutePath();
assertThat(this.resolver.resolveFile(absolutePath, "bar.txt", createContext(absolutePath)))
.isEqualTo(new File(absolutePath, "bar.txt"));
.isEqualTo(new File(absolutePath, "bar.txt"));
}
@Test
public void configuredOutputAndRelativeInput() {
File outputDir = new File("foo").getAbsoluteFile();
assertThat(this.resolver.resolveFile("bar", "baz.txt", createContext(outputDir.getAbsolutePath())))
.isEqualTo(new File(outputDir, "bar/baz.txt"));
.isEqualTo(new File(outputDir, "bar/baz.txt"));
}
@Test
@@ -69,7 +69,7 @@ public class StandardWriterResolverTests {
File outputDir = new File("foo").getAbsoluteFile();
String absolutePath = new File("bar").getAbsolutePath();
assertThat(this.resolver.resolveFile(absolutePath, "baz.txt", createContext(outputDir.getAbsolutePath())))
.isEqualTo(new File(absolutePath, "baz.txt"));
.isEqualTo(new File(absolutePath, "baz.txt"));
}
@Test

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2014-2022 the original author or authors.
* Copyright 2014-2023 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -98,9 +98,9 @@ public class StandardTemplateResourceResolverTests {
@Test
public void failsIfCustomAndDefaultSnippetsDoNotExist() {
assertThatIllegalStateException()
.isThrownBy(() -> doWithThreadContextClassLoader(this.classLoader,
() -> StandardTemplateResourceResolverTests.this.resolver.resolveTemplateResource("test")))
.withMessage("Template named 'test' could not be resolved");
.isThrownBy(() -> doWithThreadContextClassLoader(this.classLoader,
() -> StandardTemplateResourceResolverTests.this.resolver.resolveTemplateResource("test")))
.withMessage("Template named 'test' could not be resolved");
}
private <T> T doWithThreadContextClassLoader(ClassLoader classLoader, Callable<T> action) {

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2014-2021 the original author or authors.
* Copyright 2014-2023 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -110,7 +110,7 @@ public class GeneratedSnippets extends OperationTestRule {
File snippetFile = getSnippetFile(name);
try {
return FileCopyUtils
.copyToString(new InputStreamReader(new FileInputStream(snippetFile), StandardCharsets.UTF_8));
.copyToString(new InputStreamReader(new FileInputStream(snippetFile), StandardCharsets.UTF_8));
}
catch (Exception ex) {
fail("Failed to read '" + snippetFile + "'", ex);