1 package it.com.atlassian.rest.multipart;
2
3 import java.util.ArrayList;
4 import java.util.Iterator;
5
6 import javax.ws.rs.core.Response;
7 import javax.xml.bind.JAXBContext;
8 import javax.xml.bind.Unmarshaller;
9
10 import com.atlassian.plugins.rest.common.security.jersey.XsrfResourceFilter;
11 import com.atlassian.plugins.rest.multipart.FilePartObject;
12 import com.atlassian.plugins.rest.multipart.FilePartObjects;
13 import com.atlassian.rest.jersey.client.WebResourceFactory;
14
15 import org.apache.commons.httpclient.HttpClient;
16 import org.apache.commons.httpclient.methods.PostMethod;
17 import org.apache.commons.httpclient.methods.multipart.ByteArrayPartSource;
18 import org.apache.commons.httpclient.methods.multipart.FilePart;
19 import org.apache.commons.httpclient.methods.multipart.MultipartRequestEntity;
20 import org.apache.commons.httpclient.methods.multipart.Part;
21 import org.apache.commons.httpclient.methods.multipart.PartSource;
22 import org.apache.commons.httpclient.methods.multipart.StringPart;
23 import org.apache.commons.httpclient.params.HttpMethodParams;
24 import org.junit.Before;
25 import org.junit.Test;
26
27 import static junit.framework.Assert.assertTrue;
28 import static org.junit.Assert.assertEquals;
29
30
31 public class MultipartResourceTest {
32 private HttpClient client;
33
34 @Before
35 public void setUp() {
36 client = new HttpClient();
37 }
38
39 @Test
40 public void testUploadSingleFile() throws Exception {
41 FilePartObject filePartObject = new FilePartObject("file", false, "filename.txt", "text/plain", "Hello world!!");
42 FilePartObject result = (FilePartObject) uploadAndUnmarshalFileParts("single", filePartObject);
43 assertFilePartEquals(filePartObject, result);
44 }
45
46 @Test
47 public void testUploadSingleSimpleField() throws Exception {
48 FilePartObject filePartObject = new FilePartObject("file", true, null, null, "Hello world!!");
49 FilePartObject result = (FilePartObject) uploadAndUnmarshalFileParts("single", filePartObject);
50 assertFilePartEquals(filePartObject, result);
51 }
52
53 @Test
54 public void testUploadMultiple() throws Exception {
55 FilePartObject filePartObject1 = new FilePartObject("file", false, "file1.txt", "text/plain", "Hello first world!");
56 FilePartObject filePartObject2 = new FilePartObject("file", false, "file2.txt", "text/plain", "Hello second world!");
57
58 FilePartObjects result = (FilePartObjects) uploadAndUnmarshalFileParts("multiple", filePartObject1, filePartObject2);
59 assertEquals(2, result.getFileParts().size());
60 Iterator<FilePartObject> iter = result.getFileParts().iterator();
61 assertFilePartEquals(filePartObject1, iter.next());
62 assertFilePartEquals(filePartObject2, iter.next());
63 }
64
65 @Test
66 public void testMaxFileSizeUnder() throws Exception {
67 FilePartObject filePartObject = new FilePartObject("file", false, "file.txt", "text/plain", "Safe");
68 FilePartObjects result = (FilePartObjects) uploadAndUnmarshalFileParts("config", filePartObject);
69 assertEquals(1, result.getFileParts().size());
70 assertFilePartEquals(filePartObject, result.getFileParts().iterator().next());
71 }
72
73 @Test
74 public void testMaxFileSizeExceeded() throws Exception {
75
76 FilePartObject filePartObject = new FilePartObject("file", false, "file.txt", "text/plain", "This is longer than 10 characters");
77 PostMethod method = uploadFileParts("config", filePartObject);
78 assertEquals(404, method.getStatusCode());
79 assertTrue(method.getResponseBodyAsString().contains("10"));
80 }
81
82 @Test
83 public void testMaxSizeExceeded() throws Exception {
84
85
86 PostMethod method = uploadFileParts("config", new FilePartObject("file", false, "file.txt", "text/plain", "Safe"),
87 new FilePartObject("file", false, "file.txt", "text/plain", "Safe"),
88 new FilePartObject("file", false, "file.txt", "text/plain", "Safe"),
89 new FilePartObject("file", false, "file.txt", "text/plain", "Safe"),
90 new FilePartObject("file", false, "file.txt", "text/plain", "Safe"),
91 new FilePartObject("file", false, "file.txt", "text/plain", "Safe"));
92 assertEquals(404, method.getStatusCode());
93 assertTrue(method.getResponseBodyAsString().contains("1000"));
94 }
95
96 @Test
97 public void testInterceptorInvoked() throws Exception {
98 FilePartObject filePartObject = new FilePartObject("file", false, "abc.txt", "text/plain", "Upload");
99 PostMethod method = uploadFileParts("fileName", filePartObject);
100 assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?><message><message>abc.txt: Bob</message></message>", method.getResponseBodyAsString());
101 }
102
103 @Test
104 public void uploadWithEncodedNameShouldLeaveFileNameCorrect() throws Exception {
105 FilePartObject filePartObject = new FilePartObject("file", false, "=?utf-8?B?0YLQtdGB0YI=?=", "text/plain", "Hello first world!");
106 FilePartObject result = (FilePartObject) uploadAndUnmarshalFileParts("single", filePartObject);
107 assertEquals("ัะตัั", result.getFilename());
108 }
109
110 @Test
111 public void uploadWithIllegalCharacterEncodingShouldResultInClientError() throws Exception {
112 PostMethod method = uploadFileParts("single", new FilePartObject("file", false, "=?utf-unknown?B?unknown?=", "text/plain", "Hello first world!"));
113 assertEquals(Response.Status.BAD_REQUEST.getStatusCode(), method.getStatusCode());
114 }
115
116 private static void assertFilePartEquals(FilePartObject o1, FilePartObject o2) {
117 assertEquals("Field name", o1.getFieldName(), o2.getFieldName());
118 assertEquals("Is field", o1.isField(), o2.isField());
119 assertEquals("File name", o1.getFilename(), o2.getFilename());
120 assertEquals("File contents", o1.getValue(), o2.getValue());
121 }
122
123 private PostMethod uploadFileParts(String to, FilePartObject... fileParts) throws Exception {
124 ArrayList<Part> parts = new ArrayList<Part>();
125 for (FilePartObject o : fileParts) {
126 if (o.isField()) {
127 StringPart stringPart = new StringPart(o.getFieldName(), o.getValue());
128 parts.add(stringPart);
129 } else {
130 PartSource partSource = new ByteArrayPartSource(o.getFilename(), o.getValue().getBytes("UTF-8"));
131 FilePart filePart = new FilePart(o.getFieldName(), partSource, o.getContentType(), "UTF-8");
132 parts.add(filePart);
133 }
134 }
135
136 PostMethod method = new PostMethod(WebResourceFactory.getUriBuilder().path("rest").path("refimpl").path(WebResourceFactory.REST_VERSION).path("multipart").path(to).build().toString() + ".xml");
137 method.setRequestHeader(XsrfResourceFilter.TOKEN_HEADER, XsrfResourceFilter.NO_CHECK);
138 MultipartRequestEntity requestEntity = new MultipartRequestEntity(parts.toArray(new Part[parts.size()]), new HttpMethodParams());
139 method.setRequestEntity(requestEntity);
140 client.executeMethod(method);
141 return method;
142 }
143
144 private Object uploadAndUnmarshalFileParts(String to, FilePartObject... fileParts) throws Exception {
145 PostMethod method = uploadFileParts(to, fileParts);
146 Unmarshaller unmarshaller = JAXBContext.newInstance(FilePartObject.class, FilePartObjects.class).createUnmarshaller();
147 return unmarshaller.unmarshal(method.getResponseBodyAsStream());
148 }
149 }