source: josm/trunk/test/unit/org/openstreetmap/josm/plugins/PluginHandlerJOSMTooOldTest.java@ 18870

Last change on this file since 18870 was 18870, checked in by taylor.smock, 8 months ago

See #16567: Update to JUnit 5

This converts most tests to use @Annotations. There are also some performance
improvements as it relates to tests.

  • Property svn:eol-style set to native
File size: 16.0 KB
Line 
1// License: GPL. For details, see LICENSE file.
2package org.openstreetmap.josm.plugins;
3
4import static com.github.tomakehurst.wiremock.core.WireMockConfiguration.options;
5import static org.junit.jupiter.api.Assertions.assertEquals;
6import static org.junit.jupiter.api.Assertions.assertFalse;
7import static org.junit.jupiter.api.Assertions.assertNotEquals;
8
9import java.io.File;
10import java.io.IOException;
11import java.nio.file.Files;
12import java.text.DecimalFormatSymbols;
13import java.util.ArrayList;
14import java.util.Arrays;
15import java.util.Collections;
16import java.util.Comparator;
17import java.util.List;
18import java.util.stream.Collectors;
19
20import org.junit.jupiter.api.BeforeEach;
21import org.junit.jupiter.api.Test;
22import org.junit.jupiter.api.extension.RegisterExtension;
23import org.openstreetmap.josm.TestUtils;
24import org.openstreetmap.josm.data.Preferences;
25import org.openstreetmap.josm.gui.MainApplication;
26import org.openstreetmap.josm.spi.preferences.Config;
27import org.openstreetmap.josm.testutils.PluginServer;
28import org.openstreetmap.josm.testutils.annotations.AssumeRevision;
29import org.openstreetmap.josm.testutils.annotations.FullPreferences;
30import org.openstreetmap.josm.testutils.annotations.Main;
31import org.openstreetmap.josm.testutils.mockers.ExtendedDialogMocker;
32import org.openstreetmap.josm.testutils.mockers.HelpAwareOptionPaneMocker;
33
34import com.github.tomakehurst.wiremock.client.WireMock;
35import com.github.tomakehurst.wiremock.junit5.WireMockExtension;
36import com.github.tomakehurst.wiremock.junit5.WireMockRuntimeInfo;
37
38/**
39 * Test parts of {@link PluginHandler} class when the reported JOSM version is too old for the plugin.
40 */
41@AssumeRevision("Revision: 6000\n")
42@FullPreferences
43@Main
44class PluginHandlerJOSMTooOldTest {
45 /**
46 * Plugin server mock.
47 */
48 @RegisterExtension
49 static WireMockExtension pluginServerRule = WireMockExtension.newInstance().options(
50 options().dynamicPort().usingFilesUnderDirectory(TestUtils.getTestDataRoot())
51 ).build();
52
53 /**
54 * Setup test.
55 */
56 @BeforeEach
57 public void setUp() {
58 Config.getPref().putInt("pluginmanager.version", 999);
59 Config.getPref().put("pluginmanager.lastupdate", "999");
60 Config.getPref().putList("pluginmanager.sites",
61 Collections.singletonList(pluginServerRule.url("/plugins"))
62 );
63
64 this.referenceDummyJarOld = new File(TestUtils.getTestDataRoot(), "__files/plugin/dummy_plugin.v31701.jar");
65 this.referenceDummyJarNew = new File(TestUtils.getTestDataRoot(), "__files/plugin/dummy_plugin.v31772.jar");
66 this.referenceBazJarOld = new File(TestUtils.getTestDataRoot(), "__files/plugin/baz_plugin.v6.jar");
67 this.referenceBazJarNew = new File(TestUtils.getTestDataRoot(), "__files/plugin/baz_plugin.v7.jar");
68 this.referenceQuxJarOld = new File(TestUtils.getTestDataRoot(), "__files/" + referencePathQuxJarOld);
69 this.referenceQuxJarNewer = new File(TestUtils.getTestDataRoot(), "__files/" + referencePathQuxJarNewer);
70 this.pluginDir = Preferences.main().getPluginsDirectory();
71 this.targetDummyJar = new File(this.pluginDir, "dummy_plugin.jar");
72 this.targetDummyJarNew = new File(this.pluginDir, "dummy_plugin.jar.new");
73 this.targetBazJar = new File(this.pluginDir, "baz_plugin.jar");
74 this.targetBazJarNew = new File(this.pluginDir, "baz_plugin.jar.new");
75 this.targetQuxJar = new File(this.pluginDir, "qux_plugin.jar");
76 this.targetQuxJarNew = new File(this.pluginDir, "qux_plugin.jar.new");
77 this.pluginDir.mkdirs();
78 }
79
80 private static final String referencePathQuxJarOld = "plugin/qux_plugin.v345.jar";
81 private static final String referencePathQuxJarNewer = "plugin/qux_plugin.v432.jar";
82
83 private File pluginDir;
84 private File referenceDummyJarOld;
85 private File referenceDummyJarNew;
86 private File referenceBazJarOld;
87 private File referenceBazJarNew;
88 private File referenceQuxJarOld;
89 private File referenceQuxJarNewer;
90 private File targetDummyJar;
91 private File targetDummyJarNew;
92 private File targetBazJar;
93 private File targetBazJarNew;
94 private File targetQuxJar;
95 private File targetQuxJarNew;
96
97 private final String bazPluginVersionReqString = u202f("JOSM version 8\u202F001 required for plugin baz_plugin.");
98 private final String dummyPluginVersionReqString = u202f("JOSM version 7\u202F001 required for plugin dummy_plugin.");
99 private final String dummyPluginFailedString = "<html>Updating the following plugin has failed:<ul><li>dummy_plugin</li></ul>"
100 + "Please open the Preference Dialog after JOSM has started and try to update it manually.</html>";
101
102 private static String u202f(String s) {
103 return s.replace('\u202F', DecimalFormatSymbols.getInstance().getGroupingSeparator());
104 }
105
106 /**
107 * test update of plugins when those plugins turn out to require a higher JOSM version, but the
108 * user chooses to update them anyway.
109 * @throws IOException never
110 */
111 @Test
112 void testUpdatePluginsDownloadBoth(WireMockRuntimeInfo wireMockRuntimeInfo) throws IOException {
113 TestUtils.assumeWorkingJMockit();
114 final PluginServer pluginServer = new PluginServer(
115 new PluginServer.RemotePlugin(this.referenceDummyJarNew),
116 new PluginServer.RemotePlugin(this.referenceBazJarNew)
117 );
118 pluginServer.applyToWireMockServer(wireMockRuntimeInfo);
119 Config.getPref().putList("plugins", Arrays.asList("dummy_plugin", "baz_plugin"));
120
121 final ExtendedDialogMocker edMocker = new ExtendedDialogMocker();
122 edMocker.getMockResultMap().put(this.bazPluginVersionReqString, "Download Plugin");
123 edMocker.getMockResultMap().put(this.dummyPluginVersionReqString, "Download Plugin");
124
125 Files.copy(this.referenceDummyJarOld.toPath(), this.targetDummyJar.toPath());
126 Files.copy(this.referenceBazJarOld.toPath(), this.targetBazJar.toPath());
127
128 final List<PluginInformation> updatedPlugins = PluginHandler.updatePlugins(
129 MainApplication.getMainFrame(),
130 null,
131 null,
132 false
133 ).stream().sorted(Comparator.comparing(a -> a.name)).collect(Collectors.toList());
134
135 assertEquals(
136 Arrays.asList(
137 this.dummyPluginVersionReqString,
138 this.bazPluginVersionReqString
139 ),
140 edMocker.getInvocationLog().stream().map(
141 invocationEntry -> invocationEntry[1]
142 ).sorted().collect(Collectors.toList())
143 );
144
145 assertEquals(2, updatedPlugins.size());
146
147 assertEquals(updatedPlugins.get(0).name, "baz_plugin");
148 assertEquals("7", updatedPlugins.get(0).localversion);
149
150 assertEquals(updatedPlugins.get(1).name, "dummy_plugin");
151 assertEquals("31772", updatedPlugins.get(1).localversion);
152
153 assertFalse(targetDummyJarNew.exists());
154 assertFalse(targetBazJarNew.exists());
155
156 TestUtils.assertFileContentsEqual(this.referenceDummyJarNew, this.targetDummyJar);
157 TestUtils.assertFileContentsEqual(this.referenceBazJarNew, this.targetBazJar);
158
159 pluginServerRule.verify(1, WireMock.getRequestedFor(WireMock.urlEqualTo("/plugins")));
160 pluginServerRule.verify(1, WireMock.getRequestedFor(WireMock.urlEqualTo("/plugin/dummy_plugin.v31772.jar")));
161 pluginServerRule.verify(1, WireMock.getRequestedFor(WireMock.urlEqualTo("/plugin/baz_plugin.v7.jar")));
162
163 assertEquals(Config.getPref().getInt("pluginmanager.version", 111), 6000);
164 // not mocking the time so just check it's not its original value
165 assertNotEquals(Config.getPref().get("pluginmanager.lastupdate", "999"), "999");
166 }
167
168 /**
169 * test update of plugins when those plugins turn out to require a higher JOSM version, but the
170 * user chooses to update one and skip the other.
171 * @throws IOException never
172 */
173 @Test
174 void testUpdatePluginsSkipOne(WireMockRuntimeInfo wireMockRuntimeInfo) throws IOException {
175 TestUtils.assumeWorkingJMockit();
176 final PluginServer pluginServer = new PluginServer(
177 new PluginServer.RemotePlugin(this.referenceDummyJarNew),
178 new PluginServer.RemotePlugin(this.referenceBazJarNew)
179 );
180 pluginServer.applyToWireMockServer(wireMockRuntimeInfo);
181 Config.getPref().putList("plugins", Arrays.asList("dummy_plugin", "baz_plugin"));
182
183 final ExtendedDialogMocker edMocker = new ExtendedDialogMocker();
184 edMocker.getMockResultMap().put(this.bazPluginVersionReqString, "Download Plugin");
185 edMocker.getMockResultMap().put(this.dummyPluginVersionReqString, "Skip Download");
186 final HelpAwareOptionPaneMocker haMocker = new HelpAwareOptionPaneMocker();
187 haMocker.getMockResultMap().put(this.dummyPluginFailedString, "OK");
188
189 Files.copy(this.referenceDummyJarOld.toPath(), this.targetDummyJar.toPath());
190 Files.copy(this.referenceBazJarOld.toPath(), this.targetBazJar.toPath());
191
192 final List<PluginInformation> updatedPlugins = PluginHandler.updatePlugins(
193 MainApplication.getMainFrame(),
194 null,
195 null,
196 false
197 ).stream().sorted(Comparator.comparing(a -> a.name)).collect(Collectors.toList());
198
199 assertEquals(
200 Arrays.asList(
201 this.dummyPluginVersionReqString,
202 this.bazPluginVersionReqString
203 ),
204 edMocker.getInvocationLog().stream().map(
205 invocationEntry -> invocationEntry[1]
206 ).sorted().collect(Collectors.toList())
207 );
208
209 assertEquals(Collections.singletonList(this.dummyPluginFailedString),
210 haMocker.getInvocationLog().stream().map(
211 invocationEntry -> invocationEntry[1]
212 ).sorted().collect(Collectors.toList())
213 );
214
215 assertEquals(2, updatedPlugins.size());
216
217 assertEquals(updatedPlugins.get(0).name, "baz_plugin");
218 assertEquals("7", updatedPlugins.get(0).localversion);
219
220 assertEquals(updatedPlugins.get(1).name, "dummy_plugin");
221 assertEquals("31701", updatedPlugins.get(1).localversion);
222
223 assertFalse(targetDummyJarNew.exists());
224 assertFalse(targetBazJarNew.exists());
225
226 TestUtils.assertFileContentsEqual(this.referenceDummyJarOld, this.targetDummyJar);
227 TestUtils.assertFileContentsEqual(this.referenceBazJarNew, this.targetBazJar);
228
229 pluginServerRule.verify(1, WireMock.getRequestedFor(WireMock.urlEqualTo("/plugins")));
230 pluginServerRule.verify(0, WireMock.getRequestedFor(WireMock.urlEqualTo("/plugin/dummy_plugin.v31772.jar")));
231 pluginServerRule.verify(1, WireMock.getRequestedFor(WireMock.urlEqualTo("/plugin/baz_plugin.v7.jar")));
232
233 // shouldn't have been updated
234 assertEquals(Config.getPref().getInt("pluginmanager.version", 111), 999);
235 assertEquals(Config.getPref().get("pluginmanager.lastupdate", "999"), "999");
236 }
237
238 /**
239 * When the plugin list suggests that the jar file at the provided URL *doesn't* require a newer JOSM
240 * but in fact the plugin served *does*, it is installed anyway.
241 *
242 * This is probably NOT desirable and should be fixed, however this test documents the behaviour.
243 * @throws IOException never
244 */
245 @Test
246 void testUpdatePluginsUnexpectedlyJOSMTooOld(WireMockRuntimeInfo wireMockRuntimeInfo) throws IOException {
247 TestUtils.assumeWorkingJMockit();
248 final PluginServer pluginServer = new PluginServer(
249 new PluginServer.RemotePlugin(this.referenceDummyJarNew),
250 new PluginServer.RemotePlugin(this.referenceBazJarNew, Collections.singletonMap("Plugin-Mainversion", "5500"))
251 );
252 pluginServer.applyToWireMockServer(wireMockRuntimeInfo);
253 Config.getPref().putList("plugins", Collections.singletonList("baz_plugin"));
254
255 // setting up blank ExtendedDialogMocker which would raise an exception if any attempt to show
256 // and ExtendedDialog were made
257 new ExtendedDialogMocker();
258
259 Files.copy(this.referenceBazJarOld.toPath(), this.targetBazJar.toPath());
260
261 final List<PluginInformation> updatedPlugins = new ArrayList<>(PluginHandler.updatePlugins(
262 MainApplication.getMainFrame(),
263 null,
264 null,
265 false
266 ));
267
268 // questionably correct
269 assertEquals(1, updatedPlugins.size());
270
271 // questionably correct
272 assertEquals(updatedPlugins.get(0).name, "baz_plugin");
273 assertEquals("7", updatedPlugins.get(0).localversion);
274
275 assertFalse(targetBazJarNew.exists());
276
277 // questionably correct
278 TestUtils.assertFileContentsEqual(this.referenceBazJarNew, this.targetBazJar);
279
280 pluginServerRule.verify(1, WireMock.getRequestedFor(WireMock.urlEqualTo("/plugins")));
281 // questionably correct
282 pluginServerRule.verify(1, WireMock.getRequestedFor(WireMock.urlEqualTo("/plugin/baz_plugin.v7.jar")));
283
284 // should have been updated
285 assertEquals(Config.getPref().getInt("pluginmanager.version", 111), 6000);
286 assertNotEquals(Config.getPref().get("pluginmanager.lastupdate", "999"), "999");
287 }
288
289 /**
290 * When a plugin advertises several versions for compatibility with older JOSMs, but even the
291 * oldest of those is newer than our JOSM version, the user is prompted to upgrade to the newest
292 * version anyway.
293 *
294 * While this behaviour is not incorrect, it's probably less helpful than it could be - the
295 * version that's most likely to work best in this case will be the "oldest" still-available
296 * version, however this test documents the behaviour.
297 * @throws IOException never
298 */
299 @Test
300 @AssumeRevision("Revision: 7200\n")
301 void testUpdatePluginsMultiVersionInsufficient(WireMockRuntimeInfo wireMockRuntimeInfo) throws IOException {
302 TestUtils.assumeWorkingJMockit();
303
304 final PluginServer pluginServer = new PluginServer(
305 new PluginServer.RemotePlugin(this.referenceBazJarOld),
306 new PluginServer.RemotePlugin(this.referenceQuxJarNewer, Collections.singletonMap(
307 "7499_Plugin-Url", "346;" + pluginServerRule.url("/dont/bother.jar")
308 ))
309 );
310 pluginServer.applyToWireMockServer(wireMockRuntimeInfo);
311 Config.getPref().putList("plugins", Arrays.asList("qux_plugin", "baz_plugin"));
312
313 new ExtendedDialogMocker(Collections.singletonMap(u202f("JOSM version 7\u202F500 required for plugin qux_plugin."), "Download Plugin"));
314
315 Files.copy(this.referenceQuxJarOld.toPath(), this.targetQuxJar.toPath());
316 Files.copy(this.referenceBazJarOld.toPath(), this.targetBazJar.toPath());
317
318 final List<PluginInformation> updatedPlugins = PluginHandler.updatePlugins(
319 MainApplication.getMainFrame(),
320 null,
321 null,
322 false
323 ).stream().sorted(Comparator.comparing(a -> a.name)).collect(Collectors.toList());
324
325 assertEquals(2, updatedPlugins.size());
326
327 assertEquals("baz_plugin", updatedPlugins.get(0).name);
328 assertEquals("6", updatedPlugins.get(0).localversion);
329
330 assertEquals("qux_plugin", updatedPlugins.get(1).name);
331 // questionably correct
332 assertEquals("432", updatedPlugins.get(1).localversion);
333
334 assertFalse(targetQuxJarNew.exists());
335
336 TestUtils.assertFileContentsEqual(this.referenceBazJarOld, this.targetBazJar);
337 // questionably correct
338 TestUtils.assertFileContentsEqual(this.referenceQuxJarNewer, this.targetQuxJar);
339
340 assertEquals(2, pluginServerRule.getAllServeEvents().size());
341 pluginServerRule.verify(1, WireMock.getRequestedFor(WireMock.urlEqualTo("/plugins")));
342 // questionably correct
343 pluginServerRule.verify(1, WireMock.getRequestedFor(WireMock.urlEqualTo("/plugin/qux_plugin.v432.jar")));
344
345 assertEquals(7200, Config.getPref().getInt("pluginmanager.version", 111));
346 // not mocking the time so just check it's not its original value
347 assertNotEquals("999", Config.getPref().get("pluginmanager.lastupdate", "999"));
348 }
349}
Note: See TracBrowser for help on using the repository browser.