View Javadoc

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   * A test for AbstractDownloadableResource
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     @Override
161     public void setUp() throws Exception
162     {
163         super.setUp();
164         System.setProperty("atlassian.webresource.disable.minification", "false");
165         System.setProperty("atlassian.dev.mode", "false");
166     }
167 
168     public void testMinificationStrategyWrongFileType() throws Exception
169     {
170         final ResourceLocation resourceLocation = new ResourceLocation("/flintstone/fred.jpg", "fred.jpg", "stuff", "stuff", "stuff", EMPTY_PARAMS);
171         final MyDownloadableResource myDownloadableResource = new MyDownloadableResource(resourceLocation, false);
172         myDownloadableResource.streamResource(new ByteArrayOutputStream());
173 
174         assertEquals("/flintstone/fred.jpg", myDownloadableResource.passedResourceLocation);
175     }
176 
177     public void testMinificationStrategyCss() throws Exception
178     {
179         final ResourceLocation resourceLocation = new ResourceLocation("/flintstone/fred.css", "fred.css", "stuff", "stuff", "stuff", EMPTY_PARAMS);
180         final MyDownloadableResource myDownloadableResource = new MyDownloadableResource(resourceLocation, false);
181         myDownloadableResource.streamResource(new ByteArrayOutputStream());
182 
183         assertEquals("/flintstone/fred-min.css", myDownloadableResource.passedResourceLocation);
184     }
185 
186     public void testMinificationStrategyWithTwoMinsInName() throws Exception
187     {
188         final ResourceLocation resourceLocation = new ResourceLocation("/flintstone-min./fred-min.js", "fred-min.js", "stuff", "stuff", "stuff", EMPTY_PARAMS);
189         final MyDownloadableResource myDownloadableResource = new MyDownloadableResource(resourceLocation, false);
190         myDownloadableResource.streamResource(new ByteArrayOutputStream());
191 
192         assertEquals("/flintstone-min./fred-min.js", myDownloadableResource.passedResourceLocation);
193     }
194 
195     public void testMinificationStrategyAlreadyMinimised() throws Exception
196     {
197         final ResourceLocation resourceLocation = new ResourceLocation("/flintstone/fred-min.js", "fred-min.js", "stuff", "stuff", "stuff", EMPTY_PARAMS);
198         final MyDownloadableResource myDownloadableResource = new MyDownloadableResource(resourceLocation, false);
199         myDownloadableResource.streamResource(new ByteArrayOutputStream());
200 
201         assertEquals("/flintstone/fred-min.js", myDownloadableResource.passedResourceLocation);
202     }
203 
204     public void testMinificationStrategyNotMinimisedAndEnabled() throws Exception
205     {
206         final ResourceLocation resourceLocation = new ResourceLocation("/flintstone/fred.js", "fred.js", "stuff", "stuff", "stuff", EMPTY_PARAMS);
207         final MyDownloadableResource myDownloadableResource = new MyDownloadableResource(resourceLocation, false);
208         myDownloadableResource.streamResource(new ByteArrayOutputStream());
209 
210         assertEquals("/flintstone/fred-min.js", myDownloadableResource.passedResourceLocation);
211     }
212 
213     public void testMinificationStrategyNotMinimisedAndDisabled() throws Exception
214     {
215         final ResourceLocation resourceLocation = new ResourceLocation("/flintstone/fred.js", "fred.js", "stuff", "stuff", "stuff", EMPTY_PARAMS);
216         final MyDownloadableResource myDownloadableResource = new MyDownloadableResource(resourceLocation, true);
217         myDownloadableResource.streamResource(new ByteArrayOutputStream());
218 
219         assertEquals("/flintstone/fred.js", myDownloadableResource.passedResourceLocation);
220     }
221 
222     public void testMinificationStrategyNotMinimisedAndSystemDisabled() throws Exception
223     {
224         System.setProperty("atlassian.webresource.disable.minification", "true");
225 
226         final ResourceLocation resourceLocation = new ResourceLocation("/flintstone/fred.js", "fred.js", "stuff", "stuff", "stuff", EMPTY_PARAMS);
227         final MyDownloadableResource myDownloadableResource = new MyDownloadableResource(resourceLocation, false);
228         myDownloadableResource.streamResource(new ByteArrayOutputStream());
229 
230         assertEquals("/flintstone/fred.js", myDownloadableResource.passedResourceLocation);
231     }
232 
233     public void testMinificationStrategyNotMinimisedAndSystemEnabled() throws Exception
234     {
235         System.setProperty("atlassian.webresource.disable.minification", "false");
236 
237         final ResourceLocation resourceLocation = new ResourceLocation("/flintstone/fred.js", "fred.js", "stuff", "stuff", "stuff", EMPTY_PARAMS);
238         final MyDownloadableResource myDownloadableResource = new MyDownloadableResource(resourceLocation, false);
239         myDownloadableResource.streamResource(new ByteArrayOutputStream());
240 
241         assertEquals("/flintstone/fred-min.js", myDownloadableResource.passedResourceLocation);
242     }
243 
244     public void testWithMinifiedStrategyInPlay() throws DownloadException
245     {
246         // it should ask for -min files first and in this case get content back
247         final MinifiedFileServingDownloadableResource minifiedFileServingDownloadableResource = new MinifiedFileServingDownloadableResource(new ResourceLocation("/flintstone/fred.jpg", "fred.jpg", "stuff", "stuff", "stuff", EMPTY_PARAMS));
248         assertContent(minifiedFileServingDownloadableResource, MINIFIED_CONTENT);
249 
250         // it should ask for -min files first but get null and hence move on to the plain old content case.
251         final NotMinifiedFileServingDownloadableResouce notMinifiedFileServingDownloadableResource = new NotMinifiedFileServingDownloadableResouce();
252         assertContent(notMinifiedFileServingDownloadableResource, PLAIN_CONTENT);
253 
254     }
255 
256     public void testWhenSystemPropertyIsSet() throws DownloadException
257     {
258         verifySystemPropertyRespected("atlassian.webresource.disable.minification");
259     }
260 
261     public void testWhenDevModeSystemPropertyIsSet() throws DownloadException
262     {
263         verifySystemPropertyRespected(PluginUtils.ATLASSIAN_DEV_MODE);
264     }
265 
266     private void verifySystemPropertyRespected(String sysprop)
267             throws DownloadException
268     {
269         try
270         {
271             System.setProperty(sysprop, "true");
272 
273             // now in this case it must never ask for minified files.  This class used will assert that.
274             final NeverMinifiedFileServingDownloadableResource neverMinifiedFileServingDownloadableResource = new NeverMinifiedFileServingDownloadableResource();
275             assertContent(neverMinifiedFileServingDownloadableResource, NEVER_MINIFIED_CONTENT);
276 
277             final MinifiedFileServingDownloadableResource minifiedFileServingDownloadableResource = new MinifiedFileServingDownloadableResource(new ResourceLocation("/flintstone/fred.jpg", "fred.jpg", "stuff", "stuff", "stuff", EMPTY_PARAMS));
278             assertContent(minifiedFileServingDownloadableResource, PLAIN_CONTENT);
279 
280             // it should ask for -min files first but get null and hence move on to the plain old content case.
281             final NotMinifiedFileServingDownloadableResouce notMinifiedFileServingDownloadableResource = new NotMinifiedFileServingDownloadableResouce();
282             assertContent(notMinifiedFileServingDownloadableResource, PLAIN_CONTENT);
283 
284             System.setProperty(sysprop, "false");
285 
286             // it should ask for -min files first and in this case get content back
287             assertContent(minifiedFileServingDownloadableResource, MINIFIED_CONTENT);
288 
289             // it should ask for -min files first but get null and hence move on to the plain old content case.
290             assertContent(notMinifiedFileServingDownloadableResource, PLAIN_CONTENT);
291 
292             //
293             // now this test is wierd but hey.  If I call back on a never minified resource class object it should
294             // throw an assertion exception that it doesnt expect it.  This proves that it odes indeed get called
295             // with a -min version of itself
296             try
297             {
298                 assertContent(neverMinifiedFileServingDownloadableResource, "doesnt matter");
299 
300                 fail("This should have barfed in NeverMinifiedFileServingDownloadableResource");
301             }
302             catch (final AssertionFailedError expected)
303             {
304                 // this is expected since the test class asserts tgat a -min file should never be called on it.
305                 // and hence by inference the atlassian.webresource.disable.minification property is not taking effect
306             }
307         }
308         finally
309         {
310             // reset for this test
311             System.setProperty(sysprop, "false");
312         }
313     }
314 
315     private void assertContent(final AbstractDownloadableResource downloadableResource, final String content) throws DownloadException
316     {
317         final CapturingHttpServletResponse httpServletResponse = new CapturingHttpServletResponse();
318         final ByteArrayOutputStream baos = new ByteArrayOutputStream();
319 
320         try
321         {
322             downloadableResource.serveResource(null, httpServletResponse);
323         }
324         catch (final DownloadException e)
325         {
326             throw new RuntimeException(e);
327         }
328         downloadableResource.streamResource(baos);
329 
330         assertEquals(content, httpServletResponse.toString());
331         assertEquals(content, baos.toString());
332     }
333 }