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   import com.google.common.collect.ImmutableMap;
7   import org.junit.Before;
8   import org.junit.Rule;
9   import org.junit.Test;
10  import org.junit.contrib.java.lang.system.RestoreSystemProperties;
11  
12  import java.io.ByteArrayInputStream;
13  import java.io.ByteArrayOutputStream;
14  import java.io.InputStream;
15  import java.util.Map;
16  
17  import static org.junit.Assert.assertEquals;
18  import static org.junit.Assert.fail;
19  
20  /**
21   * A test for AbstractDownloadableResource
22   */
23  public class TestAbstractDownloadableResource {
24  
25      private static final String MINIFIED_CONTENT = "minified content";
26      private static final String PLAIN_CONTENT = "plain content";
27      private static final String NEVER_MINIFIED_CONTENT = "never minified content";
28      private static final Map<String, String> EMPTY_PARAMS = ImmutableMap.of();
29  
30      @Rule
31      public final RestoreSystemProperties systemPropertiesRule = new RestoreSystemProperties();
32  
33      @Before
34      public void setUp() {
35          System.setProperty("atlassian.webresource.disable.minification", "false");
36          System.setProperty("atlassian.dev.mode", "false");
37      }
38  
39      @Test
40      public void testMinificationStrategyWrongFileType() throws Exception {
41          final ResourceLocation resourceLocation = new ResourceLocation("/flintstone/fred.jpg", "fred.jpg", "stuff", "stuff", "stuff", EMPTY_PARAMS);
42          final MyDownloadableResource myDownloadableResource = new MyDownloadableResource(resourceLocation, false);
43          myDownloadableResource.streamResource(new ByteArrayOutputStream());
44  
45          assertEquals("/flintstone/fred.jpg", myDownloadableResource.passedResourceLocation);
46      }
47  
48      @Test
49      public void testMinificationStrategyCss() throws Exception {
50          final ResourceLocation resourceLocation = new ResourceLocation("/flintstone/fred.css", "fred.css", "stuff", "stuff", "stuff", EMPTY_PARAMS);
51          final MyDownloadableResource myDownloadableResource = new MyDownloadableResource(resourceLocation, false);
52          myDownloadableResource.streamResource(new ByteArrayOutputStream());
53  
54          assertEquals("/flintstone/fred-min.css", myDownloadableResource.passedResourceLocation);
55      }
56  
57      @Test
58      public void testMinificationStrategyWithTwoMinsInName() throws Exception {
59          final ResourceLocation resourceLocation = new ResourceLocation("/flintstone-min./fred-min.js", "fred-min.js", "stuff", "stuff", "stuff", EMPTY_PARAMS);
60          final MyDownloadableResource myDownloadableResource = new MyDownloadableResource(resourceLocation, false);
61          myDownloadableResource.streamResource(new ByteArrayOutputStream());
62  
63          assertEquals("/flintstone-min./fred-min.js", myDownloadableResource.passedResourceLocation);
64      }
65  
66      @Test
67      public void testMinificationStrategyAlreadyMinimised() throws Exception {
68          final ResourceLocation resourceLocation = new ResourceLocation("/flintstone/fred-min.js", "fred-min.js", "stuff", "stuff", "stuff", EMPTY_PARAMS);
69          final MyDownloadableResource myDownloadableResource = new MyDownloadableResource(resourceLocation, false);
70          myDownloadableResource.streamResource(new ByteArrayOutputStream());
71  
72          assertEquals("/flintstone/fred-min.js", myDownloadableResource.passedResourceLocation);
73      }
74  
75      @Test
76      public void testMinificationStrategyNotMinimisedAndEnabled() throws Exception {
77          final ResourceLocation resourceLocation = new ResourceLocation("/flintstone/fred.js", "fred.js", "stuff", "stuff", "stuff", EMPTY_PARAMS);
78          final MyDownloadableResource myDownloadableResource = new MyDownloadableResource(resourceLocation, false);
79          myDownloadableResource.streamResource(new ByteArrayOutputStream());
80  
81          assertEquals("/flintstone/fred-min.js", myDownloadableResource.passedResourceLocation);
82      }
83  
84      @Test
85      public void testMinificationStrategyNotMinimisedAndDisabled() throws Exception {
86          final ResourceLocation resourceLocation = new ResourceLocation("/flintstone/fred.js", "fred.js", "stuff", "stuff", "stuff", EMPTY_PARAMS);
87          final MyDownloadableResource myDownloadableResource = new MyDownloadableResource(resourceLocation, true);
88          myDownloadableResource.streamResource(new ByteArrayOutputStream());
89  
90          assertEquals("/flintstone/fred.js", myDownloadableResource.passedResourceLocation);
91      }
92  
93      @Test
94      public void testMinificationStrategyNotMinimisedAndSystemDisabled() throws Exception {
95          System.setProperty("atlassian.webresource.disable.minification", "true");
96  
97          final ResourceLocation resourceLocation = new ResourceLocation("/flintstone/fred.js", "fred.js", "stuff", "stuff", "stuff", EMPTY_PARAMS);
98          final MyDownloadableResource myDownloadableResource = new MyDownloadableResource(resourceLocation, false);
99          myDownloadableResource.streamResource(new ByteArrayOutputStream());
100 
101         assertEquals("/flintstone/fred.js", myDownloadableResource.passedResourceLocation);
102     }
103 
104     @Test
105     public void testMinificationStrategyNotMinimisedAndSystemEnabled() throws Exception {
106         System.setProperty("atlassian.webresource.disable.minification", "false");
107 
108         final ResourceLocation resourceLocation = new ResourceLocation("/flintstone/fred.js", "fred.js", "stuff", "stuff", "stuff", EMPTY_PARAMS);
109         final MyDownloadableResource myDownloadableResource = new MyDownloadableResource(resourceLocation, false);
110         myDownloadableResource.streamResource(new ByteArrayOutputStream());
111 
112         assertEquals("/flintstone/fred-min.js", myDownloadableResource.passedResourceLocation);
113     }
114 
115     @Test
116     public void testWithMinifiedStrategyInPlay() throws DownloadException {
117         // it should ask for -min files first and in this case get content back
118         final MinifiedFileServingDownloadableResource minifiedFileServingDownloadableResource = new MinifiedFileServingDownloadableResource(new ResourceLocation("/flintstone/fred.jpg", "fred.jpg", "stuff", "stuff", "stuff", EMPTY_PARAMS));
119         assertContent(minifiedFileServingDownloadableResource, MINIFIED_CONTENT);
120 
121         // it should ask for -min files first but get null and hence move on to the plain old content case.
122         final NotMinifiedFileServingDownloadableResouce notMinifiedFileServingDownloadableResource = new NotMinifiedFileServingDownloadableResouce();
123         assertContent(notMinifiedFileServingDownloadableResource, PLAIN_CONTENT);
124 
125     }
126 
127     @Test
128     public void testWhenSystemPropertyIsSet() throws DownloadException {
129         verifySystemPropertyRespected("atlassian.webresource.disable.minification");
130     }
131 
132     @Test
133     public void testWhenDevModeSystemPropertyIsSet() throws DownloadException {
134         verifySystemPropertyRespected(PluginUtils.ATLASSIAN_DEV_MODE);
135     }
136 
137     private void verifySystemPropertyRespected(String sysprop)
138             throws DownloadException {
139         System.setProperty(sysprop, "true");
140 
141         // now in this case it must never ask for minified files. This class used will assert that.
142         final NeverMinifiedFileServingDownloadableResource neverMinifiedFileServingDownloadableResource = new NeverMinifiedFileServingDownloadableResource();
143         assertContent(neverMinifiedFileServingDownloadableResource, NEVER_MINIFIED_CONTENT);
144 
145         final MinifiedFileServingDownloadableResource minifiedFileServingDownloadableResource = new MinifiedFileServingDownloadableResource(new ResourceLocation("/flintstone/fred.jpg", "fred.jpg", "stuff", "stuff", "stuff", EMPTY_PARAMS));
146         assertContent(minifiedFileServingDownloadableResource, PLAIN_CONTENT);
147 
148         // it should ask for -min files first but get null and hence move on to the plain old content case.
149         final NotMinifiedFileServingDownloadableResouce notMinifiedFileServingDownloadableResource = new NotMinifiedFileServingDownloadableResouce();
150         assertContent(notMinifiedFileServingDownloadableResource, PLAIN_CONTENT);
151 
152         System.setProperty(sysprop, "false");
153 
154         // it should ask for -min files first and in this case get content back
155         assertContent(minifiedFileServingDownloadableResource, MINIFIED_CONTENT);
156 
157         // it should ask for -min files first but get null and hence move on to the plain old content case.
158         assertContent(notMinifiedFileServingDownloadableResource, PLAIN_CONTENT);
159 
160         //
161         // now this test is weird but hey. If I call back on a never minified resource class object it should
162         // throw an assertion exception that it doesn't expect it. This proves that it does indeed get called
163         // with a -min version of itself
164         try {
165             assertContent(neverMinifiedFileServingDownloadableResource, "doesn't matter");
166 
167             fail("This should have barfed in NeverMinifiedFileServingDownloadableResource");
168         } catch (final AssertionError expected) {
169             // this is expected since the test class asserts that a -min file should never be called on it.
170             // and hence by inference the atlassian.webresource.disable.minification property is not taking effect
171         }
172     }
173 
174     private void assertContent(final AbstractDownloadableResource downloadableResource, final String content) throws DownloadException {
175         final CapturingHttpServletResponse httpServletResponse = new CapturingHttpServletResponse();
176         final ByteArrayOutputStream baos = new ByteArrayOutputStream();
177 
178         try {
179             downloadableResource.serveResource(null, httpServletResponse);
180         } catch (final DownloadException e) {
181             throw new RuntimeException(e);
182         }
183         downloadableResource.streamResource(baos);
184 
185         assertEquals(content, httpServletResponse.toString());
186         assertEquals(content, baos.toString());
187     }
188 
189     private static class MinifiedFileServingDownloadableResource extends AbstractDownloadableResource {
190 
191         MinifiedFileServingDownloadableResource(final ResourceLocation resourceLocation) {
192             super(null, resourceLocation, null);
193         }
194 
195         @Override
196         protected String getLocation() {
197             return "somecode.js";
198         }
199 
200         @Override
201         public String getContentType() {
202             return "minified/content";
203         }
204 
205         @Override
206         protected InputStream getResourceAsStream(final String resourceLocation) {
207             if (resourceLocation.contains("-min.")) {
208                 assertEquals("somecode-min.js", resourceLocation);
209                 return newStream(MINIFIED_CONTENT);
210             }
211             assertEquals("somecode.js", resourceLocation);
212             return newStream(PLAIN_CONTENT);
213         }
214 
215         private InputStream newStream(final String s) {
216             return new ByteArrayInputStream(s.getBytes());
217         }
218     }
219 
220     private static class MyDownloadableResource extends AbstractDownloadableResource {
221         private String passedResourceLocation;
222 
223         MyDownloadableResource(final ResourceLocation resourceLocation, final boolean disableMinification) {
224             super(null, resourceLocation, "", disableMinification);
225         }
226 
227         @Override
228         protected InputStream getResourceAsStream(final String resourceLocation) {
229             passedResourceLocation = resourceLocation;
230             return newStream(resourceLocation);
231         }
232 
233         private InputStream newStream(final String s) {
234             return new ByteArrayInputStream(s.getBytes());
235         }
236     }
237 
238     private static class NotMinifiedFileServingDownloadableResouce extends AbstractDownloadableResource {
239         NotMinifiedFileServingDownloadableResouce() {
240             super(null, new ResourceLocation("/flintstone/fred.jpg", "fred.jpg", "stuff", "stuff", "stuff", EMPTY_PARAMS), null);
241         }
242 
243         @Override
244         protected String getLocation() {
245             return "somemorecode.js";
246         }
247 
248         @Override
249         public String getContentType() {
250             return "plain/content";
251         }
252 
253         @Override
254         protected InputStream getResourceAsStream(final String resourceLocation) {
255             if (resourceLocation.contains("-min.")) {
256                 assertEquals("somemorecode-min.js", resourceLocation);
257                 return null;
258             }
259             assertEquals("somemorecode.js", resourceLocation);
260             return newStream(PLAIN_CONTENT);
261         }
262 
263         private InputStream newStream(final String s) {
264             return new ByteArrayInputStream(s.getBytes());
265         }
266 
267     }
268 
269     private static class NeverMinifiedFileServingDownloadableResource extends AbstractDownloadableResource {
270         NeverMinifiedFileServingDownloadableResource() {
271             super(null, new ResourceLocation("/flintstone/fred.jpg", "fred.jpg", "stuff", "stuff", "stuff", EMPTY_PARAMS), null);
272         }
273 
274         @Override
275         protected String getLocation() {
276             return "neverminified.js";
277         }
278 
279         @Override
280         public String getContentType() {
281             return "neverminified/content";
282         }
283 
284         @Override
285         protected InputStream getResourceAsStream(final String resourceLocation) {
286             if (resourceLocation.contains("-min.")) {
287                 fail("it should never ask for this");
288             }
289             assertEquals("neverminified.js", resourceLocation);
290             return newStream(NEVER_MINIFIED_CONTENT);
291         }
292 
293         private InputStream newStream(final String s) {
294             return new ByteArrayInputStream(s.getBytes());
295         }
296     }
297 
298 }