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