diff --git a/source/imaer-gml/src/main/java/nl/overheid/aerius/gml/base/geo/GML2Geometry.java b/source/imaer-gml/src/main/java/nl/overheid/aerius/gml/base/geo/GML2Geometry.java index f10983ae..69529327 100644 --- a/source/imaer-gml/src/main/java/nl/overheid/aerius/gml/base/geo/GML2Geometry.java +++ b/source/imaer-gml/src/main/java/nl/overheid/aerius/gml/base/geo/GML2Geometry.java @@ -54,6 +54,8 @@ public Geometry getGeometry(final FeatureMember fm) throws AeriusException { } else { throw e; } + } catch (final RuntimeException e) { + throw new AeriusException(ImaerExceptionReason.GML_GEOMETRY_INVALID, fm.getId()); } return geometry; } @@ -73,8 +75,7 @@ private Geometry constructGeometry(final String id, final GmlEmissionSourceGeome return geometry; } - private void isValidGeometry(final FeatureMember fm, final Geometry geometry) - throws AeriusException { + private static void isValidGeometry(final FeatureMember fm, final Geometry geometry) throws AeriusException { // check if the geometry is actually valid for this type of feature member. if (!fm.isValidGeometry(geometry.type())) { throw new AeriusException(ImaerExceptionReason.GML_GEOMETRY_NOT_PERMITTED, fm.getId()); diff --git a/source/imaer-gml/src/main/java/nl/overheid/aerius/gml/base/geo/Geo2GeometryUtil.java b/source/imaer-gml/src/main/java/nl/overheid/aerius/gml/base/geo/Geo2GeometryUtil.java index 4c1ed2c5..b1cdc999 100644 --- a/source/imaer-gml/src/main/java/nl/overheid/aerius/gml/base/geo/Geo2GeometryUtil.java +++ b/source/imaer-gml/src/main/java/nl/overheid/aerius/gml/base/geo/Geo2GeometryUtil.java @@ -45,7 +45,7 @@ /** * Class to convert gml geometry objects to data geometry objects. */ -public final class Geo2GeometryUtil { +final class Geo2GeometryUtil { private final int srid; private final GeometryFactory geometryFactory; diff --git a/source/imaer-gml/src/test/java/nl/overheid/aerius/gml/GMLValidateErrorsTest.java b/source/imaer-gml/src/test/java/nl/overheid/aerius/gml/GMLValidateErrorsTest.java index 0ea499e6..a5976194 100644 --- a/source/imaer-gml/src/test/java/nl/overheid/aerius/gml/GMLValidateErrorsTest.java +++ b/source/imaer-gml/src/test/java/nl/overheid/aerius/gml/GMLValidateErrorsTest.java @@ -49,10 +49,8 @@ void testGMLValidationFailed() throws IOException { assertResult("fout_5201_projectiesysteem", "GML Invalid projectiesystem", ImaerExceptionReason.GML_VALIDATION_FAILED, e -> { assertFalse(e.getArgs()[0].isEmpty(), "Should show list of possible options"); - assertTrue(e.getArgs()[0].contains("Invalid content was found starting with element '"), - "Invalid content was found"); - assertTrue(e.getArgs()[0].contains("Pointy"), - "Invalid content was found"); + assertContains(e, "Invalid content was found starting with element '"); + assertContains(e, "Pointy"); }); } @@ -61,10 +59,8 @@ void testGMLGeometryInvalid() throws IOException { assertResult("fout_5202_projectiesysteem", "GML Invalid geometry", ImaerExceptionReason.GML_VALIDATION_FAILED, e -> { assertFalse(e.getArgs()[0].isEmpty(), "Should show list of possible options"); - assertTrue(e.getArgs()[0].contains("Invalid content was found starting with element '"), - "Invalid content was found"); - assertTrue(e.getArgs()[0].contains(":GM_SQUARE"), - "Invalid content was found"); + assertContains(e, "Invalid content was found starting with element '"); + assertContains(e, ":GM_SQUARE"); }); } @@ -73,10 +69,8 @@ void testGMLEncodingIncorrect() throws IOException { assertResult("fout_5203_unsupported_character", "GML Incorrect encoding", ImaerExceptionReason.GML_VALIDATION_FAILED, e -> { assertFalse(e.getArgs()[0].isEmpty(), "Should show list of possible options"); - assertTrue(e.getArgs()[0].contains("Invalid content was found starting with element '"), - "Invalid content was found"); - assertTrue(e.getArgs()[0].contains("GM_SURFACE"), - "Invalid content was found"); + assertContains(e, "Invalid content was found starting with element '"); + assertContains(e, "GM_SURFACE"); }); } @@ -111,8 +105,7 @@ void testGMLGeometryUnknown() throws IOException { assertResult("fout_5206_unsupported_geometry", "GML Geometry unkown", ImaerExceptionReason.GML_VALIDATION_FAILED, e -> { assertFalse(e.getArgs()[0].isEmpty(), "Should show list of possible options"); - assertTrue(e.getArgs()[0].contains("The value of {abstract} in the element declaration for 'gml:AbstractRing' must be false"), - "Invalid content was found"); + assertContains(e, "The value of {abstract} in the element declaration for 'gml:AbstractRing' must be false"); }); } @@ -189,14 +182,13 @@ void testGMLUnsupportedLodingMeasure() throws IOException { @Test void testGMLInvalidRoadCategoryMatch() throws IOException { - assertResult("fout_5219_obsolete_roadsource", "GML Invalid road category match", - ImaerExceptionReason.GML_INVALID_ROAD_CATEGORY_MATCH); + assertResult("fout_5219_obsolete_roadsource", "GML Invalid road category match", ImaerExceptionReason.GML_INVALID_ROAD_CATEGORY_MATCH); } @Test void testGMLIdNotUnique() throws IOException { assertResult("fout_5220_conflicting_id", "GML Id not unique", ImaerExceptionReason.GML_VALIDATION_FAILED, - e -> assertTrue(e.getArgs()[0].contains("There are multiple occurrences of ID value 'ES.1'"), "Contains error")); + e -> assertContains(e, "There are multiple occurrences of ID value 'ES.1'")); } @Test @@ -208,8 +200,8 @@ void testGMLUnknownRoadCategory() throws IOException { void testGMLMetaDataEmpty() throws IOException { assertResult("fout_5222_missing_metadata", "GML Metadata empty", ImaerExceptionReason.GML_VALIDATION_FAILED, e -> { - assertTrue(e.getArgs()[0].contains("Invalid content was found starting with element '"), "Contains error"); - assertTrue(e.getArgs()[0].contains(":version"), "Contains error"); + assertContains(e, "Invalid content was found starting with element '"); + assertContains(e, ":version"); }); } @@ -232,8 +224,9 @@ void testGMLMissingNettingFactor() throws IOException { } @Test - void testGMLUnknownError() throws IOException { - assertResult("fout_666_unknown_error", "GML Unknown error", ImaerExceptionReason.INTERNAL_ERROR, IllegalArgumentException.class); + void testGMLInvalidGeometry() throws IOException { + assertResult("fout_5202_invalid_geometry", "GML invalid geomerty", ImaerExceptionReason.GML_GEOMETRY_INVALID, + e -> assertContains(e, "ES.1")); } @Test @@ -350,6 +343,12 @@ private static void assertResults(final String fileName, final List expe } } + private static void assertContains(final AeriusException e, final String containsText) { + final String exceptionText = e.getArgs()[0]; + + assertTrue(exceptionText.contains(containsText), "Exception didn't match expected text, was:" + exceptionText); + } + private static ImportParcel getImportResult(final String relativePath, final String fileName) throws IOException, AeriusException { return AssertGML.getImportResult(relativePath, fileName); diff --git a/source/imaer-gml/src/test/java/nl/overheid/aerius/gml/base/geo/GML2GeometryTest.java b/source/imaer-gml/src/test/java/nl/overheid/aerius/gml/base/geo/GML2GeometryTest.java new file mode 100644 index 00000000..f4e06ed1 --- /dev/null +++ b/source/imaer-gml/src/test/java/nl/overheid/aerius/gml/base/geo/GML2GeometryTest.java @@ -0,0 +1,137 @@ +/* + * Copyright the State of the Netherlands + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see http://www.gnu.org/licenses/. + */ +package nl.overheid.aerius.gml.base.geo; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.lenient; + +import java.util.List; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; + +import net.opengis.gml.v_3_2.DirectPositionListType; +import net.opengis.gml.v_3_2.LineStringType; +import net.opengis.gml.v_3_2.ObjectFactory; +import net.opengis.gml.v_3_2.PointType; +import net.opengis.gml.v_3_2.PolygonType; + +import nl.overheid.aerius.gml.base.FeatureMember; +import nl.overheid.aerius.shared.exception.AeriusException; +import nl.overheid.aerius.shared.exception.ImaerExceptionReason; +import nl.overheid.aerius.shared.geo.EPSG; + +/** + * Test class for {@link GML2Geometry}. + */ +@ExtendWith(MockitoExtension.class) +class GML2GeometryTest { + final ObjectFactory factory = new ObjectFactory(); + + @Mock FeatureMember featureMember; + @Mock GmlEmissionSourceGeometry gmlEmissionSourceGeometry; + @Mock GmlPoint gmlPoint; + @Mock GmlLineString gmlLineString; + @Mock GmlPolygon gmlPolygon; + + private final GML2Geometry gml2Geometry = new GML2Geometry(EPSG.RDNEW.getSrid()); + + @BeforeEach + void beforeEach() { + doReturn(gmlEmissionSourceGeometry).when(featureMember).getEmissionSourceGeometry(); + } + + @Test + void testPointIncomplete() { + mockPoint(List.of(1.0), true); + + assertGeoFail(ImaerExceptionReason.GML_GEOMETRY_INVALID, "Expected to give the reason invalid point geometry."); + } + + @Test + void testPointInvalid() { + mockPoint(List.of(1.0, 2.0), false); + + assertGeoFail(ImaerExceptionReason.GML_GEOMETRY_NOT_PERMITTED, "Expected to give the reason point geometry not permitted."); + } + + @Test + void testLineStringIncomplete() { + mockLineString(List.of(1.0, 2.0), true); + + assertGeoFail(ImaerExceptionReason.GML_GEOMETRY_INVALID, "Expected to give the reason invalid line geometry."); + } + + @Test + void testLineStringInvalid() { + mockLineString(List.of(1.0, 2.0, 2.0, 1.0), false); + + assertGeoFail(ImaerExceptionReason.GML_GEOMETRY_NOT_PERMITTED, "Expected to give the reason line geometry not permitted."); + } + + @Test + void testPolygonIncomplete() { + mockPolygon(List.of(1.0, 2.0), true); + + assertGeoFail(ImaerExceptionReason.GML_GEOMETRY_INVALID, "Expected to give the reason invalid polygon geometry."); + } + + @Test + void testPolygonInvalid() { + mockPolygon(List.of(1.0, 2.0, 2.0, 1.0, 1.0, 2.0), false); + + assertGeoFail(ImaerExceptionReason.GML_GEOMETRY_NOT_PERMITTED, "Expected to give the reason geometry not permitted."); + } + + private void assertGeoFail(final ImaerExceptionReason expectedReason, final String message) { + final AeriusException exception = assertThrows(AeriusException.class, () -> gml2Geometry.getGeometry(featureMember)); + assertEquals(expectedReason, exception.getReason(), message); + } + + private void mockPoint(final List numbers, final boolean valid) { + final PointType pointType = Geo2GeometryUtilTest.createPoint(numbers); + + lenient().doReturn(valid).when(featureMember).isValidGeometry(any()); + lenient().doReturn(gmlPoint).when(gmlEmissionSourceGeometry).getPoint(); + doReturn(pointType).when(gmlPoint).getGmlPoint(); + } + + private void mockLineString(final List numbers, final boolean valid) { + final LineStringType lineStringType = factory.createLineStringType(); + final DirectPositionListType list = new DirectPositionListType(); + list.setValue(numbers); + lineStringType.setPosList(list); + + lenient().doReturn(valid).when(featureMember).isValidGeometry(any()); + lenient().doReturn(gmlLineString).when(gmlEmissionSourceGeometry).getLineString(); + doReturn(lineStringType).when(gmlLineString).getGMLLineString(); + } + + private void mockPolygon(final List numbers, final boolean valid) { + final PolygonType polygonType = Geo2GeometryUtilTest.createPolygon(numbers); + + lenient().doReturn(valid).when(featureMember).isValidGeometry(any()); + lenient().doReturn(gmlPolygon).when(gmlEmissionSourceGeometry).getPolygon(); + doReturn(polygonType).when(gmlPolygon).getGmlPolygon(); + } +} diff --git a/source/imaer-gml/src/test/java/nl/overheid/aerius/gml/base/Geo2GeometryUtilTest.java b/source/imaer-gml/src/test/java/nl/overheid/aerius/gml/base/geo/Geo2GeometryUtilTest.java similarity index 72% rename from source/imaer-gml/src/test/java/nl/overheid/aerius/gml/base/Geo2GeometryUtilTest.java rename to source/imaer-gml/src/test/java/nl/overheid/aerius/gml/base/geo/Geo2GeometryUtilTest.java index 20d4b51c..3fde2443 100644 --- a/source/imaer-gml/src/test/java/nl/overheid/aerius/gml/base/Geo2GeometryUtilTest.java +++ b/source/imaer-gml/src/test/java/nl/overheid/aerius/gml/base/geo/Geo2GeometryUtilTest.java @@ -14,7 +14,7 @@ * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see http://www.gnu.org/licenses/. */ -package nl.overheid.aerius.gml.base; +package nl.overheid.aerius.gml.base.geo; import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.junit.jupiter.api.Assertions.assertSame; @@ -22,7 +22,7 @@ import static org.junit.jupiter.api.Assertions.assertTrue; import java.math.BigInteger; -import java.util.Arrays; +import java.util.List; import jakarta.xml.bind.JAXBElement; @@ -36,7 +36,6 @@ import net.opengis.gml.v_3_2.PointType; import net.opengis.gml.v_3_2.PolygonType; -import nl.overheid.aerius.gml.base.geo.Geo2GeometryUtil; import nl.overheid.aerius.shared.domain.v2.geojson.Geometry; import nl.overheid.aerius.shared.domain.v2.geojson.Point; import nl.overheid.aerius.shared.domain.v2.geojson.Polygon; @@ -47,54 +46,34 @@ /** * Test class for {@link Geo2GeometryUtil}. */ -public class Geo2GeometryUtilTest { +class Geo2GeometryUtilTest { private final Geo2GeometryUtil geo2GeometryUtil = new Geo2GeometryUtil(EPSG.RDNEW.getSrid()); @Test - public void testPoint() throws AeriusException { + void testPoint() throws AeriusException { final PointType pointType = createPoint(); final Geometry geometry = geo2GeometryUtil.fromXMLPoint(pointType); assertTrue(geometry instanceof Point, "Not a point"); } @Test - public void testPolygon() throws AeriusException { - final DirectPositionListType coordList = new DirectPositionListType(); - - // this polygon is closed - coordList.getValue().add(100.0); // X - coordList.getValue().add(20.0); // Y - coordList.getValue().add(400.0); - coordList.getValue().add(50.0); - coordList.getValue().add(600.0); - coordList.getValue().add(70.0); - coordList.getValue().add(100.0); - coordList.getValue().add(20.0); - - final PolygonType polygonType = createPolygon(coordList); + void testPolygon() throws AeriusException { + final PolygonType polygonType = createPolygon(List.of(100.0, 20.0, 400.0, 50.0, 600.0, 70.0, 100.0, 20.0)); final Geometry geometry = geo2GeometryUtil.fromXMLPolygon(polygonType); + assertTrue(geometry instanceof Polygon, "Not a polygon"); } @Test - public void testPolygonNotClosed() { - final DirectPositionListType coordList = new DirectPositionListType(); - - // this polygon is not closed - coordList.getValue().add(100.0); // X - coordList.getValue().add(20.0); // Y - coordList.getValue().add(400.0); - coordList.getValue().add(50.0); - coordList.getValue().add(600.0); - coordList.getValue().add(70.0); + void testPolygonNotClosed() { + final PolygonType polygonType = createPolygon(List.of(100.0, 20.0, 400.0, 50.0, 600.0, 70.0)); - final PolygonType polygonType = createPolygon(coordList); assertThrows(AeriusException.class, () -> geo2GeometryUtil.fromXMLPolygon(polygonType)); } @Test - public void testInvalidSRS() throws AeriusException { + void testInvalidSRS() throws AeriusException { final PointType pointType = createPoint(); pointType.setSrsName("unknown"); pointType.setSrsDimension(BigInteger.TEN); @@ -106,7 +85,7 @@ public void testInvalidSRS() throws AeriusException { } @Test - public void testEmptySRS() throws AeriusException { + void testEmptySRS() throws AeriusException { final PointType pointType = createPoint(); pointType.setSrsDimension(BigInteger.TEN); pointType.setSrsName(null); @@ -115,22 +94,29 @@ public void testEmptySRS() throws AeriusException { assertNotNull(geo2GeometryUtil.fromXMLPoint(pointType), "Should just return the point on empty"); } - private PointType createPoint() { + private static PointType createPoint() { + return createPoint(List.of(1.0, 1.0)); + } + + public static PointType createPoint(final List numbers) { final PointType pointType = new PointType(); final DirectPositionType value = new DirectPositionType(); - value.setValue(Arrays.asList(new Double[] {1.0, 1.0})); + + value.setValue(numbers); pointType.setPos(value); return pointType; } - private PolygonType createPolygon(final DirectPositionListType directPositionListType) { + public static PolygonType createPolygon(final List numbers) { final ObjectFactory factory = new ObjectFactory(); final PolygonType polygonType = new PolygonType(); final AbstractRingPropertyType abstractRingPropertyType = factory.createAbstractRingPropertyType(); final JAXBElement linearRingType = factory.createLinearRing(factory.createLinearRingType()); + final DirectPositionListType coordList = new DirectPositionListType(); - linearRingType.getValue().setPosList(directPositionListType); + coordList.setValue(numbers); + linearRingType.getValue().setPosList(coordList); abstractRingPropertyType.setAbstractRing(linearRingType); polygonType.setExterior(abstractRingPropertyType); return polygonType; diff --git a/source/imaer-gml/src/test/resources/gml/latest/validate/errors/fout_666_unknown_error.gml b/source/imaer-gml/src/test/resources/gml/latest/validate/errors/fout_5202_invalid_geometry.gml similarity index 100% rename from source/imaer-gml/src/test/resources/gml/latest/validate/errors/fout_666_unknown_error.gml rename to source/imaer-gml/src/test/resources/gml/latest/validate/errors/fout_5202_invalid_geometry.gml