From 0a3224a05ab690c3351eb9f19e7322248fd8fe86 Mon Sep 17 00:00:00 2001 From: Vincent Paturet Date: Tue, 7 Jan 2025 18:21:29 +0100 Subject: [PATCH] Add validation rules for ServiceLinks --- README.md | 2 + pom.xml | 2 +- ...aultServiceFrameValidationTreeFactory.java | 22 ++- ...ServiceFrameValidationTreeFactoryTest.java | 162 ++++++++++++++++++ 4 files changed, 186 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index a22d2015..296a8046 100644 --- a/README.md +++ b/README.md @@ -246,6 +246,8 @@ The NeTEx validator library comes with the following rule set by default: | SERVICE_LINK_1 | ServiceLink missing FromPointRef | | SERVICE_LINK_2 | ServiceLink missing ToPointRef | | SERVICE_LINK_3 | ServiceLink missing element Projections | +| SERVICE_LINK_4 | ServiceLink missing coordinate list | +| SERVICE_LINK_5 | ServiceLink less than 2 points | | SITE_FRAME_IN_COMMON_FILE | SiteFrame unexpected SiteFrame in Common file | | SITE_FRAME_IN_LINE_FILE | SiteFrame unexpected SiteFrame in Line file | | TIMETABLE_FRAME_IN_COMMON_FILE | TimetableFrame illegal in Common file | diff --git a/pom.xml b/pom.xml index 6001b6ab..23b246b4 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ org.entur netex-validator-java - 9.0.5-SNAPSHOT + 9.1.0-SNAPSHOT netex-validator-java Library for validating NeTEx datasets against the Nordic NeTEx Profile. diff --git a/src/main/java/org/entur/netex/validation/validator/xpath/tree/DefaultServiceFrameValidationTreeFactory.java b/src/main/java/org/entur/netex/validation/validator/xpath/tree/DefaultServiceFrameValidationTreeFactory.java index 8eca4d97..808237bf 100644 --- a/src/main/java/org/entur/netex/validation/validator/xpath/tree/DefaultServiceFrameValidationTreeFactory.java +++ b/src/main/java/org/entur/netex/validation/validator/xpath/tree/DefaultServiceFrameValidationTreeFactory.java @@ -59,6 +59,8 @@ public class DefaultServiceFrameValidationTreeFactory public static final String CODE_SERVICE_LINK_1 = "SERVICE_LINK_1"; public static final String CODE_SERVICE_LINK_2 = "SERVICE_LINK_2"; public static final String CODE_SERVICE_LINK_3 = "SERVICE_LINK_3"; + public static final String CODE_SERVICE_LINK_4 = "SERVICE_LINK_4"; + public static final String CODE_SERVICE_LINK_5 = "SERVICE_LINK_5"; public static final String CODE_FLEXIBLE_LINE_1 = "FLEXIBLE_LINE_1"; public static final String CODE_FLEXIBLE_LINE_10 = "FLEXIBLE_LINE_10"; public static final String CODE_FLEXIBLE_LINE_11 = "FLEXIBLE_LINE_11"; @@ -176,13 +178,31 @@ public ValidationTreeBuilder builder() { ) .withRule( new ValidateNotExist( - "serviceLinks/ServiceLink/projections/LinkSequenceProjection/g:LineString/g:posList[not(normalize-space(text()))]", + "serviceLinks/ServiceLink[not(projections)]", CODE_SERVICE_LINK_3, "ServiceLink missing element Projections", "Missing projections element on ServiceLink", + Severity.WARNING + ) + ) + .withRule( + new ValidateNotExist( + "serviceLinks/ServiceLink/projections/LinkSequenceProjection/g:LineString/g:posList[not(normalize-space(text()))]", + CODE_SERVICE_LINK_4, + "ServiceLink missing coordinate list", + "Missing coordinates list on ServiceLink", Severity.ERROR ) ) + .withRule( + new ValidateNotExist( + "serviceLinks/ServiceLink/projections/LinkSequenceProjection/g:LineString[count(g:pos) < 2]", + CODE_SERVICE_LINK_5, + "ServiceLink less than 2 points", + "Less then 2 points on ServiceLink", + Severity.WARNING + ) + ) .withRule( new ValidateNotExist( "destinationDisplays/DestinationDisplay[not(FrontText) or normalize-space(FrontText) = '']", diff --git a/src/test/java/org/entur/netex/validation/validator/xpath/tree/DefaultServiceFrameValidationTreeFactoryTest.java b/src/test/java/org/entur/netex/validation/validator/xpath/tree/DefaultServiceFrameValidationTreeFactoryTest.java index 2d699d31..e8ac85fe 100644 --- a/src/test/java/org/entur/netex/validation/validator/xpath/tree/DefaultServiceFrameValidationTreeFactoryTest.java +++ b/src/test/java/org/entur/netex/validation/validator/xpath/tree/DefaultServiceFrameValidationTreeFactoryTest.java @@ -11,6 +11,7 @@ import org.entur.netex.validation.validator.xpath.ValidationTree; import org.entur.netex.validation.validator.xpath.XPathRuleValidationContext; import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.MethodSource; @@ -140,6 +141,100 @@ class DefaultServiceFrameValidationTreeFactoryTest { """; + private static final String NETEX_FRAGMENT_INVALID_SERVICE_LINK_NO_PROJECTION = + """ + + + + 2030.0 + + + + + + """; + + private static final String NETEX_FRAGMENT_INVALID_SERVICE_LINK_NO_COORDINATE_LIST = + """ + + + + 2030.0 + + + + + + + + + + + + + """; + + private static final String NETEX_FRAGMENT_SERVICE_LINK_VALID_COORDINATE_LIST = + """ + + + + 2030.0 + + + + 59.551598 9.803644 59.5307 9.805698 + + + + + + + + + """; + + private static final String NETEX_FRAGMENT_INVALID_SERVICE_LINK_LESS_THAN_TWO_POINTS = + """ + + + + 2030.0 + + + + 60.075463 9.121449 + + + + + + + + + """; + + private static final String NETEX_FRAGMENT_SERVICE_LINK_VALID_TWO_POINTS = + """ + + + + 2030.0 + + + + 60.075463 9.121449 + 60.07577 9.121238 + + + + + + + + + """; + private ValidationTree validationTree; @BeforeEach @@ -202,4 +297,71 @@ void testValidServiceFrame(String code) { ); assertTrue(validationIssues.isEmpty()); } + + @Test + void testMissingProjectionOnServiceLink() { + XPathRuleValidationContext xpathValidationContext = + TestValidationContextBuilder + .ofNetexFragment(NETEX_FRAGMENT_INVALID_SERVICE_LINK_NO_PROJECTION) + .build(); + List validationIssues = validationTree.validate( + xpathValidationContext, + CODE_SERVICE_LINK_3 + ); + assertEquals(1, validationIssues.size()); + } + + @Test + void testMissingCoordinateListOnServiceLink() { + XPathRuleValidationContext xpathValidationContext = + TestValidationContextBuilder + .ofNetexFragment(NETEX_FRAGMENT_INVALID_SERVICE_LINK_NO_COORDINATE_LIST) + .build(); + List validationIssues = validationTree.validate( + xpathValidationContext, + CODE_SERVICE_LINK_4 + ); + assertEquals(1, validationIssues.size()); + } + + @Test + void testValidCoordinateListOnServiceLink() { + XPathRuleValidationContext xpathValidationContext = + TestValidationContextBuilder + .ofNetexFragment(NETEX_FRAGMENT_SERVICE_LINK_VALID_COORDINATE_LIST) + .build(); + List validationIssues = validationTree.validate( + xpathValidationContext, + CODE_SERVICE_LINK_4 + ); + assertTrue(validationIssues.isEmpty()); + } + + @Test + void testLessThanTwoPointsOnServiceLink() { + XPathRuleValidationContext xpathValidationContext = + TestValidationContextBuilder + .ofNetexFragment( + NETEX_FRAGMENT_INVALID_SERVICE_LINK_LESS_THAN_TWO_POINTS + ) + .build(); + List validationIssues = validationTree.validate( + xpathValidationContext, + CODE_SERVICE_LINK_5 + ); + assertEquals(1, validationIssues.size()); + } + + @Test + void testServiceLinkWithTwoPoints() { + XPathRuleValidationContext xpathValidationContext = + TestValidationContextBuilder + .ofNetexFragment(NETEX_FRAGMENT_SERVICE_LINK_VALID_TWO_POINTS) + .build(); + List validationIssues = validationTree.validate( + xpathValidationContext, + CODE_SERVICE_LINK_5 + ); + assertTrue(validationIssues.isEmpty()); + } }