Skip to content

Commit

Permalink
Allow additional parameters in query and form (#25)
Browse files Browse the repository at this point in the history
* 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
  • Loading branch information
Paweł Adamski authored Jul 5, 2020
1 parent d0ab84c commit 160ff07
Show file tree
Hide file tree
Showing 13 changed files with 401 additions and 46 deletions.
34 changes: 34 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ HttpClientMock is a library for mocking [Apache HttpClient](https://hc.apache.or
* [Request matching](#request-matching)
* [Define response](#define-response)
* [Verification](#verification)
* [Matching query and form parameters](#matching-query-and-form-parameters)
* [Debugging](#debugging)
* [Example 1](#example-1)
* [Example 2](#example-2)
Expand Down Expand Up @@ -217,6 +218,35 @@ httpClientMock.verify().get().called(greaterThanOrEqualTo(1));
```

## Matching query and form parameters
There are two methods that control HttpClientMock behaviour when request contains extra form
or query parameters:
- `withExtraParameters`: allows request to contain extra query parameters
- `withoutExtraParameters`: disallows request to contain extra query parameters
- `withExtraFormParameters`: allows request to contain extra form parameters
- `withoutExtraFormParameters`: disallows request to contain extra form parameters

Examples:
```
httpClientMock.onPost("/login")
.withParameter("user","John")
.withoutExtraParameters()
.doReturn("ok");
```
Above condition will not match request `http://www.example.com/login?user=John&password=secret` because
it contains extra parameter `password`.

```
httpClientMock.onPost("/login")
.withParameter("user","John")
.withExtraParameters()
.doReturn("ok");
```
Above condition will match request `http://www.example.com/login?user=John&password=secret` although
it contains extra parameter `password`.

By default HttpClientMock matches requests with extra form and query parameters.

## Debugging
HttpClientMock can help you to debug your code by displaying information which matchers matched your request.
You can use `HttpClientMock#debugOn` to turn it on and `HttpClientMock#debugOff` to turn it off.
Expand Down Expand Up @@ -276,6 +306,10 @@ httpClientMock.verify().get("/login?user=john").called();

## Release notes

1.8.0
- Added methods {`withExtraParameters`, `withoutExtraParameters`, `withExtraFormParameters`, `withoutExtraFormParameters`} to better control form and query parameters matching.
*WARNING* Breaking changes: Since this version by default HttpClientMock matches requests with extra form and query parameters.

1.7.0
- Added methods (`withFormParameter`, `withFormParameters`) for matching form parameters (URL encode parameters).
- Added action (`doReturnFormParams`) which return response with body containing provided form parameters.
Expand Down
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

<groupId>com.github.paweladamski</groupId>
<artifactId>HttpClientMock</artifactId>
<version>1.7.0</version>
<version>1.8.0</version>
<packaging>jar</packaging>

<name>${project.groupId}:${project.artifactId}</name>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -93,9 +93,8 @@ public HttpClientMockBuilder withParameter(String name, Matcher<String> matcher)
}

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

/**
* Request body must contain the given URL-encoded form parameter (typically
* found in POST requests). Alternatively, parameters may be specified all at
* once using {@link #withFormParameters(ParametersMatcher)}.
* Request body must contain the given URL-encoded form parameter (typically found in POST requests). Alternatively, parameters may be specified all at once
* using {@link #withFormParameters(ParametersMatcher)}.
*
* @param name parameter name
* @param matcher parameter value matcher
Expand All @@ -118,12 +116,11 @@ public HttpClientMockBuilder withFormParameter(String name, Matcher<String> matc
ruleBuilder.addFormParameterCondition(name, matcher);
return this;
}

/**
* Request body must contain the given URL-encoded form parameters (typically
* used in POST requests). Alternatively, parameters may be specified
* individually using {@link #withFormParameter(String, Matcher)}.
*
* Request body must contain the given URL-encoded form parameters (typically used in POST requests). Alternatively, parameters may be specified individually
* using {@link #withFormParameter(String, Matcher)}.
*
* @param parameters the parameters
* @return condition builder
*/
Expand Down Expand Up @@ -186,6 +183,46 @@ public HttpClientMockBuilder withPath(Matcher<String> matcher) {
return this;
}

/**
* Allows extra parameters (not defined in condition) in query.
*
* @return condition builder
*/
public HttpClientMockBuilder withExtraParameters() {
ruleBuilder.setAllowExtraParameters(true);
return this;
}

/**
* Disallows extra parameters (not defined in condition) in query.
*
* @return condition builder
*/
public HttpClientMockBuilder withoutExtraParameters() {
ruleBuilder.setAllowExtraParameters(false);
return this;
}

/**
* Allows extra parameters (not defined in condition) in form.
*
* @return condition builder
*/
public HttpClientMockBuilder withExtraFormParameters() {
ruleBuilder.setAllowExtraFormParameters(true);
return this;
}

/**
* Disallows extra parameters (not defined in condition) in form.
*
* @return condition builder
*/
public HttpClientMockBuilder withoutExtraFormParameters() {
ruleBuilder.setAllowExtraFormParameters(false);
return this;
}

/**
* Adds custom action.
*
Expand Down Expand Up @@ -311,7 +348,8 @@ public HttpClientResponseBuilder doReturnXML(String response, Charset charset) {
}

/**
* 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".
* 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".
*
* @param parameters parameters to return
* @return response builder
Expand All @@ -321,12 +359,15 @@ public HttpClientResponseBuilder doReturnFormParams(Collection<NameValuePair> pa
}

/**
* 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".
* 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".
*
* @param parameters parameters to return
* @return response builder
*/
public HttpClientResponseBuilder doReturnFormParams(Collection<NameValuePair> parameters, Charset charset) {
return responseBuilder.doReturnFormParams(parameters, charset);
}


}
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.util.Collection;
import org.apache.http.entity.ContentType;
import org.apache.http.NameValuePair;
import org.apache.http.entity.ContentType;

public class HttpClientResponseBuilder {

Expand Down Expand Up @@ -194,19 +194,21 @@ public HttpClientResponseBuilder doReturnXML(String response) {
public HttpClientResponseBuilder doReturnXML(String response, Charset charset) {
return doReturn(response, charset, APPLICATION_XML);
}

/**
* 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".
* 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".
*
* @param formParameters the parameters to include in the response
* @return response builder
*/
public HttpClientResponseBuilder doReturnFormParams(Collection<NameValuePair> formParameters) {
return doReturnFormParams(formParameters, StandardCharsets.UTF_8);
}

/**
* 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".
* 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".
*
* @param formParameters the parameters to include in the response
* @return response builder
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
import com.github.paweladamski.httpclientmock.condition.HeaderCondition;
import com.github.paweladamski.httpclientmock.matchers.ParametersMatcher;
import java.util.List;
import java.util.Map;
import org.hamcrest.Matcher;

public class HttpClientVerifyBuilder {
Expand Down Expand Up @@ -93,7 +92,7 @@ public HttpClientVerifyBuilder withParameter(String name, Matcher<String> matche
*
* @param name parameter name
* @param value expected parameter value
* @return condition builder
* @return verification builder
*/
public HttpClientVerifyBuilder withFormParameter(String name, String value) {
return withFormParameter(name, equalTo(value));
Expand All @@ -105,7 +104,7 @@ public HttpClientVerifyBuilder withFormParameter(String name, String value) {
*
* @param name parameter name
* @param matcher parameter value matcher
* @return condition builder
* @return verification builder
*/
public HttpClientVerifyBuilder withFormParameter(String name, Matcher<String> matcher) {
ruleBuilder.addFormParameterCondition(name, matcher);
Expand Down Expand Up @@ -178,6 +177,46 @@ public HttpClientVerifyBuilder withPath(Matcher<String> matcher) {
return this;
}

/**
* Allows extra parameters (not defined in condition) in query.
*
* @return verification builder
*/
public HttpClientVerifyBuilder withExtraParameters() {
ruleBuilder.setAllowExtraParameters(true);
return this;
}

/**
* Disallows extra parameters (not defined in condition) in query.
*
* @return condition builder
*/
public HttpClientVerifyBuilder withoutExtraParameters() {
ruleBuilder.setAllowExtraParameters(false);
return this;
}

/**
* Allows extra parameters (not defined in condition) in form.
*
* @return verification builder
*/
public HttpClientVerifyBuilder withExtraFormParameters() {
ruleBuilder.setAllowExtraFormParameters(true);
return this;
}

/**
* Disallows extra parameters (not defined in condition) in form.
*
* @return verification builder
*/
public HttpClientVerifyBuilder withoutExtraFormParameters() {
ruleBuilder.setAllowExtraFormParameters(false);
return this;
}

/**
* Verifies if there were no request matching defined conditions.
*/
Expand Down Expand Up @@ -216,4 +255,5 @@ public void called(Matcher<Integer> numberOfCalls) {
throw new IllegalStateException(String.format("Expected %s calls, but found %s.", numberOfCalls, matchingCalls));
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,16 @@ class RuleBuilder {
this.urlConditions = new UrlParser().parse(buildFinalUrl(defaultHost, url));
addCondition(new HttpMethodCondition(method));
addCondition(formParametersCondition);
setAllowExtraParameters(true);
setAllowExtraFormParameters(true);
}

RuleBuilder(String method) {
this.urlConditions = new UrlConditions();
addCondition(new HttpMethodCondition(method));
addCondition(formParametersCondition);
setAllowExtraParameters(true);
setAllowExtraFormParameters(true);
}

private String buildFinalUrl(String defaultHost, String url) {
Expand All @@ -36,8 +40,6 @@ private String buildFinalUrl(String defaultHost, String url) {
}
}



void addAction(Action o) {
actions.add(o);
}
Expand Down Expand Up @@ -83,4 +85,12 @@ Rule toRule() {
return new Rule(urlConditions, conditions, actions);
}

public void setAllowExtraParameters(boolean allowExtraParameters) {
urlConditions.getUrlQueryConditions().setAllowExtraParameters(allowExtraParameters);
}

public void setAllowExtraFormParameters(boolean allowExtraFormParameters) {
formParametersCondition.setAllowExtraParameters(allowExtraFormParameters);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,17 @@
*/
public class UrlEncodedFormCondition implements Condition {

private final ParametersMatcher expectedParameters = new ParametersMatcher();
private ParametersMatcher expectedParameters = new ParametersMatcher();
private boolean allowExtraParameters = false;

@Override
public boolean matches(Request r) {
List<NameValuePair> actualParameters = new UrlEncodedFormParser().parse(r);
return expectedParameters.matches(actualParameters);
if (allowExtraParameters) {
return expectedParameters.matchesAndAllowExtraParameters(actualParameters);
} else {
return expectedParameters.matches(actualParameters);
}
}

/**
Expand Down Expand Up @@ -56,11 +61,14 @@ public void debug(Request r, Debugger debugger) {
boolean matches = expectedParameters.matches(param.getName(), param.getValue());
String message = "form parameter " + param.getName() + " is " + expectedParameters.get(param.getName()).describe();
debugger.message(matches, message);
} else {
} else if (!allowExtraParameters) {
String message = "form parameter " + param.getName() + " was not expected to be in the request";
debugger.message(false, message);
}
}
}

public void setAllowExtraParameters(boolean allowExtraParameters) {
this.allowExtraParameters = allowExtraParameters;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ public void putAll(ParametersMatcher parametersMatcher) {
}
}

public boolean matchesAndAllowRedundantParameters(List<NameValuePair> actual) {
public boolean matchesAndAllowExtraParameters(List<NameValuePair> actual) {
return findMissingParameters(actual).isEmpty()
&& allParametersHaveMatchingValue(actual);
}
Expand Down
Loading

0 comments on commit 160ff07

Please sign in to comment.