Skip to content

Commit 160ff07

Browse files
author
Paweł Adamski
authored
Allow additional parameters in query and form (#25)
* Allow additional parameters in query and form * Raname Additional to Extra add separate method to control form parameters * By default form and query parameters should be disallowed. * rename matchesAndAllowRedundantParameters to matchesAndAllowExtraParameters * fix unit tests * bump up version to 1.8.0
1 parent d0ab84c commit 160ff07

File tree

13 files changed

+401
-46
lines changed

13 files changed

+401
-46
lines changed

README.md

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ HttpClientMock is a library for mocking [Apache HttpClient](https://hc.apache.or
99
* [Request matching](#request-matching)
1010
* [Define response](#define-response)
1111
* [Verification](#verification)
12+
* [Matching query and form parameters](#matching-query-and-form-parameters)
1213
* [Debugging](#debugging)
1314
* [Example 1](#example-1)
1415
* [Example 2](#example-2)
@@ -217,6 +218,35 @@ httpClientMock.verify().get().called(greaterThanOrEqualTo(1));
217218
218219
```
219220

221+
## Matching query and form parameters
222+
There are two methods that control HttpClientMock behaviour when request contains extra form
223+
or query parameters:
224+
- `withExtraParameters`: allows request to contain extra query parameters
225+
- `withoutExtraParameters`: disallows request to contain extra query parameters
226+
- `withExtraFormParameters`: allows request to contain extra form parameters
227+
- `withoutExtraFormParameters`: disallows request to contain extra form parameters
228+
229+
Examples:
230+
```
231+
httpClientMock.onPost("/login")
232+
.withParameter("user","John")
233+
.withoutExtraParameters()
234+
.doReturn("ok");
235+
```
236+
Above condition will not match request `http://www.example.com/login?user=John&password=secret` because
237+
it contains extra parameter `password`.
238+
239+
```
240+
httpClientMock.onPost("/login")
241+
.withParameter("user","John")
242+
.withExtraParameters()
243+
.doReturn("ok");
244+
```
245+
Above condition will match request `http://www.example.com/login?user=John&password=secret` although
246+
it contains extra parameter `password`.
247+
248+
By default HttpClientMock matches requests with extra form and query parameters.
249+
220250
## Debugging
221251
HttpClientMock can help you to debug your code by displaying information which matchers matched your request.
222252
You can use `HttpClientMock#debugOn` to turn it on and `HttpClientMock#debugOff` to turn it off.
@@ -276,6 +306,10 @@ httpClientMock.verify().get("/login?user=john").called();
276306

277307
## Release notes
278308

309+
1.8.0
310+
- Added methods {`withExtraParameters`, `withoutExtraParameters`, `withExtraFormParameters`, `withoutExtraFormParameters`} to better control form and query parameters matching.
311+
*WARNING* Breaking changes: Since this version by default HttpClientMock matches requests with extra form and query parameters.
312+
279313
1.7.0
280314
- Added methods (`withFormParameter`, `withFormParameters`) for matching form parameters (URL encode parameters).
281315
- Added action (`doReturnFormParams`) which return response with body containing provided form parameters.

pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
<groupId>com.github.paweladamski</groupId>
66
<artifactId>HttpClientMock</artifactId>
7-
<version>1.7.0</version>
7+
<version>1.8.0</version>
88
<packaging>jar</packaging>
99

1010
<name>${project.groupId}:${project.artifactId}</name>

src/main/java/com/github/paweladamski/httpclientmock/HttpClientMockBuilder.java

Lines changed: 54 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -93,9 +93,8 @@ public HttpClientMockBuilder withParameter(String name, Matcher<String> matcher)
9393
}
9494

9595
/**
96-
* Request body must contain the given URL-encoded form parameter (typically
97-
* found in POST requests). Alternatively, parameters may be specified all at
98-
* once using {@link #withFormParameters(ParametersMatcher)}.
96+
* Request body must contain the given URL-encoded form parameter (typically found in POST requests). Alternatively, parameters may be specified all at once
97+
* using {@link #withFormParameters(ParametersMatcher)}.
9998
*
10099
* @param name parameter name
101100
* @param value expected parameter value
@@ -106,9 +105,8 @@ public HttpClientMockBuilder withFormParameter(String name, String value) {
106105
}
107106

108107
/**
109-
* Request body must contain the given URL-encoded form parameter (typically
110-
* found in POST requests). Alternatively, parameters may be specified all at
111-
* once using {@link #withFormParameters(ParametersMatcher)}.
108+
* Request body must contain the given URL-encoded form parameter (typically found in POST requests). Alternatively, parameters may be specified all at once
109+
* using {@link #withFormParameters(ParametersMatcher)}.
112110
*
113111
* @param name parameter name
114112
* @param matcher parameter value matcher
@@ -118,12 +116,11 @@ public HttpClientMockBuilder withFormParameter(String name, Matcher<String> matc
118116
ruleBuilder.addFormParameterCondition(name, matcher);
119117
return this;
120118
}
121-
119+
122120
/**
123-
* Request body must contain the given URL-encoded form parameters (typically
124-
* used in POST requests). Alternatively, parameters may be specified
125-
* individually using {@link #withFormParameter(String, Matcher)}.
126-
*
121+
* Request body must contain the given URL-encoded form parameters (typically used in POST requests). Alternatively, parameters may be specified individually
122+
* using {@link #withFormParameter(String, Matcher)}.
123+
*
127124
* @param parameters the parameters
128125
* @return condition builder
129126
*/
@@ -186,6 +183,46 @@ public HttpClientMockBuilder withPath(Matcher<String> matcher) {
186183
return this;
187184
}
188185

186+
/**
187+
* Allows extra parameters (not defined in condition) in query.
188+
*
189+
* @return condition builder
190+
*/
191+
public HttpClientMockBuilder withExtraParameters() {
192+
ruleBuilder.setAllowExtraParameters(true);
193+
return this;
194+
}
195+
196+
/**
197+
* Disallows extra parameters (not defined in condition) in query.
198+
*
199+
* @return condition builder
200+
*/
201+
public HttpClientMockBuilder withoutExtraParameters() {
202+
ruleBuilder.setAllowExtraParameters(false);
203+
return this;
204+
}
205+
206+
/**
207+
* Allows extra parameters (not defined in condition) in form.
208+
*
209+
* @return condition builder
210+
*/
211+
public HttpClientMockBuilder withExtraFormParameters() {
212+
ruleBuilder.setAllowExtraFormParameters(true);
213+
return this;
214+
}
215+
216+
/**
217+
* Disallows extra parameters (not defined in condition) in form.
218+
*
219+
* @return condition builder
220+
*/
221+
public HttpClientMockBuilder withoutExtraFormParameters() {
222+
ruleBuilder.setAllowExtraFormParameters(false);
223+
return this;
224+
}
225+
189226
/**
190227
* Adds custom action.
191228
*
@@ -311,7 +348,8 @@ public HttpClientResponseBuilder doReturnXML(String response, Charset charset) {
311348
}
312349

313350
/**
314-
* Adds action which returns provided URL-encoded parameter response in UTF-8 and status 200. Additionally it sets "Content-type" header to "application/x-www-form-urlencoded".
351+
* Adds action which returns provided URL-encoded parameter response in UTF-8 and status 200. Additionally it sets "Content-type" header to
352+
* "application/x-www-form-urlencoded".
315353
*
316354
* @param parameters parameters to return
317355
* @return response builder
@@ -321,12 +359,15 @@ public HttpClientResponseBuilder doReturnFormParams(Collection<NameValuePair> pa
321359
}
322360

323361
/**
324-
* Adds action which returns provided URL-encoded parameter response in provided charset and status 200. Additionally it sets "Content-type" header to "application/x-www-form-urlencoded".
362+
* Adds action which returns provided URL-encoded parameter response in provided charset and status 200. Additionally it sets "Content-type" header to
363+
* "application/x-www-form-urlencoded".
325364
*
326365
* @param parameters parameters to return
327366
* @return response builder
328367
*/
329368
public HttpClientResponseBuilder doReturnFormParams(Collection<NameValuePair> parameters, Charset charset) {
330369
return responseBuilder.doReturnFormParams(parameters, charset);
331370
}
371+
372+
332373
}

src/main/java/com/github/paweladamski/httpclientmock/HttpClientResponseBuilder.java

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,8 @@
1414
import java.nio.charset.Charset;
1515
import java.nio.charset.StandardCharsets;
1616
import java.util.Collection;
17-
import org.apache.http.entity.ContentType;
1817
import org.apache.http.NameValuePair;
18+
import org.apache.http.entity.ContentType;
1919

2020
public class HttpClientResponseBuilder {
2121

@@ -194,19 +194,21 @@ public HttpClientResponseBuilder doReturnXML(String response) {
194194
public HttpClientResponseBuilder doReturnXML(String response, Charset charset) {
195195
return doReturn(response, charset, APPLICATION_XML);
196196
}
197-
197+
198198
/**
199-
* Adds action which returns provided name/value pairs as URL-encoded form response in UTF-8 and status 200. Additionally it sets "Content-type" header to "application/x-www-form-urlencoded".
199+
* Adds action which returns provided name/value pairs as URL-encoded form response in UTF-8 and status 200. Additionally it sets "Content-type" header to
200+
* "application/x-www-form-urlencoded".
200201
*
201202
* @param formParameters the parameters to include in the response
202203
* @return response builder
203204
*/
204205
public HttpClientResponseBuilder doReturnFormParams(Collection<NameValuePair> formParameters) {
205206
return doReturnFormParams(formParameters, StandardCharsets.UTF_8);
206207
}
207-
208+
208209
/**
209-
* Adds action which returns provided name/value pairs as URL-encoded form response and status 200. Additionally it sets "Content-type" header to "application/x-www-form-urlencoded".
210+
* Adds action which returns provided name/value pairs as URL-encoded form response and status 200. Additionally it sets "Content-type" header to
211+
* "application/x-www-form-urlencoded".
210212
*
211213
* @param formParameters the parameters to include in the response
212214
* @return response builder

src/main/java/com/github/paweladamski/httpclientmock/HttpClientVerifyBuilder.java

Lines changed: 43 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@
77
import com.github.paweladamski.httpclientmock.condition.HeaderCondition;
88
import com.github.paweladamski.httpclientmock.matchers.ParametersMatcher;
99
import java.util.List;
10-
import java.util.Map;
1110
import org.hamcrest.Matcher;
1211

1312
public class HttpClientVerifyBuilder {
@@ -93,7 +92,7 @@ public HttpClientVerifyBuilder withParameter(String name, Matcher<String> matche
9392
*
9493
* @param name parameter name
9594
* @param value expected parameter value
96-
* @return condition builder
95+
* @return verification builder
9796
*/
9897
public HttpClientVerifyBuilder withFormParameter(String name, String value) {
9998
return withFormParameter(name, equalTo(value));
@@ -105,7 +104,7 @@ public HttpClientVerifyBuilder withFormParameter(String name, String value) {
105104
*
106105
* @param name parameter name
107106
* @param matcher parameter value matcher
108-
* @return condition builder
107+
* @return verification builder
109108
*/
110109
public HttpClientVerifyBuilder withFormParameter(String name, Matcher<String> matcher) {
111110
ruleBuilder.addFormParameterCondition(name, matcher);
@@ -178,6 +177,46 @@ public HttpClientVerifyBuilder withPath(Matcher<String> matcher) {
178177
return this;
179178
}
180179

180+
/**
181+
* Allows extra parameters (not defined in condition) in query.
182+
*
183+
* @return verification builder
184+
*/
185+
public HttpClientVerifyBuilder withExtraParameters() {
186+
ruleBuilder.setAllowExtraParameters(true);
187+
return this;
188+
}
189+
190+
/**
191+
* Disallows extra parameters (not defined in condition) in query.
192+
*
193+
* @return condition builder
194+
*/
195+
public HttpClientVerifyBuilder withoutExtraParameters() {
196+
ruleBuilder.setAllowExtraParameters(false);
197+
return this;
198+
}
199+
200+
/**
201+
* Allows extra parameters (not defined in condition) in form.
202+
*
203+
* @return verification builder
204+
*/
205+
public HttpClientVerifyBuilder withExtraFormParameters() {
206+
ruleBuilder.setAllowExtraFormParameters(true);
207+
return this;
208+
}
209+
210+
/**
211+
* Disallows extra parameters (not defined in condition) in form.
212+
*
213+
* @return verification builder
214+
*/
215+
public HttpClientVerifyBuilder withoutExtraFormParameters() {
216+
ruleBuilder.setAllowExtraFormParameters(false);
217+
return this;
218+
}
219+
181220
/**
182221
* Verifies if there were no request matching defined conditions.
183222
*/
@@ -216,4 +255,5 @@ public void called(Matcher<Integer> numberOfCalls) {
216255
throw new IllegalStateException(String.format("Expected %s calls, but found %s.", numberOfCalls, matchingCalls));
217256
}
218257
}
258+
219259
}

src/main/java/com/github/paweladamski/httpclientmock/RuleBuilder.java

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,12 +20,16 @@ class RuleBuilder {
2020
this.urlConditions = new UrlParser().parse(buildFinalUrl(defaultHost, url));
2121
addCondition(new HttpMethodCondition(method));
2222
addCondition(formParametersCondition);
23+
setAllowExtraParameters(true);
24+
setAllowExtraFormParameters(true);
2325
}
2426

2527
RuleBuilder(String method) {
2628
this.urlConditions = new UrlConditions();
2729
addCondition(new HttpMethodCondition(method));
2830
addCondition(formParametersCondition);
31+
setAllowExtraParameters(true);
32+
setAllowExtraFormParameters(true);
2933
}
3034

3135
private String buildFinalUrl(String defaultHost, String url) {
@@ -36,8 +40,6 @@ private String buildFinalUrl(String defaultHost, String url) {
3640
}
3741
}
3842

39-
40-
4143
void addAction(Action o) {
4244
actions.add(o);
4345
}
@@ -83,4 +85,12 @@ Rule toRule() {
8385
return new Rule(urlConditions, conditions, actions);
8486
}
8587

88+
public void setAllowExtraParameters(boolean allowExtraParameters) {
89+
urlConditions.getUrlQueryConditions().setAllowExtraParameters(allowExtraParameters);
90+
}
91+
92+
public void setAllowExtraFormParameters(boolean allowExtraFormParameters) {
93+
formParametersCondition.setAllowExtraParameters(allowExtraFormParameters);
94+
}
95+
8696
}

src/main/java/com/github/paweladamski/httpclientmock/condition/UrlEncodedFormCondition.java

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,12 +15,17 @@
1515
*/
1616
public class UrlEncodedFormCondition implements Condition {
1717

18-
private final ParametersMatcher expectedParameters = new ParametersMatcher();
18+
private ParametersMatcher expectedParameters = new ParametersMatcher();
19+
private boolean allowExtraParameters = false;
1920

2021
@Override
2122
public boolean matches(Request r) {
2223
List<NameValuePair> actualParameters = new UrlEncodedFormParser().parse(r);
23-
return expectedParameters.matches(actualParameters);
24+
if (allowExtraParameters) {
25+
return expectedParameters.matchesAndAllowExtraParameters(actualParameters);
26+
} else {
27+
return expectedParameters.matches(actualParameters);
28+
}
2429
}
2530

2631
/**
@@ -56,11 +61,14 @@ public void debug(Request r, Debugger debugger) {
5661
boolean matches = expectedParameters.matches(param.getName(), param.getValue());
5762
String message = "form parameter " + param.getName() + " is " + expectedParameters.get(param.getName()).describe();
5863
debugger.message(matches, message);
59-
} else {
64+
} else if (!allowExtraParameters) {
6065
String message = "form parameter " + param.getName() + " was not expected to be in the request";
6166
debugger.message(false, message);
6267
}
6368
}
6469
}
6570

71+
public void setAllowExtraParameters(boolean allowExtraParameters) {
72+
this.allowExtraParameters = allowExtraParameters;
73+
}
6674
}

src/main/java/com/github/paweladamski/httpclientmock/matchers/ParametersMatcher.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ public void putAll(ParametersMatcher parametersMatcher) {
3434
}
3535
}
3636

37-
public boolean matchesAndAllowRedundantParameters(List<NameValuePair> actual) {
37+
public boolean matchesAndAllowExtraParameters(List<NameValuePair> actual) {
3838
return findMissingParameters(actual).isEmpty()
3939
&& allParametersHaveMatchingValue(actual);
4040
}

0 commit comments

Comments
 (0)