Fix handling of empty querty string parameters

Previously empty parameters in a query string were handled
inconsistently such that they sometimes had a value of "" in a list
and sometimes were represented as an empty list. This inconsistency
lead to the parameter appearing twice in the cURL request snippet.

This commit removes the inconsistency by always using an empty string
to represent an empty query parameter value.

Fixes gh-647
This commit is contained in:
Andy Wilkinson
2019-10-04 18:17:53 +01:00
parent 92926d65bc
commit 97ddf3dcec
5 changed files with 52 additions and 4 deletions

View File

@@ -64,10 +64,8 @@ public class QueryStringParser {
parameters.add(decode(name), decode(value));
}
else {
List<String> values = parameters.get(components[0]);
if (values == null) {
parameters.put(components[0], new LinkedList<String>());
}
List<String> values = parameters.computeIfAbsent(components[0], (p) -> new LinkedList<String>());
values.add("");
}
}
else {

View File

@@ -81,4 +81,18 @@ public class QueryStringParserTests {
this.queryStringParser.parse(URI.create("http://localhost?a=apple=avocado"));
}
@Test
public void emptyParameter() {
Parameters parameters = this.queryStringParser.parse(URI.create("http://localhost?a="));
assertThat(parameters.size()).isEqualTo(1);
assertThat(parameters).containsEntry("a", Arrays.asList(""));
}
@Test
public void emptyAndNotEmptyParameter() {
Parameters parameters = this.queryStringParser.parse(URI.create("http://localhost?a=&a=alpha"));
assertThat(parameters.size()).isEqualTo(1);
assertThat(parameters).containsEntry("a", Arrays.asList("", "alpha"));
}
}

View File

@@ -185,6 +185,19 @@ public class MockMvcRestDocumentationIntegrationTests {
+ " -H 'Accept: application/json' \\%n" + " -d 'a=alpha'"))));
}
@Test
public void curlSnippetWithEmptyParameterQueryString() throws Exception {
MockMvc mockMvc = MockMvcBuilders.webAppContextSetup(this.context)
.apply(documentationConfiguration(this.restDocumentation)).build();
mockMvc.perform(get("/").param("a", "").accept(MediaType.APPLICATION_JSON)).andExpect(status().isOk())
.andDo(document("curl-snippet-with-empty-parameter-query-string"));
assertThat(
new File("build/generated-snippets/curl-snippet-with-empty-parameter-query-string/curl-request.adoc"))
.has(content(codeBlock(TemplateFormats.asciidoctor(), "bash")
.withContent(String.format("$ curl 'http://localhost:8080/?a=' -i -X GET \\%n"
+ " -H 'Accept: application/json'"))));
}
@Test
public void curlSnippetWithContentAndParametersOnPost() throws Exception {
MockMvc mockMvc = MockMvcBuilders.webAppContextSetup(this.context)

View File

@@ -120,6 +120,18 @@ public class RestAssuredRestDocumentationIntegrationTests {
+ " -H 'Content-Type: " + contentType + "' \\%n" + " --cookie 'cookieName=cookieVal'"))));
}
@Test
public void curlSnippetWithEmptyParameterQueryString() throws Exception {
given().port(tomcat.getPort()).filter(documentationConfiguration(this.restDocumentation))
.filter(document("curl-snippet-with-empty-parameter-query-string")).accept("application/json")
.param("a", "").get("/").then().statusCode(200);
assertThat(
new File("build/generated-snippets/curl-snippet-with-empty-parameter-query-string/curl-request.adoc"))
.has(content(codeBlock(TemplateFormats.asciidoctor(), "bash")
.withContent(String.format("$ curl 'http://localhost:" + tomcat.getPort()
+ "/?a=' -i -X GET \\%n -H 'Accept: application/json'"))));
}
@Test
public void curlSnippetWithQueryStringOnPost() throws Exception {
given().port(tomcat.getPort()).filter(documentationConfiguration(this.restDocumentation))

View File

@@ -165,6 +165,17 @@ public class WebTestClientRestDocumentationIntegrationTests {
+ " -H 'Accept: application/json' \\%n" + " --cookie 'cookieName=cookieVal'"))));
}
@Test
public void curlSnippetWithEmptyParameterQueryString() throws Exception {
this.webTestClient.get().uri("/?a=").accept(MediaType.APPLICATION_JSON).exchange().expectStatus().isOk()
.expectBody().consumeWith(document("curl-snippet-with-empty-parameter-query-string"));
assertThat(
new File("build/generated-snippets/curl-snippet-with-empty-parameter-query-string/curl-request.adoc"))
.has(content(codeBlock(TemplateFormats.asciidoctor(), "bash")
.withContent(String.format("$ curl 'https://api.example.com/?a=' -i -X GET \\%n"
+ " -H 'Accept: application/json'"))));
}
@Test
public void httpieSnippetWithCookies() throws Exception {
this.webTestClient.get().uri("/").cookie("cookieName", "cookieVal").accept(MediaType.APPLICATION_JSON)