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     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         // it should ask for -min files first and in this case get content back
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         // it should ask for -min files first but get null and hence move on to the plain old content case.
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             // now in this case it must never ask for minified files.  This class used will assert that.
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             // it should ask for -min files first but get null and hence move on to the plain old content case.
273             final NotMinifiedFileServingDownloadableResouce notMinifiedFileServingDownloadableResource = new NotMinifiedFileServingDownloadableResouce();
274             assertContent(notMinifiedFileServingDownloadableResource, PLAIN_CONTENT);
275 
276             System.setProperty(sysprop, "false");
277 
278             // it should ask for -min files first and in this case get content back
279             assertContent(minifiedFileServingDownloadableResource, MINIFIED_CONTENT);
280 
281             // it should ask for -min files first but get null and hence move on to the plain old content case.
282             assertContent(notMinifiedFileServingDownloadableResource, PLAIN_CONTENT);
283 
284             //
285             // now this test is wierd but hey.  If I call back on a never minified resource class object it should
286             // throw an assertion exception that it doesnt expect it.  This proves that it odes indeed get called
287             // with a -min version of itself
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                 // this is expected since the test class asserts tgat a -min file should never be called on it.
297                 // and hence by inference the atlassian.webresource.disable.minification property is not taking effect
298             }
299         }
300         finally
301         {
302             // reset for this test
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 }