diff --git a/spring-test/src/main/java/org/springframework/test/web/client/match/ContentRequestMatchers.java b/spring-test/src/main/java/org/springframework/test/web/client/match/ContentRequestMatchers.java index 41e8f195e2a8..82e46711040d 100644 --- a/spring-test/src/main/java/org/springframework/test/web/client/match/ContentRequestMatchers.java +++ b/spring-test/src/main/java/org/springframework/test/web/client/match/ContentRequestMatchers.java @@ -60,6 +60,8 @@ */ public class ContentRequestMatchers { + private static final String DEFAULT_ENCODING = "UTF-8"; + private final XmlExpectationsHelper xmlHelper; private final JsonExpectationsHelper jsonHelper; @@ -363,7 +365,9 @@ private static class MultipartHelper { public static MultiValueMap parse(MockClientHttpRequest request) { try { FileUpload fileUpload = new FileUpload(); - fileUpload.setFileItemFactory(new DiskFileItemFactory()); + DiskFileItemFactory factory = new DiskFileItemFactory(); + factory.setDefaultCharset(DEFAULT_ENCODING); + fileUpload.setFileItemFactory(factory); List fileItems = fileUpload.parseRequest(new UploadContext() { private final byte[] body = request.getBodyAsBytes(); diff --git a/spring-test/src/test/java/org/springframework/test/web/client/match/ContentRequestMatchersTests.java b/spring-test/src/test/java/org/springframework/test/web/client/match/ContentRequestMatchersTests.java index 2210fcf08bcd..3910653762bd 100644 --- a/spring-test/src/test/java/org/springframework/test/web/client/match/ContentRequestMatchersTests.java +++ b/spring-test/src/test/java/org/springframework/test/web/client/match/ContentRequestMatchersTests.java @@ -18,6 +18,7 @@ import java.nio.charset.StandardCharsets; import java.util.Collections; +import java.util.Map; import org.junit.jupiter.api.Test; @@ -124,6 +125,72 @@ public void testFormDataContains() throws Exception { .match(this.request); } + @Test + public void testMultipartData() throws Exception { + String contentType = "multipart/form-data;boundary=1234567890"; + String body = "--1234567890\r\n" + + "Content-Disposition: form-data; name=\"name 1\"\r\n" + + "\r\n" + + "vølue 1\r\n" + + "--1234567890\r\n" + + "Content-Disposition: form-data; name=\"name 2\"\r\n" + + "\r\n" + + "value 🙂\r\n" + + "--1234567890\r\n" + + "Content-Disposition: form-data; name=\"name 3\"\r\n" + + "\r\n" + + "value 漢字\r\n" + + "--1234567890\r\n" + + "Content-Disposition: form-data; name=\"name 4\"\r\n" + + "\r\n" + + "\r\n" + + "--1234567890--\r\n"; + + this.request.getHeaders().setContentType(MediaType.parseMediaType(contentType)); + this.request.getBody().write(body.getBytes(StandardCharsets.UTF_8)); + + MultiValueMap map = new LinkedMultiValueMap<>(); + map.add("name 1", "vølue 1"); + map.add("name 2", "value 🙂"); + map.add("name 3", "value 漢字"); + map.add("name 4", ""); + MockRestRequestMatchers.content().multipartData(map).match(this.request); + } + + @Test + public void testMultipartDataContains() throws Exception { + String contentType = "multipart/form-data;boundary=1234567890"; + String body = "--1234567890\r\n" + + "Content-Disposition: form-data; name=\"name 1\"\r\n" + + "\r\n" + + "vølue 1\r\n" + + "--1234567890\r\n" + + "Content-Disposition: form-data; name=\"name 2\"\r\n" + + "\r\n" + + "value 🙂\r\n" + + "--1234567890\r\n" + + "Content-Disposition: form-data; name=\"name 3\"\r\n" + + "\r\n" + + "value 漢字\r\n" + + "--1234567890\r\n" + + "Content-Disposition: form-data; name=\"name 4\"\r\n" + + "\r\n" + + "\r\n" + + "--1234567890--\r\n"; + + this.request.getHeaders().setContentType(MediaType.parseMediaType(contentType)); + this.request.getBody().write(body.getBytes(StandardCharsets.UTF_8)); + + MockRestRequestMatchers.content() + .multipartDataContains(Map.of( + "name 1", "vølue 1", + "name 2", "value 🙂", + "name 3", "value 漢字", + "name 4", "") + ) + .match(this.request); + } + @Test public void testXml() throws Exception { String content = "bazbazz";