1 package com.atlassian.plugin.util;
2
3 import java.util.HashSet;
4 import java.util.List;
5
6 import com.atlassian.fugue.Option;
7 import com.atlassian.plugin.Application;
8 import com.atlassian.plugin.InstallationMode;
9 import com.atlassian.plugin.ModuleDescriptor;
10 import com.atlassian.plugin.Plugin;
11 import com.atlassian.plugin.descriptors.MockUnusedModuleDescriptor;
12 import com.atlassian.plugin.descriptors.RequiresRestart;
13
14 import com.atlassian.plugin.impl.AbstractDelegatingPlugin;
15 import com.google.common.base.Function;
16 import com.google.common.collect.Lists;
17
18 import org.dom4j.Element;
19 import org.junit.Rule;
20 import org.junit.Test;
21 import org.junit.contrib.java.lang.system.RestoreSystemProperties;
22 import org.junit.runner.RunWith;
23 import org.mockito.runners.MockitoJUnitRunner;
24
25 import static com.atlassian.plugin.util.PluginUtils.ATLASSIAN_DEV_MODE;
26 import static com.google.common.collect.Lists.newArrayList;
27 import static com.google.common.collect.Sets.newHashSet;
28 import static org.hamcrest.Matchers.nullValue;
29 import static org.hamcrest.core.Is.is;
30 import static org.junit.Assert.assertFalse;
31 import static org.junit.Assert.assertThat;
32 import static org.junit.Assert.assertTrue;
33 import static org.mockito.Mockito.mock;
34 import static org.mockito.Mockito.when;
35
36 @RunWith(MockitoJUnitRunner.class)
37 public final class TestPluginUtils
38 {
39 @Rule
40 public RestoreSystemProperties restoreSystemProperties = new RestoreSystemProperties(ATLASSIAN_DEV_MODE);
41
42 @Test
43 public void testPluginWithNoModuleDoesNotRequireRestartInDevMode()
44 {
45 System.setProperty(ATLASSIAN_DEV_MODE, "true");
46 final Plugin plugin = mockPluginWithModuleDescriptors();
47
48 assertFalse(PluginUtils.doesPluginRequireRestart(plugin));
49 }
50
51 @Test
52 public void testPluginWithNoModuleDoesNotRequireRestartNoDevMode()
53 {
54 final Plugin plugin = mockPluginWithModuleDescriptors();
55
56 assertFalse(PluginUtils.doesPluginRequireRestart(plugin));
57 }
58
59 @Test
60 public void testPluginWithModuleRequiringRestartDoesNotRequireRestartInDevMode()
61 {
62 System.setProperty(ATLASSIAN_DEV_MODE, "true");
63 final Plugin plugin = mockPluginWithModuleDescriptors(new DynamicModuleDescriptor(), new RequiresRestartModuleDescriptor());
64
65 assertFalse(PluginUtils.doesPluginRequireRestart(plugin));
66 }
67
68 @Test
69 public void testPluginWithModuleRequiringRestartDoesRequireRestartNoDevMode()
70 {
71 final Plugin plugin = mockPluginWithModuleDescriptors(new DynamicModuleDescriptor(), new RequiresRestartModuleDescriptor());
72
73 assertTrue(PluginUtils.doesPluginRequireRestart(plugin));
74 }
75
76 @Test
77 public void testPluginWithNoModuleRequiringRestartDoesNotRequireRestartNoDevMode()
78 {
79 final Plugin plugin = mockPluginWithModuleDescriptors(new DynamicModuleDescriptor());
80
81 assertFalse(PluginUtils.doesPluginRequireRestart(plugin));
82 }
83
84 private Plugin mockPluginWithModuleDescriptors(final ModuleDescriptor<?>... descriptors)
85 {
86 final Plugin plugin = mock(Plugin.class);
87 when(plugin.getModuleDescriptors()).thenReturn(Lists.newArrayList(descriptors));
88 return plugin;
89 }
90
91 @Test
92 public void testModuleElementAppliesWithNoInformation()
93 {
94 assertTrue(PluginUtils.doesModuleElementApplyToApplication(newMockModuleElement(null), applications(), InstallationMode.REMOTE));
95 }
96
97 @Test
98 public void testModuleElementAppliesWithApplicationAttributeJira()
99 {
100 assertTrue(PluginUtils.doesModuleElementApplyToApplication(newMockModuleElement("jira"), applications(), InstallationMode.REMOTE));
101 }
102
103 @Test
104 public void testModuleElementAppliesWithApplicationAttributeBamboo()
105 {
106 assertFalse(PluginUtils.doesModuleElementApplyToApplication(newMockModuleElement("bamboo"), applications(), InstallationMode.REMOTE));
107 }
108
109 @Test
110 public void testModuleElementAppliesWithApplicationAttributeJiraBamboo()
111 {
112 assertTrue(PluginUtils.doesModuleElementApplyToApplication(newMockModuleElement("jira,bamboo"), applications(), InstallationMode.REMOTE));
113 }
114
115 @Test
116 public void testModuleElementAppliesWithApplicationAttributeBambooConfluence()
117 {
118 assertTrue(PluginUtils.doesModuleElementApplyToApplication(newMockModuleElement("bamboo,confluence"), applications(), InstallationMode.REMOTE));
119 }
120
121 @Test
122 public void testModuleElementAppliesWithApplicationAttributeBambooCrowd()
123 {
124 assertFalse(PluginUtils.doesModuleElementApplyToApplication(newMockModuleElement("bamboo,crowd"), applications(), InstallationMode.REMOTE));
125 }
126
127 @Test
128 public void testModuleElementAppliesWithApplicationAttributeBambooCrowdAndBlank()
129 {
130 assertFalse(PluginUtils.doesModuleElementApplyToApplication(newMockModuleElement("bamboo,,crowd, ,"), applications(), InstallationMode.REMOTE));
131 }
132
133 @Test
134 public void testModuleElementAppliesWithApplicationAttributeBambooConfluenceAndBlank()
135 {
136 assertTrue(PluginUtils.doesModuleElementApplyToApplication(newMockModuleElement("bamboo,, , confluence, "), applications(), InstallationMode.REMOTE));
137 }
138
139 @Test
140 public void testModuleElementAppliesWithApplicationAttributeBlank()
141 {
142 assertTrue(PluginUtils.doesModuleElementApplyToApplication(newMockModuleElement(" "), applications(), InstallationMode.REMOTE));
143 assertTrue(PluginUtils.doesModuleElementApplyToApplication(newMockModuleElement(" ,"), applications(), InstallationMode.REMOTE));
144 assertTrue(PluginUtils.doesModuleElementApplyToApplication(newMockModuleElement(" ,, "), applications(), InstallationMode.REMOTE));
145 assertTrue(PluginUtils.doesModuleElementApplyToApplication(newMockModuleElement(" ,, ,,,"), applications(), InstallationMode.REMOTE));
146 }
147
148 @Test
149 public void testModuleElementAppliesWithRestrictElementJira()
150 {
151 assertTrue(PluginUtils.doesModuleElementApplyToApplication(newMockModuleElement(null, Lists.newArrayList(newMockRestrictElement("jira", Option.<InstallationMode>none()))), applications(), InstallationMode.REMOTE));
152 }
153
154 @Test
155 public void testModuleElementAppliesWithRestrictElementBamboo()
156 {
157 assertFalse(PluginUtils.doesModuleElementApplyToApplication(newMockModuleElement(null, Lists.newArrayList(newMockRestrictElement("bamboo", Option.<InstallationMode>none()))), applications(), InstallationMode.REMOTE));
158 }
159
160 @Test
161 public void testModuleElementAppliesWithRestrictElementJiraBamboo()
162 {
163 assertTrue(PluginUtils.doesModuleElementApplyToApplication(newMockModuleElement(null, Lists.newArrayList(newMockRestrictElement("jira", Option.<InstallationMode>none()), newMockRestrictElement("bamboo", Option.<InstallationMode>none()))), applications(), InstallationMode.REMOTE));
164 }
165
166 @Test
167 public void testModuleElementAppliesWithRestrictElementJiraConfluence()
168 {
169 assertTrue(PluginUtils.doesModuleElementApplyToApplication(newMockModuleElement(null, Lists.newArrayList(newMockRestrictElement("jira", Option.<InstallationMode>none()), newMockRestrictElement("confluence", Option.<InstallationMode>none()))), applications(), InstallationMode.REMOTE));
170 }
171
172 @Test
173 public void testModuleElementAppliesWithRestrictElementJiraAndVersionInRange()
174 {
175 assertTrue(PluginUtils.doesModuleElementApplyToApplication(
176 newMockModuleElement(null, Lists.newArrayList(newMockRestrictElement("jira", Option.<InstallationMode>none(), "[4.0,)"))), applications(), InstallationMode.REMOTE));
177 }
178
179 @Test
180 public void testModuleElementAppliesWithRestrictElementJiraAndVersionOutOfRange()
181 {
182 assertFalse(PluginUtils.doesModuleElementApplyToApplication(
183 newMockModuleElement(null, Lists.newArrayList(newMockRestrictElement("jira", Option.<InstallationMode>none(), "(,5.0)"))), applications(), InstallationMode.REMOTE));
184 }
185
186 @Test
187 public void testModuleElementAppliesWithRestrictElementJiraAndVersionsInRange()
188 {
189 assertTrue(PluginUtils.doesModuleElementApplyToApplication(
190 newMockModuleElement(null, Lists.newArrayList(newMockRestrictElement("jira", Option.<InstallationMode>none(), "(,4.0)", "5.0"))), applications(), InstallationMode.REMOTE));
191 }
192
193 @Test
194 public void testModuleElementAppliesWithRestrictElementJiraAndVersionsOutOfRange()
195 {
196 assertFalse(PluginUtils.doesModuleElementApplyToApplication(
197 newMockModuleElement(null, Lists.newArrayList(newMockRestrictElement("jira", Option.<InstallationMode>none(), "(,4.0]", "(5.0,)"))), applications(), InstallationMode.REMOTE));
198 }
199
200 @Test
201 public void testModuleElementAppliesWithRestrictElementMatchingInstallMode()
202 {
203 assertTrue(PluginUtils.doesModuleElementApplyToApplication(
204 newMockModuleElement(null, Lists.newArrayList(newMockRestrictElement("jira", Option.some(InstallationMode.LOCAL)))), applications(), InstallationMode.LOCAL));
205 }
206
207 @Test
208 public void testModuleElementAppliesWithRestrictElementNonMatchingInstallMode()
209 {
210 assertFalse(PluginUtils.doesModuleElementApplyToApplication(
211 newMockModuleElement(null, Lists.newArrayList(newMockRestrictElement("jira", Option.some(InstallationMode.REMOTE)))), applications(), InstallationMode.LOCAL));
212 }
213
214 @Test
215 public void testModuleElementAppliesWithRestrictElementInstallModeUnspecified()
216 {
217 assertTrue(PluginUtils.doesModuleElementApplyToApplication(
218 newMockModuleElement(null, Lists.newArrayList(newMockRestrictElement("jira", Option.<InstallationMode>none()))), applications(), InstallationMode.LOCAL));
219 }
220
221 @Test
222 public void testModuleElementAppliesWithRestrictElementInstallModeSpecifiedOnDifferentAppVersion()
223 {
224 final List<Element> restricts = Lists.newArrayList(
225 newMockRestrictElement("jira", Option.some(InstallationMode.LOCAL), "5.0"),
226 newMockRestrictElement("jira", Option.some(InstallationMode.REMOTE), "6.0"));
227
228 assertTrue(PluginUtils.doesModuleElementApplyToApplication(newMockModuleElement(null, restricts), applications(), InstallationMode.LOCAL));
229 assertFalse(PluginUtils.doesModuleElementApplyToApplication(newMockModuleElement(null, restricts), applications(), InstallationMode.REMOTE));
230 }
231
232 @Test
233 public void testUnwrapPluginNull()
234 {
235 assertThat(PluginUtils.unwrapPlugin(null), nullValue());
236 }
237
238 @Test
239 public void testUnwrapPluginNotWrapped()
240 {
241 final Plugin plugin = mock(Plugin.class);
242
243 assertThat(PluginUtils.unwrapPlugin(plugin), is(plugin));
244 }
245
246 @Test
247 public void testUnwrapPlugin()
248 {
249 final Plugin kid = mock(Plugin.class);
250 final AbstractDelegatingPlugin dad = mock(AbstractDelegatingPlugin.class);
251 when(dad.getDelegate()).thenReturn(kid);
252 final AbstractDelegatingPlugin grandpa = mock(AbstractDelegatingPlugin.class);
253 when(grandpa.getDelegate()).thenReturn(dad);
254
255 assertThat(PluginUtils.unwrapPlugin(grandpa), is(kid));
256 }
257
258 private Element newMockRestrictElement(final String app, final Option<InstallationMode> modeOption, final String... versions)
259 {
260 final Element restrict = mock(Element.class);
261 when(restrict.attributeValue("application")).thenReturn(app);
262 if (modeOption.isDefined())
263 {
264 when(restrict.attributeValue("mode")).thenReturn(modeOption.get().toString().toLowerCase());
265 }
266 if (versions != null && versions.length == 1)
267 {
268 when(restrict.attributeValue("version")).thenReturn(versions[0]);
269 }
270 else if (versions != null)
271 {
272 when(restrict.elements("version")).thenReturn(Lists.transform(newArrayList(versions), new Function<String, Element>()
273 {
274 @Override
275 public Element apply(final String version)
276 {
277 final Element versionE = mock(Element.class);
278 when(versionE.getText()).thenReturn(version);
279 return versionE;
280 }
281 }));
282 }
283
284 return restrict;
285 }
286
287 private HashSet<Application> applications()
288 {
289 return newHashSet(jira50(), confluence40());
290 }
291
292 private Application confluence40()
293 {
294 return newApplication("confluence", "4.0");
295 }
296
297 private Application jira50()
298 {
299 return newApplication("jira", "5.0");
300 }
301
302 private Element newMockModuleElement(final String app)
303 {
304 return newMockModuleElement(app, Lists.<Element>newArrayList());
305 }
306
307 private Element newMockModuleElement(final String app, final List<Element> restricts)
308 {
309 final Element element = mock(Element.class);
310 when(element.attributeValue("application")).thenReturn(app);
311 when(element.elements("restrict")).thenReturn(restricts);
312 return element;
313 }
314
315 private Application newApplication(final String name, final String version)
316 {
317 final Application app = mock(Application.class);
318 when(app.getKey()).thenReturn(name);
319 when(app.getVersion()).thenReturn(version);
320 return app;
321 }
322
323 static class DynamicModuleDescriptor extends MockUnusedModuleDescriptor
324 {
325 }
326
327 @RequiresRestart
328 static class RequiresRestartModuleDescriptor extends MockUnusedModuleDescriptor
329 {
330 }
331 }