-
Notifications
You must be signed in to change notification settings - Fork 86
Replacement for binary content of multipart requests #369
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
package capital.scalable.restdocs.response; | ||
|
||
import org.springframework.http.HttpHeaders; | ||
import org.springframework.http.MediaType; | ||
import org.springframework.restdocs.operation.OperationRequest; | ||
import org.springframework.restdocs.operation.OperationRequestFactory; | ||
import org.springframework.restdocs.operation.OperationRequestPart; | ||
import org.springframework.restdocs.operation.OperationRequestPartFactory; | ||
import org.springframework.restdocs.operation.preprocess.OperationPreprocessorAdapter; | ||
|
||
import java.util.List; | ||
|
||
import static java.nio.charset.StandardCharsets.UTF_8; | ||
import static java.util.stream.Collectors.toList; | ||
|
||
public class MultipartContentOperationPreprocessor extends OperationPreprocessorAdapter { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is there a reason why you are extending There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I extending OperationPreprocessorAdapter because ContentModifier takes original content (look at ContentModifyingOperationPreprocessor. In case of multipart/form-data content is empty byte array and all binary data holds in There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Thanks, this makes sense. |
||
private static final byte[] BINARY_REPLACEMENT = "<binary>".getBytes(UTF_8); | ||
|
||
private final OperationRequestPartFactory partFactory = new OperationRequestPartFactory(); | ||
private final OperationRequestFactory requestFactory = new OperationRequestFactory(); | ||
|
||
@Override | ||
public OperationRequest preprocess(OperationRequest request) { | ||
if (isMultipart(request)) { | ||
List<OperationRequestPart> parts = request.getParts().stream() | ||
.map(this::replaceBinary) | ||
.collect(toList()); | ||
return requestFactory.create(request.getUri(), | ||
request.getMethod(), request.getContent(), request.getHeaders(), request.getParameters() | ||
, parts); | ||
} | ||
return request; | ||
} | ||
|
||
private boolean isMultipart(OperationRequest request) { | ||
List<String> contentTypes = request.getHeaders().get(HttpHeaders.CONTENT_TYPE); | ||
return contentTypes != null && contentTypes.contains(MediaType.MULTIPART_FORM_DATA_VALUE); | ||
} | ||
|
||
private OperationRequestPart replaceBinary(OperationRequestPart part) { | ||
return partFactory.create(part.getName(), part.getSubmittedFileName() | ||
, BINARY_REPLACEMENT, part.getHeaders()); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,79 @@ | ||
package capital.scalable.restdocs.response; | ||
|
||
import org.junit.Before; | ||
import org.junit.Test; | ||
import org.springframework.http.HttpHeaders; | ||
import org.springframework.http.HttpMethod; | ||
import org.springframework.http.MediaType; | ||
import org.springframework.restdocs.operation.OperationRequest; | ||
import org.springframework.restdocs.operation.OperationRequestFactory; | ||
import org.springframework.restdocs.operation.OperationRequestPart; | ||
import org.springframework.restdocs.operation.OperationRequestPartFactory; | ||
import org.springframework.restdocs.operation.Parameters; | ||
|
||
import java.net.URI; | ||
import java.net.URISyntaxException; | ||
import java.nio.charset.StandardCharsets; | ||
import java.util.ArrayList; | ||
import java.util.List; | ||
|
||
import static org.junit.Assert.assertArrayEquals; | ||
import static org.junit.Assert.assertEquals; | ||
|
||
public class MultipartContentOperationPreprocessorTest { | ||
private static final byte[] EXPECTED_CONTENT = "<binary>".getBytes(StandardCharsets.UTF_8); | ||
private static final byte[] BINARY_CONTENT = new byte[]{1, 2, 3, 3, 3}; | ||
private MultipartContentOperationPreprocessor preprocessor; | ||
private OperationRequestFactory requestFactory; | ||
private OperationRequestPartFactory partFactory; | ||
|
||
@Before | ||
public void setUp() { | ||
preprocessor = new MultipartContentOperationPreprocessor(); | ||
requestFactory = new OperationRequestFactory(); | ||
partFactory = new OperationRequestPartFactory(); | ||
} | ||
|
||
@Test | ||
public void shouldReplaceContent() throws URISyntaxException { | ||
OperationRequest request = createRequestWithContentType(MediaType.MULTIPART_FORM_DATA_VALUE); | ||
|
||
OperationRequest processedRequest = preprocessor.preprocess(request); | ||
assertArrayEquals(request.getContent(), processedRequest.getContent()); | ||
assertEquals(request.getHeaders(), processedRequest.getHeaders()); | ||
assertEquals(request.getMethod(), processedRequest.getMethod()); | ||
assertEquals(request.getUri(), processedRequest.getUri()); | ||
assertEquals(request.getParameters(), processedRequest.getParameters()); | ||
for (OperationRequestPart part : processedRequest.getParts()) { | ||
assertArrayEquals(EXPECTED_CONTENT, part.getContent()); | ||
} | ||
} | ||
|
||
@Test | ||
public void shouldNotReplaceWhenNotMultipart() throws URISyntaxException { | ||
OperationRequest request = createRequestWithContentType(MediaType.APPLICATION_OCTET_STREAM_VALUE); | ||
|
||
OperationRequest processedRequest = preprocessor.preprocess(request); | ||
assertArrayEquals(request.getContent(), processedRequest.getContent()); | ||
assertEquals(request.getHeaders(), processedRequest.getHeaders()); | ||
assertEquals(request.getMethod(), processedRequest.getMethod()); | ||
assertEquals(request.getUri(), processedRequest.getUri()); | ||
assertEquals(request.getParameters(), processedRequest.getParameters()); | ||
|
||
OperationRequestPart[] expectedParts = request.getParts().toArray(new OperationRequestPart[0]); | ||
OperationRequestPart[] operationRequestParts = processedRequest.getParts().toArray(new OperationRequestPart[0]); | ||
for (int i = 0; i < operationRequestParts.length; i++) { | ||
assertEquals(expectedParts[i], operationRequestParts[i]); | ||
} | ||
} | ||
|
||
private OperationRequest createRequestWithContentType(String contentType) throws URISyntaxException { | ||
HttpHeaders headers = new HttpHeaders(); | ||
headers.add(HttpHeaders.CONTENT_TYPE, contentType); | ||
Parameters parameters = new Parameters(); | ||
parameters.add("parameter", "value"); | ||
List<OperationRequestPart> requestParts = new ArrayList<>(); | ||
requestParts.add(partFactory.create("first", "file1", BINARY_CONTENT, new HttpHeaders())); | ||
return requestFactory.create(new URI("http://localhost"), HttpMethod.POST, BINARY_CONTENT, headers, parameters, requestParts); | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The headers above the new files are missing but I can add them as well. We have a Maven plugin configured that adds them automatically.