MockServerHttpRequest builder supports query params

Issue: SPR-16280
This commit is contained in:
Rossen Stoyanchev 2017-12-19 15:38:12 -05:00
parent 6df1a7874a
commit a8cf275aed
4 changed files with 126 additions and 18 deletions

View File

@ -133,6 +133,8 @@ public class MockServerHttpRequest extends AbstractServerHttpRequest {
/** /**
* Alternative to {@link #method(HttpMethod, URI)} that accepts a URI template. * Alternative to {@link #method(HttpMethod, URI)} that accepts a URI template.
* The given URI may contain query parameters, or those may be added later via
* {@link BaseBuilder#queryParam queryParam} builder methods.
* @param method the HTTP method (GET, POST, etc) * @param method the HTTP method (GET, POST, etc)
* @param urlTemplate the URL template * @param urlTemplate the URL template
* @param vars variables to expand into the template * @param vars variables to expand into the template
@ -144,7 +146,9 @@ public class MockServerHttpRequest extends AbstractServerHttpRequest {
} }
/** /**
* Create an HTTP GET builder with the given url. * Create an HTTP GET builder with the given URI template. The given URI may
* contain query parameters, or those may be added later via
* {@link BaseBuilder#queryParam queryParam} builder methods.
* @param urlTemplate a URL template; the resulting URL will be encoded * @param urlTemplate a URL template; the resulting URL will be encoded
* @param uriVars zero or more URI variables * @param uriVars zero or more URI variables
* @return the created builder * @return the created builder
@ -154,7 +158,7 @@ public class MockServerHttpRequest extends AbstractServerHttpRequest {
} }
/** /**
* Create an HTTP HEAD builder with the given url. * HTTP HEAD variant. See {@link #get(String, Object...)} for general info.
* @param urlTemplate a URL template; the resulting URL will be encoded * @param urlTemplate a URL template; the resulting URL will be encoded
* @param uriVars zero or more URI variables * @param uriVars zero or more URI variables
* @return the created builder * @return the created builder
@ -164,7 +168,7 @@ public class MockServerHttpRequest extends AbstractServerHttpRequest {
} }
/** /**
* Create an HTTP POST builder with the given url. * HTTP POST variant. See {@link #get(String, Object...)} for general info.
* @param urlTemplate a URL template; the resulting URL will be encoded * @param urlTemplate a URL template; the resulting URL will be encoded
* @param uriVars zero or more URI variables * @param uriVars zero or more URI variables
* @return the created builder * @return the created builder
@ -174,7 +178,8 @@ public class MockServerHttpRequest extends AbstractServerHttpRequest {
} }
/** /**
* Create an HTTP PUT builder with the given url. * HTTP PUT variant. See {@link #get(String, Object...)} for general info.
* {@link BaseBuilder#queryParam queryParam} builder methods.
* @param urlTemplate a URL template; the resulting URL will be encoded * @param urlTemplate a URL template; the resulting URL will be encoded
* @param uriVars zero or more URI variables * @param uriVars zero or more URI variables
* @return the created builder * @return the created builder
@ -184,7 +189,7 @@ public class MockServerHttpRequest extends AbstractServerHttpRequest {
} }
/** /**
* Create an HTTP PATCH builder with the given url. * HTTP PATCH variant. See {@link #get(String, Object...)} for general info.
* @param urlTemplate a URL template; the resulting URL will be encoded * @param urlTemplate a URL template; the resulting URL will be encoded
* @param uriVars zero or more URI variables * @param uriVars zero or more URI variables
* @return the created builder * @return the created builder
@ -194,7 +199,7 @@ public class MockServerHttpRequest extends AbstractServerHttpRequest {
} }
/** /**
* Create an HTTP DELETE builder with the given url. * HTTP DELETE variant. See {@link #get(String, Object...)} for general info.
* @param urlTemplate a URL template; the resulting URL will be encoded * @param urlTemplate a URL template; the resulting URL will be encoded
* @param uriVars zero or more URI variables * @param uriVars zero or more URI variables
* @return the created builder * @return the created builder
@ -204,7 +209,7 @@ public class MockServerHttpRequest extends AbstractServerHttpRequest {
} }
/** /**
* Creates an HTTP OPTIONS builder with the given url. * HTTP OPTIONS variant. See {@link #get(String, Object...)} for general info.
* @param urlTemplate a URL template; the resulting URL will be encoded * @param urlTemplate a URL template; the resulting URL will be encoded
* @param uriVars zero or more URI variables * @param uriVars zero or more URI variables
* @return the created builder * @return the created builder
@ -225,6 +230,25 @@ public class MockServerHttpRequest extends AbstractServerHttpRequest {
*/ */
B contextPath(String contextPath); B contextPath(String contextPath);
/**
* Append the given query parameter to the existing query parameters.
* If no values are given, the resulting URI will contain the query
* parameter name only (i.e. {@code ?foo} instead of {@code ?foo=bar}).
* <p>The provided query name and values will be encoded.
* @param name the query parameter name
* @param values the query parameter values
* @return this UriComponentsBuilder
*/
B queryParam(String name, Object... values);
/**
* Add the given query parameters and values. The provided query name
* and corresponding values will be encoded.
* @param params the params
* @return this UriComponentsBuilder
*/
B queryParams(MultiValueMap<String, String> params);
/** /**
* Set the remote address to return. * Set the remote address to return.
*/ */
@ -375,6 +399,8 @@ public class MockServerHttpRequest extends AbstractServerHttpRequest {
@Nullable @Nullable
private String contextPath; private String contextPath;
private final UriComponentsBuilder queryParamsBuilder = UriComponentsBuilder.newInstance();
private final HttpHeaders headers = new HttpHeaders(); private final HttpHeaders headers = new HttpHeaders();
private final MultiValueMap<String, HttpCookie> cookies = new LinkedMultiValueMap<>(); private final MultiValueMap<String, HttpCookie> cookies = new LinkedMultiValueMap<>();
@ -397,6 +423,18 @@ public class MockServerHttpRequest extends AbstractServerHttpRequest {
return this; return this;
} }
@Override
public BodyBuilder queryParam(String name, Object... values) {
this.queryParamsBuilder.queryParam(name, values);
return this;
}
@Override
public BodyBuilder queryParams(MultiValueMap<String, String> params) {
this.queryParamsBuilder.queryParams(params);
return this;
}
@Override @Override
public BodyBuilder remoteAddress(InetSocketAddress remoteAddress) { public BodyBuilder remoteAddress(InetSocketAddress remoteAddress) {
this.remoteAddress = remoteAddress; this.remoteAddress = remoteAddress;
@ -506,7 +544,7 @@ public class MockServerHttpRequest extends AbstractServerHttpRequest {
@Override @Override
public MockServerHttpRequest body(Publisher<? extends DataBuffer> body) { public MockServerHttpRequest body(Publisher<? extends DataBuffer> body) {
applyCookiesIfNecessary(); applyCookiesIfNecessary();
return new MockServerHttpRequest(this.method, this.url, this.contextPath, return new MockServerHttpRequest(this.method, getUrlToUse(), this.contextPath,
this.headers, this.cookies, this.remoteAddress, this.sslInfo, body); this.headers, this.cookies, this.remoteAddress, this.sslInfo, body);
} }
@ -516,6 +554,17 @@ public class MockServerHttpRequest extends AbstractServerHttpRequest {
.forEach(cookie -> this.headers.add(HttpHeaders.COOKIE, cookie.toString())); .forEach(cookie -> this.headers.add(HttpHeaders.COOKIE, cookie.toString()));
} }
} }
private URI getUrlToUse() {
MultiValueMap<String, String> params =
this.queryParamsBuilder.buildAndExpand().encode().getQueryParams();
if (!params.isEmpty()) {
return UriComponentsBuilder.fromUri(this.url).queryParams(params).build(true).toUri();
}
return this.url;
}
} }
} }

View File

@ -30,7 +30,6 @@ import static org.junit.Assert.assertEquals;
*/ */
public class MockServerHttpRequestTests { public class MockServerHttpRequestTests {
@Test @Test
public void cookieHeaderSet() throws Exception { public void cookieHeaderSet() throws Exception {
HttpCookie foo11 = new HttpCookie("foo1", "bar1"); HttpCookie foo11 = new HttpCookie("foo1", "bar1");
@ -47,4 +46,15 @@ public class MockServerHttpRequestTests {
request.getHeaders().get(HttpHeaders.COOKIE)); request.getHeaders().get(HttpHeaders.COOKIE));
} }
@Test
public void queryParams() throws Exception {
MockServerHttpRequest request = MockServerHttpRequest.get("/foo bar?a=b")
.queryParam("name A", "value A1", "value A2")
.queryParam("name B", "value B1")
.build();
assertEquals("/foo%20bar?a=b&name%20A=value%20A1&name%20A=value%20A2&name%20B=value%20B1",
request.getURI().toString());
}
} }

View File

@ -632,7 +632,7 @@ public class UriComponentsBuilder implements UriBuilder, Cloneable {
* Append the given query parameter to the existing query parameters. The * Append the given query parameter to the existing query parameters. The
* given name or any of the values may contain URI template variables. If no * given name or any of the values may contain URI template variables. If no
* values are given, the resulting URI will contain the query parameter name * values are given, the resulting URI will contain the query parameter name
* only (i.e. {@code ?foo} instead of {@code ?foo=bar}. * only (i.e. {@code ?foo} instead of {@code ?foo=bar}).
* @param name the query parameter name * @param name the query parameter name
* @param values the query parameter values * @param values the query parameter values
* @return this UriComponentsBuilder * @return this UriComponentsBuilder

View File

@ -133,6 +133,8 @@ public class MockServerHttpRequest extends AbstractServerHttpRequest {
/** /**
* Alternative to {@link #method(HttpMethod, URI)} that accepts a URI template. * Alternative to {@link #method(HttpMethod, URI)} that accepts a URI template.
* The given URI may contain query parameters, or those may be added later via
* {@link BaseBuilder#queryParam queryParam} builder methods.
* @param method the HTTP method (GET, POST, etc) * @param method the HTTP method (GET, POST, etc)
* @param urlTemplate the URL template * @param urlTemplate the URL template
* @param vars variables to expand into the template * @param vars variables to expand into the template
@ -144,7 +146,9 @@ public class MockServerHttpRequest extends AbstractServerHttpRequest {
} }
/** /**
* Create an HTTP GET builder with the given url. * Create an HTTP GET builder with the given URI template. The given URI may
* contain query parameters, or those may be added later via
* {@link BaseBuilder#queryParam queryParam} builder methods.
* @param urlTemplate a URL template; the resulting URL will be encoded * @param urlTemplate a URL template; the resulting URL will be encoded
* @param uriVars zero or more URI variables * @param uriVars zero or more URI variables
* @return the created builder * @return the created builder
@ -154,7 +158,7 @@ public class MockServerHttpRequest extends AbstractServerHttpRequest {
} }
/** /**
* Create an HTTP HEAD builder with the given url. * HTTP HEAD variant. See {@link #get(String, Object...)} for general info.
* @param urlTemplate a URL template; the resulting URL will be encoded * @param urlTemplate a URL template; the resulting URL will be encoded
* @param uriVars zero or more URI variables * @param uriVars zero or more URI variables
* @return the created builder * @return the created builder
@ -164,7 +168,7 @@ public class MockServerHttpRequest extends AbstractServerHttpRequest {
} }
/** /**
* Create an HTTP POST builder with the given url. * HTTP POST variant. See {@link #get(String, Object...)} for general info.
* @param urlTemplate a URL template; the resulting URL will be encoded * @param urlTemplate a URL template; the resulting URL will be encoded
* @param uriVars zero or more URI variables * @param uriVars zero or more URI variables
* @return the created builder * @return the created builder
@ -174,7 +178,8 @@ public class MockServerHttpRequest extends AbstractServerHttpRequest {
} }
/** /**
* Create an HTTP PUT builder with the given url. * HTTP PUT variant. See {@link #get(String, Object...)} for general info.
* {@link BaseBuilder#queryParam queryParam} builder methods.
* @param urlTemplate a URL template; the resulting URL will be encoded * @param urlTemplate a URL template; the resulting URL will be encoded
* @param uriVars zero or more URI variables * @param uriVars zero or more URI variables
* @return the created builder * @return the created builder
@ -184,7 +189,7 @@ public class MockServerHttpRequest extends AbstractServerHttpRequest {
} }
/** /**
* Create an HTTP PATCH builder with the given url. * HTTP PATCH variant. See {@link #get(String, Object...)} for general info.
* @param urlTemplate a URL template; the resulting URL will be encoded * @param urlTemplate a URL template; the resulting URL will be encoded
* @param uriVars zero or more URI variables * @param uriVars zero or more URI variables
* @return the created builder * @return the created builder
@ -194,7 +199,7 @@ public class MockServerHttpRequest extends AbstractServerHttpRequest {
} }
/** /**
* Create an HTTP DELETE builder with the given url. * HTTP DELETE variant. See {@link #get(String, Object...)} for general info.
* @param urlTemplate a URL template; the resulting URL will be encoded * @param urlTemplate a URL template; the resulting URL will be encoded
* @param uriVars zero or more URI variables * @param uriVars zero or more URI variables
* @return the created builder * @return the created builder
@ -204,7 +209,7 @@ public class MockServerHttpRequest extends AbstractServerHttpRequest {
} }
/** /**
* Creates an HTTP OPTIONS builder with the given url. * HTTP OPTIONS variant. See {@link #get(String, Object...)} for general info.
* @param urlTemplate a URL template; the resulting URL will be encoded * @param urlTemplate a URL template; the resulting URL will be encoded
* @param uriVars zero or more URI variables * @param uriVars zero or more URI variables
* @return the created builder * @return the created builder
@ -225,6 +230,25 @@ public class MockServerHttpRequest extends AbstractServerHttpRequest {
*/ */
B contextPath(String contextPath); B contextPath(String contextPath);
/**
* Append the given query parameter to the existing query parameters.
* If no values are given, the resulting URI will contain the query
* parameter name only (i.e. {@code ?foo} instead of {@code ?foo=bar}).
* <p>The provided query name and values will be encoded.
* @param name the query parameter name
* @param values the query parameter values
* @return this UriComponentsBuilder
*/
B queryParam(String name, Object... values);
/**
* Add the given query parameters and values. The provided query name
* and corresponding values will be encoded.
* @param params the params
* @return this UriComponentsBuilder
*/
B queryParams(MultiValueMap<String, String> params);
/** /**
* Set the remote address to return. * Set the remote address to return.
*/ */
@ -375,6 +399,8 @@ public class MockServerHttpRequest extends AbstractServerHttpRequest {
@Nullable @Nullable
private String contextPath; private String contextPath;
private final UriComponentsBuilder queryParamsBuilder = UriComponentsBuilder.newInstance();
private final HttpHeaders headers = new HttpHeaders(); private final HttpHeaders headers = new HttpHeaders();
private final MultiValueMap<String, HttpCookie> cookies = new LinkedMultiValueMap<>(); private final MultiValueMap<String, HttpCookie> cookies = new LinkedMultiValueMap<>();
@ -397,6 +423,18 @@ public class MockServerHttpRequest extends AbstractServerHttpRequest {
return this; return this;
} }
@Override
public BodyBuilder queryParam(String name, Object... values) {
this.queryParamsBuilder.queryParam(name, values);
return this;
}
@Override
public BodyBuilder queryParams(MultiValueMap<String, String> params) {
this.queryParamsBuilder.queryParams(params);
return this;
}
@Override @Override
public BodyBuilder remoteAddress(InetSocketAddress remoteAddress) { public BodyBuilder remoteAddress(InetSocketAddress remoteAddress) {
this.remoteAddress = remoteAddress; this.remoteAddress = remoteAddress;
@ -506,7 +544,7 @@ public class MockServerHttpRequest extends AbstractServerHttpRequest {
@Override @Override
public MockServerHttpRequest body(Publisher<? extends DataBuffer> body) { public MockServerHttpRequest body(Publisher<? extends DataBuffer> body) {
applyCookiesIfNecessary(); applyCookiesIfNecessary();
return new MockServerHttpRequest(this.method, this.url, this.contextPath, return new MockServerHttpRequest(this.method, getUrlToUse(), this.contextPath,
this.headers, this.cookies, this.remoteAddress, this.sslInfo, body); this.headers, this.cookies, this.remoteAddress, this.sslInfo, body);
} }
@ -516,6 +554,17 @@ public class MockServerHttpRequest extends AbstractServerHttpRequest {
.forEach(cookie -> this.headers.add(HttpHeaders.COOKIE, cookie.toString())); .forEach(cookie -> this.headers.add(HttpHeaders.COOKIE, cookie.toString()));
} }
} }
private URI getUrlToUse() {
MultiValueMap<String, String> params =
this.queryParamsBuilder.buildAndExpand().encode().getQueryParams();
if (!params.isEmpty()) {
return UriComponentsBuilder.fromUri(this.url).queryParams(params).build(true).toUri();
}
return this.url;
}
} }
} }