1 package com.atlassian.plugin.webresource;
2
3 import static java.util.Arrays.asList;
4 import static org.mockito.Mockito.mock;
5 import static org.mockito.Mockito.times;
6 import static org.mockito.Mockito.verify;
7 import static org.mockito.Mockito.when;
8
9 import com.atlassian.plugin.ModuleDescriptor;
10 import com.atlassian.plugin.Plugin;
11 import com.atlassian.plugin.PluginAccessor;
12 import com.atlassian.plugin.PluginInformation;
13 import com.atlassian.plugin.elements.ResourceDescriptor;
14 import com.atlassian.plugin.elements.ResourceLocation;
15 import com.atlassian.plugin.event.PluginEventManager;
16 import com.atlassian.plugin.servlet.DownloadableClasspathResource;
17 import com.atlassian.plugin.servlet.DownloadableResource;
18 import com.atlassian.plugin.servlet.ForwardableResource;
19 import com.atlassian.plugin.servlet.ServletContextFactory;
20 import com.atlassian.plugin.webresource.transformer.WebResourceTransformer;
21 import com.atlassian.plugin.webresource.transformer.WebResourceTransformerModuleDescriptor;
22
23 import org.dom4j.DocumentHelper;
24 import org.dom4j.Element;
25 import org.mockito.Mock;
26 import org.mockito.MockitoAnnotations;
27
28 import java.util.Arrays;
29 import java.util.Collections;
30 import java.util.HashMap;
31 import java.util.HashSet;
32 import java.util.List;
33 import java.util.Map;
34 import java.util.Set;
35 import java.util.TreeMap;
36
37 import junit.framework.TestCase;
38
39 public class TestPluginResourceLocatorImpl extends TestCase
40 {
41 private PluginResourceLocatorImpl pluginResourceLocator;
42 @Mock
43 private WebResourceIntegration mockWebResourceIntegration;
44 @Mock
45 private PluginAccessor mockPluginAccessor;
46 @Mock
47 private ServletContextFactory mockServletContextFactory;
48 @Mock
49 private ResourceBatchingConfiguration mockBatchingConfiguration;
50 @Mock
51 private WebResourceUrlProvider mockWebResourceUrlProvider;
52
53 @Mock
54 private PluginEventManager mockEventPublisher;
55
56 private static final String TEST_PLUGIN_KEY = "test.plugin";
57 private static final String TEST_MODULE_KEY = "web-resources";
58 private static final String TEST_MODULE_COMPLETE_KEY = TEST_PLUGIN_KEY + ":" + TEST_MODULE_KEY;
59
60 @Override
61 protected void setUp() throws Exception
62 {
63 super.setUp();
64
65 MockitoAnnotations.initMocks(this);
66 when(mockWebResourceIntegration.getPluginAccessor()).thenReturn(mockPluginAccessor);
67
68 pluginResourceLocator = new PluginResourceLocatorImpl(mockWebResourceIntegration, mockServletContextFactory, mockWebResourceUrlProvider,
69 mockBatchingConfiguration, mockEventPublisher);
70 }
71
72 @Override
73 protected void tearDown() throws Exception
74 {
75 pluginResourceLocator = null;
76 mockWebResourceIntegration = null;
77 mockPluginAccessor = null;
78 mockServletContextFactory = null;
79 mockBatchingConfiguration = null;
80 mockWebResourceUrlProvider = null;
81 mockEventPublisher = null;
82
83 super.tearDown();
84 }
85
86 public void testMatches()
87 {
88 assertTrue(pluginResourceLocator.matches("/download/superbatch/css/batch.css"));
89 assertTrue(pluginResourceLocator.matches("/download/superbatch/css/images/background/blah.gif"));
90 assertTrue(pluginResourceLocator.matches("/download/batch/plugin.key:module-key/plugin.key.js"));
91 assertTrue(pluginResourceLocator.matches("/download/resources/plugin.key:module-key/foo.png"));
92 assertTrue(pluginResourceLocator.matches("/download/contextbatch/css/contexta/batch.css"));
93 assertTrue(pluginResourceLocator.matches("/download/contextbatch/css/contexta/images/blah.png"));
94 }
95
96 public void testNotMatches()
97 {
98 assertFalse(pluginResourceLocator.matches("/superbatch/batch.css"));
99 assertFalse(pluginResourceLocator.matches("/download/blah.css"));
100 }
101
102 public void testGetAndParseUrl()
103 {
104 final SinglePluginResource resource = new SinglePluginResource("plugin.key:my-resources", "foo.css", false);
105 final String url = resource.getUrl();
106 assertTrue(pluginResourceLocator.matches(url));
107 }
108
109 public void testGetPluginResourcesWithoutBatching() throws Exception
110 {
111 final Plugin mockPlugin = mock(Plugin.class);
112 when(mockPlugin.getPluginsVersion()).thenReturn(1);
113
114 final List<ResourceDescriptor> resourceDescriptors = TestUtils.createResourceDescriptors("master-ie.css", "master.css", "comments.css");
115
116 when(mockPluginAccessor.getEnabledPluginModule(TEST_MODULE_COMPLETE_KEY)).thenReturn(
117 (ModuleDescriptor) TestUtils.createWebResourceModuleDescriptor(TEST_MODULE_COMPLETE_KEY, mockPlugin, resourceDescriptors));
118
119 when(mockBatchingConfiguration.isPluginWebResourceBatchingEnabled()).thenReturn(false);
120 final List<PluginResource> resources = pluginResourceLocator.getPluginResources(TEST_MODULE_COMPLETE_KEY);
121 assertEquals(3, resources.size());
122
123 for (final PluginResource resource : resources)
124 {
125 if (resource.getResourceName().contains("ie"))
126 {
127 assertEquals("true", resource.getParams().get("ieonly"));
128 }
129 else
130 {
131 assertNull(resource.getParams().get("ieonly"));
132 }
133 }
134 }
135
136 public void testGetPluginResourcesWithBatching() throws Exception
137 {
138 final Plugin mockPlugin = mock(Plugin.class);
139 when(mockPlugin.getPluginsVersion()).thenReturn(1);
140
141 final PluginInformation pluginInformation = mock(PluginInformation.class);
142 when(pluginInformation.getVersion()).thenReturn("4.4");
143 when(mockPlugin.getPluginInformation()).thenReturn(pluginInformation);
144
145 when(mockBatchingConfiguration.isPluginWebResourceBatchingEnabled()).thenReturn(true);
146
147 final List<ResourceDescriptor> resourceDescriptors = TestUtils.createResourceDescriptors("master-ie.css", "master.css", "comments.css");
148
149 when(mockPluginAccessor.getEnabledPluginModule(TEST_MODULE_COMPLETE_KEY)).thenReturn(
150 (ModuleDescriptor) TestUtils.createWebResourceModuleDescriptor(TEST_MODULE_COMPLETE_KEY, mockPlugin, resourceDescriptors));
151
152 final List<PluginResource> resources = pluginResourceLocator.getPluginResources(TEST_MODULE_COMPLETE_KEY);
153 assertEquals(2, resources.size());
154
155 final BatchPluginResource ieBatch = (BatchPluginResource) resources.get(0);
156 assertEquals(TEST_MODULE_COMPLETE_KEY, ieBatch.getModuleCompleteKey());
157 assertEquals("css", ieBatch.getType());
158 assertEquals(1, ieBatch.getParams().size());
159 assertEquals("true", ieBatch.getParams().get("ieonly"));
160
161 final BatchPluginResource batch = (BatchPluginResource) resources.get(1);
162 assertEquals(TEST_MODULE_COMPLETE_KEY, batch.getModuleCompleteKey());
163 assertEquals("css", batch.getType());
164 assertEquals(0, batch.getParams().size());
165 }
166
167 public void testGetPluginResourcesWithBatchParameter() throws Exception
168 {
169 final Plugin mockPlugin = mock(Plugin.class);
170 when(mockPlugin.getPluginsVersion()).thenReturn(1);
171
172 final PluginInformation pluginInformation = mock(PluginInformation.class);
173 when(pluginInformation.getVersion()).thenReturn("4.4");
174 when(mockPlugin.getPluginInformation()).thenReturn(pluginInformation);
175
176 when(mockBatchingConfiguration.isPluginWebResourceBatchingEnabled()).thenReturn(true);
177
178 final List<ResourceDescriptor> resourceDescriptors = TestUtils.createResourceDescriptors("master.css", "comments.css");
179 final Map<String, String> nonBatchParams = new TreeMap<String, String>();
180 nonBatchParams.put("batch", "false");
181 resourceDescriptors.add(TestUtils.createResourceDescriptor("nonbatch.css", nonBatchParams));
182
183 when(mockPluginAccessor.getEnabledPluginModule(TEST_MODULE_COMPLETE_KEY)).thenReturn(
184 (ModuleDescriptor) TestUtils.createWebResourceModuleDescriptor(TEST_MODULE_COMPLETE_KEY, mockPlugin, resourceDescriptors));
185
186 final List<PluginResource> resources = pluginResourceLocator.getPluginResources(TEST_MODULE_COMPLETE_KEY);
187 assertEquals(2, resources.size());
188
189 final BatchPluginResource batch = (BatchPluginResource) resources.get(0);
190 assertEquals(TEST_MODULE_COMPLETE_KEY, batch.getModuleCompleteKey());
191 assertEquals("css", batch.getType());
192 assertEquals(0, batch.getParams().size());
193
194 final SinglePluginResource single = (SinglePluginResource) resources.get(1);
195 assertEquals(TEST_MODULE_COMPLETE_KEY, single.getModuleCompleteKey());
196 }
197
198 public void testGetPluginResourcesWithForwarding() throws Exception
199 {
200 final Plugin mockPlugin = mock(Plugin.class);
201 when(mockPlugin.getPluginsVersion()).thenReturn(1);
202
203 final PluginInformation pluginInformation = mock(PluginInformation.class);
204 when(pluginInformation.getVersion()).thenReturn("4.4");
205 when(mockPlugin.getPluginInformation()).thenReturn(pluginInformation);
206
207 when(mockBatchingConfiguration.isPluginWebResourceBatchingEnabled()).thenReturn(true);
208
209 final List<ResourceDescriptor> resourceDescriptors = TestUtils.createResourceDescriptors("master.css", "comments.css");
210 final Map<String, String> params = new TreeMap<String, String>();
211 params.put("source", "webContext");
212 resourceDescriptors.add(TestUtils.createResourceDescriptor("forward.css", params));
213
214 when(mockPluginAccessor.getEnabledPluginModule(TEST_MODULE_COMPLETE_KEY)).thenReturn(
215 (ModuleDescriptor) TestUtils.createWebResourceModuleDescriptor(TEST_MODULE_COMPLETE_KEY, mockPlugin, resourceDescriptors));
216
217 final List<PluginResource> resources = pluginResourceLocator.getPluginResources(TEST_MODULE_COMPLETE_KEY);
218 assertEquals(2, resources.size());
219
220 final BatchPluginResource batch = (BatchPluginResource) resources.get(0);
221 assertEquals(TEST_MODULE_COMPLETE_KEY, batch.getModuleCompleteKey());
222 assertEquals("css", batch.getType());
223 assertEquals(0, batch.getParams().size());
224
225 final SinglePluginResource single = (SinglePluginResource) resources.get(1);
226 assertEquals(TEST_MODULE_COMPLETE_KEY, single.getModuleCompleteKey());
227 }
228
229 public void testGetForwardableResource() throws Exception
230 {
231 final String resourceName = "test.css";
232 final String url = "/download/resources/" + TEST_MODULE_COMPLETE_KEY + "/" + resourceName;
233 final Map<String, String> params = new TreeMap<String, String>();
234 params.put("source", "webContext");
235
236 final Plugin mockPlugin = mock(Plugin.class);
237 final ModuleDescriptor mockModuleDescriptor = mock(ModuleDescriptor.class);
238 when(mockModuleDescriptor.getPluginKey()).thenReturn(TEST_PLUGIN_KEY);
239 when(mockModuleDescriptor.getResourceLocation("download", resourceName)).thenReturn(
240 new ResourceLocation("", resourceName, "download", "text/css", "", params));
241
242 when(mockPluginAccessor.getEnabledPluginModule(TEST_MODULE_COMPLETE_KEY)).thenReturn(mockModuleDescriptor);
243 when(mockPluginAccessor.getPlugin(TEST_PLUGIN_KEY)).thenReturn(mockPlugin);
244
245 final DownloadableResource resource = pluginResourceLocator.getDownloadableResource(url, Collections.<String, String> emptyMap());
246
247 assertTrue(resource instanceof ForwardableResource);
248 }
249
250 public void testGetDownloadableClasspathResource() throws Exception
251 {
252 final String resourceName = "test.css";
253 final String url = "/download/resources/" + TEST_MODULE_COMPLETE_KEY + "/" + resourceName;
254
255 final Plugin mockPlugin = mock(Plugin.class);
256 final ModuleDescriptor mockModuleDescriptor = mock(ModuleDescriptor.class);
257 when(mockModuleDescriptor.getPluginKey()).thenReturn(TEST_PLUGIN_KEY);
258 when(mockModuleDescriptor.getResourceLocation("download", resourceName)).thenReturn(
259 new ResourceLocation("", resourceName, "download", "text/css", "", Collections.<String, String> emptyMap()));
260
261 when(mockPluginAccessor.getEnabledPluginModule(TEST_MODULE_COMPLETE_KEY)).thenReturn(mockModuleDescriptor);
262 when(mockPluginAccessor.getPlugin(TEST_PLUGIN_KEY)).thenReturn(mockPlugin);
263
264 final DownloadableResource resource = pluginResourceLocator.getDownloadableResource(url, Collections.<String, String> emptyMap());
265
266 assertTrue(resource instanceof DownloadableClasspathResource);
267 }
268
269 public void testGetTransformedDownloadableClasspathResource() throws Exception
270 {
271 final String resourceName = "test.js";
272 final String url = "/download/resources/" + TEST_MODULE_COMPLETE_KEY + "/" + resourceName;
273
274 final DownloadableResource transformedResource = mock(DownloadableResource.class);
275 final WebResourceTransformation trans = new WebResourceTransformation(DocumentHelper.parseText(
276 "<transformation extension=\"js\">\n" + "<transformer key=\"foo\" />\n" + "</transformation>").getRootElement());
277 final WebResourceTransformer transformer = new WebResourceTransformer()
278 {
279 public DownloadableResource transform(final Element configElement, final ResourceLocation location, final String filePath, final DownloadableResource nextResource)
280 {
281 return transformedResource;
282 }
283 };
284
285 final WebResourceTransformerModuleDescriptor transDescriptor = mock(WebResourceTransformerModuleDescriptor.class);
286 when(transDescriptor.getKey()).thenReturn("foo");
287 when(transDescriptor.getModule()).thenReturn(transformer);
288
289 final Plugin mockPlugin = mock(Plugin.class);
290 final WebResourceModuleDescriptor descriptor = mock(WebResourceModuleDescriptor.class);
291 when(descriptor.getPluginKey()).thenReturn(TEST_PLUGIN_KEY);
292 when(descriptor.getResourceLocation("download", resourceName)).thenReturn(
293 new ResourceLocation("", resourceName, "download", "text/css", "", Collections.<String, String> emptyMap()));
294 when(descriptor.getTransformations()).thenReturn(Arrays.asList(trans));
295
296 when(mockPluginAccessor.getEnabledModuleDescriptorsByClass(WebResourceTransformerModuleDescriptor.class)).thenReturn(
297 Arrays.asList(transDescriptor));
298 when(mockPluginAccessor.getEnabledPluginModule(TEST_MODULE_COMPLETE_KEY)).thenReturn((ModuleDescriptor) descriptor);
299 when(mockPluginAccessor.getPlugin(TEST_PLUGIN_KEY)).thenReturn(mockPlugin);
300
301 final DownloadableResource resource = pluginResourceLocator.getDownloadableResource(url, Collections.<String, String> emptyMap());
302
303 assertTrue(resource == transformedResource);
304 }
305
306 public void testGetUnmatchedTransformDownloadableClasspathResource() throws Exception
307 {
308 final String resourceName = "test.css";
309 final String url = "/download/resources/" + TEST_MODULE_COMPLETE_KEY + "/" + resourceName;
310
311 final DownloadableResource transformedResource = mock(DownloadableResource.class);
312 final WebResourceTransformation trans = new WebResourceTransformation(DocumentHelper.parseText(
313 "<transformation extension=\"js\">\n" + "<transformer key=\"foo\" />\n" + "</transformation>").getRootElement());
314 final WebResourceTransformer transformer = new WebResourceTransformer()
315 {
316 public DownloadableResource transform(final Element configElement, final ResourceLocation location, final String extraPath, final DownloadableResource nextResource)
317 {
318 return transformedResource;
319 }
320 };
321
322 final WebResourceTransformerModuleDescriptor transDescriptor = mock(WebResourceTransformerModuleDescriptor.class);
323 when(transDescriptor.getKey()).thenReturn("foo");
324 when(transDescriptor.getModule()).thenReturn(transformer);
325
326 final Plugin mockPlugin = mock(Plugin.class);
327 final WebResourceModuleDescriptor descriptor = mock(WebResourceModuleDescriptor.class);
328 when(descriptor.getPluginKey()).thenReturn(TEST_PLUGIN_KEY);
329 when(descriptor.getResourceLocation("download", resourceName)).thenReturn(
330 new ResourceLocation("", resourceName, "download", "text/css", "", Collections.<String, String> emptyMap()));
331 when(descriptor.getTransformations()).thenReturn(Arrays.asList(trans));
332
333 when(mockPluginAccessor.getEnabledModuleDescriptorsByClass(WebResourceTransformerModuleDescriptor.class)).thenReturn(
334 Arrays.asList(transDescriptor));
335 when(mockPluginAccessor.getEnabledPluginModule(TEST_MODULE_COMPLETE_KEY)).thenReturn((ModuleDescriptor) descriptor);
336 when(mockPluginAccessor.getPlugin(TEST_PLUGIN_KEY)).thenReturn(mockPlugin);
337
338 final DownloadableResource resource = pluginResourceLocator.getDownloadableResource(url, Collections.<String, String> emptyMap());
339
340 assertTrue(resource instanceof DownloadableClasspathResource);
341 }
342
343 public void testGetMissingTransformerDownloadableClasspathResource() throws Exception
344 {
345 final String resourceName = "test.css";
346 final String url = "/download/resources/" + TEST_MODULE_COMPLETE_KEY + "/" + resourceName;
347
348 final DownloadableResource transformedResource = mock(DownloadableResource.class);
349 final WebResourceTransformation trans = new WebResourceTransformation(DocumentHelper.parseText(
350 "<transformation extension=\"js\">\n" + "<transformer key=\"foo\" />\n" + "</transformation>").getRootElement());
351 final WebResourceTransformer transformer = new WebResourceTransformer()
352 {
353 public DownloadableResource transform(final Element configElement, final ResourceLocation location, final String extraPath, final DownloadableResource nextResource)
354 {
355 return transformedResource;
356 }
357 };
358
359 final WebResourceTransformerModuleDescriptor transDescriptor = mock(WebResourceTransformerModuleDescriptor.class);
360 when(transDescriptor.getKey()).thenReturn("bar");
361 when(transDescriptor.getModule()).thenReturn(transformer);
362
363 final Plugin mockPlugin = mock(Plugin.class);
364 final WebResourceModuleDescriptor descriptor = mock(WebResourceModuleDescriptor.class);
365 when(descriptor.getPluginKey()).thenReturn(TEST_PLUGIN_KEY);
366 when(descriptor.getResourceLocation("download", resourceName)).thenReturn(
367 new ResourceLocation("", resourceName, "download", "text/css", "", Collections.<String, String> emptyMap()));
368 when(descriptor.getTransformations()).thenReturn(Arrays.asList(trans));
369
370 when(mockPluginAccessor.getEnabledModuleDescriptorsByClass(WebResourceTransformerModuleDescriptor.class)).thenReturn(
371 Arrays.asList(transDescriptor));
372 when(mockPluginAccessor.getEnabledPluginModule(TEST_MODULE_COMPLETE_KEY)).thenReturn((ModuleDescriptor) descriptor);
373 when(mockPluginAccessor.getPlugin(TEST_PLUGIN_KEY)).thenReturn(mockPlugin);
374
375 final DownloadableResource resource = pluginResourceLocator.getDownloadableResource(url, Collections.<String, String> emptyMap());
376
377 assertTrue(resource instanceof DownloadableClasspathResource);
378 }
379
380 public void testGetDownloadableBatchResource() throws Exception
381 {
382 final String url = "/download/batch/" + TEST_MODULE_COMPLETE_KEY + "/all.css";
383 final String ieResourceName = "master-ie.css";
384 final Map<String, String> params = new TreeMap<String, String>();
385 params.put("ieonly", "true");
386
387 final List<ResourceDescriptor> resourceDescriptors = TestUtils.createResourceDescriptors(ieResourceName, "master.css");
388
389 final Plugin mockPlugin = mock(Plugin.class);
390 final ModuleDescriptor mockModuleDescriptor = mock(ModuleDescriptor.class);
391 when(mockModuleDescriptor.getPluginKey()).thenReturn(TEST_PLUGIN_KEY);
392 when(mockModuleDescriptor.getCompleteKey()).thenReturn(TEST_MODULE_COMPLETE_KEY);
393 when(mockModuleDescriptor.getResourceDescriptors()).thenReturn(resourceDescriptors);
394 when(mockModuleDescriptor.getResourceLocation("download", ieResourceName)).thenReturn(
395 new ResourceLocation("", ieResourceName, "download", "text/css", "", Collections.<String, String> emptyMap()));
396
397 when(mockPluginAccessor.isPluginModuleEnabled(TEST_MODULE_COMPLETE_KEY)).thenReturn(Boolean.TRUE);
398 when(mockPluginAccessor.getEnabledPluginModule(TEST_MODULE_COMPLETE_KEY)).thenReturn(mockModuleDescriptor);
399 when(mockPluginAccessor.getPluginModule(TEST_MODULE_COMPLETE_KEY)).thenReturn(mockModuleDescriptor);
400 when(mockPluginAccessor.getPlugin(TEST_PLUGIN_KEY)).thenReturn(mockPlugin);
401
402 final DownloadableResource resource = pluginResourceLocator.getDownloadableResource(url, params);
403
404 assertTrue(resource instanceof BatchDownloadableResource);
405 }
406
407 public void testGetDownloadableBatchResourceWithConditionalComments() throws Exception
408 {
409 final String url = "/download/batch/" + TEST_MODULE_COMPLETE_KEY + "/all.css";
410 final String ieResourceName = "master-conditional.css";
411 final Map<String, String> params = new TreeMap<String, String>();
412 params.put("conditionalComment", "IE");
413
414 final List<ResourceDescriptor> resourceDescriptors = asList(TestUtils.createResourceDescriptor(ieResourceName, new HashMap<String, String>(
415 params)), TestUtils.createResourceDescriptor(ieResourceName));
416
417 final Plugin mockPlugin = mock(Plugin.class);
418 final ModuleDescriptor mockModuleDescriptor = mock(ModuleDescriptor.class);
419 when(mockModuleDescriptor.getPluginKey()).thenReturn(TEST_PLUGIN_KEY);
420 when(mockModuleDescriptor.getCompleteKey()).thenReturn(TEST_MODULE_COMPLETE_KEY);
421 when(mockModuleDescriptor.getResourceDescriptors()).thenReturn(resourceDescriptors);
422 when(mockModuleDescriptor.getResourceLocation("download", ieResourceName)).thenReturn(
423 new ResourceLocation("", ieResourceName, "download", "text/css", "", Collections.<String, String> emptyMap()));
424
425 when(mockPluginAccessor.isPluginModuleEnabled(TEST_MODULE_COMPLETE_KEY)).thenReturn(Boolean.TRUE);
426 when(mockPluginAccessor.getEnabledPluginModule(TEST_MODULE_COMPLETE_KEY)).thenReturn(mockModuleDescriptor);
427 when(mockPluginAccessor.getPluginModule(TEST_MODULE_COMPLETE_KEY)).thenReturn(mockModuleDescriptor);
428 when(mockPluginAccessor.getPlugin(TEST_PLUGIN_KEY)).thenReturn(mockPlugin);
429
430 final DownloadableResource resource = pluginResourceLocator.getDownloadableResource(url, params);
431
432 assertTrue(resource instanceof BatchDownloadableResource);
433 }
434
435 public void testGetDownloadableBatchResourceWhenModuleIsUnkown() throws Exception
436 {
437 final String url = "/download/batch/" + TEST_MODULE_COMPLETE_KEY + "invalid.stuff" + "/all.css";
438 final Map<String, String> params = new TreeMap<String, String>();
439 params.put("ieonly", "true");
440
441 when(mockPluginAccessor.getEnabledPluginModule(TEST_MODULE_COMPLETE_KEY + "invalid.stuff")).thenReturn(null);
442
443 final DownloadableResource resource = pluginResourceLocator.getDownloadableResource(url, params);
444 assertNull(resource);
445 }
446
447 public void testGetDownloadableBatchResourceFallbacksToSingle() throws Exception
448 {
449 final String resourceName = "images/foo.png";
450 final String url = "/download/batch/" + TEST_MODULE_COMPLETE_KEY + "/" + resourceName;
451
452 final Plugin mockPlugin = mock(Plugin.class);
453 final ModuleDescriptor mockModuleDescriptor = mock(ModuleDescriptor.class);
454 when(mockModuleDescriptor.getPluginKey()).thenReturn(TEST_PLUGIN_KEY);
455 when(mockModuleDescriptor.getCompleteKey()).thenReturn(TEST_MODULE_COMPLETE_KEY);
456 when(mockModuleDescriptor.getResourceLocation("download", resourceName)).thenReturn(
457 new ResourceLocation("", resourceName, "download", "text/css", "", Collections.<String, String> emptyMap()));
458
459 when(mockPluginAccessor.isPluginModuleEnabled(TEST_MODULE_COMPLETE_KEY)).thenReturn(Boolean.TRUE);
460 when(mockPluginAccessor.getEnabledPluginModule(TEST_MODULE_COMPLETE_KEY)).thenReturn(mockModuleDescriptor);
461 when(mockPluginAccessor.getPluginModule(TEST_MODULE_COMPLETE_KEY)).thenReturn(mockModuleDescriptor);
462 when(mockPluginAccessor.getPlugin(TEST_PLUGIN_KEY)).thenReturn(mockPlugin);
463
464 final DownloadableResource resource = pluginResourceLocator.getDownloadableResource(url, Collections.<String, String> emptyMap());
465
466 assertTrue(resource instanceof DownloadableClasspathResource);
467 }
468
469 public void testGetDownloadableSuperBatchResource() throws Exception
470 {
471 final String url = "/download/superbatch/css/batch.css";
472
473 final Plugin testPlugin = TestUtils.createTestPlugin(TEST_PLUGIN_KEY, "1");
474 final List<ResourceDescriptor> resourceDescriptors = TestUtils.createResourceDescriptors("atlassian.css", "master.css");
475
476 final WebResourceModuleDescriptor webModuleDescriptor = TestUtils.createWebResourceModuleDescriptor(TEST_MODULE_COMPLETE_KEY, testPlugin,
477 resourceDescriptors);
478
479 when(mockWebResourceIntegration.getSuperBatchVersion()).thenReturn("1.0");
480 when(mockBatchingConfiguration.isSuperBatchingEnabled()).thenReturn(true);
481 when(mockBatchingConfiguration.getSuperBatchModuleCompleteKeys()).thenReturn(Arrays.asList(TEST_MODULE_COMPLETE_KEY));
482
483 when(mockPluginAccessor.getEnabledPluginModule(TEST_MODULE_COMPLETE_KEY)).thenReturn((ModuleDescriptor) webModuleDescriptor);
484 when(mockPluginAccessor.getPlugin(TEST_PLUGIN_KEY)).thenReturn(testPlugin);
485
486 final DownloadableResource resource = pluginResourceLocator.getDownloadableResource(url, Collections.<String, String> emptyMap());
487 assertTrue(resource instanceof SuperBatchDownloadableResource);
488
489 final SuperBatchDownloadableResource superBatchPluginResource = (SuperBatchDownloadableResource) resource;
490 assertFalse(superBatchPluginResource.isEmpty());
491 }
492
493 public void testGetDownloadableSuperBatchSubResource() throws Exception
494 {
495 final String url = "/download/superbatch/css/images/foo.png";
496 final String cssResourcesXml = "<resource name=\"css/\" type=\"download\" location=\"css/images/\" />";
497
498 final List<ResourceDescriptor> resourceDescriptors = TestUtils.createResourceDescriptors("atlassian.css", "master.css");
499 resourceDescriptors.add(new ResourceDescriptor(DocumentHelper.parseText(cssResourcesXml).getRootElement()));
500
501 final Plugin testPlugin = TestUtils.createTestPlugin(TEST_PLUGIN_KEY, "1");
502 final WebResourceModuleDescriptor webModuleDescriptor = TestUtils.createWebResourceModuleDescriptor(TEST_MODULE_COMPLETE_KEY, testPlugin,
503 resourceDescriptors);
504
505 when(mockWebResourceIntegration.getSuperBatchVersion()).thenReturn("1.0");
506 when(mockBatchingConfiguration.isSuperBatchingEnabled()).thenReturn(true);
507 when(mockBatchingConfiguration.getSuperBatchModuleCompleteKeys()).thenReturn(Arrays.asList(TEST_MODULE_COMPLETE_KEY));
508
509 when(mockPluginAccessor.getEnabledPluginModule(TEST_MODULE_COMPLETE_KEY)).thenReturn((ModuleDescriptor) webModuleDescriptor);
510 when(mockPluginAccessor.getPlugin(TEST_PLUGIN_KEY)).thenReturn(testPlugin);
511
512 final DownloadableResource resource = pluginResourceLocator.getDownloadableResource(url, Collections.<String, String> emptyMap());
513 assertTrue(resource instanceof DownloadableClasspathResource);
514 }
515
516 public void testGetDownloadableContextBatchSubResource() throws Exception
517 {
518 final String url = "/download/contextbatch/css/contexta,contextb/images/foo.png";
519 final String cssResourcesXml = "<resource name=\"css/\" type=\"download\" location=\"css/images/\" />";
520
521 final List<ResourceDescriptor> resourceDescriptors = TestUtils.createResourceDescriptors("atlassian.css", "master.css");
522 resourceDescriptors.add(new ResourceDescriptor(DocumentHelper.parseText(cssResourcesXml).getRootElement()));
523
524 final String context = "contexta";
525 final Set<String> contexts = new HashSet<String>();
526 contexts.add(context);
527
528 final Plugin testPlugin = TestUtils.createTestPlugin(TEST_PLUGIN_KEY, "1");
529 final WebResourceModuleDescriptor webModuleDescriptor = TestUtils.createWebResourceModuleDescriptor(TEST_MODULE_COMPLETE_KEY, testPlugin,
530 resourceDescriptors, Collections.<String> emptyList(), contexts);
531
532 when(mockPluginAccessor.getEnabledModuleDescriptorsByClass(WebResourceModuleDescriptor.class)).thenReturn(Arrays.asList(webModuleDescriptor));
533 when(mockPluginAccessor.getEnabledPluginModule(TEST_MODULE_COMPLETE_KEY)).thenReturn((ModuleDescriptor) webModuleDescriptor);
534 when(mockPluginAccessor.getPlugin(TEST_PLUGIN_KEY)).thenReturn(testPlugin);
535
536 final DownloadableResource resource = pluginResourceLocator.getDownloadableResource(url, Collections.<String, String> emptyMap());
537 assertTrue(resource instanceof DownloadableClasspathResource);
538 }
539
540 public void testGetDownloadableContextBatchResource() throws Exception
541 {
542 final Set<String> contexts = new HashSet<String>();
543 final String context = "contextA";
544 contexts.add(context);
545 contexts.add("contextB");
546 final String url = "/download/contextbatch/css/contextA/batch.css";
547 final List<ResourceDescriptor> resourceDescriptors = TestUtils.createResourceDescriptors("atlassian.css", "master.css");
548
549 final Plugin testPlugin = TestUtils.createTestPlugin(TEST_PLUGIN_KEY, "1");
550 final WebResourceModuleDescriptor webModuleDescriptor = TestUtils.createWebResourceModuleDescriptor(TEST_MODULE_COMPLETE_KEY, testPlugin,
551 resourceDescriptors, Collections.<String> emptyList(), contexts);
552
553 when(mockPluginAccessor.getEnabledModuleDescriptorsByClass(WebResourceModuleDescriptor.class)).thenReturn(Arrays.asList(webModuleDescriptor));
554 when(mockPluginAccessor.getEnabledPluginModule(TEST_MODULE_COMPLETE_KEY)).thenReturn((ModuleDescriptor) webModuleDescriptor);
555
556 final DownloadableResource resource = pluginResourceLocator.getDownloadableResource(url, Collections.<String, String> emptyMap());
557 assertTrue(resource instanceof ContextBatchDownloadableResource);
558
559 verify(mockPluginAccessor, times(3)).getEnabledPluginModule(TEST_MODULE_COMPLETE_KEY);
560 }
561
562 public void testGetDownloadableMergedContextBatchResource() throws Exception
563 {
564 final Set<String> contexts1 = new HashSet<String>();
565 final String context1 = "contextA";
566 contexts1.add(context1);
567
568 final Set<String> contexts2 = new HashSet<String>();
569 final String context2 = "contextB";
570 contexts2.add(context2);
571 final String url = "/download/contextbatch/css/contextA,contextB/batch.css";
572
573 final Plugin testPlugin = TestUtils.createTestPlugin(TEST_PLUGIN_KEY, "1");
574
575 final List<ResourceDescriptor> resourceDescriptors1 = TestUtils.createResourceDescriptors("atlassian.css", "master.css");
576 final String completeKey1 = TEST_PLUGIN_KEY + ":" + "a-resources";
577 final WebResourceModuleDescriptor webModuleDescriptor1 = TestUtils.createWebResourceModuleDescriptor(completeKey1, testPlugin,
578 resourceDescriptors1, Collections.<String> emptyList(), contexts1);
579
580 final List<ResourceDescriptor> resourceDescriptors2 = TestUtils.createResourceDescriptors("test.css", "default.css");
581 final String completeKey2 = TEST_PLUGIN_KEY + ":" + "b-resources";
582 final WebResourceModuleDescriptor webModuleDescriptor2 = TestUtils.createWebResourceModuleDescriptor(completeKey2, testPlugin,
583 resourceDescriptors2, Collections.<String> emptyList(), contexts2);
584
585 when(mockPluginAccessor.getEnabledModuleDescriptorsByClass(WebResourceModuleDescriptor.class)).thenReturn(
586 Arrays.asList(webModuleDescriptor1, webModuleDescriptor2));
587
588 when(mockPluginAccessor.getEnabledPluginModule(completeKey1)).thenReturn((ModuleDescriptor) webModuleDescriptor1);
589 when(mockPluginAccessor.getEnabledPluginModule(completeKey2)).thenReturn((ModuleDescriptor) webModuleDescriptor2);
590
591 final DownloadableResource resource = pluginResourceLocator.getDownloadableResource(url, Collections.<String, String> emptyMap());
592 assertTrue(resource instanceof ContextBatchDownloadableResource);
593
594 verify(mockPluginAccessor, times(3)).getEnabledPluginModule(completeKey1);
595 verify(mockPluginAccessor, times(3)).getEnabledPluginModule(completeKey2);
596 }
597
598 public void testGetDownloadableMergedContextBatchResourceWithOverlap() throws Exception
599 {
600 final Set<String> contexts1 = new HashSet<String>();
601 final String context1 = "contextA";
602 contexts1.add(context1);
603
604 final Set<String> contexts2 = new HashSet<String>();
605 final String context2 = "contextB";
606 contexts2.add(context2);
607 final String url = "/download/contextbatch/css/contextA,contextB/batch.css";
608
609 final Plugin testPlugin = TestUtils.createTestPlugin(TEST_PLUGIN_KEY, "1");
610
611 final List<ResourceDescriptor> parentResourceDescriptors = TestUtils.createResourceDescriptors("parent.css");
612 final String parentKey = TEST_PLUGIN_KEY + ":" + "parent-resources";
613 final WebResourceModuleDescriptor parentWebModuleDescriptor = TestUtils.createWebResourceModuleDescriptor(parentKey, testPlugin,
614 parentResourceDescriptors);
615
616 final List<ResourceDescriptor> resourceDescriptors1 = TestUtils.createResourceDescriptors("atlassian.css", "master.css");
617 final String completeKey1 = TEST_PLUGIN_KEY + ":" + "a-resources";
618 final WebResourceModuleDescriptor webModuleDescriptor1 = TestUtils.createWebResourceModuleDescriptor(completeKey1, testPlugin,
619 resourceDescriptors1, Arrays.asList(parentKey), contexts1);
620
621 final List<ResourceDescriptor> resourceDescriptors2 = TestUtils.createResourceDescriptors("test.css", "default.css");
622 final String completeKey2 = TEST_PLUGIN_KEY + ":" + "b-resources";
623 final WebResourceModuleDescriptor webModuleDescriptor2 = TestUtils.createWebResourceModuleDescriptor(completeKey2, testPlugin,
624 resourceDescriptors2, Arrays.asList(parentKey), contexts2);
625
626 when(mockPluginAccessor.getEnabledModuleDescriptorsByClass(WebResourceModuleDescriptor.class)).thenReturn(
627 Arrays.asList(parentWebModuleDescriptor, webModuleDescriptor1, webModuleDescriptor2));
628
629 when(mockPluginAccessor.getEnabledPluginModule(parentKey)).thenReturn((ModuleDescriptor) parentWebModuleDescriptor);
630 when(mockPluginAccessor.getEnabledPluginModule(completeKey1)).thenReturn((ModuleDescriptor) webModuleDescriptor1);
631 when(mockPluginAccessor.getEnabledPluginModule(completeKey2)).thenReturn((ModuleDescriptor) webModuleDescriptor2);
632
633 final DownloadableResource resource = pluginResourceLocator.getDownloadableResource(url, Collections.<String, String> emptyMap());
634 assertTrue(resource instanceof ContextBatchDownloadableResource);
635
636 verify(mockPluginAccessor, times(3)).getEnabledPluginModule(completeKey1);
637 verify(mockPluginAccessor, times(3)).getEnabledPluginModule(completeKey2);
638
639
640
641
642 verify(mockPluginAccessor, times(3)).getEnabledPluginModule(parentKey);
643 }
644
645 public void testSplitLastPathPart()
646 {
647 final String[] parts = pluginResourceLocator.splitLastPathPart("http://localhost:8080/confluence/download/foo/bar/baz");
648 assertEquals(2, parts.length);
649 assertEquals("http://localhost:8080/confluence/download/foo/bar/", parts[0]);
650 assertEquals("baz", parts[1]);
651
652 final String[] anotherParts = pluginResourceLocator.splitLastPathPart(parts[0]);
653 assertEquals(2, anotherParts.length);
654 assertEquals("http://localhost:8080/confluence/download/foo/", anotherParts[0]);
655 assertEquals("bar/", anotherParts[1]);
656
657 assertNull(pluginResourceLocator.splitLastPathPart("noslashes"));
658 }
659 }