From 71c494aeb66f46c99e08a980650440d63de92e0c Mon Sep 17 00:00:00 2001 From: Taylor Smock Date: Tue, 22 Dec 2020 17:19:07 -0700 Subject: [PATCH] Add initial code to check if this version of the plugin should not upload to OSM Signed-off-by: Taylor Smock --- .../mapwithai/tools/BlacklistUtils.java | 68 ++++++++++ .../mapwithai/tools/BlacklistUtilsTest.java | 125 ++++++++++++++++++ 2 files changed, 193 insertions(+) create mode 100644 src/main/java/org/openstreetmap/josm/plugins/mapwithai/tools/BlacklistUtils.java create mode 100644 test/unit/org/openstreetmap/josm/plugins/mapwithai/tools/BlacklistUtilsTest.java diff --git a/src/main/java/org/openstreetmap/josm/plugins/mapwithai/tools/BlacklistUtils.java b/src/main/java/org/openstreetmap/josm/plugins/mapwithai/tools/BlacklistUtils.java new file mode 100644 index 0000000..4e6bef6 --- /dev/null +++ b/src/main/java/org/openstreetmap/josm/plugins/mapwithai/tools/BlacklistUtils.java @@ -0,0 +1,68 @@ +// License: GPL. For details, see LICENSE file. +package org.openstreetmap.josm.plugins.mapwithai.tools; + +import java.io.BufferedReader; +import java.io.IOException; + +import javax.json.Json; +import javax.json.JsonArray; +import javax.json.JsonException; +import javax.json.JsonObject; +import javax.json.JsonReader; +import javax.json.JsonString; +import javax.json.JsonStructure; +import javax.json.JsonValue; + +import org.openstreetmap.josm.io.CachedFile; +import org.openstreetmap.josm.plugins.mapwithai.MapWithAIPlugin; +import org.openstreetmap.josm.tools.Logging; + +/** + * Check if this version has been blacklisted (i.e., bad data is uploaded) + * + * @author Taylor Smock + * + */ +public class BlacklistUtils { + static final String DEFAULT_BLACKLIST_URL = "https://gokaart.gitlab.io/JOSM_MapWithAI/json/blacklisted_versions.json"; + private static String blacklistUrl = DEFAULT_BLACKLIST_URL; + + private BlacklistUtils() { + // Don't instantiate + } + + /** + * Check if this version is known to make bad data + * + * @return {@code true} if no data should be uploaded or added. Defaults to + * {@code true}. + */ + public static boolean isBlacklisted() { + String version = MapWithAIPlugin.getVersionInfo(); + try (CachedFile blacklist = new CachedFile(blacklistUrl); + BufferedReader bufferedReader = blacklist.getContentReader(); + JsonReader reader = Json.createReader(bufferedReader)) { + JsonStructure structure = reader.read(); + if (structure.getValueType() == JsonValue.ValueType.ARRAY) { + JsonArray array = (JsonArray) structure; + return array.stream().filter(v -> v.getValueType() == JsonValue.ValueType.STRING) + .map(v -> ((JsonString) v).getString()).anyMatch(version::equals); + } else if (structure.getValueType() == JsonValue.ValueType.OBJECT) { + JsonObject object = (JsonObject) structure; + return object.keySet().contains(version); + } + } catch (IOException | JsonException e) { + Logging.error(e); + } + return true; + } + + /** + * Set a new blacklist URL. Should only be used for testing. + * + * @param url The url to check. + */ + static void setBlacklistUrl(String url) { + blacklistUrl = url; + } +} diff --git a/test/unit/org/openstreetmap/josm/plugins/mapwithai/tools/BlacklistUtilsTest.java b/test/unit/org/openstreetmap/josm/plugins/mapwithai/tools/BlacklistUtilsTest.java new file mode 100644 index 0000000..9aa28c2 --- /dev/null +++ b/test/unit/org/openstreetmap/josm/plugins/mapwithai/tools/BlacklistUtilsTest.java @@ -0,0 +1,125 @@ +// License: GPL. For details, see LICENSE file. +package org.openstreetmap.josm.plugins.mapwithai.tools; + +import static com.github.tomakehurst.wiremock.client.WireMock.aResponse; +import static com.github.tomakehurst.wiremock.client.WireMock.get; +import static com.github.tomakehurst.wiremock.client.WireMock.noContent; +import static com.github.tomakehurst.wiremock.client.WireMock.notFound; +import static com.github.tomakehurst.wiremock.client.WireMock.urlMatching; +import static com.github.tomakehurst.wiremock.core.WireMockConfiguration.options; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; +import org.openstreetmap.josm.plugins.mapwithai.MapWithAIPlugin; +import org.openstreetmap.josm.testutils.JOSMTestRules; + +import com.github.tomakehurst.wiremock.WireMockServer; + +import mockit.Mock; +import mockit.MockUp; + +/** + * Tests for {@link BlacklistUtils} + * + * @author Taylor Smock + * + */ +class BlacklistUtilsTest { + + private static class MapWithAIPluginMock extends MockUp { + @Mock + public static String getVersionInfo() { + return "1.0"; + } + } + + @RegisterExtension + static JOSMTestRules rules = new JOSMTestRules(); + + private static WireMockServer wireMock; + + @BeforeAll + static void setup() { + wireMock = new WireMockServer(options().dynamicPort()); + wireMock.start(); + BlacklistUtils.setBlacklistUrl(wireMock.baseUrl() + "/JOSM_MapWithAI/json/blacklisted_versions.json"); + new MapWithAIPluginMock(); + } + + @BeforeEach + void clear() { + wireMock.resetMappings(); + } + + @AfterAll + static void tearDown() { + BlacklistUtils.setBlacklistUrl(BlacklistUtils.DEFAULT_BLACKLIST_URL); + assertTrue(wireMock.findAllUnmatchedRequests().isEmpty()); + wireMock.stop(); + } + + @Test + void testArrayBad() { + wireMock.addStubMapping(get(urlMatching("/JOSM_MapWithAI/json/blacklisted_versions.json")) + .willReturn(aResponse().withStatus(200).withBody("[\"" + MapWithAIPlugin.getVersionInfo() + "\"]")) + .build()); + assertTrue(BlacklistUtils.isBlacklisted()); + } + + @Test + void testArrayGood() { + wireMock.addStubMapping(get(urlMatching("/JOSM_MapWithAI/json/blacklisted_versions.json")) + .willReturn(aResponse().withStatus(200).withBody("[null, 0, false]")).build()); + assertFalse(BlacklistUtils.isBlacklisted()); + } + + @Test + void testObjectBad() { + wireMock.addStubMapping(get(urlMatching("/JOSM_MapWithAI/json/blacklisted_versions.json")) + .willReturn(aResponse().withStatus(200) + .withBody("{ \"" + MapWithAIPlugin.getVersionInfo() + "\": \"reason here\"}")) + .build()); + assertTrue(BlacklistUtils.isBlacklisted()); + } + + @Test + void testObjectGood() { + wireMock.addStubMapping(get(urlMatching("/JOSM_MapWithAI/json/blacklisted_versions.json")) + .willReturn(aResponse().withStatus(200).withBody("{ \"version\": \"reason here\"}")).build()); + assertFalse(BlacklistUtils.isBlacklisted()); + } + + @Test + void testNullJson() { + wireMock.addStubMapping(get(urlMatching("/JOSM_MapWithAI/json/blacklisted_versions.json")) + .willReturn(aResponse().withStatus(200).withBody("null")).build()); + assertTrue(BlacklistUtils.isBlacklisted()); + } + + @Test + void testBrokenJson() { + wireMock.addStubMapping(get(urlMatching("/JOSM_MapWithAI/json/blacklisted_versions.json")).willReturn( + aResponse().withStatus(200).withBody("{ \"" + MapWithAIPlugin.getVersionInfo() + "\": \"reason here\"")) + .build()); + assertTrue(BlacklistUtils.isBlacklisted()); + } + + @Test + void testNoResponse() { + wireMock.addStubMapping( + get(urlMatching("/JOSM_MapWithAI/json/blacklisted_versions.json")).willReturn(noContent()).build()); + assertTrue(BlacklistUtils.isBlacklisted()); + } + + @Test + void testNotFound() { + wireMock.addStubMapping( + get(urlMatching("/JOSM_MapWithAI/json/blacklisted_versions.json")).willReturn(notFound()).build()); + assertTrue(BlacklistUtils.isBlacklisted()); + } +}