View Javadoc

1   package com.atlassian.plugin.webresource;
2   
3   import static com.google.common.collect.Iterables.isEmpty;
4   import static com.google.common.collect.Iterables.size;
5   import static org.mockito.Mockito.when;
6   
7   import com.atlassian.plugin.ModuleDescriptor;
8   import com.atlassian.plugin.Plugin;
9   import com.atlassian.plugin.PluginAccessor;
10  import com.atlassian.plugin.elements.ResourceDescriptor;
11  
12  import org.mockito.Mock;
13  import org.mockito.MockitoAnnotations;
14  
15  import java.util.ArrayList;
16  import java.util.Arrays;
17  import java.util.Collections;
18  import java.util.HashSet;
19  import java.util.List;
20  import java.util.Set;
21  
22  import junit.framework.TestCase;
23  
24  public class TestDefaultResourceDependencyResolver extends TestCase
25  {
26      @Mock
27      private WebResourceIntegration mockWebResourceIntegration;
28      @Mock
29      private PluginAccessor mockPluginAccessor;
30      @Mock
31      private ResourceBatchingConfiguration mockBatchingConfiguration;
32  
33      private ResourceDependencyResolver dependencyResolver;
34  
35      private Plugin testPlugin;
36      private final List<String> superBatchKeys = new ArrayList<String>();
37      private final List<WebResourceModuleDescriptor> moduleDescriptors = new ArrayList<WebResourceModuleDescriptor>();
38  
39      @Override
40      protected void setUp() throws Exception
41      {
42          super.setUp();
43  
44          testPlugin = TestUtils.createTestPlugin();
45  
46          MockitoAnnotations.initMocks(this);
47          when(mockWebResourceIntegration.getPluginAccessor()).thenReturn(mockPluginAccessor);
48          when(mockWebResourceIntegration.getSuperBatchVersion()).thenReturn("1");
49          when(mockPluginAccessor.getEnabledModuleDescriptorsByClass(WebResourceModuleDescriptor.class)).thenReturn(moduleDescriptors);
50          when(mockBatchingConfiguration.isSuperBatchingEnabled()).thenReturn(true);
51          when(mockBatchingConfiguration.getSuperBatchModuleCompleteKeys()).thenReturn(superBatchKeys);
52  
53          dependencyResolver = new DefaultResourceDependencyResolver(mockWebResourceIntegration, mockBatchingConfiguration);
54      }
55  
56      @Override
57      protected void tearDown() throws Exception
58      {
59          dependencyResolver = null;
60          mockWebResourceIntegration = null;
61          mockPluginAccessor = null;
62          mockBatchingConfiguration = null;
63  
64          testPlugin = null;
65  
66          super.tearDown();
67      }
68  
69      public void testSuperBatchingNotEnabled()
70      {
71          when(mockBatchingConfiguration.isSuperBatchingEnabled()).thenReturn(true);
72          when(mockBatchingConfiguration.getSuperBatchModuleCompleteKeys()).thenReturn(superBatchKeys);
73  
74          assertTrue(isEmpty(dependencyResolver.getSuperBatchDependencies()));
75      }
76  
77      public void testGetSuperBatchDependenciesInOrder()
78      {
79          final String superBatchResource1 = "plugin.key:resource1";
80          final String superBatchResource2 = "plugin.key:resource2";
81          final String superBatchResource3 = "plugin.key:resource3";
82  
83          superBatchKeys.add(superBatchResource1);
84          superBatchKeys.add(superBatchResource2);
85          superBatchKeys.add(superBatchResource3);
86  
87          when(mockWebResourceIntegration.getSuperBatchVersion()).thenReturn("1.0");
88  
89          addModuleDescriptor(superBatchResource1);
90          addModuleDescriptor(superBatchResource2);
91          addModuleDescriptor(superBatchResource3);
92  
93          final Iterable<WebResourceModuleDescriptor> resources = dependencyResolver.getSuperBatchDependencies();
94          assertNotNull(resources);
95          assertOrder(resources, superBatchResource1, superBatchResource2, superBatchResource3);
96      }
97  
98      public void testGetSuperBatchDependenciesWithCylicDependency()
99      {
100         final String superBatchResource1 = "plugin.key:resource1";
101         final String superBatchResource2 = "plugin.key:resource2";
102 
103         superBatchKeys.add(superBatchResource1);
104         superBatchKeys.add(superBatchResource2);
105 
106         when(mockWebResourceIntegration.getSuperBatchVersion()).thenReturn("1.0");
107 
108         addModuleDescriptor(superBatchResource1, Arrays.asList(superBatchResource2));
109         addModuleDescriptor(superBatchResource2, Arrays.asList(superBatchResource1));
110 
111         final Iterable<WebResourceModuleDescriptor> resources = dependencyResolver.getSuperBatchDependencies();
112         assertNotNull(resources);
113         assertOrder(resources, superBatchResource2, superBatchResource1);
114     }
115 
116     public void testGetSuperBatchDependenciesWithDependencies()
117     {
118         final String superBatchResource1 = "test.atlassian:super1";
119         final String superBatchResource2 = "test.atlassian:super2";
120 
121         superBatchKeys.add(superBatchResource1);
122         superBatchKeys.add(superBatchResource2);
123         when(mockWebResourceIntegration.getSuperBatchVersion()).thenReturn("1.0");
124 
125         // dependcies
126         final String resourceA = "test.atlassian:a";
127         final String resourceB = "test.atlassian:b";
128         final String resourceC = "test.atlassian:c";
129         final String resourceD = "test.atlassian:d";
130 
131         // super batch 1 depends on A, B
132         addModuleDescriptor(resourceA);
133         addModuleDescriptor(resourceB);
134         addModuleDescriptor(superBatchResource1, Arrays.asList(resourceA, resourceB));
135 
136         // super batch 2 depends on C
137         addModuleDescriptor(resourceD);
138         addModuleDescriptor(resourceC, Arrays.asList(resourceD));
139         addModuleDescriptor(superBatchResource2, Collections.singletonList(resourceC));
140 
141         final Iterable<WebResourceModuleDescriptor> resources = dependencyResolver.getSuperBatchDependencies();
142         assertNotNull(resources);
143         assertOrder(resources, resourceA, resourceB, superBatchResource1, resourceD, resourceC, superBatchResource2);
144     }
145 
146     public void testGetDependenciesExcludesSuperBatch()
147     {
148         final String superBatchResource1 = "test.atlassian:super1";
149         final String superBatchResource2 = "test.atlassian:super2";
150         final String moduleKey = "test.atlassian:foo";
151 
152         superBatchKeys.add(superBatchResource1);
153         superBatchKeys.add(superBatchResource2);
154         when(mockWebResourceIntegration.getSuperBatchVersion()).thenReturn("1.0");
155 
156         // module depends on super batch 1
157         addModuleDescriptor(moduleKey, Arrays.asList(superBatchResource1));
158         addModuleDescriptor(superBatchResource1);
159         addModuleDescriptor(superBatchResource2);
160 
161         final Iterable<WebResourceModuleDescriptor> resources = dependencyResolver.getDependencies(moduleKey, true);
162         assertNotNull(resources);
163         assertOrder(resources, moduleKey);
164     }
165 
166     public void testGetDependenciesIncludesSuperBatch()
167     {
168         final String superBatchResource1 = "test.atlassian:super1";
169         final String superBatchResource2 = "test.atlassian:super2";
170         final String moduleKey = "test.atlassian:foo";
171 
172         superBatchKeys.add(superBatchResource1);
173         superBatchKeys.add(superBatchResource2);
174         when(mockWebResourceIntegration.getSuperBatchVersion()).thenReturn("1.0");
175 
176         // module depends on super batch 1
177         addModuleDescriptor(moduleKey, Arrays.asList(superBatchResource1));
178         addModuleDescriptor(superBatchResource1);
179         addModuleDescriptor(superBatchResource2);
180 
181         final Iterable<WebResourceModuleDescriptor> resources = dependencyResolver.getDependencies(moduleKey, false);
182         assertNotNull(resources);
183         assertOrder(resources, superBatchResource1, moduleKey);
184     }
185 
186     public void testGetDependenciesInContext()
187     {
188         final String moduleKey1 = "test.atlassian:foo";
189         final String moduleKey2 = "test.atlassian:bar";
190 
191         final String context1 = "connie";
192         final Set<String> contexts1 = new HashSet<String>(Arrays.asList(context1));
193         final String context2 = "jira";
194         final Set<String> contexts2 = new HashSet<String>(Arrays.asList(context2));
195 
196         addModuleDescriptor(moduleKey1, Collections.<String> emptyList(), contexts1);
197         addModuleDescriptor(moduleKey2, Collections.<String> emptyList(), contexts2);
198 
199         Iterable<WebResourceModuleDescriptor> resources = dependencyResolver.getDependenciesInContext(context1);
200         assertOrder(resources, moduleKey1);
201 
202         resources = dependencyResolver.getDependenciesInContext(context2);
203         assertOrder(resources, moduleKey2);
204     }
205 
206     public void testGetDependenciesInContextWithMultipleEntries()
207     {
208         final String moduleKey1 = "test.atlassian:foo";
209         final String moduleKey2 = "test.atlassian:bar";
210 
211         final String context = "connie";
212         final Set<String> contexts = new HashSet<String>(Arrays.asList(context));
213 
214         addModuleDescriptor(moduleKey1, Collections.<String> emptyList(), contexts);
215         addModuleDescriptor(moduleKey2, Collections.<String> emptyList(), contexts);
216 
217         final Iterable<WebResourceModuleDescriptor> resources = dependencyResolver.getDependenciesInContext(context);
218         assertOrder(resources, moduleKey1, moduleKey2);
219     }
220 
221     public void testGetDependenciesInContextWithSharedDependenciesInDifferentContexts()
222     {
223         final String moduleKey1 = "test.atlassian:foo";
224         final String moduleKey2 = "test.atlassian:bar";
225         final String sharedModuleKey = "test.atlassian:shared";
226 
227         final String context1 = "connie";
228         final Set<String> contexts1 = new HashSet<String>(Arrays.asList(context1));
229         final String context2 = "jira";
230         final Set<String> contexts2 = new HashSet<String>(Arrays.asList(context2));
231 
232         addModuleDescriptor(moduleKey1, Arrays.asList(sharedModuleKey), contexts1);
233         addModuleDescriptor(moduleKey2, Arrays.asList(sharedModuleKey), contexts2);
234         // Even if the parent is added last, it should appear first in the list.
235         addModuleDescriptor(sharedModuleKey);
236 
237         Iterable<WebResourceModuleDescriptor> resources = dependencyResolver.getDependenciesInContext(context1);
238         assertOrder(resources, sharedModuleKey, moduleKey1);
239 
240         resources = dependencyResolver.getDependenciesInContext(context2);
241         assertOrder(resources, sharedModuleKey, moduleKey2);
242     }
243 
244     public void testGetDependenciesInContextWithSharedDependenciesInTheSameContext()
245     {
246         final String moduleKey1 = "test.atlassian:foo";
247         final String moduleKey2 = "test.atlassian:bar";
248         final String sharedModuleKey = "test.atlassian:shared";
249 
250         final String context = "connie";
251         final Set<String> contexts = new HashSet<String>(Arrays.asList(context));
252 
253         addModuleDescriptor(moduleKey1, Arrays.asList(sharedModuleKey), contexts);
254         addModuleDescriptor(moduleKey2, Arrays.asList(sharedModuleKey), contexts);
255         // Even if the parent is added last, it should appear first in the list.
256         addModuleDescriptor(sharedModuleKey);
257 
258         final Iterable<WebResourceModuleDescriptor> resources = dependencyResolver.getDependenciesInContext(context);
259         assertOrder(resources, sharedModuleKey, moduleKey1, moduleKey2);
260     }
261 
262     public void testGetDependenciesInContextWithDuplicateResources()
263     {
264         final String moduleKey1 = "test.atlassian:foo";
265         final String parentModuleKey = "test.atlassian:parent";
266 
267         final String context1 = "connie";
268         final Set<String> contexts1 = new HashSet<String>(Arrays.asList(context1));
269 
270         addModuleDescriptor(parentModuleKey, Collections.<String> emptyList(), contexts1);
271         addModuleDescriptor(moduleKey1, Arrays.asList(parentModuleKey), contexts1);
272 
273         final Iterable<WebResourceModuleDescriptor> resources = dependencyResolver.getDependenciesInContext(context1);
274         assertOrder(resources, parentModuleKey, moduleKey1);
275     }
276 
277     public void testSkippedConditions() throws ClassNotFoundException
278     {
279         testPlugin = TestUtils.createTestPlugin("test.atlassian", "1", AlwaysTrueCondition.class, AlwaysFalseCondition.class);
280         final String moduleKey1 = "test.atlassian:foo";
281         final String parentModuleKey = "test.atlassian:parent";
282         final String skippedParentModuleKey = "test.atlassian:skipped-parent";
283         final String skippedModuleKey = "test.atlassian:skipped";
284 
285         final String context1 = "connie";
286         final Set<String> contexts1 = new HashSet<String>(Arrays.asList(context1));
287 
288         addModuleDescriptor(parentModuleKey, Collections.<String> emptyList(), contexts1);
289         addModuleDescriptor(moduleKey1, Arrays.asList(parentModuleKey), contexts1);
290         addModuleDescriptor(skippedParentModuleKey, Collections.<String> emptyList());
291 
292         final WebResourceModuleDescriptor skippedModuleDescriptor = new WebResourceModuleDescriptorBuilder(testPlugin, "skipped").setCondition(
293             AlwaysTrueCondition.class).addDescriptor("skipped.js").addDependency(skippedParentModuleKey).addContext(context1).build();
294         addModuleDescriptor(skippedModuleDescriptor);
295 
296         final Set<String> skippedResources = new HashSet<String>();
297         final Iterable<WebResourceModuleDescriptor> resources = dependencyResolver.getDependenciesInContext(context1, skippedResources);
298         assertOrder(resources, parentModuleKey, moduleKey1);
299 
300         // The parent shouldn't be included
301         assertEquals(1, skippedResources.size());
302         assertEquals(skippedModuleKey, skippedResources.toArray()[0]);
303     }
304 
305     private void addModuleDescriptor(final String moduleKey)
306     {
307         addModuleDescriptor(moduleKey, Collections.<String> emptyList());
308     }
309 
310     private void addModuleDescriptor(final String moduleKey, final List<String> dependencies)
311     {
312         addModuleDescriptor(moduleKey, dependencies, Collections.<String> emptySet());
313     }
314 
315     private void addModuleDescriptor(final String moduleKey, final List<String> dependencies, final Set<String> contexts)
316     {
317         final WebResourceModuleDescriptor webResourceModuleDescriptor = TestUtils.createWebResourceModuleDescriptor(moduleKey, testPlugin,
318             Collections.<ResourceDescriptor> emptyList(), dependencies, contexts);
319 
320         addModuleDescriptor(webResourceModuleDescriptor);
321     }
322 
323     private void addModuleDescriptor(final WebResourceModuleDescriptor webResourceModuleDescriptor)
324     {
325         moduleDescriptors.add(webResourceModuleDescriptor);
326 
327         when(mockPluginAccessor.getEnabledPluginModule(webResourceModuleDescriptor.getCompleteKey())).thenReturn(
328             (ModuleDescriptor) webResourceModuleDescriptor);
329     }
330 
331     private void assertOrder(final Iterable<WebResourceModuleDescriptor> resources, final String... expectedResources)
332     {
333         assertEquals(size(resources), expectedResources.length);
334 
335         int i = 0;
336         for (final WebResourceModuleDescriptor resource : resources)
337         {
338             assertEquals(expectedResources[i], resource.getCompleteKey());
339             i++;
340         }
341     }
342 }