MultiPartFormPostingTest.java
/**
* The MIT License
*
* Copyright for portions of unirest-java are held by Kong Inc (c) 2013.
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
package BehaviorTests;
import kong.unirest.core.ContentType;
import kong.unirest.core.MultipartMode;
import kong.unirest.core.Unirest;
import org.junit.jupiter.api.Test;
import java.io.*;
import java.net.URISyntaxException;
import static BehaviorTests.TestUtil.*;
import static java.util.Arrays.asList;
import static kong.unirest.core.ContentType.APPLICATION_JSON;
import static kong.unirest.core.ContentType.APPLICATION_PDF;
import static org.junit.jupiter.api.Assertions.assertEquals;
class MultiPartFormPostingTest extends BddTest {
@Test
void testMultipart() {
Unirest.post(MockServer.POST)
.field("name", "Mark")
.field("funky", "bunch")
.field("file", rezFile("/test.txt"))
.asObject(RequestCapture.class)
.getBody()
.assertParam("name", "Mark")
.assertMultiPartContentType()
.getFile("test.txt")
.assertBody("This is a test file")
.assertFileType("application/octet-stream");
}
@Test
void fileSizeDoesntChange() throws Exception {
var file = rezFile("/image.jpg");
var size = file.length();
RequestCapture capture = Unirest.post(MockServer.POST)
.field("file", file)
.field("file2", new FileInputStream(file), "file2.jpg")
.asObject(RequestCapture.class)
.getBody()
.assertMultiPartContentType();
capture.getFile("image.jpg").assertSize(size);
capture.getFile("file2.jpg").assertSize(size);
}
@Test
void testMultipartContentType() {
Unirest.post(MockServer.POST)
.field("name", "Mark")
.field("file", rezFile("/image.jpg"), "image/jpeg")
.asObject(RequestCapture.class)
.getBody()
.assertMultiPartContentType()
.assertParam("name", "Mark")
.getFile("image.jpg")
.assertFileType("image/jpeg");
}
@Test
void canSendRawInputStreamsWithoutAFileName() throws Exception {
var stream = new FileInputStream(rezFile("/test.txt"));
Unirest.post(MockServer.POST)
.field("file", stream)
.asObject(RequestCapture.class)
.getBody()
.assertParam("file", "This is a test file");
}
@Test
void multipleFiles_sameField() {
var body = Unirest.post(MockServer.POST)
.field("file", rezFile("/image.jpg"))
.field("file", rezFile("/spidey.jpg"))
.asObject(RequestCapture.class)
.getBody();
body.getFile("image.jpg").exists();
body.getFile("spidey.jpg").exists();
assertEquals(2, body.getAllFilesByInput("file").size());
}
@Test
void testMultipartInputStreamContentType() throws Exception {
FileInputStream stream = new FileInputStream(rezFile("/image.jpg"));
Unirest.post(MockServer.POST)
.header("accept", ContentType.MULTIPART_FORM_DATA.toString())
.field("name", "Mark")
.field("file", stream, ContentType.APPLICATION_OCTET_STREAM, "image.jpg")
.asObject(RequestCapture.class)
.getBody()
.assertMultiPartContentType()
.assertHeader("Accept", "multipart/form-data")
.assertParam("name", "Mark")
.getFile("image.jpg")
.assertFileType("application/octet-stream");
}
@Test
void testMultipartInputStreamContentTypeAsync() throws Exception {
Unirest.post(MockServer.POST)
.field("name", "Mark")
.field("file", new FileInputStream(rezFile("/test.txt")), ContentType.APPLICATION_OCTET_STREAM, "test.txt")
.asJsonAsync(new MockCallback<>(this, r -> parse(r)
.assertParam("name", "Mark")
.assertMultiPartContentType()
.getFile("test.txt")
.assertFileType("application/octet-stream"))
);
assertAsync();
}
@Test
void testMultipartByteContentType() throws Exception {
var bytes = getFileBytes("/image.jpg");
Unirest.post(MockServer.POST)
.field("boot", "boot")
.field("file", bytes, "image.jpg")
.asObject(RequestCapture.class)
.getBody()
.assertMultiPartContentType()
.getFile("image.jpg")
.assertFileType("application/octet-stream");
}
@Test
void testMultipartByteContentTypeAsync() throws Exception {
var bytes = getFileBytes("/test.txt");
Unirest.post(MockServer.POST)
.field("name", "Mark")
.field("file", bytes, "test.txt")
.asJsonAsync(new MockCallback<>(this, r ->
parse(r)
.assertParam("name", "Mark")
.assertMultiPartContentType()
.getFile("test.txt")
.assertFileType("application/octet-stream"))
);
assertAsync();
}
@Test
void testMultipartAsync() {
Unirest.post(MockServer.POST)
.field("name", "Mark")
.field("file", rezFile("/test.txt"))
.asJsonAsync(new MockCallback<>(this, r ->
parse(r)
.assertParam("name", "Mark")
.assertMultiPartContentType()
.getFile("test.txt")
.assertFileType("application/octet-stream")
.assertBody("This is a test file"))
);
assertAsync();
}
@Test
void utf8FileNames() {
var fileData = new ByteArrayInputStream(new byte[]{'t', 'e', 's', 't'});
var filename = "file������.p��f";
Unirest.post(MockServer.POST)
.field("file", fileData, filename)
.asObject(RequestCapture.class)
.getBody()
.assertMultiPartContentType()
.getFile(filename)
.assertFileName(filename);
}
@Test
void simpleMultiPart() {
Unirest.post(MockServer.POST)
.field("foo", "bar")
.field("fruit", "apple")
.asObject(RequestCapture.class)
.getBody()
.assertParam("foo", "bar");
}
@Test
void canSetModeToStrictForLegacySupport() {
var fileData = new ByteArrayInputStream(new byte[]{'t', 'e', 's', 't'});
var filename = "file������.p��f";
Unirest.post(MockServer.POST)
.field("file", fileData, filename)
.mode(MultipartMode.STRICT)
.asObject(RequestCapture.class)
.getBody()
.assertMultiPartContentType()
.getFile("file???.p?f")
.assertFileName("file???.p?f");
}
@Test
void canPostInputStreamWithContentType() throws Exception {
var file = TestUtil.getImageFile();
Unirest.post(MockServer.POST)
.field("testfile", new FileInputStream(file), ContentType.IMAGE_JPEG, "image.jpg")
.asObject(RequestCapture.class)
.getBody()
.assertMultiPartContentType()
.getFileByInput("testfile")
.assertFileName("image.jpg")
.assertFileType("image/jpeg");
}
@Test
void canPostInputStream() throws Exception {
var file = TestUtil.getImageFile();
Unirest.post(MockServer.POST)
.field("testfile", new FileInputStream(file), "image.jpg")
.asObject(RequestCapture.class)
.getBody()
.assertMultiPartContentType()
.getFileByInput("testfile")
.assertFileName("image.jpg")
.assertFileType("application/octet-stream");
}
@Test
void postFieldsAsMap() throws URISyntaxException {
var file = TestUtil.getImageFile();
Unirest.post(MockServer.POST)
.fields(TestUtil.mapOf("big", "bird", "charlie", 42, "testfile", file, "gonzo", null))
.asObject(RequestCapture.class)
.getBody()
.assertParam("big", "bird")
.assertParam("charlie", "42")
.assertParam("gonzo", "")
.assertMultiPartContentType()
.getFile("image.jpg")
.assertFileType("application/octet-stream");
}
@Test
void postFileWithoutContentType() {
var file = TestUtil.getImageFile();
Unirest.post(MockServer.POST)
.field("testfile", file)
.asObject(RequestCapture.class)
.getBody()
.assertMultiPartContentType()
.getFile("image.jpg")
.assertFileType("application/octet-stream");
}
@Test
void postFileWithContentType() {
var file = TestUtil.getImageFile();
Unirest.post(MockServer.POST)
.field("testfile", file, ContentType.IMAGE_JPEG.getMimeType())
.asObject(RequestCapture.class)
.getBody()
.assertMultiPartContentType()
.getFile("image.jpg")
.assertFileType(ContentType.IMAGE_JPEG);
}
@Test
void multiPartInputStreamAsFile() throws FileNotFoundException {
Unirest.post(MockServer.POST)
.field("foo", "bar")
.field("filecontents", new FileInputStream(rezFile("/image.jpg")), "image.jpg")
.asObject(RequestCapture.class)
.getBody()
.assertMultiPartContentType()
.assertParam("foo", "bar")
.getFileByInput("filecontents")
.assertFileType(ContentType.APPLICATION_OCTET_STREAM)
.assertFileName("image.jpg");
}
@Test
void testPostMulipleFIles() {
var cap = Unirest.post(MockServer.POST)
.field("name", asList(rezFile("/test.txt"), rezFile("/test2.txt")))
.asObject(RequestCapture.class)
.getBody()
.assertMultiPartContentType();
cap.getFile("test.txt").assertBody("This is a test file");
cap.getFile("test2.txt").assertBody("this is another test");
}
@Test
void testPostMultipleFiles() throws Exception {
Unirest.post(MockServer.POST)
.field("param3", "wot")
.field("file1", rezFile("/test.txt"))
.field("file2", rezFile("/test.txt"))
.asObject(RequestCapture.class)
.getBody()
.assertMultiPartContentType()
.assertParam("param3", "wot")
.assertFileContent("file1", "This is a test file")
.assertFileContent("file2", "This is a test file");
}
@Test
void testPostBinaryUTF8() throws Exception {
Unirest.post(MockServer.POST)
.header("Accept", ContentType.MULTIPART_FORM_DATA.getMimeType())
.field("param3", "���������������")
.field("file", rezFile("/test.txt"))
.asObject(RequestCapture.class)
.getBody()
.assertMultiPartContentType()
.assertParam("param3", "���������������")
.assertFileContent("file", "This is a test file");
}
@Test
void testMultipeInputStreams() throws FileNotFoundException {
Unirest.post(MockServer.POST)
.field("name", asList(new FileInputStream(rezFile("/test.txt")), new FileInputStream(rezFile("/test2.txt"))))
.asObject(RequestCapture.class)
.getBody()
.assertMultiPartContentType()
.assertParam("name", "This is a test file")
.assertParam("name", "this is another test");
}
@Test
void multiPartInputStream() throws FileNotFoundException {
Unirest.post(MockServer.POST)
.field("foo", "bar")
.field("filecontents", new FileInputStream(rezFile("/test.txt")), ContentType.WILDCARD)
.asObject(RequestCapture.class)
.getBody()
.assertMultiPartContentType()
.assertParam("foo", "bar")
.assertParam("filecontents", "This is a test file");
}
@Test
void passFileAsByteArray() {
Unirest.post(MockServer.POST)
.field("foo", "bar")
.field("filecontents", TestUtil.getFileBytes("/image.jpg"), ContentType.IMAGE_JPEG, "image.jpg")
.asObject(RequestCapture.class)
.getBody()
.assertMultiPartContentType()
.assertParam("foo", "bar")
.getFileByInput("filecontents")
.assertFileType(ContentType.IMAGE_JPEG)
.assertFileName("image.jpg");
}
@Test
void nullFileResultsInEmptyPost() {
Unirest.post(MockServer.POST)
.field("testfile", (Object) null, ContentType.IMAGE_JPEG.getMimeType())
.asObject(RequestCapture.class)
.getBody()
.assertParam("testfile", "");
}
@Test
void canForceIntoMultiPart() {
Unirest.post(MockServer.POST)
.multiPartContent()
.field("foo", "bar")
.asObject(RequestCapture.class)
.getBody()
.assertMultiPartContentType()
.assertParam("foo", "bar");
}
@Test
void rawInspection() {
var body = Unirest.post(MockServer.ECHO_RAW)
.field("marky", "mark")
.field("funky", "bunch")
.field("file", rezFile("/test.txt"))
.asString()
.getBody();
var expected = TestUtil.getResource("rawPost.txt").replaceAll("\r", "").trim();
var id = body.substring(2, body.indexOf("\n") - 1);
body = body.replaceAll(id, "IDENTIFIER").replaceAll("\r", "").trim();
assertEquals(expected, body);
}
@Test
void mediaTypesForParts() {
Unirest.post(MockServer.POST)
.field("content", rezInput("/spidey.pdf"), APPLICATION_PDF, "spiderman")
.field("metadata", "{\"foo\": 1}", APPLICATION_JSON)
.asObject(RequestCapture.class)
.getBody()
.assertHeader("Content-Type", h -> {
h.assertMainValue("multipart/form-data");
h.assertHasParam("boundary");
h.assertParam("charset", "UTF-8");
// Lets create a way to tell unirest what the boundary should be so we can test it easier.
//h.assertRawValue("multipart/form-data; boundary=4ebf68bc-70f8-462b-b3a5-48dadb236af3;charset=UTF-8");
})
.assertBodyPart("content", p -> {
p.assertFileName("spiderman");
p.assertContentType("application/pdf");
p.assertContentDisposition("form-data; name=\"content\"; filename=\"spiderman\"");
})
.assertBodyPart("metadata", p -> {
p.assertBody("{\"foo\": 1}");
p.assertContentType("application/json");
p.assertContentDisposition("form-data; name=\"metadata\"");
});
}
@Test
void defaultMediaTypes() {
Unirest.post(MockServer.POST)
.field("content", rezInput("/spidey.pdf"), "spiderman")
.field("metadata", "{\"foo\": 1}")
.asObject(RequestCapture.class)
.getBody()
.assertHeader("Content-Type", h -> {
h.assertMainValue("multipart/form-data");
h.assertHasParam("boundary");
h.assertParam("charset", "UTF-8");
// Lets create a way to tell unirest what the boundary should be so we can test it easier.
//h.assertRawValue("multipart/form-data; boundary=4ebf68bc-70f8-462b-b3a5-48dadb236af3;charset=UTF-8");
})
.assertBodyPart("content", p -> {
p.assertFileName("spiderman");
p.assertContentType("application/octet-stream");
p.assertContentDisposition("form-data; name=\"content\"; filename=\"spiderman\"");
})
.assertBodyPart("metadata", p -> {
p.assertBody("{\"foo\": 1}");
p.assertContentType("application/x-www-form-urlencoded; charset=UTF-8");
p.assertContentDisposition("form-data; name=\"metadata\"");
});
}
@Test
void settingTheBoundary() {
String boundary = "ABC-123-BOUNDARY";
Unirest.post(MockServer.POST)
.field("spidey", rezFile("/spidey.pdf"))
.field("something", "else")
.boundary(boundary)
.asObject(RequestCapture.class)
.getBody()
.assertHeader("Content-Type", h -> {
h.assertParam("boundary", boundary);
});
}
@Test
void overridingForcingMultiTypeOverridesHeader(){
Unirest.config()
.setDefaultHeader("Accept", "application/json")
.setDefaultHeader("Content-Type", "application/json")
.setDefaultHeader("Authorization", "Bearer xxx-abc-123");
Unirest.post(MockServer.POST)
.basicAuth("username", "password")
.multiPartContent()
.field("username", "xxx")
.field("token", "abc")
.field("grant_type", "password")
.asObject(RequestCapture.class)
.getBody()
.assertHeaderSize("Content-Type", 1)
.assertMultiPartContentType();
}
}