1 package com.atlassian.plugin.webresource;
2
3 import static java.util.Arrays.asList;
4 import static org.mockito.Matchers.eq;
5 import static org.mockito.Matchers.isA;
6 import static org.mockito.Mockito.mock;
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.elements.ResourceDescriptor;
13
14 import com.atlassian.plugin.event.PluginEventManager;
15 import org.dom4j.DocumentException;
16
17 import com.google.common.base.Supplier;
18
19 import java.io.StringWriter;
20 import java.util.Arrays;
21 import java.util.Collection;
22 import java.util.Collections;
23 import java.util.HashMap;
24 import java.util.HashSet;
25 import java.util.List;
26 import java.util.Map;
27 import java.util.Set;
28 import java.util.regex.Matcher;
29 import java.util.regex.Pattern;
30
31 import junit.framework.TestCase;
32
33 public class TestWebResourceManagerImpl extends TestCase
34 {
35 private WebResourceIntegration mockWebResourceIntegration = mock(WebResourceIntegration.class);
36 private PluginAccessor mockPluginAccessor = mock(PluginAccessor.class);
37 private final WebResourceUrlProvider mockUrlProvider = mock(WebResourceUrlProvider.class);
38 private ResourceBatchingConfiguration mockBatchingConfiguration = mock(ResourceBatchingConfiguration.class);
39 private PluginResourceLocator pluginResourceLocator;
40 private WebResourceManagerImpl webResourceManager;
41 private PluginEventManager mockEventPublisher = mock(PluginEventManager.class);
42 private Plugin testPlugin;
43
44 private static final String BASEURL = "http://www.foo.com";
45 private static final String SYSTEM_COUNTER = "123";
46 private static final String SYSTEM_BUILD_NUMBER = "650";
47
48 @Override
49 protected void setUp() throws Exception
50 {
51 super.setUp();
52
53 when(mockWebResourceIntegration.getPluginAccessor()).thenReturn(mockPluginAccessor);
54 when(mockWebResourceIntegration.getSuperBatchVersion()).thenReturn(SYSTEM_BUILD_NUMBER);
55
56 pluginResourceLocator = new PluginResourceLocatorImpl(mockWebResourceIntegration, null, mockUrlProvider, mockBatchingConfiguration, mockEventPublisher);
57 webResourceManager = new WebResourceManagerImpl(pluginResourceLocator, mockWebResourceIntegration, mockUrlProvider, mockBatchingConfiguration);
58
59 when(mockUrlProvider.getBaseUrl()).thenReturn(BASEURL);
60 when(mockUrlProvider.getBaseUrl(UrlMode.ABSOLUTE)).thenReturn(BASEURL);
61 when(mockUrlProvider.getBaseUrl(UrlMode.AUTO)).thenReturn("");
62 when(mockUrlProvider.getBaseUrl(UrlMode.RELATIVE)).thenReturn("");
63 when(mockBatchingConfiguration.isPluginWebResourceBatchingEnabled()).thenReturn(true);
64 testPlugin = TestUtils.createTestPlugin();
65 }
66
67 @Override
68 protected void tearDown() throws Exception
69 {
70 webResourceManager = null;
71 mockPluginAccessor = null;
72 mockWebResourceIntegration = null;
73 testPlugin = null;
74 mockBatchingConfiguration = null;
75
76 super.tearDown();
77 }
78
79 private void mockEnabledPluginModule(final String key)
80 {
81 final ModuleDescriptor md = TestUtils.createWebResourceModuleDescriptor(key, testPlugin);
82 mockEnabledPluginModule(key, md);
83 }
84
85 private void mockEnabledPluginModule(final String key, final ModuleDescriptor md)
86 {
87 when(mockPluginAccessor.getEnabledPluginModule(key)).thenReturn(md);
88 }
89
90 public void testRequireResources()
91 {
92 final String resource1 = "test.atlassian:cool-stuff";
93 final String resource2 = "test.atlassian:hot-stuff";
94
95 mockEnabledPluginModule(resource1);
96 mockEnabledPluginModule(resource2);
97
98 final Map<String, Object> requestCache = setupRequestCache();
99 webResourceManager.requireResource(resource1);
100 webResourceManager.requireResource(resource2);
101 webResourceManager.requireResource(resource1);
102
103 final Collection<?> resources = (Collection<?>) requestCache.get(WebResourceManagerImpl.REQUEST_CACHE_RESOURCE_KEY);
104 assertEquals(2, resources.size());
105 assertTrue(resources.contains(resource1));
106 assertTrue(resources.contains(resource2));
107 }
108
109 public void testRequireResourcesWithCondition() throws ClassNotFoundException
110 {
111 final String resource1 = "test.atlassian:cool-stuff";
112 final String resource2 = "test.atlassian:hot-stuff";
113 final Plugin plugin = TestUtils.createTestPlugin("test.atlassian", "1", AlwaysTrueCondition.class, AlwaysFalseCondition.class);
114
115 mockEnabledPluginModule(resource1,
116 new WebResourceModuleDescriptorBuilder(plugin, "cool-stuff").setCondition(AlwaysTrueCondition.class).addDescriptor("cool.js").build());
117 mockEnabledPluginModule(resource2,
118 new WebResourceModuleDescriptorBuilder(plugin, "hot-stuff").setCondition(AlwaysFalseCondition.class).addDescriptor("hot.js").build());
119
120 setupRequestCache();
121 webResourceManager.requireResource(resource1);
122 webResourceManager.requireResource(resource2);
123
124 final String tags = webResourceManager.getRequiredResources(UrlMode.AUTO);
125 assertTrue(tags.contains(resource1));
126 assertFalse(tags.contains(resource2));
127 }
128
129 public void testRequireResourcesWithDependencies()
130 {
131 final String resource = "test.atlassian:cool-stuff";
132 final String dependencyResource = "test.atlassian:hot-stuff";
133
134
135 mockEnabledPluginModule(resource, TestUtils.createWebResourceModuleDescriptor(resource, testPlugin,
136 Collections.<ResourceDescriptor> emptyList(), Collections.singletonList(dependencyResource)));
137 mockEnabledPluginModule(dependencyResource, TestUtils.createWebResourceModuleDescriptor(dependencyResource, testPlugin));
138
139 final Map<String, Object> requestCache = setupRequestCache();
140 webResourceManager.requireResource(resource);
141
142 final Collection<?> resources = (Collection<?>) requestCache.get(WebResourceManagerImpl.REQUEST_CACHE_RESOURCE_KEY);
143 assertEquals(2, resources.size());
144 final Object[] resourceArray = resources.toArray();
145 assertEquals(dependencyResource, resourceArray[0]);
146 assertEquals(resource, resourceArray[1]);
147 }
148
149 public void testRequireResourcesWithDependencyHiddenByCondition() throws ClassNotFoundException
150 {
151 final String resource1 = "test.atlassian:cool-stuff";
152 final String resource2 = "test.atlassian:hot-stuff";
153 final Plugin plugin = TestUtils.createTestPlugin("test.atlassian", "1", AlwaysTrueCondition.class, AlwaysFalseCondition.class);
154
155 mockEnabledPluginModule(
156 resource1,
157 new WebResourceModuleDescriptorBuilder(plugin, "cool-stuff").setCondition(AlwaysTrueCondition.class).addDependency(resource2).addDescriptor(
158 "cool.js").build());
159 mockEnabledPluginModule(resource2,
160 new WebResourceModuleDescriptorBuilder(plugin, "hot-stuff").setCondition(AlwaysFalseCondition.class).addDescriptor("hot.js").build());
161
162 setupRequestCache();
163 webResourceManager.requireResource(resource1);
164
165 final String tags = webResourceManager.getRequiredResources(UrlMode.AUTO);
166 assertTrue(tags.contains(resource1));
167 assertFalse(tags.contains(resource2));
168 }
169
170 public void testRequireResourcesWithCyclicDependency()
171 {
172 final String resource1 = "test.atlassian:cool-stuff";
173 final String resource2 = "test.atlassian:hot-stuff";
174
175
176 mockEnabledPluginModule(resource1, TestUtils.createWebResourceModuleDescriptor(resource1, testPlugin,
177 Collections.<ResourceDescriptor> emptyList(), Collections.singletonList(resource2)));
178 mockEnabledPluginModule(resource2, TestUtils.createWebResourceModuleDescriptor(resource2, testPlugin,
179 Collections.<ResourceDescriptor> emptyList(), Collections.singletonList(resource1)));
180
181 final Map<String, Object> requestCache = setupRequestCache();
182 webResourceManager.requireResource(resource1);
183
184 final Collection<?> resources = (Collection<?>) requestCache.get(WebResourceManagerImpl.REQUEST_CACHE_RESOURCE_KEY);
185 assertEquals(2, resources.size());
186 final Object[] resourceArray = resources.toArray();
187 assertEquals(resource2, resourceArray[0]);
188 assertEquals(resource1, resourceArray[1]);
189 }
190
191 public void testRequireResourcesWithComplexCyclicDependency()
192 {
193 final String resourceA = "test.atlassian:a";
194 final String resourceB = "test.atlassian:b";
195 final String resourceC = "test.atlassian:c";
196 final String resourceD = "test.atlassian:d";
197 final String resourceE = "test.atlassian:e";
198
199
200 mockEnabledPluginModule(resourceA, TestUtils.createWebResourceModuleDescriptor(resourceA, testPlugin,
201 Collections.<ResourceDescriptor> emptyList(), Arrays.asList(resourceB, resourceC)));
202
203 mockEnabledPluginModule(resourceB, TestUtils.createWebResourceModuleDescriptor(resourceB, testPlugin,
204 Collections.<ResourceDescriptor> emptyList(), Collections.singletonList(resourceD)));
205
206 mockEnabledPluginModule(resourceC, TestUtils.createWebResourceModuleDescriptor(resourceC, testPlugin));
207
208 mockEnabledPluginModule(resourceD, TestUtils.createWebResourceModuleDescriptor(resourceD, testPlugin,
209 Collections.<ResourceDescriptor> emptyList(), Arrays.asList(resourceE, resourceA)));
210
211 mockEnabledPluginModule(resourceE, TestUtils.createWebResourceModuleDescriptor(resourceE, testPlugin));
212
213 final Map<String, Object> requestCache = setupRequestCache();
214 webResourceManager.requireResource(resourceA);
215
216 webResourceManager.requireResource(resourceD);
217
218 final Collection<?> resources = (Collection<?>) requestCache.get(WebResourceManagerImpl.REQUEST_CACHE_RESOURCE_KEY);
219 assertEquals(5, resources.size());
220 final Object[] resourceArray = resources.toArray();
221 assertEquals(resourceE, resourceArray[0]);
222 assertEquals(resourceD, resourceArray[1]);
223 assertEquals(resourceB, resourceArray[2]);
224 assertEquals(resourceC, resourceArray[3]);
225 assertEquals(resourceA, resourceArray[4]);
226 }
227
228 public void testGetResourceContext() throws Exception
229 {
230 when(mockBatchingConfiguration.isContextBatchingEnabled()).thenReturn(true);
231 final String resourceA = "test.atlassian:a";
232 final String resourceB = "test.atlassian:b";
233 final String resourceC = "test.atlassian:c";
234
235 final WebResourceModuleDescriptor descriptor1 = TestUtils.createWebResourceModuleDescriptor(resourceA, testPlugin,
236 TestUtils.createResourceDescriptors("resourceA.css"), Collections.<String> emptyList(), Collections.<String> emptySet());
237 final WebResourceModuleDescriptor descriptor2 = TestUtils.createWebResourceModuleDescriptor(resourceB, testPlugin,
238 TestUtils.createResourceDescriptors("resourceB.css"), Collections.<String> emptyList(), new HashSet<String>()
239 {
240 {
241 add("foo");
242 }
243 });
244 final WebResourceModuleDescriptor descriptor3 = TestUtils.createWebResourceModuleDescriptor(resourceC, testPlugin,
245 TestUtils.createResourceDescriptors("resourceC.css"), Collections.<String> emptyList(), new HashSet<String>()
246 {
247 {
248 add("foo");
249 add("bar");
250 }
251 });
252
253 final List<WebResourceModuleDescriptor> descriptors = Arrays.asList(descriptor1, descriptor2, descriptor3);
254
255 when(mockPluginAccessor.getEnabledModuleDescriptorsByClass(WebResourceModuleDescriptor.class)).thenReturn(descriptors);
256 mockEnabledPluginModule(resourceA, descriptor1);
257 mockEnabledPluginModule(resourceB, descriptor2);
258 mockEnabledPluginModule(resourceC, descriptor3);
259
260 setupRequestCache();
261
262
263 webResourceManager.requireResourcesForContext("foo");
264 StringWriter writer = new StringWriter();
265 webResourceManager.includeResources(writer, UrlMode.AUTO);
266 String resources = writer.toString();
267 assertFalse(resources.contains(resourceA + ".css"));
268 assertFalse(resources.contains(resourceB + ".css"));
269 assertFalse(resources.contains(resourceC + ".css"));
270 assertTrue(resources.contains("/contextbatch/css/foo/batch.css"));
271 assertFalse(resources.contains("/contextbatch/css/bar/batch.css"));
272
273
274 webResourceManager.requireResourcesForContext("bar");
275 writer = new StringWriter();
276 webResourceManager.includeResources(writer, UrlMode.AUTO);
277 resources = writer.toString();
278 assertFalse(resources.contains(resourceA + ".css"));
279 assertFalse(resources.contains(resourceB + ".css"));
280 assertFalse(resources.contains(resourceC + ".css"));
281 assertFalse(resources.contains("/contextbatch/css/foo/batch.css"));
282 assertTrue(resources.contains("/contextbatch/css/bar/batch.css"));
283 }
284
285 public void testGetResourceContextWithCondition() throws ClassNotFoundException, DocumentException
286 {
287 when(mockBatchingConfiguration.isContextBatchingEnabled()).thenReturn(true);
288
289 final String resource1 = "test.atlassian:cool-stuff";
290 final String resource2 = "test.atlassian:hot-stuff";
291 final Plugin plugin = TestUtils.createTestPlugin("test.atlassian", "1", AlwaysTrueCondition.class, AlwaysFalseCondition.class);
292 final WebResourceModuleDescriptor resource1Descriptor = new WebResourceModuleDescriptorBuilder(plugin, "cool-stuff").setCondition(
293 AlwaysTrueCondition.class).addDescriptor("cool.js").addContext("foo").build();
294 mockEnabledPluginModule(resource1, resource1Descriptor);
295
296 final WebResourceModuleDescriptor resource2Descriptor = new WebResourceModuleDescriptorBuilder(plugin, "hot-stuff").setCondition(
297 AlwaysFalseCondition.class).addDescriptor("hot.js").addContext("foo").build();
298 mockEnabledPluginModule(resource2, resource2Descriptor);
299
300 final String resource3 = "test.atlassian:warm-stuff";
301 final WebResourceModuleDescriptor resourceDescriptor3 = TestUtils.createWebResourceModuleDescriptor(resource3, testPlugin,
302 TestUtils.createResourceDescriptors("warm.js"), Collections.<String> emptyList(), new HashSet<String>()
303 {
304 {
305 add("foo");
306 }
307 });
308 mockEnabledPluginModule(resource3, resourceDescriptor3);
309
310 when(mockPluginAccessor.getEnabledModuleDescriptorsByClass(WebResourceModuleDescriptor.class)).thenReturn(
311 asList(resource1Descriptor, resource2Descriptor, resourceDescriptor3));
312
313 setupRequestCache();
314 webResourceManager.requireResourcesForContext("foo");
315
316 final String tags = webResourceManager.getRequiredResources(UrlMode.AUTO);
317 assertTrue(tags.contains(resource1));
318 assertFalse(tags.contains(resource2));
319 assertTrue(tags.contains("foo/batch.js"));
320 }
321
322 private Map<String, Object> setupRequestCache()
323 {
324 final Map<String, Object> requestCache = new HashMap<String, Object>();
325 when(mockWebResourceIntegration.getRequestCache()).thenReturn(requestCache);
326 return requestCache;
327 }
328
329 public void testRequireResourceWithDuplicateDependencies()
330 {
331 final String resourceA = "test.atlassian:a";
332 final String resourceB = "test.atlassian:b";
333 final String resourceC = "test.atlassian:c";
334 final String resourceD = "test.atlassian:d";
335 final String resourceE = "test.atlassian:e";
336
337
338 mockEnabledPluginModule(resourceA, TestUtils.createWebResourceModuleDescriptor(resourceA, testPlugin,
339 Collections.<ResourceDescriptor> emptyList(), Arrays.asList(resourceB, resourceC)));
340
341 mockEnabledPluginModule(resourceB, TestUtils.createWebResourceModuleDescriptor(resourceB, testPlugin,
342 Collections.<ResourceDescriptor> emptyList(), Collections.singletonList(resourceD)));
343
344 mockEnabledPluginModule(resourceC, TestUtils.createWebResourceModuleDescriptor(resourceC, testPlugin,
345 Collections.<ResourceDescriptor> emptyList(), Collections.singletonList(resourceE)));
346
347 mockEnabledPluginModule(resourceD, TestUtils.createWebResourceModuleDescriptor(resourceD, testPlugin,
348 Collections.<ResourceDescriptor> emptyList(), Collections.singletonList(resourceC)));
349
350 mockEnabledPluginModule(resourceE, TestUtils.createWebResourceModuleDescriptor(resourceE, testPlugin));
351
352 final Map<String, Object> requestCache = setupRequestCache();
353 webResourceManager.requireResource(resourceA);
354
355 final Collection<?> resources = (Collection<?>) requestCache.get(WebResourceManagerImpl.REQUEST_CACHE_RESOURCE_KEY);
356 assertEquals(5, resources.size());
357 final Object[] resourceArray = resources.toArray();
358 assertEquals(resourceE, resourceArray[0]);
359 assertEquals(resourceC, resourceArray[1]);
360 assertEquals(resourceD, resourceArray[2]);
361 assertEquals(resourceB, resourceArray[3]);
362 assertEquals(resourceA, resourceArray[4]);
363 }
364
365 public void testRequireSingleResourceGetsDeps() throws Exception
366 {
367 final String resourceA = "test.atlassian:a";
368 final String resourceB = "test.atlassian:b";
369
370 final List<ResourceDescriptor> resourceDescriptorsA = TestUtils.createResourceDescriptors("resourceA.css");
371 final List<ResourceDescriptor> resourceDescriptorsB = TestUtils.createResourceDescriptors("resourceB.css", "resourceB-more.css");
372
373
374 mockEnabledPluginModule(resourceA, TestUtils.createWebResourceModuleDescriptor(resourceA, testPlugin, resourceDescriptorsA,
375 Collections.singletonList(resourceB)));
376 mockEnabledPluginModule(resourceB, TestUtils.createWebResourceModuleDescriptor(resourceB, testPlugin, resourceDescriptorsB,
377 Collections.<String> emptyList()));
378
379 final String s = webResourceManager.getResourceTags(resourceA, UrlMode.AUTO);
380 final int indexA = s.indexOf(resourceA);
381 final int indexB = s.indexOf(resourceB);
382
383 assertNotSame(-1, indexA);
384 assertNotSame(-1, indexB);
385 assertTrue(indexB < indexA);
386 }
387
388 public void testIncludeResourcesWithResourceList() throws Exception
389 {
390 final String resourceA = "test.atlassian:a";
391
392 final List<ResourceDescriptor> resourceDescriptorsA = TestUtils.createResourceDescriptors("resourceA.css");
393
394 mockEnabledPluginModule(resourceA, TestUtils.createWebResourceModuleDescriptor(resourceA, testPlugin, resourceDescriptorsA,
395 Collections.<String> emptyList()));
396
397 final StringWriter requiredResourceWriter = new StringWriter();
398 webResourceManager.includeResources(Arrays.<String> asList(resourceA), requiredResourceWriter, UrlMode.ABSOLUTE);
399 final String result = requiredResourceWriter.toString();
400 assertTrue(result.contains(resourceA));
401 }
402
403 public void testIncludeResourcesWithResourceListIgnoresRequireResource() throws Exception
404 {
405 final String resourceA = "test.atlassian:a";
406 final String resourceB = "test.atlassian:b";
407
408 final List<ResourceDescriptor> resourceDescriptorsA = TestUtils.createResourceDescriptors("resourceA.css");
409 final List<ResourceDescriptor> resourceDescriptorsB = TestUtils.createResourceDescriptors("resourceB.css", "resourceB-more.css");
410
411 final Map<String, Object> requestCache = new HashMap<String, Object>();
412 when(mockWebResourceIntegration.getRequestCache()).thenReturn(requestCache);
413
414 mockEnabledPluginModule(resourceA, TestUtils.createWebResourceModuleDescriptor(resourceA, testPlugin, resourceDescriptorsA,
415 Collections.<String> emptyList()));
416
417 mockEnabledPluginModule(resourceB, TestUtils.createWebResourceModuleDescriptor(resourceB, testPlugin, resourceDescriptorsB,
418 Collections.<String> emptyList()));
419
420 final StringWriter requiredResourceWriter = new StringWriter();
421 webResourceManager.requireResource(resourceB);
422 webResourceManager.includeResources(Arrays.<String> asList(resourceA), requiredResourceWriter, UrlMode.ABSOLUTE);
423 final String result = requiredResourceWriter.toString();
424 assertFalse(result.contains(resourceB));
425 }
426
427 public void testIncludeResourcesWithResourceListIncludesDependences() throws Exception
428 {
429 final String resourceA = "test.atlassian:a";
430 final String resourceB = "test.atlassian:b";
431
432 final List<ResourceDescriptor> resourceDescriptorsA = TestUtils.createResourceDescriptors("resourceA.css");
433 final List<ResourceDescriptor> resourceDescriptorsB = TestUtils.createResourceDescriptors("resourceB.css", "resourceB-more.css");
434
435
436 mockEnabledPluginModule(resourceA, TestUtils.createWebResourceModuleDescriptor(resourceA, testPlugin, resourceDescriptorsA,
437 Collections.singletonList(resourceB)));
438 mockEnabledPluginModule(resourceB, TestUtils.createWebResourceModuleDescriptor(resourceB, testPlugin, resourceDescriptorsB,
439 Collections.<String> emptyList()));
440
441 final StringWriter requiredResourceWriter = new StringWriter();
442 webResourceManager.includeResources(Arrays.<String> asList(resourceA), requiredResourceWriter, UrlMode.ABSOLUTE);
443 final String result = requiredResourceWriter.toString();
444 assertTrue(result.contains(resourceB));
445 }
446
447 public void testIncludeResourcesWithResourceListIncludesDependencesFromSuperBatch() throws Exception
448 {
449 final String resourceA = "test.atlassian:a";
450 final String resourceB = "test.atlassian:b";
451
452 final ResourceBatchingConfiguration mockBatchingConfiguration = mock(ResourceBatchingConfiguration.class);
453 when(mockBatchingConfiguration.isSuperBatchingEnabled()).thenReturn(true);
454 when(mockBatchingConfiguration.getSuperBatchModuleCompleteKeys()).thenReturn(Arrays.asList(resourceB));
455
456 webResourceManager = new WebResourceManagerImpl(pluginResourceLocator, mockWebResourceIntegration, mockUrlProvider, mockBatchingConfiguration);
457
458 final List<ResourceDescriptor> resourceDescriptorsA = TestUtils.createResourceDescriptors("resourceA.css");
459 final List<ResourceDescriptor> resourceDescriptorsB = TestUtils.createResourceDescriptors("resourceB.css");
460
461
462 mockEnabledPluginModule(resourceA, TestUtils.createWebResourceModuleDescriptor(resourceA, testPlugin, resourceDescriptorsA,
463 Collections.singletonList(resourceB)));
464 mockEnabledPluginModule(resourceB, TestUtils.createWebResourceModuleDescriptor(resourceB, testPlugin, resourceDescriptorsB,
465 Collections.<String> emptyList()));
466
467 final StringWriter requiredResourceWriter = new StringWriter();
468 webResourceManager.includeResources(Arrays.<String> asList(resourceA), requiredResourceWriter, UrlMode.ABSOLUTE);
469 final String result = requiredResourceWriter.toString();
470 assertTrue(result.contains(resourceB));
471 }
472
473 public void testIncludeResourcesWithSharedDependencies() throws Exception
474 {
475 final String resourceA = "test.atlassian:a";
476 final String resourceB = "test.atlassian:b";
477 final String resourceShared = "test.atlassian:c";
478
479 when(mockBatchingConfiguration.getSuperBatchModuleCompleteKeys()).thenReturn(Arrays.asList(resourceB));
480
481 webResourceManager = new WebResourceManagerImpl(pluginResourceLocator, mockWebResourceIntegration, mockUrlProvider, mockBatchingConfiguration);
482
483 final List<ResourceDescriptor> resourceDescriptorsA = TestUtils.createResourceDescriptors("resourceA.css");
484 final List<ResourceDescriptor> resourceDescriptorsB = TestUtils.createResourceDescriptors("resourceB.css");
485 final List<ResourceDescriptor> resourceDescriptorsShared = TestUtils.createResourceDescriptors("resourceC.css");
486
487
488 mockEnabledPluginModule(resourceA, TestUtils.createWebResourceModuleDescriptor(resourceA, testPlugin, resourceDescriptorsA,
489 Collections.singletonList(resourceShared)));
490
491 mockEnabledPluginModule(resourceB, TestUtils.createWebResourceModuleDescriptor(resourceB, testPlugin, resourceDescriptorsB,
492 Collections.singletonList(resourceShared)));
493 mockEnabledPluginModule(resourceShared, TestUtils.createWebResourceModuleDescriptor(resourceShared, testPlugin, resourceDescriptorsShared,
494 Collections.<String> emptyList()));
495
496 final StringWriter requiredResourceWriter = new StringWriter();
497 webResourceManager.includeResources(Arrays.<String> asList(resourceA, resourceB), requiredResourceWriter, UrlMode.ABSOLUTE);
498 final String result = requiredResourceWriter.toString();
499 assertTrue(result.contains(resourceA));
500 assertTrue(result.contains(resourceB));
501
502 final Pattern resourceCount = Pattern.compile("/download/batch/test\\.atlassian:c/test\\.atlassian:c.css");
503 final Matcher m = resourceCount.matcher(result);
504
505 assertTrue(m.find());
506 assertFalse(m.find(m.end()));
507 }
508
509 public void testRequireResourcesAreClearedAfterIncludesResourcesIsCalled() throws Exception
510 {
511 final String moduleKey = "cool-resources";
512 final String completeModuleKey = "test.atlassian:" + moduleKey;
513
514 final List<ResourceDescriptor> resourceDescriptors1 = TestUtils.createResourceDescriptors("cool.css", "more-cool.css", "cool.js");
515
516 setupRequestCache();
517
518 mockEnabledPluginModule(completeModuleKey, TestUtils.createWebResourceModuleDescriptor(completeModuleKey, testPlugin, resourceDescriptors1));
519
520
521 webResourceManager.requireResource(completeModuleKey);
522 webResourceManager.includeResources(new StringWriter(), UrlMode.RELATIVE);
523
524 final StringWriter requiredResourceWriter = new StringWriter();
525 webResourceManager.includeResources(requiredResourceWriter, UrlMode.RELATIVE);
526 assertEquals("", requiredResourceWriter.toString());
527 }
528
529
530
531 public void testRequireResourceAndResourceTagMethods() throws Exception
532 {
533 final String completeModuleKey = "test.atlassian:cool-resources";
534 final String staticBase = setupRequireResourceAndResourceTagMethods(false, completeModuleKey);
535
536
537 final StringWriter requiredResourceWriter = new StringWriter();
538 webResourceManager.requireResource(completeModuleKey);
539 final String requiredResourceResult = webResourceManager.getRequiredResources(UrlMode.RELATIVE);
540 webResourceManager.includeResources(requiredResourceWriter, UrlMode.RELATIVE);
541 assertEquals(requiredResourceResult, requiredResourceWriter.toString());
542
543 assertTrue(requiredResourceResult.contains("href=\"" + staticBase + "/" + completeModuleKey + "/" + completeModuleKey + ".css"));
544 assertTrue(requiredResourceResult.contains("src=\"" + staticBase + "/" + completeModuleKey + "/" + completeModuleKey + ".js"));
545
546
547 final StringWriter resourceTagsWriter = new StringWriter();
548 webResourceManager.requireResource(completeModuleKey, resourceTagsWriter, UrlMode.RELATIVE);
549 final String resourceTagsResult = webResourceManager.getResourceTags(completeModuleKey, UrlMode.RELATIVE);
550 assertEquals(resourceTagsResult, resourceTagsWriter.toString());
551
552
553 assertEquals(requiredResourceResult, resourceTagsResult);
554 }
555
556 public void testRequireResourceAndResourceTagMethodsWithAbsoluteUrlMode() throws Exception
557 {
558 testRequireResourceAndResourceTagMethods(UrlMode.ABSOLUTE, true);
559 }
560
561 public void testRequireResourceAndResourceTagMethodsWithRelativeUrlMode() throws Exception
562 {
563 testRequireResourceAndResourceTagMethods(UrlMode.RELATIVE, false);
564 }
565
566 public void testRequireResourceAndResourceTagMethodsWithAutoUrlMode() throws Exception
567 {
568 testRequireResourceAndResourceTagMethods(UrlMode.AUTO, false);
569 }
570
571 private void testRequireResourceAndResourceTagMethods(final UrlMode urlMode, final boolean baseUrlExpected) throws Exception
572 {
573 final String completeModuleKey = "test.atlassian:cool-resources";
574 final String staticBase = setupRequireResourceAndResourceTagMethods(baseUrlExpected, completeModuleKey);
575
576
577 final StringWriter requiredResourceWriter = new StringWriter();
578 webResourceManager.requireResource(completeModuleKey);
579 final String requiredResourceResult = webResourceManager.getRequiredResources(urlMode);
580 webResourceManager.includeResources(requiredResourceWriter, urlMode);
581 assertEquals(requiredResourceResult, requiredResourceWriter.toString());
582
583 assertTrue(requiredResourceResult.contains("href=\"" + staticBase + "/" + completeModuleKey + "/" + completeModuleKey + ".css"));
584 assertTrue(requiredResourceResult.contains("src=\"" + staticBase + "/" + completeModuleKey + "/" + completeModuleKey + ".js"));
585
586
587 final StringWriter resourceTagsWriter = new StringWriter();
588 webResourceManager.requireResource(completeModuleKey, resourceTagsWriter, urlMode);
589 final String resourceTagsResult = webResourceManager.getResourceTags(completeModuleKey, urlMode);
590 assertEquals(resourceTagsResult, resourceTagsWriter.toString());
591
592
593 assertEquals(requiredResourceResult, resourceTagsResult);
594 }
595
596 private String setupRequireResourceAndResourceTagMethods(final boolean baseUrlExpected, final String completeModuleKey) throws DocumentException
597 {
598 final List<ResourceDescriptor> descriptors = TestUtils.createResourceDescriptors("cool.css", "more-cool.css", "cool.js");
599
600 final Map<String, Object> requestCache = new HashMap<String, Object>();
601 when(mockWebResourceIntegration.getRequestCache()).thenReturn(requestCache);
602
603 mockEnabledPluginModule(completeModuleKey, TestUtils.createWebResourceModuleDescriptor(completeModuleKey, testPlugin, descriptors));
604
605 final String staticPrefix = (baseUrlExpected ? BASEURL : "") + "/" + WebResourceManagerImpl.STATIC_RESOURCE_PREFIX + "/" + SYSTEM_BUILD_NUMBER + "/" + SYSTEM_COUNTER + "/" + testPlugin.getPluginInformation().getVersion() + "/" + WebResourceManagerImpl.STATIC_RESOURCE_SUFFIX;
606 when(mockUrlProvider.getStaticResourcePrefix(eq("1"), isA(UrlMode.class))).thenReturn(staticPrefix);
607 return staticPrefix + BatchPluginResource.URL_PREFIX;
608 }
609
610
611
612 public void testRequireResourceWithCacheParameter() throws Exception
613 {
614 final String completeModuleKey = "test.atlassian:no-cache-resources";
615
616 final String expectedResult = setupRequireResourceWithCacheParameter(false, completeModuleKey);
617 assertTrue(webResourceManager.getResourceTags(completeModuleKey, UrlMode.AUTO).contains(expectedResult));
618 }
619
620 public void testRequireResourceWithCacheParameterAndAbsoluteUrlMode() throws Exception
621 {
622 testRequireResourceWithCacheParameter(UrlMode.ABSOLUTE, true);
623 }
624
625 public void testRequireResourceWithCacheParameterAndRelativeUrlMode() throws Exception
626 {
627 testRequireResourceWithCacheParameter(UrlMode.RELATIVE, false);
628 }
629
630 public void testRequireResourceWithCacheParameterAndAutoUrlMode() throws Exception
631 {
632 testRequireResourceWithCacheParameter(UrlMode.AUTO, false);
633 }
634
635 private void testRequireResourceWithCacheParameter(final UrlMode urlMode, final boolean baseUrlExpected) throws Exception
636 {
637 final String completeModuleKey = "test.atlassian:no-cache-resources";
638 final String expectedResult = setupRequireResourceWithCacheParameter(baseUrlExpected, completeModuleKey);
639 assertTrue(webResourceManager.getResourceTags(completeModuleKey, urlMode).contains(expectedResult));
640 }
641
642 private String setupRequireResourceWithCacheParameter(final boolean baseUrlExpected, final String completeModuleKey) throws DocumentException
643 {
644 final Map<String, String> params = new HashMap<String, String>();
645 params.put("cache", "false");
646 final ResourceDescriptor resourceDescriptor = TestUtils.createResourceDescriptor("no-cache.js", params);
647
648 mockEnabledPluginModule(completeModuleKey, TestUtils.createWebResourceModuleDescriptor(completeModuleKey, testPlugin,
649 Collections.singletonList(resourceDescriptor)));
650
651 return "src=\"" + (baseUrlExpected ? BASEURL : "") + BatchPluginResource.URL_PREFIX + "/" + completeModuleKey + "/" + completeModuleKey + ".js?cache=false";
652 }
653
654 public void testGetRequiredResourcesWithFilter() throws Exception
655 {
656 final String moduleKey = "cool-resources";
657 final String completeModuleKey = "test.atlassian:" + moduleKey;
658
659 final List<ResourceDescriptor> resourceDescriptors1 = TestUtils.createResourceDescriptors("cool.css", "cool.js", "more-cool.css");
660
661 setupRequestCache();
662
663 mockEnabledPluginModule(completeModuleKey, TestUtils.createWebResourceModuleDescriptor(completeModuleKey, testPlugin, resourceDescriptors1));
664
665
666 webResourceManager.requireResource(completeModuleKey);
667
668 final String staticPrefix = BASEURL + "/" + WebResourceManagerImpl.STATIC_RESOURCE_PREFIX + "/" + SYSTEM_BUILD_NUMBER + "/" + SYSTEM_COUNTER + "/" + testPlugin.getPluginInformation().getVersion() + "/" + WebResourceManagerImpl.STATIC_RESOURCE_SUFFIX;
669 when(mockUrlProvider.getStaticResourcePrefix("1", UrlMode.ABSOLUTE)).thenReturn(staticPrefix);
670 final String staticBase = staticPrefix + BatchPluginResource.URL_PREFIX;
671
672 final String cssRef = "href=\"" + staticBase + "/" + completeModuleKey + "/" + completeModuleKey + ".css";
673 final String jsRef = "src=\"" + staticBase + "/" + completeModuleKey + "/" + completeModuleKey + ".js";
674
675
676 String requiredResourceResult = webResourceManager.getRequiredResources(UrlMode.ABSOLUTE, new CssWebResource());
677 assertTrue(requiredResourceResult.contains(cssRef));
678 assertFalse(requiredResourceResult.contains(jsRef));
679
680
681 requiredResourceResult = webResourceManager.getRequiredResources(UrlMode.ABSOLUTE, new JavascriptWebResource());
682 assertFalse(requiredResourceResult.contains(cssRef));
683 assertTrue(requiredResourceResult.contains(jsRef));
684
685
686 requiredResourceResult = webResourceManager.getRequiredResources(UrlMode.ABSOLUTE);
687 assertTrue(requiredResourceResult.contains(cssRef));
688 assertTrue(requiredResourceResult.contains(jsRef));
689 }
690
691 public void testGetRequiredResourcesWithCustomFilters() throws Exception
692 {
693 final WebResourceFilter atlassianFilter = new WebResourceFilter()
694 {
695 public boolean matches(final String resourceName)
696 {
697 return resourceName.contains("atlassian");
698 }
699 };
700 final WebResourceFilter bogusFilter = new WebResourceFilter()
701 {
702 public boolean matches(final String resourceName)
703 {
704 return true;
705 }
706 };
707
708 final String moduleKey = "cool-resources";
709 final String completeModuleKey = "test.atlassian:" + moduleKey;
710
711 final List<ResourceDescriptor> resources = TestUtils.createResourceDescriptors("foo.css", "foo-bar.js", "atlassian.css",
712 "atlassian-plugins.js");
713
714 setupRequestCache();
715 mockEnabledPluginModule(completeModuleKey, TestUtils.createWebResourceModuleDescriptor(completeModuleKey, testPlugin, resources));
716
717
718 when(mockBatchingConfiguration.isPluginWebResourceBatchingEnabled()).thenReturn(false);
719 webResourceManager.requireResource(completeModuleKey);
720 final String atlassianResources = webResourceManager.getRequiredResources(UrlMode.RELATIVE, atlassianFilter);
721 assertEquals(-1, atlassianResources.indexOf("foo"));
722 assertTrue(atlassianResources.contains("atlassian.css"));
723 assertTrue(atlassianResources.contains("atlassian-plugins.js"));
724
725 final String allResources = webResourceManager.getRequiredResources(UrlMode.RELATIVE, bogusFilter);
726 for (final ResourceDescriptor resource : resources)
727 {
728 assertTrue(allResources.contains(resource.getName()));
729 }
730 }
731
732 public void testGetRequiredResourcesWithExcludedResources() throws Exception
733 {
734 final String moduleKey = "cool-resources";
735 final String completeModuleKey = "test.atlassian:" + moduleKey;
736
737 final String existingModuleKey = "test.atlassian:alphabets";
738
739 final List<ResourceDescriptor> resourceDescriptors1 = TestUtils.createResourceDescriptors("cool.js", "more-cool.js");
740 final List<ResourceDescriptor> resourceDescriptors2 = TestUtils.createResourceDescriptors("abc.js", "def.js");
741
742 setupRequestCache();
743
744 mockEnabledPluginModule(completeModuleKey, TestUtils.createWebResourceModuleDescriptor(completeModuleKey, testPlugin, resourceDescriptors1));
745 mockEnabledPluginModule(existingModuleKey, TestUtils.createWebResourceModuleDescriptor(completeModuleKey, testPlugin, resourceDescriptors2));
746
747
748 webResourceManager.requireResource(completeModuleKey);
749 webResourceManager.requireResource(existingModuleKey);
750
751 final String staticPrefix = BASEURL + "/" + WebResourceManagerImpl.STATIC_RESOURCE_PREFIX + "/" + SYSTEM_BUILD_NUMBER + "/" + SYSTEM_COUNTER + "/" + testPlugin.getPluginInformation().getVersion() + "/" + WebResourceManagerImpl.STATIC_RESOURCE_SUFFIX;
752 when(mockUrlProvider.getStaticResourcePrefix("1", UrlMode.ABSOLUTE)).thenReturn(staticPrefix);
753 final String staticBase = staticPrefix + BatchPluginResource.URL_PREFIX;
754
755 String requiredResourceResult = webResourceManager.getRequiredResources(UrlMode.ABSOLUTE, new JavascriptWebResource(), Collections.singleton(existingModuleKey), Collections.<String>emptyList());
756 assertTrue(requiredResourceResult.contains(staticBase + "/" + completeModuleKey + "/" + completeModuleKey + ".js"));
757 assertFalse(requiredResourceResult.contains(existingModuleKey));
758 }
759
760 public void testGetRequiredResourcesOrdersByType() throws Exception
761 {
762 final String moduleKey1 = "cool-resources";
763 final String moduleKey2 = "hot-resources";
764 final String completeModuleKey1 = "test.atlassian:" + moduleKey1;
765 final String completeModuleKey2 = "test.atlassian:" + moduleKey2;
766
767 final List<ResourceDescriptor> resourceDescriptors1 = TestUtils.createResourceDescriptors("cool.js", "cool.css", "more-cool.css");
768 final List<ResourceDescriptor> resourceDescriptors2 = TestUtils.createResourceDescriptors("hot.js", "hot.css", "more-hot.css");
769
770 final Plugin plugin = TestUtils.createTestPlugin();
771
772 setupRequestCache();
773
774 mockEnabledPluginModule(completeModuleKey1, TestUtils.createWebResourceModuleDescriptor(completeModuleKey1, plugin, resourceDescriptors1));
775 mockEnabledPluginModule(completeModuleKey2, TestUtils.createWebResourceModuleDescriptor(completeModuleKey2, plugin, resourceDescriptors2));
776
777
778 webResourceManager.requireResource(completeModuleKey1);
779 webResourceManager.requireResource(completeModuleKey2);
780
781 final String staticPrefix = BASEURL + "/" + WebResourceManagerImpl.STATIC_RESOURCE_PREFIX + "/" + SYSTEM_BUILD_NUMBER + "/" + SYSTEM_COUNTER + "/" + plugin.getPluginInformation().getVersion() + "/" + WebResourceManagerImpl.STATIC_RESOURCE_SUFFIX;
782 when(mockUrlProvider.getStaticResourcePrefix("1", UrlMode.ABSOLUTE)).thenReturn(staticPrefix);
783 final String staticBase = staticPrefix + BatchPluginResource.URL_PREFIX;
784
785 final String cssRef1 = "href=\"" + staticBase + "/" + completeModuleKey1 + "/" + completeModuleKey1 + ".css";
786 final String cssRef2 = "href=\"" + staticBase + "/" + completeModuleKey2 + "/" + completeModuleKey2 + ".css";
787 final String jsRef1 = "src=\"" + staticBase + "/" + completeModuleKey1 + "/" + completeModuleKey1 + ".js";
788 final String jsRef2 = "src=\"" + staticBase + "/" + completeModuleKey2 + "/" + completeModuleKey2 + ".js";
789
790 final String requiredResourceResult = webResourceManager.getRequiredResources(UrlMode.ABSOLUTE);
791
792 assertTrue(requiredResourceResult.contains(cssRef1));
793 assertTrue(requiredResourceResult.contains(cssRef2));
794 assertTrue(requiredResourceResult.contains(jsRef1));
795 assertTrue(requiredResourceResult.contains(jsRef2));
796
797 final int cssRef1Index = requiredResourceResult.indexOf(cssRef1);
798 final int cssRef2Index = requiredResourceResult.indexOf(cssRef2);
799 final int jsRef1Index = requiredResourceResult.indexOf(jsRef1);
800 final int jsRef2Index = requiredResourceResult.indexOf(jsRef2);
801
802 assertTrue(cssRef1Index < jsRef1Index);
803 assertTrue(cssRef2Index < jsRef2Index);
804 assertTrue(cssRef2Index < jsRef1Index);
805 }
806
807 public void testRequireResourceInSuperbatch() throws ClassNotFoundException
808 {
809 setupSuperBatch();
810
811 final Map<String, Object> requestCache = setupRequestCache();
812 mockOutSuperbatchPluginAccesses();
813
814 webResourceManager.requireResource("test.atlassian:superbatch");
815
816 final Collection<?> resources = (Collection<?>) requestCache.get(WebResourceManagerImpl.REQUEST_CACHE_RESOURCE_KEY);
817 assertEquals(0, resources.size());
818 }
819
820 public void testRequireResourceWithDependencyInSuperbatch() throws DocumentException, ClassNotFoundException
821 {
822 setupSuperBatch();
823
824 mockOutSuperbatchPluginAccesses();
825
826 final Map<String, Object> requestCache = setupRequestCache();
827
828 mockEnabledPluginModule("test.atlassian:included-resource", TestUtils.createWebResourceModuleDescriptor("test.atlassian:included-resource",
829 testPlugin, Collections.<ResourceDescriptor> emptyList(), Collections.singletonList("test.atlassian:superbatch")));
830
831 webResourceManager.requireResource("test.atlassian:included-resource");
832
833 final Collection<?> resources = (Collection<?>) requestCache.get(WebResourceManagerImpl.REQUEST_CACHE_RESOURCE_KEY);
834 assertEquals(1, resources.size());
835 assertEquals("test.atlassian:included-resource", resources.iterator().next());
836 }
837
838 public void testSuperBatchResolution() throws DocumentException, ClassNotFoundException
839 {
840 setupSuperBatch();
841
842 TestUtils.setupSuperbatchTestContent(mockPluginAccessor, testPlugin);
843
844 final List<PluginResource> cssResources = webResourceManager.getSuperBatchResources(CssWebResource.FORMATTER);
845 assertEquals(2, cssResources.size());
846
847 final SuperBatchPluginResource superBatch1 = (SuperBatchPluginResource) cssResources.get(0);
848 assertEquals("batch.css", superBatch1.getResourceName());
849 assertTrue(superBatch1.getParams().isEmpty());
850
851 Set<BatchedWebResourceDescriptor> batchedWebResourceDescriptors = superBatch1.getBatchedWebResourceDescriptors();
852 Set<BatchedWebResourceDescriptor> expectedBatchedWebResourceDescriptors = new HashSet<BatchedWebResourceDescriptor>(2);
853 expectedBatchedWebResourceDescriptors.add(new BatchedWebResourceDescriptor("1","test.atlassian:superbatch"));
854 expectedBatchedWebResourceDescriptors.add(new BatchedWebResourceDescriptor("1","test.atlassian:superbatch2"));
855 assertEquals(expectedBatchedWebResourceDescriptors, batchedWebResourceDescriptors);
856
857 final SuperBatchPluginResource superBatch2 = (SuperBatchPluginResource) cssResources.get(1);
858 assertEquals("batch.css", superBatch2.getResourceName());
859 assertEquals("true", superBatch2.getParams().get("ieonly"));
860
861 batchedWebResourceDescriptors = superBatch2.getBatchedWebResourceDescriptors();
862 expectedBatchedWebResourceDescriptors = new HashSet<BatchedWebResourceDescriptor>(1);
863 expectedBatchedWebResourceDescriptors.add(new BatchedWebResourceDescriptor("1", "test.atlassian:superbatch"));
864 assertEquals(expectedBatchedWebResourceDescriptors, batchedWebResourceDescriptors);
865
866 final List<PluginResource> jsResources = webResourceManager.getSuperBatchResources(JavascriptWebResource.FORMATTER);
867 assertEquals(1, jsResources.size());
868
869 final SuperBatchPluginResource jsSuperBatch = (SuperBatchPluginResource)jsResources.get(0);
870 assertEquals("batch.js", jsSuperBatch.getResourceName());
871 assertEquals(0, jsSuperBatch.getParams().size());
872
873 batchedWebResourceDescriptors = jsSuperBatch.getBatchedWebResourceDescriptors();
874 expectedBatchedWebResourceDescriptors = new HashSet<BatchedWebResourceDescriptor>(2);
875 expectedBatchedWebResourceDescriptors.add(new BatchedWebResourceDescriptor("1","test.atlassian:superbatch"));
876 expectedBatchedWebResourceDescriptors.add(new BatchedWebResourceDescriptor("1","test.atlassian:superbatch2"));
877 assertEquals(expectedBatchedWebResourceDescriptors, batchedWebResourceDescriptors);
878 }
879
880
881
882
883
884 public void testNestedContextExclusivity() throws Exception
885 {
886
887 final String moduleKey1 = "cool-resources";
888 final String moduleKey2 = "hot-resources";
889 final String completeModuleKey1 = "test.atlassian:" + moduleKey1;
890 final String completeModuleKey2 = "test.atlassian:" + moduleKey2;
891
892 final List<ResourceDescriptor> resourceDescriptors1 = TestUtils.createResourceDescriptors("cool.js", "cool.css", "more-cool.css");
893 final List<ResourceDescriptor> resourceDescriptors2 = TestUtils.createResourceDescriptors("hot.js", "hot.css", "more-hot.css");
894
895 final Plugin plugin = TestUtils.createTestPlugin();
896
897 setupRequestCache();
898
899 mockEnabledPluginModule(completeModuleKey1, TestUtils.createWebResourceModuleDescriptor(completeModuleKey1, plugin, resourceDescriptors1));
900 mockEnabledPluginModule(completeModuleKey2, TestUtils.createWebResourceModuleDescriptor(completeModuleKey2, plugin, resourceDescriptors2));
901
902 final String cssRef1 = completeModuleKey1 + "/" + completeModuleKey1 + ".css";
903 final String cssRef2 = completeModuleKey2 + "/" + completeModuleKey2 + ".css";
904 final String jsRef1 = completeModuleKey1 + "/" + completeModuleKey1 + ".js";
905 final String jsRef2 = completeModuleKey2 + "/" + completeModuleKey2 + ".js";
906
907
908 webResourceManager.requireResource(completeModuleKey1);
909 webResourceManager.executeInNewContext(new Supplier<Void>()
910 {
911 public Void get()
912 {
913 webResourceManager.requireResource(completeModuleKey2);
914
915 final StringWriter writer = new StringWriter();
916 webResourceManager.includeResources(writer, UrlMode.AUTO);
917 final String resources = writer.toString();
918
919 assertFalse(resources.contains(cssRef1));
920 assertTrue(resources.contains(cssRef2));
921
922 assertFalse(resources.contains(jsRef1));
923 assertTrue(resources.contains(jsRef2));
924 return null;
925 }
926 });
927
928 final StringWriter writer = new StringWriter();
929 webResourceManager.includeResources(writer, UrlMode.AUTO);
930 final String resources = writer.toString();
931
932 assertTrue(resources.contains(cssRef1));
933 assertFalse(resources.contains(cssRef2));
934
935 assertTrue(resources.contains(jsRef1));
936 assertFalse(resources.contains(jsRef2));
937
938 }
939
940
941
942 public void testNestedContextOnEmptyBase() throws Exception
943 {
944 final String moduleKey1 = "cool-resources";
945 final String completeModuleKey1 = "test.atlassian:" + moduleKey1;
946
947 final List<ResourceDescriptor> resourceDescriptors1 = TestUtils.createResourceDescriptors("cool.js", "cool.css", "more-cool.css");
948
949 final Plugin plugin = TestUtils.createTestPlugin();
950
951 setupRequestCache();
952
953 mockEnabledPluginModule(completeModuleKey1, TestUtils.createWebResourceModuleDescriptor(completeModuleKey1, plugin, resourceDescriptors1));
954
955 final String cssRef1 = completeModuleKey1 + "/" + completeModuleKey1 + ".css";
956 final String jsRef1 = completeModuleKey1 + "/" + completeModuleKey1 + ".js";
957
958
959 webResourceManager.executeInNewContext(new Supplier<Void>()
960 {
961 public Void get()
962 {
963 webResourceManager.requireResource(completeModuleKey1);
964
965 final StringWriter writer = new StringWriter();
966 webResourceManager.includeResources(writer, UrlMode.AUTO);
967 final String resources = writer.toString();
968
969 assertTrue(resources.contains(cssRef1));
970 assertTrue(resources.contains(jsRef1));
971
972 return null;
973 }
974 });
975
976 final StringWriter writer = new StringWriter();
977 webResourceManager.includeResources(writer, UrlMode.AUTO);
978 final String resources = writer.toString();
979
980 assertFalse(resources.contains(cssRef1));
981 assertFalse(resources.contains(jsRef1));
982 }
983
984
985
986 public void testNestedContextWithoutWriting() throws Exception
987 {
988 final String moduleKey1 = "cool-resources";
989 final String completeModuleKey1 = "test.atlassian:" + moduleKey1;
990
991 final List<ResourceDescriptor> resourceDescriptors1 = TestUtils.createResourceDescriptors("cool.js", "cool.css", "more-cool.css");
992
993 final Plugin plugin = TestUtils.createTestPlugin();
994
995 setupRequestCache();
996
997 mockEnabledPluginModule(completeModuleKey1, TestUtils.createWebResourceModuleDescriptor(completeModuleKey1, plugin, resourceDescriptors1));
998
999 final String cssRef1 = completeModuleKey1 + "/" + completeModuleKey1 + ".css";
1000 final String jsRef1 = completeModuleKey1 + "/" + completeModuleKey1 + ".js";
1001
1002
1003 webResourceManager.executeInNewContext(new Supplier<Void>()
1004 {
1005 public Void get()
1006 {
1007 webResourceManager.requireResource(completeModuleKey1);
1008 return null;
1009 }
1010 });
1011
1012 final StringWriter writer = new StringWriter();
1013 webResourceManager.includeResources(writer, UrlMode.AUTO);
1014 final String resources = writer.toString();
1015
1016
1017 assertFalse(resources.contains(cssRef1));
1018 assertFalse(resources.contains(jsRef1));
1019 }
1020
1021
1022
1023 public void testMultipleNestedContexts() throws Exception
1024 {
1025 final String moduleKey1 = "cool-resources";
1026 final String moduleKey2 = "hot-resources";
1027 final String moduleKey3 = "warm-resources";
1028 final String completeModuleKey1 = "test.atlassian:" + moduleKey1;
1029 final String completeModuleKey2 = "test.atlassian:" + moduleKey2;
1030 final String completeModuleKey3 = "test.atlassian:" + moduleKey3;
1031
1032 final List<ResourceDescriptor> resourceDescriptors1 = TestUtils.createResourceDescriptors("cool.js", "cool.css", "more-cool.css");
1033 final List<ResourceDescriptor> resourceDescriptors2 = TestUtils.createResourceDescriptors("hot.js", "hot.css", "more-hot.css");
1034 final List<ResourceDescriptor> resourceDescriptors3 = TestUtils.createResourceDescriptors("warm.js", "warm.css", "more-warm.css");
1035
1036 final Plugin plugin = TestUtils.createTestPlugin();
1037
1038 setupRequestCache();
1039
1040 mockEnabledPluginModule(completeModuleKey1, TestUtils.createWebResourceModuleDescriptor(completeModuleKey1, plugin, resourceDescriptors1));
1041 mockEnabledPluginModule(completeModuleKey2, TestUtils.createWebResourceModuleDescriptor(completeModuleKey2, plugin, resourceDescriptors2));
1042 mockEnabledPluginModule(completeModuleKey3, TestUtils.createWebResourceModuleDescriptor(completeModuleKey3, plugin, resourceDescriptors3));
1043
1044 final String cssRef1 = completeModuleKey1 + "/" + completeModuleKey1 + ".css";
1045 final String cssRef2 = completeModuleKey2 + "/" + completeModuleKey2 + ".css";
1046 final String cssRef3 = completeModuleKey3 + "/" + completeModuleKey3 + ".css";
1047 final String jsRef1 = completeModuleKey1 + "/" + completeModuleKey1 + ".js";
1048 final String jsRef2 = completeModuleKey2 + "/" + completeModuleKey2 + ".js";
1049 final String jsRef3 = completeModuleKey3 + "/" + completeModuleKey3 + ".js";
1050
1051 setupRequestCache();
1052
1053
1054 webResourceManager.requireResource(completeModuleKey1);
1055
1056
1057 webResourceManager.executeInNewContext(new Supplier<Void>()
1058 {
1059 public Void get()
1060 {
1061 webResourceManager.requireResource(completeModuleKey2);
1062
1063 webResourceManager.executeInNewContext(new Supplier<Void>()
1064 {
1065 public Void get()
1066 {
1067 webResourceManager.requireResource(completeModuleKey3);
1068
1069
1070 final StringWriter writer = new StringWriter();
1071 webResourceManager.includeResources(writer, UrlMode.AUTO);
1072 final String resources = writer.toString();
1073
1074 assertTrue(resources.contains(cssRef3));
1075 assertTrue(resources.contains(jsRef3));
1076 assertFalse(resources.contains(cssRef1));
1077 assertFalse(resources.contains(jsRef1));
1078 assertFalse(resources.contains(cssRef2));
1079 assertFalse(resources.contains(jsRef2));
1080
1081 return null;
1082 }
1083 });
1084
1085
1086 final StringWriter writer = new StringWriter();
1087 webResourceManager.includeResources(writer, UrlMode.AUTO);
1088 final String resources = writer.toString();
1089
1090 assertTrue(resources.contains(cssRef2));
1091 assertTrue(resources.contains(jsRef2));
1092 assertFalse(resources.contains(cssRef1));
1093 assertFalse(resources.contains(jsRef1));
1094 assertFalse(resources.contains(cssRef3));
1095 assertFalse(resources.contains(jsRef3));
1096
1097 return null;
1098 }
1099 });
1100
1101
1102
1103 final StringWriter writer = new StringWriter();
1104 webResourceManager.includeResources(writer, UrlMode.AUTO);
1105 final String resources = writer.toString();
1106
1107 assertTrue(resources.contains(cssRef1));
1108 assertTrue(resources.contains(jsRef1));
1109 assertFalse(resources.contains(cssRef2));
1110 assertFalse(resources.contains(jsRef2));
1111 assertFalse(resources.contains(cssRef3));
1112 assertFalse(resources.contains(jsRef3));
1113 }
1114
1115 private void setupSuperBatch()
1116 {
1117 when(mockBatchingConfiguration.isSuperBatchingEnabled()).thenReturn(true);
1118 when(mockBatchingConfiguration.getSuperBatchModuleCompleteKeys()).thenReturn(
1119 Arrays.asList("test.atlassian:superbatch", "test.atlassian:superbatch2", "test.atlassian:missing-plugin"));
1120 }
1121
1122 private void mockOutSuperbatchPluginAccesses() throws ClassNotFoundException
1123 {
1124 mockOutPluginModule("test.atlassian:superbatch");
1125 mockOutPluginModule("test.atlassian:superbatch2");
1126 when(mockPluginAccessor.getPluginModule("test.atlassian:missing-plugin")).thenReturn(null);
1127 when(mockPluginAccessor.getEnabledPluginModule("test.atlassian:missing-plugin")).thenReturn(null);
1128 }
1129
1130 private void mockOutPluginModule(final String moduleKey) throws ClassNotFoundException
1131 {
1132 final Plugin p = TestUtils.createTestPlugin();
1133 final ModuleDescriptor module = TestUtils.createWebResourceModuleDescriptor(moduleKey, p);
1134 when(mockPluginAccessor.getPluginModule(moduleKey)).thenReturn(module);
1135 when(mockPluginAccessor.getEnabledPluginModule(moduleKey)).thenReturn(module);
1136 }
1137 }