1 package com.atlassian.plugin.servlet;
2
3 import com.atlassian.plugin.elements.ResourceLocation;
4 import com.atlassian.plugin.servlet.util.CapturingHttpServletResponse;
5 import com.atlassian.plugin.util.PluginUtils;
6
7 import com.google.common.collect.ImmutableMap;
8
9 import java.io.ByteArrayInputStream;
10 import java.io.ByteArrayOutputStream;
11 import java.io.InputStream;
12 import java.util.Map;
13
14 import junit.framework.AssertionFailedError;
15 import junit.framework.TestCase;
16
17
18
19
20 public class TestAbstractDownloadableResource extends TestCase
21 {
22 private static final String MINIFIED_CONTENT = "minified content";
23 private static final String PLAIN_CONTENT = "plain content";
24 private static final String NEVER_MINIFIED_CONTENT = "never minified content";
25 private static final Map<String, String> EMPTY_PARAMS = ImmutableMap.of();
26
27 private class MinifiedFileServingDownloadableResource extends AbstractDownloadableResource
28 {
29 public MinifiedFileServingDownloadableResource(final ResourceLocation resourceLocation)
30 {
31 super(null, resourceLocation, null);
32 }
33
34 @Override
35 protected String getLocation()
36 {
37 return "somecode.js";
38 }
39
40 @Override
41 public String getContentType()
42 {
43 return "minified/content";
44 }
45
46 @Override
47 protected InputStream getResourceAsStream(final String resourceLocation)
48 {
49 if (resourceLocation.contains("-min."))
50 {
51 assertEquals("somecode-min.js", resourceLocation);
52 return newStream(MINIFIED_CONTENT);
53 }
54 assertEquals("somecode.js", resourceLocation);
55 return newStream(PLAIN_CONTENT);
56 }
57
58 private InputStream newStream(final String s)
59 {
60 return new ByteArrayInputStream(s.getBytes());
61 }
62 }
63
64 private class MyDownloadableResource extends AbstractDownloadableResource
65 {
66 private String passedResourceLocation;
67
68 public MyDownloadableResource(final ResourceLocation resourceLocation, final boolean disableMinification)
69 {
70 super(null, resourceLocation, "", disableMinification);
71 }
72
73 @Override
74 protected InputStream getResourceAsStream(final String resourceLocation)
75 {
76 passedResourceLocation = resourceLocation;
77 return newStream(resourceLocation);
78 }
79
80 private InputStream newStream(final String s)
81 {
82 return new ByteArrayInputStream(s.getBytes());
83 }
84 }
85
86 private class NotMinifiedFileServingDownloadableResouce extends AbstractDownloadableResource
87 {
88 public NotMinifiedFileServingDownloadableResouce()
89 {
90 super(null, new ResourceLocation("/flintstone/fred.jpg", "fred.jpg", "stuff", "stuff", "stuff", EMPTY_PARAMS), null);
91 }
92
93 @Override
94 protected String getLocation()
95 {
96 return "somemorecode.js";
97 }
98
99 @Override
100 public String getContentType()
101 {
102 return "plain/content";
103 }
104
105 @Override
106 protected InputStream getResourceAsStream(final String resourceLocation)
107 {
108 if (resourceLocation.contains("-min."))
109 {
110 assertEquals("somemorecode-min.js", resourceLocation);
111 return null;
112 }
113 assertEquals("somemorecode.js", resourceLocation);
114 return newStream(PLAIN_CONTENT);
115 }
116
117 private InputStream newStream(final String s)
118 {
119 return new ByteArrayInputStream(s.getBytes());
120 }
121
122 }
123
124 private class NeverMinifiedFileServingDownloadableResource extends AbstractDownloadableResource
125 {
126 public NeverMinifiedFileServingDownloadableResource()
127 {
128 super(null, new ResourceLocation("/flintstone/fred.jpg", "fred.jpg", "stuff", "stuff", "stuff", EMPTY_PARAMS), null);
129 }
130
131 @Override
132 protected String getLocation()
133 {
134 return "neverminified.js";
135 }
136
137 @Override
138 public String getContentType()
139 {
140 return "neverminified/content";
141 }
142
143 @Override
144 protected InputStream getResourceAsStream(final String resourceLocation)
145 {
146 if (resourceLocation.contains("-min."))
147 {
148 fail("it should never ask for this");
149 }
150 assertEquals("neverminified.js", resourceLocation);
151 return newStream(NEVER_MINIFIED_CONTENT);
152 }
153
154 private InputStream newStream(final String s)
155 {
156 return new ByteArrayInputStream(s.getBytes());
157 }
158 }
159
160 public void testMinificationStrategyWrongFileType() throws Exception
161 {
162 final ResourceLocation resourceLocation = new ResourceLocation("/flintstone/fred.jpg", "fred.jpg", "stuff", "stuff", "stuff", EMPTY_PARAMS);
163 final MyDownloadableResource myDownloadableResource = new MyDownloadableResource(resourceLocation, false);
164 myDownloadableResource.streamResource(new ByteArrayOutputStream());
165
166 assertEquals("/flintstone/fred.jpg", myDownloadableResource.passedResourceLocation);
167 }
168
169 public void testMinificationStrategyCss() throws Exception
170 {
171 final ResourceLocation resourceLocation = new ResourceLocation("/flintstone/fred.css", "fred.css", "stuff", "stuff", "stuff", EMPTY_PARAMS);
172 final MyDownloadableResource myDownloadableResource = new MyDownloadableResource(resourceLocation, false);
173 myDownloadableResource.streamResource(new ByteArrayOutputStream());
174
175 assertEquals("/flintstone/fred-min.css", myDownloadableResource.passedResourceLocation);
176 }
177
178 public void testMinificationStrategyWithTwoMinsInName() throws Exception
179 {
180 final ResourceLocation resourceLocation = new ResourceLocation("/flintstone-min./fred-min.js", "fred-min.js", "stuff", "stuff", "stuff", EMPTY_PARAMS);
181 final MyDownloadableResource myDownloadableResource = new MyDownloadableResource(resourceLocation, false);
182 myDownloadableResource.streamResource(new ByteArrayOutputStream());
183
184 assertEquals("/flintstone-min./fred-min.js", myDownloadableResource.passedResourceLocation);
185 }
186
187 public void testMinificationStrategyAlreadyMinimised() throws Exception
188 {
189 final ResourceLocation resourceLocation = new ResourceLocation("/flintstone/fred-min.js", "fred-min.js", "stuff", "stuff", "stuff", EMPTY_PARAMS);
190 final MyDownloadableResource myDownloadableResource = new MyDownloadableResource(resourceLocation, false);
191 myDownloadableResource.streamResource(new ByteArrayOutputStream());
192
193 assertEquals("/flintstone/fred-min.js", myDownloadableResource.passedResourceLocation);
194 }
195
196 public void testMinificationStrategyNotMinimisedAndEnabled() throws Exception
197 {
198 final ResourceLocation resourceLocation = new ResourceLocation("/flintstone/fred.js", "fred.js", "stuff", "stuff", "stuff", EMPTY_PARAMS);
199 final MyDownloadableResource myDownloadableResource = new MyDownloadableResource(resourceLocation, false);
200 myDownloadableResource.streamResource(new ByteArrayOutputStream());
201
202 assertEquals("/flintstone/fred-min.js", myDownloadableResource.passedResourceLocation);
203 }
204
205 public void testMinificationStrategyNotMinimisedAndDisabled() throws Exception
206 {
207 final ResourceLocation resourceLocation = new ResourceLocation("/flintstone/fred.js", "fred.js", "stuff", "stuff", "stuff", EMPTY_PARAMS);
208 final MyDownloadableResource myDownloadableResource = new MyDownloadableResource(resourceLocation, true);
209 myDownloadableResource.streamResource(new ByteArrayOutputStream());
210
211 assertEquals("/flintstone/fred.js", myDownloadableResource.passedResourceLocation);
212 }
213
214 public void testMinificationStrategyNotMinimisedAndSystemDisabled() throws Exception
215 {
216 System.setProperty("atlassian.webresource.disable.minification", "true");
217
218 final ResourceLocation resourceLocation = new ResourceLocation("/flintstone/fred.js", "fred.js", "stuff", "stuff", "stuff", EMPTY_PARAMS);
219 final MyDownloadableResource myDownloadableResource = new MyDownloadableResource(resourceLocation, false);
220 myDownloadableResource.streamResource(new ByteArrayOutputStream());
221
222 assertEquals("/flintstone/fred.js", myDownloadableResource.passedResourceLocation);
223 }
224
225 public void testMinificationStrategyNotMinimisedAndSystemEnabled() throws Exception
226 {
227 System.setProperty("atlassian.webresource.disable.minification", "false");
228
229 final ResourceLocation resourceLocation = new ResourceLocation("/flintstone/fred.js", "fred.js", "stuff", "stuff", "stuff", EMPTY_PARAMS);
230 final MyDownloadableResource myDownloadableResource = new MyDownloadableResource(resourceLocation, false);
231 myDownloadableResource.streamResource(new ByteArrayOutputStream());
232
233 assertEquals("/flintstone/fred-min.js", myDownloadableResource.passedResourceLocation);
234 }
235
236 public void testWithMinifiedStrategyInPlay() throws DownloadException
237 {
238
239 final MinifiedFileServingDownloadableResource minifiedFileServingDownloadableResource = new MinifiedFileServingDownloadableResource(new ResourceLocation("/flintstone/fred.jpg", "fred.jpg", "stuff", "stuff", "stuff", EMPTY_PARAMS));
240 assertContent(minifiedFileServingDownloadableResource, MINIFIED_CONTENT);
241
242
243 final NotMinifiedFileServingDownloadableResouce notMinifiedFileServingDownloadableResource = new NotMinifiedFileServingDownloadableResouce();
244 assertContent(notMinifiedFileServingDownloadableResource, PLAIN_CONTENT);
245
246 }
247
248 public void testWhenSystemPropertyIsSet() throws DownloadException
249 {
250 verifySystemPropertyRespected("atlassian.webresource.disable.minification");
251 }
252
253 public void testWhenDevModeSystemPropertyIsSet() throws DownloadException
254 {
255 verifySystemPropertyRespected(PluginUtils.ATLASSIAN_DEV_MODE);
256 }
257
258 private void verifySystemPropertyRespected(String sysprop)
259 throws DownloadException
260 {
261 try
262 {
263 System.setProperty(sysprop, "true");
264
265
266 final NeverMinifiedFileServingDownloadableResource neverMinifiedFileServingDownloadableResource = new NeverMinifiedFileServingDownloadableResource();
267 assertContent(neverMinifiedFileServingDownloadableResource, NEVER_MINIFIED_CONTENT);
268
269 final MinifiedFileServingDownloadableResource minifiedFileServingDownloadableResource = new MinifiedFileServingDownloadableResource(new ResourceLocation("/flintstone/fred.jpg", "fred.jpg", "stuff", "stuff", "stuff", EMPTY_PARAMS));
270 assertContent(minifiedFileServingDownloadableResource, PLAIN_CONTENT);
271
272
273 final NotMinifiedFileServingDownloadableResouce notMinifiedFileServingDownloadableResource = new NotMinifiedFileServingDownloadableResouce();
274 assertContent(notMinifiedFileServingDownloadableResource, PLAIN_CONTENT);
275
276 System.setProperty(sysprop, "false");
277
278
279 assertContent(minifiedFileServingDownloadableResource, MINIFIED_CONTENT);
280
281
282 assertContent(notMinifiedFileServingDownloadableResource, PLAIN_CONTENT);
283
284
285
286
287
288 try
289 {
290 assertContent(neverMinifiedFileServingDownloadableResource, "doesnt matter");
291
292 fail("This should have barfed in NeverMinifiedFileServingDownloadableResource");
293 }
294 catch (final AssertionFailedError expected)
295 {
296
297
298 }
299 }
300 finally
301 {
302
303 System.setProperty(sysprop, "false");
304 }
305 }
306
307 private void assertContent(final AbstractDownloadableResource downloadableResource, final String content) throws DownloadException
308 {
309 final CapturingHttpServletResponse httpServletResponse = new CapturingHttpServletResponse();
310 final ByteArrayOutputStream baos = new ByteArrayOutputStream();
311
312 try
313 {
314 downloadableResource.serveResource(null, httpServletResponse);
315 }
316 catch (final DownloadException e)
317 {
318 throw new RuntimeException(e);
319 }
320 downloadableResource.streamResource(baos);
321
322 assertEquals(content, httpServletResponse.toString());
323 assertEquals(content, baos.toString());
324 }
325 }