View Javadoc
1   package com.atlassian.plugin.manager;
2   
3   import com.atlassian.plugin.MockPluginAccessor;
4   import com.atlassian.plugin.Plugin;
5   import com.atlassian.plugin.PluginAccessor;
6   import com.atlassian.plugin.PluginController;
7   import com.atlassian.plugin.PluginDependencies;
8   import com.atlassian.plugin.PluginState;
9   import com.atlassian.plugin.exception.PluginExceptionInterception;
10  import com.google.common.collect.ImmutableSet;
11  import org.junit.Before;
12  import org.junit.Rule;
13  import org.junit.Test;
14  import org.junit.contrib.java.lang.system.RestoreSystemProperties;
15  import org.mockito.Mock;
16  import org.mockito.junit.MockitoJUnit;
17  import org.mockito.junit.MockitoRule;
18  
19  import java.util.Collections;
20  
21  import static org.hamcrest.MatcherAssert.assertThat;
22  import static org.hamcrest.Matchers.is;
23  import static org.hamcrest.Matchers.notNullValue;
24  import static org.mockito.Mockito.mock;
25  
26  public class TestPluginEnablerTransitiveDeps {
27  
28      @Rule
29      public final MockitoRule mockito = MockitoJUnit.rule();
30      @Rule
31      public final RestoreSystemProperties restoreSystemProperties = new RestoreSystemProperties();
32  
33      @Mock
34      private PluginController pluginController;
35      @Mock
36      private PluginExceptionInterception pluginExceptionInterception;
37      private PluginEnabler pluginEnabler;
38  
39      @Before
40      public void setUp() throws Exception {
41      }
42  
43      private PluginAccessor mockAccessor(Plugin... plugins) {
44          final MockPluginAccessor accessor = new MockPluginAccessor();
45  
46          for (Plugin p : plugins) {
47              accessor.addPlugin(p);
48          }
49          return accessor;
50      }
51  
52      private void assertPluginState(PluginState expected, PluginAccessor accessor, String... keys) {
53          for (String key : keys) {
54              Plugin p = accessor.getPlugin(key);
55              assertThat("Plugin " + key + " not found", p, is(notNullValue()));
56              assertThat(p + " not in " + expected + " state", p.getPluginState(), is(expected));
57          }
58      }
59  
60      @Test
61      public void enablingPluginAlsoEnablesRequiredPluginsTransitively() {
62          final PluginAccessor accessor = mockAccessor(
63                  new PluginWithDeps("foo", "foo2"),
64                  new PluginWithDeps("foo2", "foo3"),
65                  new PluginWithDeps("foo3"));
66  
67          pluginEnabler = new PluginEnabler(accessor, mock(PluginController.class), pluginExceptionInterception);
68  
69          // Enable a single plugin, which will recursively enable all deps
70          pluginEnabler.enableAllRecursively(Collections.singletonList(accessor.getPlugin("foo")));
71  
72          assertPluginState(PluginState.ENABLED, accessor, "foo", "foo2", "foo3");
73      }
74  
75      @Test
76      public void enablingPluginAlsoEnablesRequiredPluginsTransitivelyWithCycles() {
77          final PluginAccessor accessor = mockAccessor(
78                  new PluginWithDeps("foo", "foo2"),
79                  new PluginWithDeps("foo2", "foo3", "foo"),
80                  new PluginWithDeps("foo3", "foo2", "foo"));
81  
82          pluginEnabler = new PluginEnabler(accessor, mock(PluginController.class), pluginExceptionInterception);
83  
84          // Enable a single plugin, which will recursively enable all deps
85          pluginEnabler.enableAllRecursively(Collections.singletonList(accessor.getPlugin("foo")));
86  
87          assertPluginState(PluginState.ENABLED, accessor, "foo", "foo2", "foo3");
88      }
89  
90      @Test
91      public void enablingPluginDoesNotEnableTransitivelyOptionalDepending() {
92          final PluginAccessor accessor = mockAccessor(
93                  new PluginWithDeps("foo", "mandatory1"),
94                  new PluginWithDeps("mandatory1", new PluginDependencies(
95                          ImmutableSet.of("mandatory2"),
96                          ImmutableSet.of("optional"),
97                          ImmutableSet.of("dynamic"))),
98                  new PluginWithDeps("mandatory2"),
99                  new PluginWithDeps("optional", "mandatory_for_optional"),
100                 new PluginWithDeps("dynamic", "mandatory_for_dynamic"),
101                 new PluginWithDeps("mandatory_for_optional"),
102                 new PluginWithDeps("mandatory_for_dynamic"));
103 
104         pluginEnabler = new PluginEnabler(accessor, mock(PluginController.class), pluginExceptionInterception);
105 
106         // Enable a single plugin, which will recursively enable all deps
107         pluginEnabler.enableAllRecursively(Collections.singletonList(accessor.getPlugin("foo")));
108 
109         assertPluginState(PluginState.ENABLED, accessor, "foo", "mandatory1", "mandatory2");
110         assertPluginState(PluginState.DISABLED, accessor, "optional", "mandatory_for_optional");
111         assertPluginState(PluginState.DISABLED, accessor, "dynamic", "mandatory_for_dynamic");
112     }
113 }