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

Last change on this file was 19050, checked in by taylor.smock, 15 months ago

Revert most var changes from r19048, fix most new compile warnings and checkstyle issues

Also, document why various ErrorProne checks were originally disabled and fix
generic SonarLint issues.

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