Skip to content

Commit 2897b8d

Browse files
committed
Provide a preprocessor for modifying a request’s parameters
Closes gh-155
1 parent c4b7438 commit 2897b8d

File tree

5 files changed

+356
-3
lines changed

5 files changed

+356
-3
lines changed

docs/src/docs/asciidoc/customizing-requests-and-responses.adoc

+9
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,7 @@ the name is equal to any of the given header names.
109109
response where the name matches any of the given regular expression patterns.
110110

111111

112+
112113
[[customizing-requests-and-responses-preprocessors-replace-patterns]]
113114
==== Replacing patterns
114115

@@ -118,6 +119,14 @@ replaced.
118119

119120

120121

122+
[[customizing-requests-and-responses-preprocessors-modify-request-parameters]]
123+
==== Modifying request parameters
124+
125+
`modifyParameters` on `Preprocessors` can be used to add, set, and remove request
126+
parameters.
127+
128+
129+
121130
[[customizing-requests-and-responses-preprocessors-modify-uris]]
122131
==== Modifying URIs
123132

spring-restdocs-core/src/main/java/org/springframework/restdocs/operation/OperationRequestFactory.java

+18-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2014-2015 the original author or authors.
2+
* Copyright 2014-2016 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -72,7 +72,7 @@ public OperationRequest createFrom(OperationRequest original, byte[] newContent)
7272
* @param original The original request
7373
* @param newHeaders The new headers
7474
*
75-
* @return The new request with the new content
75+
* @return The new request with the new headers
7676
*/
7777
public OperationRequest createFrom(OperationRequest original,
7878
HttpHeaders newHeaders) {
@@ -81,6 +81,22 @@ public OperationRequest createFrom(OperationRequest original,
8181
original.getParts());
8282
}
8383

84+
/**
85+
* Creates a new {@code OperationRequest} based on the given {@code original} but with
86+
* the given {@code newParameters}.
87+
*
88+
* @param original The original request
89+
* @param newParameters The new parameters
90+
*
91+
* @return The new request with the new parameters
92+
*/
93+
public OperationRequest createFrom(OperationRequest original,
94+
Parameters newParameters) {
95+
return new StandardOperationRequest(original.getUri(), original.getMethod(),
96+
original.getContent(), original.getHeaders(), newParameters,
97+
original.getParts());
98+
}
99+
84100
private HttpHeaders augmentHeaders(HttpHeaders originalHeaders, URI uri,
85101
byte[] content) {
86102
return new HttpHeadersHelper(originalHeaders)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,181 @@
1+
/*
2+
* Copyright 2012-2016 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.springframework.restdocs.operation.preprocess;
18+
19+
import java.util.ArrayList;
20+
import java.util.Arrays;
21+
import java.util.List;
22+
23+
import org.springframework.restdocs.operation.OperationRequest;
24+
import org.springframework.restdocs.operation.OperationRequestFactory;
25+
import org.springframework.restdocs.operation.Parameters;
26+
import org.springframework.util.Assert;
27+
28+
/**
29+
* An {@link OperationPreprocessor} that can be used to modify a request's
30+
* {@link OperationRequest#getParameters()} by adding, setting, and removing parameters.
31+
*
32+
* @author Andy Wilkinson
33+
* @since 1.1.0
34+
*/
35+
public final class ParametersModifyingOperationPreprocessor
36+
extends OperationPreprocessorAdapter {
37+
38+
private final OperationRequestFactory requestFactory = new OperationRequestFactory();
39+
40+
private final List<Modification> modifications = new ArrayList<>();
41+
42+
@Override
43+
public OperationRequest preprocess(OperationRequest request) {
44+
Parameters parameters = new Parameters();
45+
parameters.putAll(request.getParameters());
46+
for (Modification modification : this.modifications) {
47+
modification.apply(parameters);
48+
}
49+
return this.requestFactory.createFrom(request, parameters);
50+
}
51+
52+
/**
53+
* Adds a parameter with the given {@code name} and {@code value}.
54+
*
55+
* @param name the name
56+
* @param value the value
57+
* @return {@code this}
58+
*/
59+
public ParametersModifyingOperationPreprocessor add(String name, String value) {
60+
this.modifications.add(new AddParameterModification(name, value));
61+
return this;
62+
}
63+
64+
/**
65+
* Sets the parameter with the given {@code name} to have the given {@code values}.
66+
*
67+
* @param name the name
68+
* @param values the values
69+
* @return {@code this}
70+
*/
71+
public ParametersModifyingOperationPreprocessor set(String name, String... values) {
72+
Assert.notEmpty(values, "At least one value must be provided");
73+
this.modifications.add(new SetParameterModification(name, Arrays.asList(values)));
74+
return this;
75+
}
76+
77+
/**
78+
* Removes the parameter with the given {@code name}.
79+
*
80+
* @param name the name of the parameter
81+
* @return {@code this}
82+
*/
83+
public ParametersModifyingOperationPreprocessor remove(String name) {
84+
this.modifications.add(new RemoveParameterModification(name));
85+
return this;
86+
}
87+
88+
/**
89+
* Removes the given {@code value} from the parameter with the given {@code name}.
90+
*
91+
* @param name the name
92+
* @param value the value
93+
* @return {@code this}
94+
*/
95+
public ParametersModifyingOperationPreprocessor remove(String name, String value) {
96+
this.modifications.add(new RemoveValueParameterModification(name, value));
97+
return this;
98+
}
99+
100+
private interface Modification {
101+
102+
void apply(Parameters parameters);
103+
104+
}
105+
106+
private static final class AddParameterModification implements Modification {
107+
108+
private final String name;
109+
110+
private final String value;
111+
112+
private AddParameterModification(String name, String value) {
113+
this.name = name;
114+
this.value = value;
115+
}
116+
117+
@Override
118+
public void apply(Parameters parameters) {
119+
parameters.add(this.name, this.value);
120+
}
121+
122+
}
123+
124+
private static final class SetParameterModification implements Modification {
125+
126+
private final String name;
127+
128+
private final List<String> values;
129+
130+
private SetParameterModification(String name, List<String> values) {
131+
this.name = name;
132+
this.values = values;
133+
}
134+
135+
@Override
136+
public void apply(Parameters parameters) {
137+
parameters.put(this.name, this.values);
138+
}
139+
140+
}
141+
142+
private static final class RemoveParameterModification implements Modification {
143+
144+
private final String name;
145+
146+
private RemoveParameterModification(String name) {
147+
this.name = name;
148+
}
149+
150+
@Override
151+
public void apply(Parameters parameters) {
152+
parameters.remove(this.name);
153+
}
154+
155+
}
156+
157+
private static final class RemoveValueParameterModification implements Modification {
158+
159+
private final String name;
160+
161+
private final String value;
162+
163+
private RemoveValueParameterModification(String name, String value) {
164+
this.name = name;
165+
this.value = value;
166+
}
167+
168+
@Override
169+
public void apply(Parameters parameters) {
170+
List<String> values = parameters.get(this.name);
171+
if (values != null) {
172+
values.remove(this.value);
173+
if (values.isEmpty()) {
174+
parameters.remove(this.name);
175+
}
176+
}
177+
}
178+
179+
}
180+
181+
}

spring-restdocs-core/src/main/java/org/springframework/restdocs/operation/preprocess/Preprocessors.java

+12-1
Original file line numberDiff line numberDiff line change
@@ -127,7 +127,7 @@ public static OperationPreprocessor maskLinks(String mask) {
127127

128128
/**
129129
* Returns an {@code OperationPreprocessor} that will modify the content of the
130-
* request or response by replacing occurences of the given {@code pattern} with the
130+
* request or response by replacing occurrences of the given {@code pattern} with the
131131
* given {@code replacement}.
132132
*
133133
* @param pattern the pattern
@@ -140,4 +140,15 @@ public static OperationPreprocessor replacePattern(Pattern pattern,
140140
new PatternReplacingContentModifier(pattern, replacement));
141141
}
142142

143+
/**
144+
* Returns a {@code ParametersModifyingOperationPreprocessor} that can then be
145+
* configured to modify the parameters of the request.
146+
*
147+
* @return the preprocessor
148+
* @since 1.1.0
149+
*/
150+
public static ParametersModifyingOperationPreprocessor modifyParameters() {
151+
return new ParametersModifyingOperationPreprocessor();
152+
}
153+
143154
}

0 commit comments

Comments
 (0)