Fix #22440: NPE in MapWithAIInfo#getConflationUrl

Signed-off-by: Taylor Smock <tsmock@meta.com>
pull/4/head v1.9.19
Taylor Smock 2022-10-11 10:46:43 -06:00
rodzic ff3a9d38c3
commit 88a48a5fdb
Nie znaleziono w bazie danych klucza dla tego podpisu
ID klucza GPG: 625F6A74A3E4311A
2 zmienionych plików z 102 dodań i 1 usunięć

Wyświetl plik

@ -453,7 +453,29 @@ public class MapWithAIInfo extends
return getNonConflatedUrl();
}
StringBuilder sb = new StringBuilder();
sb.append(conflationUrl.replace("{id}", this.id));
if (this.conflationUrl.contains("{id}") && this.id != null) {
sb.append(conflationUrl.replace("{id}", this.id));
} else if (this.conflationUrl.contains("{id}")) {
// We need to trigger synchronization. This means that the current download
// may won't be conflated.
// But this should automatically correct the behavior for the next attempt.
final MapWithAILayerInfo mwli = MapWithAILayerInfo.getInstance();
mwli.load(false, () -> {
Optional<MapWithAIInfo> defaultLayer = mwli.getAllDefaultLayers().stream().filter(this::equals)
.findFirst();
if (defaultLayer.isPresent()) {
this.id = defaultLayer.get().id;
} else {
MapWithAIInfo newInfo = mwli.getAllDefaultLayers().stream()
.filter(layer -> Objects.equals(this.url, layer.url) && Objects.nonNull(layer.id))
.findFirst().orElse(this);
this.id = newInfo.id;
}
});
return getNonConflatedUrl();
} else {
sb.append(conflationUrl);
}
List<String> parametersString = getConflationParameterString();
if (!parametersString.isEmpty()) {

Wyświetl plik

@ -1,7 +1,11 @@
// License: GPL. For details, see LICENSE file.
package org.openstreetmap.josm.plugins.mapwithai.data.mapwithai;
import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNull;
import static org.junit.jupiter.api.Assertions.assertSame;
import static org.junit.jupiter.api.Assertions.assertTrue;
import javax.json.Json;
import javax.json.JsonArray;
@ -15,15 +19,21 @@ import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.stream.Stream;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.Arguments;
import org.junit.jupiter.params.provider.MethodSource;
import org.openstreetmap.josm.TestUtils;
import org.openstreetmap.josm.gui.MainApplication;
import org.openstreetmap.josm.gui.util.GuiHelper;
import org.openstreetmap.josm.testutils.annotations.BasicPreferences;
import org.openstreetmap.josm.tools.Logging;
import mockit.Mock;
import mockit.MockUp;
import nl.jqno.equalsverifier.EqualsVerifier;
import nl.jqno.equalsverifier.Warning;
@ -117,4 +127,73 @@ class MapWithAIInfoTest {
EqualsVerifier.forClass(MapWithAIInfo.class).suppress(Warning.NONFINAL_FIELDS)
.withOnlyTheseFields("url", "sourceType").usingGetClass().verify();
}
/**
* Non-regression test for #22440: NPE in
* {@link MapWithAIInfo#getConflationUrl}. This is caused by the
* {@link MapWithAIInfo#getId()} being {@code null}.
*/
@Test
void testNonRegression22440UpdateFallback() {
TestUtils.assumeWorkingJMockit();
MapWithAIInfo info = new MapWithAIInfo("22440", "https://test.example", null);
info.setConflationUrl("https://test.example/{id}");
info.setConflation(true);
MapWithAILayerInfo.getInstance().clear();
MapWithAILayerInfo.getInstance().add(info);
AtomicBoolean updateCalled = new AtomicBoolean();
new MockUp<MapWithAILayerInfo>() {
@Mock
public void load(boolean fastFail, MapWithAILayerInfo.FinishListener listener) {
updateCalled.set(true);
listener.onFinish();
}
};
assertDoesNotThrow(info::getUrlExpanded);
MainApplication.worker.submit(() -> {
/* Sync thread */ });
GuiHelper.runInEDTAndWait(() -> {
/* Sync thread */ });
assertTrue(updateCalled.get());
assertEquals(1, MapWithAILayerInfo.getInstance().getLayers().size());
assertSame(info, MapWithAILayerInfo.getInstance().getLayers().get(0));
}
/**
* Non-regression test for #22440: NPE in
* {@link MapWithAIInfo#getConflationUrl}. This is caused by the
* {@link MapWithAIInfo#getId()} being {@code null}.
*/
@Test
void testNonRegression22440Update() {
TestUtils.assumeWorkingJMockit();
MapWithAIInfo info = new MapWithAIInfo("22440", "https://test.example", null);
info.setConflationUrl("https://test.example/{id}");
info.setConflation(true);
MapWithAILayerInfo.getInstance().clear();
MapWithAILayerInfo.getInstance().add(info);
AtomicBoolean updateCalled = new AtomicBoolean();
new MockUp<MapWithAILayerInfo>() {
@Mock
public void load(boolean fastFail, MapWithAILayerInfo.FinishListener listener) {
updateCalled.set(true);
listener.onFinish();
}
@Mock
public List<MapWithAIInfo> getAllDefaultLayers() {
return Collections.singletonList(new MapWithAIInfo("22440Update", "https://test.example", "22"));
}
};
assertNull(info.getId());
assertDoesNotThrow(info::getUrlExpanded);
MainApplication.worker.submit(() -> {
/* Sync thread */ });
GuiHelper.runInEDTAndWait(() -> {
/* Sync thread */ });
assertTrue(updateCalled.get());
assertEquals(1, MapWithAILayerInfo.getInstance().getLayers().size());
assertSame(info, MapWithAILayerInfo.getInstance().getLayers().get(0));
assertEquals("22", info.getId());
}
}