Add BoundingBoxMapWithAIDownloaderTest

Signed-off-by: Taylor Smock <tsmock@fb.com>
pull/1/head
Taylor Smock 2022-01-05 09:35:33 -07:00
rodzic 526688ab4f
commit a739e55eb7
Nie znaleziono w bazie danych klucza dla tego podpisu
ID klucza GPG: 625F6A74A3E4311A
3 zmienionych plików z 197 dodań i 23 usunięć

Wyświetl plik

@ -8,6 +8,7 @@ import javax.json.JsonValue;
import javax.json.stream.JsonParser;
import java.awt.geom.Area;
import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.SocketTimeoutException;
@ -180,30 +181,31 @@ public class BoundingBoxMapWithAIDownloader extends BoundingBoxDownloader {
// Fall back to Esri Feature Server check. They don't always indicate a json
// return type. :(
|| this.info.getSourceType() == MapWithAIType.ESRI_FEATURE_SERVER) {
if (source.markSupported()) {
source.mark(1024);
try (JsonParser parser = Json.createParser(source)) {
while (parser.hasNext()) {
JsonParser.Event event = parser.next();
if (event == JsonParser.Event.START_OBJECT) {
parser.getObjectStream().filter(entry -> "properties".equals(entry.getKey()))
.filter(entry -> entry.getValue().getValueType() == JsonValue.ValueType.OBJECT)
.map(entry -> entry.getValue().asJsonObject())
.filter(value -> value.containsKey("exceededTransferLimit") && value
.get("exceededTransferLimit").getValueType() == JsonValue.ValueType.TRUE)
.findFirst().ifPresent(val -> {
Logging.error("Could not fully download {0}", this.downloadArea);
});
}
}
source.reset();
} catch (IOException e) {
throw new JosmRuntimeException(e);
}
if (!source.markSupported()) {
source = new BufferedInputStream(source);
}
ds = GeoJSONReader.parseDataSet(source, progressMonitor);
if (info.getReplacementTags() != null) {
GetDataRunnable.replaceKeys(ds, info.getReplacementTags());
source.mark(1024);
try (JsonParser parser = Json.createParser(source)) {
while (parser.hasNext()) {
JsonParser.Event event = parser.next();
if (event == JsonParser.Event.START_OBJECT) {
parser.getObjectStream().filter(entry -> "properties".equals(entry.getKey()))
.filter(entry -> entry.getValue().getValueType() == JsonValue.ValueType.OBJECT)
.map(entry -> entry.getValue().asJsonObject())
.filter(value -> value.containsKey("exceededTransferLimit") && value
.get("exceededTransferLimit").getValueType() == JsonValue.ValueType.TRUE)
.findFirst().ifPresent(val -> {
Logging.error("Could not fully download {0}", this.downloadArea);
});
}
}
source.reset();
ds = GeoJSONReader.parseDataSet(source, progressMonitor);
if (info.getReplacementTags() != null) {
GetDataRunnable.replaceKeys(ds, info.getReplacementTags());
}
} catch (IOException e) {
throw new JosmRuntimeException(e);
}
} else {
// Fall back to XML parsing

Wyświetl plik

@ -0,0 +1,76 @@
// License: GPL. For details, see LICENSE file.
package org.openstreetmap.josm.plugins.mapwithai.backend;
import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;
import javax.json.Json;
import javax.json.JsonObjectBuilder;
import java.util.List;
import org.junit.jupiter.api.extension.RegisterExtension;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.ValueSource;
import org.openstreetmap.josm.data.Bounds;
import org.openstreetmap.josm.data.osm.DataSet;
import org.openstreetmap.josm.gui.progress.NullProgressMonitor;
import org.openstreetmap.josm.plugins.mapwithai.data.mapwithai.MapWithAIInfo;
import org.openstreetmap.josm.plugins.mapwithai.testutils.annotations.MapWithAIConfig;
import org.openstreetmap.josm.plugins.mapwithai.testutils.annotations.Wiremock;
import org.openstreetmap.josm.testutils.JOSMTestRules;
import org.openstreetmap.josm.testutils.annotations.BasicPreferences;
import org.openstreetmap.josm.testutils.annotations.BasicWiremock;
import org.openstreetmap.josm.testutils.annotations.HTTP;
import org.openstreetmap.josm.tools.Logging;
import com.github.tomakehurst.wiremock.WireMockServer;
import com.github.tomakehurst.wiremock.client.WireMock;
/**
* Test class for {@link BoundingBoxMapWithAIDownloader}
*
* @author Taylor Smock
*/
@BasicPreferences
@HTTP
@Wiremock
@MapWithAIConfig
class BoundingBoxMapWithAIDownloaderTest {
@RegisterExtension
JOSMTestRules josmTestRules = new JOSMTestRules().fakeAPI();
@BasicWiremock
public WireMockServer wireMockServer;
@ParameterizedTest
@ValueSource(strings = { "text/json", "application/json", "application/geo+json" })
void testEsriExceededTransferLimit(String responseType) {
final Bounds downloadBounds = new Bounds(10, 10, 20, 20);
final MapWithAIInfo info = new MapWithAIInfo("testEsriExceededTransferLimit",
wireMockServer.baseUrl() + "/esriExceededLimit");
final BoundingBoxMapWithAIDownloader boundingBoxMapWithAIDownloader = new BoundingBoxMapWithAIDownloader(
downloadBounds, info, false);
final JsonObjectBuilder objectBuilder = Json.createObjectBuilder();
objectBuilder.add("type", "FeatureCollection");
objectBuilder.add("properties", Json.createObjectBuilder().add("exceededTransferLimit", true));
objectBuilder.add("features", Json.createArrayBuilder());
wireMockServer.stubFor(WireMock
.get(boundingBoxMapWithAIDownloader
.getRequestForBbox(downloadBounds.getMinLon(), downloadBounds.getMinLat(),
downloadBounds.getMinLon(), downloadBounds.getMinLat())
.replace(wireMockServer.baseUrl(), ""))
.willReturn(WireMock.aResponse().withHeader("Content-Type", responseType)
.withBody(objectBuilder.build().toString())));
Logging.clearLastErrorAndWarnings();
final DataSet ds = assertDoesNotThrow(
() -> boundingBoxMapWithAIDownloader.parseOsm(NullProgressMonitor.INSTANCE));
List<String> errors = Logging.getLastErrorAndWarnings();
assertEquals(1, errors.size(),
"We weren't handling transfer limit issues. Are we now?\n" + String.join("\n", errors));
assertTrue(errors.get(0).contains("Could not fully download"));
assertTrue(ds.isEmpty());
}
}

Wyświetl plik

@ -0,0 +1,96 @@
// License: GPL. For details, see LICENSE file.
package org.openstreetmap.josm.plugins.mapwithai.testutils.annotations;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.util.stream.Stream;
import org.junit.jupiter.api.extension.AfterEachCallback;
import org.junit.jupiter.api.extension.BeforeEachCallback;
import org.junit.jupiter.api.extension.ExtendWith;
import org.junit.jupiter.api.extension.ExtensionContext;
import org.openstreetmap.josm.plugins.mapwithai.spi.preferences.IMapWithAIUrls;
import com.github.tomakehurst.wiremock.WireMockServer;
/**
* Set the MapWithAI config for the test
*
* @author Taylor Smock
*/
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@ExtendWith(MapWithAIConfig.MapWithAIConfigExtension.class)
@Wiremock
public @interface MapWithAIConfig {
class MapWithAIConfigExtension extends Wiremock.WiremockExtension implements BeforeEachCallback, AfterEachCallback {
@Override
public void beforeEach(ExtensionContext context) throws Exception {
org.openstreetmap.josm.plugins.mapwithai.spi.preferences.MapWithAIConfig
.setUrlsProvider(new WireMockMapWithAIUrls(getWiremock(context)));
}
@Override
public void afterEach(ExtensionContext context) {
org.openstreetmap.josm.plugins.mapwithai.spi.preferences.MapWithAIConfig
.setUrlsProvider(new UnsupportedMapWithAIUrls(
org.openstreetmap.josm.plugins.mapwithai.spi.preferences.MapWithAIConfig.getUrls()));
}
private static final class WireMockMapWithAIUrls implements IMapWithAIUrls {
private final WireMockServer wireMockServer;
public WireMockMapWithAIUrls(final WireMockServer wireMockServer) {
this.wireMockServer = wireMockServer;
}
@Override
public String getConflationServerJson() {
return this.wireMockServer.baseUrl() + "/JOSM_MapWithAI/json/conflation_servers.json";
}
@Override
public String getMapWithAISourcesJson() {
return this.wireMockServer.baseUrl() + "/JOSM_MapWithAI/json/sources.json";
}
@Override
public String getMapWithAIPaintStyle() {
return this.wireMockServer.baseUrl() + "/josmfile?page=Styles/MapWithAI&zip=1";
}
}
private static final class UnsupportedMapWithAIUrls implements IMapWithAIUrls {
private IMapWithAIUrls oldUrls;
public UnsupportedMapWithAIUrls(IMapWithAIUrls oldUrls) {
this.oldUrls = oldUrls;
}
@Override
public String getConflationServerJson() {
throw new UnsupportedOperationException("Use @MapWithAIConfig");
}
@Override
public String getMapWithAISourcesJson() {
throw new UnsupportedOperationException("Use @MapWithAIConfig");
}
@Override
public String getMapWithAIPaintStyle() {
if (this.oldUrls != null && Stream.of(Thread.currentThread().getStackTrace())
.map(StackTraceElement::getMethodName).anyMatch("afterAll"::equals)) {
final IMapWithAIUrls urls = this.oldUrls;
this.oldUrls = null;
return urls.getMapWithAIPaintStyle();
}
throw new UnsupportedOperationException("Use @MapWithAIConfig");
}
}
}
}