1 package com.atlassian.plugin.webresource;
2
3 import com.atlassian.plugin.Plugin;
4 import com.atlassian.plugin.PluginAccessor;
5 import com.atlassian.plugin.elements.ResourceDescriptor;
6 import com.atlassian.plugin.impl.StaticPlugin;
7 import com.atlassian.plugin.servlet.AbstractFileServerServlet;
8 import com.mockobjects.dynamic.C;
9 import com.mockobjects.dynamic.Mock;
10 import junit.framework.TestCase;
11
12 import java.io.StringWriter;
13 import java.util.Arrays;
14 import java.util.Collection;
15 import java.util.Collections;
16 import java.util.HashMap;
17 import java.util.HashSet;
18 import java.util.List;
19 import java.util.Map;
20
21 import org.dom4j.DocumentException;
22
23 public class TestWebResourceManagerImpl extends TestCase
24 {
25
26 private Mock mockWebResourceIntegration;
27 private Mock mockPluginAccessor;
28 private WebResourceManagerImpl webResourceManager;
29 private PluginResourceLocator pluginResourceLocator;
30 private TestResourceBatchingConfiguration resourceBatchingConfiguration;
31 private Plugin testPlugin;
32
33 private static final String ANIMAL_PLUGIN_VERSION = "2";
34 private static final String BASEURL = "http://www.foo.com";
35 private static final String SYSTEM_COUNTER = "123";
36 private static final String SYSTEM_BUILD_NUMBER = "650";
37
38 protected void setUp() throws Exception
39 {
40 super.setUp();
41
42 mockPluginAccessor = new Mock(PluginAccessor.class);
43
44 mockWebResourceIntegration = new Mock(WebResourceIntegration.class);
45 mockWebResourceIntegration.matchAndReturn("getPluginAccessor", mockPluginAccessor.proxy());
46
47 resourceBatchingConfiguration = new TestResourceBatchingConfiguration();
48 pluginResourceLocator = new PluginResourceLocatorImpl((WebResourceIntegration) mockWebResourceIntegration.proxy(), null);
49 webResourceManager = new WebResourceManagerImpl(pluginResourceLocator, (WebResourceIntegration) mockWebResourceIntegration.proxy(), resourceBatchingConfiguration);
50
51
52 mockWebResourceIntegration.matchAndReturn("getBaseUrl", BASEURL);
53 mockWebResourceIntegration.matchAndReturn("getBaseUrl", C.args(C.eq(UrlMode.ABSOLUTE)), BASEURL);
54 mockWebResourceIntegration.matchAndReturn("getBaseUrl", C.args(C.eq(UrlMode.RELATIVE)), "");
55 mockWebResourceIntegration.matchAndReturn("getBaseUrl", C.args(C.eq(UrlMode.AUTO)), "");
56 mockWebResourceIntegration.matchAndReturn("getSystemBuildNumber", SYSTEM_BUILD_NUMBER);
57 mockWebResourceIntegration.matchAndReturn("getSystemCounter", SYSTEM_COUNTER);
58 mockWebResourceIntegration.matchAndReturn("getSuperBatchVersion", "12");
59
60 testPlugin = TestUtils.createTestPlugin();
61 }
62
63 protected void tearDown() throws Exception
64 {
65 webResourceManager = null;
66 mockPluginAccessor = null;
67 mockWebResourceIntegration = null;
68 testPlugin = null;
69 resourceBatchingConfiguration = null;
70
71 super.tearDown();
72 }
73
74 public void testRequireResources()
75 {
76 String resource1 = "test.atlassian:cool-stuff";
77 String resource2 = "test.atlassian:hot-stuff";
78
79 mockPluginAccessor.matchAndReturn("getEnabledPluginModule", C.args(C.eq(resource1)),
80 TestUtils.createWebResourceModuleDescriptor(resource1, testPlugin));
81 mockPluginAccessor.matchAndReturn("getEnabledPluginModule", C.args(C.eq(resource2)),
82 TestUtils.createWebResourceModuleDescriptor(resource2, testPlugin));
83
84 Map requestCache = setupRequestCache();
85 webResourceManager.requireResource(resource1);
86 webResourceManager.requireResource(resource2);
87 webResourceManager.requireResource(resource1);
88
89 Collection resources = (Collection) requestCache.get(WebResourceManagerImpl.REQUEST_CACHE_RESOURCE_KEY);
90 assertEquals(2, resources.size());
91 assertTrue(resources.contains(resource1));
92 assertTrue(resources.contains(resource2));
93 }
94
95 public void testRequireResourcesWithDependencies()
96 {
97 String resource = "test.atlassian:cool-stuff";
98 String dependencyResource = "test.atlassian:hot-stuff";
99
100
101 mockPluginAccessor.matchAndReturn("getEnabledPluginModule", C.args(C.eq(resource)),
102 TestUtils.createWebResourceModuleDescriptor(resource, testPlugin, Collections.EMPTY_LIST, Collections.singletonList(dependencyResource)));
103 mockPluginAccessor.matchAndReturn("getEnabledPluginModule", C.args(C.eq(dependencyResource)),
104 TestUtils.createWebResourceModuleDescriptor(dependencyResource, testPlugin));
105
106 Map requestCache = setupRequestCache();
107 webResourceManager.requireResource(resource);
108
109 Collection resources = (Collection) requestCache.get(WebResourceManagerImpl.REQUEST_CACHE_RESOURCE_KEY);
110 assertEquals(2, resources.size());
111 Object[] resourceArray = resources.toArray();
112 assertEquals(dependencyResource, resourceArray[0]);
113 assertEquals(resource, resourceArray[1]);
114 }
115
116 public void testRequireResourcesWithCyclicDependency()
117 {
118 String resource1 = "test.atlassian:cool-stuff";
119 String resource2 = "test.atlassian:hot-stuff";
120
121
122 mockPluginAccessor.matchAndReturn("getEnabledPluginModule", C.args(C.eq(resource1)),
123 TestUtils.createWebResourceModuleDescriptor(resource1, testPlugin, Collections.EMPTY_LIST, Collections.singletonList(resource2)));
124 mockPluginAccessor.matchAndReturn("getEnabledPluginModule", C.args(C.eq(resource2)),
125 TestUtils.createWebResourceModuleDescriptor(resource2, testPlugin, Collections.EMPTY_LIST, Collections.singletonList(resource1)));
126
127 Map requestCache = setupRequestCache();
128 webResourceManager.requireResource(resource1);
129
130 Collection resources = (Collection) requestCache.get(WebResourceManagerImpl.REQUEST_CACHE_RESOURCE_KEY);
131 assertEquals(2, resources.size());
132 Object[] resourceArray = resources.toArray();
133 assertEquals(resource2, resourceArray[0]);
134 assertEquals(resource1, resourceArray[1]);
135 }
136
137 public void testRequireResourcesWithComplexCyclicDependency()
138 {
139 String resourceA = "test.atlassian:a";
140 String resourceB = "test.atlassian:b";
141 String resourceC = "test.atlassian:c";
142 String resourceD = "test.atlassian:d";
143 String resourceE = "test.atlassian:e";
144
145
146 mockPluginAccessor.matchAndReturn("getEnabledPluginModule", C.args(C.eq(resourceA)),
147 TestUtils.createWebResourceModuleDescriptor(resourceA, testPlugin, Collections.EMPTY_LIST, Arrays.asList(resourceB, resourceC)));
148
149 mockPluginAccessor.matchAndReturn("getEnabledPluginModule", C.args(C.eq(resourceB)),
150 TestUtils.createWebResourceModuleDescriptor(resourceB, testPlugin, Collections.EMPTY_LIST, Collections.singletonList(resourceD)));
151
152 mockPluginAccessor.matchAndReturn("getEnabledPluginModule", C.args(C.eq(resourceC)),
153 TestUtils.createWebResourceModuleDescriptor(resourceC, testPlugin));
154
155 mockPluginAccessor.matchAndReturn("getEnabledPluginModule", C.args(C.eq(resourceD)),
156 TestUtils.createWebResourceModuleDescriptor(resourceD, testPlugin, Collections.EMPTY_LIST, Arrays.asList(resourceE, resourceA)));
157
158 mockPluginAccessor.matchAndReturn("getEnabledPluginModule", C.args(C.eq(resourceE)),
159 TestUtils.createWebResourceModuleDescriptor(resourceE, testPlugin));
160
161 Map requestCache = setupRequestCache();
162 webResourceManager.requireResource(resourceA);
163
164 webResourceManager.requireResource(resourceD);
165
166 Collection resources = (Collection) requestCache.get(WebResourceManagerImpl.REQUEST_CACHE_RESOURCE_KEY);
167 assertEquals(5, resources.size());
168 Object[] resourceArray = resources.toArray();
169 assertEquals(resourceE, resourceArray[0]);
170 assertEquals(resourceD, resourceArray[1]);
171 assertEquals(resourceB, resourceArray[2]);
172 assertEquals(resourceC, resourceArray[3]);
173 assertEquals(resourceA, resourceArray[4]);
174 }
175
176 public void testGetResourceContext() throws Exception
177 {
178 final String resourceA = "test.atlassian:a";
179 final String resourceB = "test.atlassian:b";
180 final String resourceC = "test.atlassian:c";
181
182 final WebResourceModuleDescriptor descriptor1 = TestUtils.createWebResourceModuleDescriptor(
183 resourceA, testPlugin, TestUtils.createResourceDescriptors("resourceA.css"), Collections.EMPTY_LIST, Collections.EMPTY_SET);
184 final WebResourceModuleDescriptor descriptor2 = TestUtils.createWebResourceModuleDescriptor(
185 resourceB, testPlugin, TestUtils.createResourceDescriptors("resourceB.css"), Collections.EMPTY_LIST, new HashSet<String>() {{
186 add("foo");
187 }});
188 final WebResourceModuleDescriptor descriptor3 = TestUtils.createWebResourceModuleDescriptor(
189 resourceC, testPlugin, TestUtils.createResourceDescriptors("resourceC.css"), Collections.EMPTY_LIST, new HashSet<String>() {{
190 add("foo");
191 add("bar");
192 }});
193
194 final List<WebResourceModuleDescriptor> descriptors = Arrays.asList(descriptor1, descriptor2, descriptor3);
195
196 mockPluginAccessor.matchAndReturn("getEnabledModuleDescriptorsByClass", C.args(C.eq(WebResourceModuleDescriptor.class)), descriptors);
197 mockPluginAccessor.matchAndReturn("getEnabledPluginModule", C.args(C.eq(resourceA)), descriptor1);
198 mockPluginAccessor.matchAndReturn("getEnabledPluginModule", C.args(C.eq(resourceB)), descriptor2);
199 mockPluginAccessor.matchAndReturn("getEnabledPluginModule", C.args(C.eq(resourceC)), descriptor3);
200
201 setupRequestCache();
202
203
204 webResourceManager.requireResourcesForContext("foo");
205 StringWriter writer = new StringWriter();
206 webResourceManager.includeResources(writer);
207 String resources = writer.toString();
208 assertFalse(resources.contains(resourceA + ".css"));
209 assertTrue(resources.contains(resourceB + ".css"));
210 assertTrue(resources.contains(resourceC + ".css"));
211
212
213 webResourceManager.requireResourcesForContext("bar");
214 writer = new StringWriter();
215 webResourceManager.includeResources(writer);
216 resources = writer.toString();
217 assertFalse(resources.contains(resourceA + ".css"));
218 assertFalse(resources.contains(resourceB + ".css"));
219 assertTrue(resources.contains(resourceC + ".css"));
220 }
221
222 private Map setupRequestCache()
223 {
224 Map requestCache = new HashMap();
225 mockWebResourceIntegration.matchAndReturn("getRequestCache", requestCache);
226 return requestCache;
227 }
228
229 public void testRequireResourceWithDuplicateDependencies()
230 {
231 String resourceA = "test.atlassian:a";
232 String resourceB = "test.atlassian:b";
233 String resourceC = "test.atlassian:c";
234 String resourceD = "test.atlassian:d";
235 String resourceE = "test.atlassian:e";
236
237
238 mockPluginAccessor.matchAndReturn("getEnabledPluginModule", C.args(C.eq(resourceA)),
239 TestUtils.createWebResourceModuleDescriptor(resourceA, testPlugin, Collections.EMPTY_LIST, Arrays.asList(resourceB, resourceC)));
240
241 mockPluginAccessor.matchAndReturn("getEnabledPluginModule", C.args(C.eq(resourceB)),
242 TestUtils.createWebResourceModuleDescriptor(resourceB, testPlugin, Collections.EMPTY_LIST, Collections.singletonList(resourceD)));
243
244 mockPluginAccessor.matchAndReturn("getEnabledPluginModule", C.args(C.eq(resourceC)),
245 TestUtils.createWebResourceModuleDescriptor(resourceC, testPlugin, Collections.EMPTY_LIST, Collections.singletonList(resourceE)));
246
247 mockPluginAccessor.matchAndReturn("getEnabledPluginModule", C.args(C.eq(resourceD)),
248 TestUtils.createWebResourceModuleDescriptor(resourceD, testPlugin, Collections.EMPTY_LIST, Collections.singletonList(resourceC)));
249
250 mockPluginAccessor.matchAndReturn("getEnabledPluginModule", C.args(C.eq(resourceE)),
251 TestUtils.createWebResourceModuleDescriptor(resourceE, testPlugin));
252
253 Map requestCache = setupRequestCache();
254 webResourceManager.requireResource(resourceA);
255
256 Collection resources = (Collection) requestCache.get(WebResourceManagerImpl.REQUEST_CACHE_RESOURCE_KEY);
257 assertEquals(5, resources.size());
258 Object[] resourceArray = resources.toArray();
259 assertEquals(resourceE, resourceArray[0]);
260 assertEquals(resourceC, resourceArray[1]);
261 assertEquals(resourceD, resourceArray[2]);
262 assertEquals(resourceB, resourceArray[3]);
263 assertEquals(resourceA, resourceArray[4]);
264 }
265
266 public void testRequireSingleResourceGetsDeps() throws Exception
267 {
268 String resourceA = "test.atlassian:a";
269 String resourceB = "test.atlassian:b";
270
271 final List<ResourceDescriptor> resourceDescriptorsA = TestUtils.createResourceDescriptors("resourceA.css");
272 final List<ResourceDescriptor> resourceDescriptorsB = TestUtils.createResourceDescriptors("resourceB.css", "resourceB-more.css");
273
274
275 mockPluginAccessor.matchAndReturn("getEnabledPluginModule", C.args(C.eq(resourceA)),
276 TestUtils.createWebResourceModuleDescriptor(resourceA, testPlugin, resourceDescriptorsA, Collections.singletonList(resourceB)));
277 mockPluginAccessor.matchAndReturn("getEnabledPluginModule", C.args(C.eq(resourceB)),
278 TestUtils.createWebResourceModuleDescriptor(resourceB, testPlugin, resourceDescriptorsB, Collections.EMPTY_LIST));
279
280 String s = webResourceManager.getResourceTags(resourceA);
281 int indexA = s.indexOf(resourceA);
282 int indexB = s.indexOf(resourceB);
283
284 assertNotSame(-1, indexA);
285 assertNotSame(-1, indexB);
286 assertTrue(indexB < indexA);
287 }
288
289 public void testIncludeResourcesWithResourceList() throws Exception
290 {
291 String resourceA = "test.atlassian:a";
292
293 final List<ResourceDescriptor> resourceDescriptorsA = TestUtils.createResourceDescriptors("resourceA.css");
294 final List<ResourceDescriptor> resourceDescriptorsB = TestUtils.createResourceDescriptors("resourceB.css", "resourceB-more.css");
295
296 mockPluginAccessor.matchAndReturn("getEnabledPluginModule", C.args(C.eq(resourceA)),
297 TestUtils.createWebResourceModuleDescriptor(resourceA, testPlugin, resourceDescriptorsA, Collections.<String>emptyList()));
298
299 StringWriter requiredResourceWriter = new StringWriter();
300 webResourceManager.includeResources(Arrays.<String>asList(resourceA), requiredResourceWriter, UrlMode.ABSOLUTE);
301 String result = requiredResourceWriter.toString();
302 assertTrue(result.contains(resourceA));
303 }
304
305 public void testIncludeResourcesWithResourceListIgnoresRequireResource() throws Exception
306 {
307 String resourceA = "test.atlassian:a";
308 String resourceB = "test.atlassian:b";
309
310 final List<ResourceDescriptor> resourceDescriptorsA = TestUtils.createResourceDescriptors("resourceA.css");
311 final List<ResourceDescriptor> resourceDescriptorsB = TestUtils.createResourceDescriptors("resourceB.css", "resourceB-more.css");
312
313 final Map requestCache = new HashMap();
314 mockWebResourceIntegration.matchAndReturn("getRequestCache", requestCache);
315
316
317 mockPluginAccessor.matchAndReturn("getEnabledPluginModule", C.args(C.eq(resourceA)),
318 TestUtils.createWebResourceModuleDescriptor(resourceA, testPlugin, resourceDescriptorsA, Collections.<String>emptyList()));
319
320 mockPluginAccessor.matchAndReturn("getEnabledPluginModule", C.args(C.eq(resourceB)),
321 TestUtils.createWebResourceModuleDescriptor(resourceB, testPlugin, resourceDescriptorsB, Collections.<String>emptyList()));
322
323
324 StringWriter requiredResourceWriter = new StringWriter();
325 webResourceManager.requireResource(resourceB);
326 webResourceManager.includeResources(Arrays.<String>asList(resourceA), requiredResourceWriter, UrlMode.ABSOLUTE);
327 String result = requiredResourceWriter.toString();
328 assertFalse(result.contains(resourceB));
329 }
330
331
332 public void testIncludeResourcesWithResourceListIncludesDependences() throws Exception
333 {
334 String resourceA = "test.atlassian:a";
335 String resourceB = "test.atlassian:b";
336
337 final List<ResourceDescriptor> resourceDescriptorsA = TestUtils.createResourceDescriptors("resourceA.css");
338 final List<ResourceDescriptor> resourceDescriptorsB = TestUtils.createResourceDescriptors("resourceB.css", "resourceB-more.css");
339
340
341 mockPluginAccessor.matchAndReturn("getEnabledPluginModule", C.args(C.eq(resourceA)),
342 TestUtils.createWebResourceModuleDescriptor(resourceA, testPlugin, resourceDescriptorsA, Collections.singletonList(resourceB)));
343 mockPluginAccessor.matchAndReturn("getEnabledPluginModule", C.args(C.eq(resourceB)),
344 TestUtils.createWebResourceModuleDescriptor(resourceB, testPlugin, resourceDescriptorsB, Collections.EMPTY_LIST));
345
346 StringWriter requiredResourceWriter = new StringWriter();
347 webResourceManager.includeResources(Arrays.<String>asList(resourceA), requiredResourceWriter, UrlMode.ABSOLUTE);
348 String result = requiredResourceWriter.toString();
349 assertTrue(result.contains(resourceB));
350 }
351
352 public void testIncludeResourcesWithResourceListIncludesDependencesFromSuperBatch() throws Exception
353 {
354 final String resourceA = "test.atlassian:a";
355 final String resourceB = "test.atlassian:b";
356
357 ResourceBatchingConfiguration batchingConfiguration = new ResourceBatchingConfiguration()
358 {
359 public boolean isSuperBatchingEnabled()
360 {
361 return true;
362 }
363
364 public List<String> getSuperBatchModuleCompleteKeys()
365 {
366 return Arrays.asList(resourceB);
367 }
368 };
369
370 webResourceManager = new WebResourceManagerImpl(pluginResourceLocator, (WebResourceIntegration) mockWebResourceIntegration.proxy(), batchingConfiguration);
371
372 final List<ResourceDescriptor> resourceDescriptorsA = TestUtils.createResourceDescriptors("resourceA.css");
373 final List<ResourceDescriptor> resourceDescriptorsB = TestUtils.createResourceDescriptors("resourceB.css");
374
375
376 mockPluginAccessor.matchAndReturn("getEnabledPluginModule", C.args(C.eq(resourceA)),
377 TestUtils.createWebResourceModuleDescriptor(resourceA, testPlugin, resourceDescriptorsA, Collections.singletonList(resourceB)));
378 mockPluginAccessor.matchAndReturn("getEnabledPluginModule", C.args(C.eq(resourceB)),
379 TestUtils.createWebResourceModuleDescriptor(resourceB, testPlugin, resourceDescriptorsB, Collections.<String>emptyList()));
380
381 StringWriter requiredResourceWriter = new StringWriter();
382 webResourceManager.includeResources(Arrays.<String>asList(resourceA), requiredResourceWriter, UrlMode.ABSOLUTE);
383 String result = requiredResourceWriter.toString();
384 assertTrue(result.contains(resourceB));
385 }
386
387 public void testRequireResourcesAreClearedAfterIncludesResourcesIsCalled() throws Exception
388 {
389 final String moduleKey = "cool-resources";
390 final String completeModuleKey = "test.atlassian:" + moduleKey;
391
392 final List<ResourceDescriptor> resourceDescriptors1 = TestUtils.createResourceDescriptors("cool.css", "more-cool.css", "cool.js");
393
394 setupRequestCache();
395
396 mockPluginAccessor.matchAndReturn("getEnabledPluginModule", C.args(C.eq(completeModuleKey)),
397 TestUtils.createWebResourceModuleDescriptor(completeModuleKey, testPlugin, resourceDescriptors1));
398
399
400 webResourceManager.requireResource(completeModuleKey);
401 webResourceManager.includeResources(new StringWriter(), UrlMode.RELATIVE);
402
403 StringWriter requiredResourceWriter = new StringWriter();
404 webResourceManager.includeResources(requiredResourceWriter, UrlMode.RELATIVE);
405 assertEquals("", requiredResourceWriter.toString());
406 }
407
408
409
410 public void testRequireResourceAndResourceTagMethods() throws Exception
411 {
412 final String completeModuleKey = "test.atlassian:cool-resources";
413 final String staticBase = setupRequireResourceAndResourceTagMethods(false, completeModuleKey);
414
415
416 StringWriter requiredResourceWriter = new StringWriter();
417 webResourceManager.requireResource(completeModuleKey);
418 String requiredResourceResult = webResourceManager.getRequiredResources(UrlMode.RELATIVE);
419 webResourceManager.includeResources(requiredResourceWriter, UrlMode.RELATIVE);
420 assertEquals(requiredResourceResult, requiredResourceWriter.toString());
421
422 assertTrue(requiredResourceResult.contains("href=\"" + staticBase + "/" + completeModuleKey + "/" + completeModuleKey + ".css"));
423 assertTrue(requiredResourceResult.contains("src=\"" + staticBase + "/" + completeModuleKey + "/" + completeModuleKey + ".js"));
424
425
426 StringWriter resourceTagsWriter = new StringWriter();
427 webResourceManager.requireResource(completeModuleKey, resourceTagsWriter, UrlMode.RELATIVE);
428 String resourceTagsResult = webResourceManager.getResourceTags(completeModuleKey, UrlMode.RELATIVE);
429 assertEquals(resourceTagsResult, resourceTagsWriter.toString());
430
431
432 assertEquals(requiredResourceResult, resourceTagsResult);
433 }
434
435 public void testRequireResourceAndResourceTagMethodsWithAbsoluteUrlMode() throws Exception
436 {
437 testRequireResourceAndResourceTagMethods(UrlMode.ABSOLUTE, true);
438 }
439
440 public void testRequireResourceAndResourceTagMethodsWithRelativeUrlMode() throws Exception
441 {
442 testRequireResourceAndResourceTagMethods(UrlMode.RELATIVE, false);
443 }
444
445 public void testRequireResourceAndResourceTagMethodsWithAutoUrlMode() throws Exception
446 {
447 testRequireResourceAndResourceTagMethods(UrlMode.AUTO, false);
448 }
449
450 private void testRequireResourceAndResourceTagMethods(UrlMode urlMode, boolean baseUrlExpected) throws Exception
451 {
452 final String completeModuleKey = "test.atlassian:cool-resources";
453 final String staticBase = setupRequireResourceAndResourceTagMethods(baseUrlExpected, completeModuleKey);
454
455
456 final StringWriter requiredResourceWriter = new StringWriter();
457 webResourceManager.requireResource(completeModuleKey);
458 final String requiredResourceResult = webResourceManager.getRequiredResources(urlMode);
459 webResourceManager.includeResources(requiredResourceWriter, urlMode);
460 assertEquals(requiredResourceResult, requiredResourceWriter.toString());
461
462 assertTrue(requiredResourceResult.contains("href=\"" + staticBase + "/" + completeModuleKey + "/" + completeModuleKey + ".css"));
463 assertTrue(requiredResourceResult.contains("src=\"" + staticBase + "/" + completeModuleKey + "/" + completeModuleKey + ".js"));
464
465
466 StringWriter resourceTagsWriter = new StringWriter();
467 webResourceManager.requireResource(completeModuleKey, resourceTagsWriter, urlMode);
468 String resourceTagsResult = webResourceManager.getResourceTags(completeModuleKey, urlMode);
469 assertEquals(resourceTagsResult, resourceTagsWriter.toString());
470
471
472 assertEquals(requiredResourceResult, resourceTagsResult);
473 }
474
475 private String setupRequireResourceAndResourceTagMethods(boolean baseUrlExpected, String completeModuleKey)
476 throws DocumentException
477 {
478 final List<ResourceDescriptor> descriptors = TestUtils.createResourceDescriptors("cool.css", "more-cool.css", "cool.js");
479
480 final Map requestCache = new HashMap();
481 mockWebResourceIntegration.matchAndReturn("getRequestCache", requestCache);
482
483 mockPluginAccessor.matchAndReturn("getEnabledPluginModule", C.args(C.eq(completeModuleKey)),
484 TestUtils.createWebResourceModuleDescriptor(completeModuleKey, testPlugin, descriptors));
485
486 final String staticBase = (baseUrlExpected ? BASEURL : "") +
487 "/" + WebResourceManagerImpl.STATIC_RESOURCE_PREFIX + "/" + SYSTEM_BUILD_NUMBER + "/" + SYSTEM_COUNTER +
488 "/" + testPlugin.getPluginInformation().getVersion() + "/" + WebResourceManagerImpl.STATIC_RESOURCE_SUFFIX + BatchPluginResource.URL_PREFIX;
489 return staticBase;
490 }
491
492
493
494 public void testRequireResourceWithCacheParameter() throws Exception
495 {
496 final String completeModuleKey = "test.atlassian:no-cache-resources";
497
498 final String expectedResult = setupRequireResourceWithCacheParameter(false, completeModuleKey);
499 assertTrue(webResourceManager.getResourceTags(completeModuleKey).contains(expectedResult));
500 }
501
502 public void testRequireResourceWithCacheParameterAndAbsoluteUrlMode() throws Exception
503 {
504 testRequireResourceWithCacheParameter(UrlMode.ABSOLUTE, true);
505 }
506
507 public void testRequireResourceWithCacheParameterAndRelativeUrlMode() throws Exception
508 {
509 testRequireResourceWithCacheParameter(UrlMode.RELATIVE, false);
510 }
511
512 public void testRequireResourceWithCacheParameterAndAutoUrlMode() throws Exception
513 {
514 testRequireResourceWithCacheParameter(UrlMode.AUTO, false);
515 }
516
517 private void testRequireResourceWithCacheParameter(UrlMode urlMode, boolean baseUrlExpected) throws Exception
518 {
519 final String completeModuleKey = "test.atlassian:no-cache-resources";
520 final String expectedResult = setupRequireResourceWithCacheParameter(baseUrlExpected, completeModuleKey);
521 assertTrue(webResourceManager.getResourceTags(completeModuleKey, urlMode).contains(expectedResult));
522 }
523
524 private String setupRequireResourceWithCacheParameter(boolean baseUrlExpected, String completeModuleKey)
525 throws DocumentException
526 {
527 final Map<String, String> params = new HashMap<String, String>();
528 params.put("cache", "false");
529 ResourceDescriptor resourceDescriptor = TestUtils.createResourceDescriptor("no-cache.js", params);
530
531 mockPluginAccessor.matchAndReturn("getEnabledPluginModule", C.args(C.eq(completeModuleKey)),
532 TestUtils.createWebResourceModuleDescriptor(completeModuleKey, testPlugin,
533 Collections.singletonList(resourceDescriptor)));
534
535 return "src=\"" + (baseUrlExpected ? BASEURL : "") + BatchPluginResource.URL_PREFIX +
536 "/" + completeModuleKey + "/" + completeModuleKey + ".js?cache=false";
537 }
538
539
540
541 public void testGetStaticResourcePrefix()
542 {
543 final String expectedPrefix = setupGetStaticResourcePrefix(false);
544 assertEquals(expectedPrefix, webResourceManager.getStaticResourcePrefix());
545 }
546
547 public void testGetStaticResourcePrefixWithAbsoluteUrlMode()
548 {
549 testGetStaticResourcePrefix(UrlMode.ABSOLUTE, true);
550 }
551
552 public void testGetStaticResourcePrefixWithRelativeUrlMode()
553 {
554 testGetStaticResourcePrefix(UrlMode.RELATIVE, false);
555 }
556
557 public void testGetStaticResourcePrefixWithAutoUrlMode()
558 {
559 testGetStaticResourcePrefix(UrlMode.AUTO, false);
560 }
561
562 private void testGetStaticResourcePrefix(UrlMode urlMode, boolean baseUrlExpected)
563 {
564 final String expectedPrefix = setupGetStaticResourcePrefix(baseUrlExpected);
565 assertEquals(expectedPrefix, webResourceManager.getStaticResourcePrefix(urlMode));
566 }
567
568 private String setupGetStaticResourcePrefix(boolean baseUrlExpected)
569 {
570 return (baseUrlExpected ? BASEURL : "") +
571 "/" + WebResourceManagerImpl.STATIC_RESOURCE_PREFIX + "/" +
572 SYSTEM_BUILD_NUMBER + "/" + SYSTEM_COUNTER + "/" + WebResourceManagerImpl.STATIC_RESOURCE_SUFFIX;
573 }
574
575
576
577 public void testGetStaticResourcePrefixWithCounter()
578 {
579 final String resourceCounter = "456";
580 final String expectedPrefix = setupGetStaticResourcePrefixWithCounter(false, resourceCounter);
581 assertEquals(expectedPrefix, webResourceManager.getStaticResourcePrefix(resourceCounter));
582 }
583
584 public void testGetStaticResourcePrefixWithCounterAndAbsoluteUrlMode()
585 {
586 testGetStaticResourcePrefixWithCounter(UrlMode.ABSOLUTE, true);
587 }
588
589 public void testGetStaticResourcePrefixWithCounterAndRelativeUrlMode()
590 {
591 testGetStaticResourcePrefixWithCounter(UrlMode.RELATIVE, false);
592 }
593
594 public void testGetStaticResourcePrefixWithCounterAndAutoUrlMode()
595 {
596 testGetStaticResourcePrefixWithCounter(UrlMode.AUTO, false);
597 }
598
599 private void testGetStaticResourcePrefixWithCounter(UrlMode urlMode, boolean baseUrlExpected)
600 {
601 final String resourceCounter = "456";
602 final String expectedPrefix = setupGetStaticResourcePrefixWithCounter(baseUrlExpected, resourceCounter);
603 assertEquals(expectedPrefix, webResourceManager.getStaticResourcePrefix(resourceCounter, urlMode));
604 }
605
606 private String setupGetStaticResourcePrefixWithCounter(boolean baseUrlExpected, String resourceCounter)
607 {
608 return (baseUrlExpected ? BASEURL : "") +
609 "/" + WebResourceManagerImpl.STATIC_RESOURCE_PREFIX + "/" +
610 SYSTEM_BUILD_NUMBER + "/" + SYSTEM_COUNTER + "/" + resourceCounter +
611 "/" + WebResourceManagerImpl.STATIC_RESOURCE_SUFFIX;
612 }
613
614
615
616 public void testGetStaticPluginResourcePrefix()
617 {
618 final String moduleKey = "confluence.extra.animal:animal";
619 final String resourceName = "foo.js";
620
621 final String expectedPrefix = setupGetStaticPluginResourcePrefix(false, moduleKey, resourceName);
622
623 assertEquals(expectedPrefix, webResourceManager.getStaticPluginResource(moduleKey, resourceName));
624 }
625
626 public void testGetStaticPluginResourcePrefixWithAbsoluteUrlMode()
627 {
628 testGetStaticPluginResourcePrefix(UrlMode.ABSOLUTE, true);
629 }
630
631 public void testGetStaticPluginResourcePrefixWithRelativeUrlMode()
632 {
633 testGetStaticPluginResourcePrefix(UrlMode.RELATIVE, false);
634 }
635
636 public void testGetStaticPluginResourcePrefixWithAutoUrlMode()
637 {
638 testGetStaticPluginResourcePrefix(UrlMode.AUTO, false);
639 }
640
641 private void testGetStaticPluginResourcePrefix(UrlMode urlMode, boolean baseUrlExpected)
642 {
643 final String moduleKey = "confluence.extra.animal:animal";
644 final String resourceName = "foo.js";
645
646 final String expectedPrefix = setupGetStaticPluginResourcePrefix(baseUrlExpected, moduleKey, resourceName);
647
648 assertEquals(expectedPrefix, webResourceManager.getStaticPluginResource(moduleKey, resourceName, urlMode));
649 }
650
651 private String setupGetStaticPluginResourcePrefix(boolean baseUrlExpected, String moduleKey, String resourceName)
652 {
653 final Plugin animalPlugin = new StaticPlugin();
654 animalPlugin.setKey("confluence.extra.animal");
655 animalPlugin.setPluginsVersion(Integer.parseInt(ANIMAL_PLUGIN_VERSION));
656
657 mockPluginAccessor.expectAndReturn("getEnabledPluginModule", C.args(C.eq(moduleKey)),
658 TestUtils.createWebResourceModuleDescriptor(moduleKey, animalPlugin));
659
660 return (baseUrlExpected ? BASEURL : "") +
661 "/" + WebResourceManagerImpl.STATIC_RESOURCE_PREFIX + "/" + SYSTEM_BUILD_NUMBER +
662 "/" + SYSTEM_COUNTER + "/" + ANIMAL_PLUGIN_VERSION + "/" + WebResourceManagerImpl.STATIC_RESOURCE_SUFFIX +
663 "/" + AbstractFileServerServlet.SERVLET_PATH + "/" + AbstractFileServerServlet.RESOURCE_URL_PREFIX +
664 "/" + moduleKey + "/" + resourceName;
665 }
666
667 public void testGetRequiredResourcesWithFilter() throws Exception
668 {
669 final String moduleKey = "cool-resources";
670 final String completeModuleKey = "test.atlassian:" + moduleKey;
671
672 final List<ResourceDescriptor> resourceDescriptors1 = TestUtils.createResourceDescriptors("cool.css", "cool.js", "more-cool.css");
673
674 setupRequestCache();
675
676 mockPluginAccessor.matchAndReturn("getEnabledPluginModule", C.args(C.eq(completeModuleKey)),
677 TestUtils.createWebResourceModuleDescriptor(completeModuleKey, testPlugin, resourceDescriptors1));
678
679
680 webResourceManager.requireResource(completeModuleKey);
681
682 String staticBase = BASEURL + "/" + WebResourceManagerImpl.STATIC_RESOURCE_PREFIX + "/" + SYSTEM_BUILD_NUMBER
683 + "/" + SYSTEM_COUNTER + "/" + testPlugin.getPluginInformation().getVersion() + "/"
684 + WebResourceManagerImpl.STATIC_RESOURCE_SUFFIX + BatchPluginResource.URL_PREFIX;
685
686 String cssRef = "href=\"" + staticBase + "/" + completeModuleKey + "/" + completeModuleKey + ".css";
687 String jsRef = "src=\"" + staticBase + "/" + completeModuleKey + "/" + completeModuleKey + ".js";
688
689
690 String requiredResourceResult = webResourceManager.getRequiredResources(UrlMode.ABSOLUTE, new CssWebResource());
691 assertTrue(requiredResourceResult.contains(cssRef));
692 assertFalse(requiredResourceResult.contains(jsRef));
693
694
695 requiredResourceResult = webResourceManager.getRequiredResources(UrlMode.ABSOLUTE, new JavascriptWebResource());
696 assertFalse(requiredResourceResult.contains(cssRef));
697 assertTrue(requiredResourceResult.contains(jsRef));
698
699
700 requiredResourceResult = webResourceManager.getRequiredResources(UrlMode.ABSOLUTE);
701 assertTrue(requiredResourceResult.contains(cssRef));
702 assertTrue(requiredResourceResult.contains(jsRef));
703 }
704
705 public void testGetRequiredResourcesWithCustomFilters() throws Exception
706 {
707 WebResourceFilter atlassianFilter = new WebResourceFilter(){
708 public boolean matches(String resourceName)
709 {
710 if (resourceName.contains("atlassian"))
711 return true;
712 return false;
713 }
714 };
715 WebResourceFilter bogusFilter = new WebResourceFilter() {
716 public boolean matches(String resourceName)
717 {
718 return true;
719 }
720 };
721
722 final String moduleKey = "cool-resources";
723 final String completeModuleKey = "test.atlassian:" + moduleKey;
724
725 final List<ResourceDescriptor> resources = TestUtils.createResourceDescriptors(
726 "foo.css", "foo-bar.js",
727 "atlassian.css", "atlassian-plugins.js");
728
729 setupRequestCache();
730 mockPluginAccessor.matchAndReturn("getEnabledPluginModule", C.args(C.eq(completeModuleKey)),
731 TestUtils.createWebResourceModuleDescriptor(completeModuleKey, testPlugin, resources));
732
733
734 System.setProperty(PluginResourceLocatorImpl.PLUGIN_WEBRESOURCE_BATCHING_OFF, "true");
735 try
736 {
737 webResourceManager.requireResource(completeModuleKey);
738 String atlassianResources = webResourceManager.getRequiredResources(UrlMode.RELATIVE, atlassianFilter);
739 assertEquals(-1, atlassianResources.indexOf("foo"));
740 assertTrue(atlassianResources.contains("atlassian.css"));
741 assertTrue(atlassianResources.contains("atlassian-plugins.js"));
742
743 String allResources = webResourceManager.getRequiredResources(UrlMode.RELATIVE, bogusFilter);
744 for (ResourceDescriptor resource : resources)
745 {
746 assertTrue(allResources.contains(resource.getName()));
747 }
748 }
749 finally
750 {
751 System.setProperty(PluginResourceLocatorImpl.PLUGIN_WEBRESOURCE_BATCHING_OFF, "false");
752 }
753 }
754
755 public void testGetRequiredResourcesOrdersByType() throws Exception
756 {
757 final String moduleKey1 = "cool-resources";
758 final String moduleKey2 = "hot-resources";
759 final String completeModuleKey1 = "test.atlassian:" + moduleKey1;
760 final String completeModuleKey2 = "test.atlassian:" + moduleKey2;
761
762 final List<ResourceDescriptor> resourceDescriptors1 = TestUtils.createResourceDescriptors("cool.js", "cool.css", "more-cool.css");
763 final List<ResourceDescriptor> resourceDescriptors2 = TestUtils.createResourceDescriptors("hot.js", "hot.css", "more-hot.css");
764
765 final Plugin plugin = TestUtils.createTestPlugin();
766
767 setupRequestCache();
768
769 mockPluginAccessor.matchAndReturn("getEnabledPluginModule", C.args(C.eq(completeModuleKey1)),
770 TestUtils.createWebResourceModuleDescriptor(completeModuleKey1, plugin, resourceDescriptors1));
771 mockPluginAccessor.matchAndReturn("getEnabledPluginModule", C.args(C.eq(completeModuleKey2)),
772 TestUtils.createWebResourceModuleDescriptor(completeModuleKey2, plugin, resourceDescriptors2));
773
774
775 webResourceManager.requireResource(completeModuleKey1);
776 webResourceManager.requireResource(completeModuleKey2);
777
778 String staticBase = BASEURL + "/" + WebResourceManagerImpl.STATIC_RESOURCE_PREFIX + "/" + SYSTEM_BUILD_NUMBER
779 + "/" + SYSTEM_COUNTER + "/" + plugin.getPluginInformation().getVersion() + "/"
780 + WebResourceManagerImpl.STATIC_RESOURCE_SUFFIX + BatchPluginResource.URL_PREFIX;
781
782 String cssRef1 = "href=\"" + staticBase + "/" + completeModuleKey1 + "/" + completeModuleKey1 + ".css";
783 String cssRef2 = "href=\"" + staticBase + "/" + completeModuleKey2 + "/" + completeModuleKey2 + ".css";
784 String jsRef1 = "src=\"" + staticBase + "/" + completeModuleKey1 + "/" + completeModuleKey1 + ".js";
785 String jsRef2 = "src=\"" + staticBase + "/" + completeModuleKey2 + "/" + completeModuleKey2 + ".js";
786
787 String requiredResourceResult = webResourceManager.getRequiredResources(UrlMode.ABSOLUTE);
788
789 assertTrue(requiredResourceResult.contains(cssRef1));
790 assertTrue(requiredResourceResult.contains(cssRef2));
791 assertTrue(requiredResourceResult.contains(jsRef1));
792 assertTrue(requiredResourceResult.contains(jsRef2));
793
794 int cssRef1Index = requiredResourceResult.indexOf(cssRef1);
795 int cssRef2Index = requiredResourceResult.indexOf(cssRef2);
796 int jsRef1Index = requiredResourceResult.indexOf(jsRef1);
797 int jsRef2Index = requiredResourceResult.indexOf(jsRef2);
798
799 assertTrue(cssRef1Index < jsRef1Index);
800 assertTrue(cssRef2Index < jsRef2Index);
801 assertTrue(cssRef2Index < jsRef1Index);
802 }
803
804 public void testRequireResourceInSuperbatch()
805 {
806 resourceBatchingConfiguration.enabled = true;
807 Map requestCache = setupRequestCache();
808 mockOutSuperbatchPluginAccesses();
809
810 webResourceManager.requireResource("test.atlassian:superbatch");
811
812 Collection resources = (Collection) requestCache.get(WebResourceManagerImpl.REQUEST_CACHE_RESOURCE_KEY);
813 assertEquals(0, resources.size());
814 }
815
816 public void testRequireResourceWithDependencyInSuperbatch() throws DocumentException
817 {
818 resourceBatchingConfiguration.enabled = true;
819 mockOutSuperbatchPluginAccesses();
820
821 Map requestCache = setupRequestCache();
822
823 mockPluginAccessor.matchAndReturn("getEnabledPluginModule", C.args(C.eq("test.atlassian:included-resource")),
824 TestUtils.createWebResourceModuleDescriptor("test.atlassian:included-resource", testPlugin, Collections.EMPTY_LIST, Collections.singletonList("test.atlassian:superbatch")));
825
826 webResourceManager.requireResource("test.atlassian:included-resource");
827
828 Collection resources = (Collection) requestCache.get(WebResourceManagerImpl.REQUEST_CACHE_RESOURCE_KEY);
829 assertEquals(1, resources.size());
830 assertEquals("test.atlassian:included-resource", resources.iterator().next());
831 }
832
833 public void testSuperBatchResolution() throws DocumentException
834 {
835 TestUtils.setupSuperbatchTestContent(resourceBatchingConfiguration, mockPluginAccessor, testPlugin);
836 mockOutSuperbatchPluginAccesses();
837
838 List<PluginResource> cssResources = webResourceManager.getSuperBatchResources(CssWebResource.FORMATTER);
839 assertEquals(2, cssResources.size());
840
841 SuperBatchPluginResource superBatch1 = (SuperBatchPluginResource) cssResources.get(0);
842 assertEquals("batch.css", superBatch1.getResourceName());
843 assertTrue(superBatch1.getParams().isEmpty());
844
845 SuperBatchPluginResource superBatch2 = (SuperBatchPluginResource) cssResources.get(1);
846 assertEquals("batch.css", superBatch2.getResourceName());
847 assertEquals("true", superBatch2.getParams().get("ieonly"));
848
849 List<PluginResource> jsResources = webResourceManager.getSuperBatchResources(JavascriptWebResource.FORMATTER);
850 assertEquals(1, jsResources.size());
851 assertEquals("batch.js", jsResources.get(0).getResourceName());
852 assertEquals(0, jsResources.get(0).getParams().size());
853 }
854
855 private void mockOutSuperbatchPluginAccesses()
856 {
857 mockOutPluginModule("test.atlassian:superbatch");
858 mockOutPluginModule("test.atlassian:superbatch2");
859 mockPluginAccessor.matchAndReturn("getPluginModule", "test.atlassian:missing-plugin", null);
860 mockPluginAccessor.matchAndReturn("getEnabledPluginModule", "test.atlassian:missing-plugin", null);
861 }
862
863 private void mockOutPluginModule(String moduleKey)
864 {
865 Plugin p = TestUtils.createTestPlugin();
866 WebResourceModuleDescriptor module = TestUtils.createWebResourceModuleDescriptor(moduleKey, p);
867 mockPluginAccessor.matchAndReturn("getPluginModule", moduleKey, module);
868 mockPluginAccessor.matchAndReturn("getEnabledPluginModule", moduleKey, module);
869 }
870 }