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