Skip to content

Commit

Permalink
Add Unit tests
Browse files Browse the repository at this point in the history
  • Loading branch information
vpaturet committed Dec 20, 2024
1 parent 4c15270 commit 070fb30
Show file tree
Hide file tree
Showing 8 changed files with 324 additions and 4 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/push.yml
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ jobs:
wget https://raw.githubusercontent.com/entur/ror-maven-settings/master/.m2/settings.xml -O .github/workflows/settings.xml
- uses: actions/setup-java@v4
with:
java-version: 17.0.13
java-version: 17
distribution: liberica
- name: Cache Maven dependencies
uses: actions/cache@v4
Expand All @@ -47,7 +47,7 @@ jobs:
SONAR_PROJECT_NAME: ${{ github.event.repository.name }}
SONAR_PROJECT_KEY: entur_${{ github.event.repository.name }}
run: |
mvn -s .github/workflows/settings.xml \
mvn -Psonar -s .github/workflows/settings.xml \
org.jacoco:jacoco-maven-plugin:prepare-agent verify \
org.jacoco:jacoco-maven-plugin:report sonar:sonar \
-Dmaven.main.skip \
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;
import org.entur.netex.validation.exception.NetexValidationException;
import org.yaml.snakeyaml.LoaderOptions;
import org.yaml.snakeyaml.Yaml;
import org.yaml.snakeyaml.constructor.Constructor;
Expand Down Expand Up @@ -45,6 +46,13 @@ private Map<String, ValidationRuleConfig> loadConfigurationFile(
.currentThread()
.getContextClassLoader()
.getResourceAsStream(configurationFile);

if (inputStream == null) {
throw new NetexValidationException(
"Validation rules configuration file not found: " + configurationFile
);
}

Yaml yaml = new Yaml(
new Constructor(ValidationConfig.class, new LoaderOptions())
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,14 +27,14 @@ public class NetexSchemaValidator
NetexSchemaValidator.class
);

static final ValidationRule RULE_ERROR = new ValidationRule(
public static final ValidationRule RULE_ERROR = new ValidationRule(
"XML_SCHEMA_ERROR",
"NeTEx XML Schema validation error",
"%s",
Severity.CRITICAL
);

static final ValidationRule RULE_WARNING = new ValidationRule(
public static final ValidationRule RULE_WARNING = new ValidationRule(
"XML_SCHEMA_WARNING",
"NeTEx XML Schema validation warning",
"%s",
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
package org.entur.netex.validation.configuration;

import static org.junit.jupiter.api.Assertions.*;

import java.util.List;
import org.entur.netex.validation.exception.NetexValidationException;
import org.entur.netex.validation.validator.Severity;
import org.junit.jupiter.api.Test;

class DefaultValidationConfigLoaderTest {

private static final String RULE_CODE = "RULE_1";
private static final String CONFIGURATION_FILE_NAME =
"configuration.test.yaml";
private static final String CONFIGURATION_FILE_NAME_OVERLOAD =
"configuration.test.overloaded.yaml";

@Test
void loadConfiguration() {
DefaultValidationConfigLoader loader = new DefaultValidationConfigLoader(
CONFIGURATION_FILE_NAME
);
ValidationRuleConfig validationRuleConfig = loader.getValidationRuleConfig(
RULE_CODE
);
assertNotNull(validationRuleConfig);
assertEquals(Severity.ERROR, validationRuleConfig.getSeverity());
}

@Test
void loadConfigurationNonExistingFile() {
assertThrows(
NetexValidationException.class,
() -> new DefaultValidationConfigLoader("missing.yaml")
);
}

@Test
void loadOverloadedConfiguration() {
DefaultValidationConfigLoader loader = new DefaultValidationConfigLoader(
List.of(CONFIGURATION_FILE_NAME, CONFIGURATION_FILE_NAME_OVERLOAD)
);
ValidationRuleConfig validationRuleConfig = loader.getValidationRuleConfig(
RULE_CODE
);
assertNotNull(validationRuleConfig);
assertEquals(Severity.WARNING, validationRuleConfig.getSeverity());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,152 @@

import static org.junit.jupiter.api.Assertions.*;

import java.nio.charset.StandardCharsets;
import java.util.List;
import java.util.Set;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.stream.Collectors;
import org.entur.netex.validation.validator.id.VersionOnLocalNetexIdValidator;
import org.entur.netex.validation.validator.schema.NetexSchemaValidationContext;
import org.entur.netex.validation.validator.schema.NetexSchemaValidator;
import org.entur.netex.validation.validator.xpath.XPathValidationContext;
import org.entur.netex.validation.xml.NetexXMLParser;
import org.junit.jupiter.api.Test;

class NetexValidatorsRunnerTest {

private static final String TEST_CODESPACE = "ENT";
private static final String TEST_FILENAME = "netex.xml";
private static final String TEST_VALIDATION_REPORT_ID =
"validation report id";

private static final String NETEX_FRAGMENT =
"""
<PublicationDelivery xmlns="http://www.netex.org.uk/netex" xmlns:ns2="http://www.opengis.net/gml/3.2" xmlns:ns3="http://www.siri.org.uk/siri" version="1.15:NO-NeTEx-networktimetable:1.5">
<dataObjects>
<ServiceFrame id="ENT:ServiceFrame:1" version="2223">
<lines>
<Line id="ENT:Line:2_1" version="2223">
</Line>
</lines>
</ServiceFrame>
</dataObjects>
</PublicationDelivery>
""";

@Test
void testNoValidator() {
NetexValidatorsRunner runner = NetexValidatorsRunner.of().build();
ValidationReport report = validationReport(runner);
assertTrue(report.getValidationReportEntries().isEmpty());
assertEquals(TEST_CODESPACE, report.getCodespace());
assertEquals(TEST_VALIDATION_REPORT_ID, report.getValidationReportId());
}

@Test
void testReportSchemaValidationError() {
NetexValidatorsRunner runner = NetexValidatorsRunner
.of()
.withNetexSchemaValidator(
new TestNetexSchemaValidator(
List.of(
new ValidationIssue(
NetexSchemaValidator.RULE_ERROR,
DataLocation.EMPTY_LOCATION,
"an error"
)
)
)
)
.build();
ValidationReport report = validationReport(runner);

assertEquals(1, report.getValidationReportEntries().size());
}

@Test
void testSkipXPathValidationOnSchemaError() {
NetexValidatorsRunner runner = NetexValidatorsRunner
.of()
.withNetexSchemaValidator(
new TestNetexSchemaValidator(
List.of(
new ValidationIssue(
NetexSchemaValidator.RULE_ERROR,
DataLocation.EMPTY_LOCATION,
"an error"
)
)
)
)
.withNetexXMLParser(new NetexXMLParser())
.withXPathValidators(
List.of(
new XPathValidator() {
@Override
public List<ValidationIssue> validate(
XPathValidationContext validationContext
) {
fail(
"XPath validator should be skipped when Netex schema validation fails"
);
return List.of();
}

@Override
public Set<ValidationRule> getRules() {
return Set.of();
}
}
)
)
.build();
ValidationReport report = validationReport(runner);

assertEquals(1, report.getValidationReportEntries().size());
}

@Test
void testRunXPathValidationIfNoSchemaError() {
AtomicBoolean xpathValidation = new AtomicBoolean();
NetexValidatorsRunner runner = NetexValidatorsRunner
.of()
.withNetexSchemaValidator(
new NetexSchemaValidator(0) {
@Override
public List<ValidationIssue> validate(
NetexSchemaValidationContext validationContext
) {
return List.of();
}
}
)
.withNetexXMLParser(new NetexXMLParser())
.withXPathValidators(
List.of(
new XPathValidator() {
@Override
public List<ValidationIssue> validate(
XPathValidationContext validationContext
) {
xpathValidation.set(true);
return List.of();
}

@Override
public Set<ValidationRule> getRules() {
return Set.of();
}
}
)
)
.build();
ValidationReport report = validationReport(runner);

assertEquals(0, report.getValidationReportEntries().size());
assertTrue(xpathValidation.get());
}

@Test
void testDescriptions() {
XPathValidator xPathValidator = new VersionOnLocalNetexIdValidator();
Expand All @@ -28,4 +165,32 @@ void testDescriptions() {
.collect(Collectors.toUnmodifiableSet());
assertEquals(xpathRuleDescriptions, ruleDescriptions);
}

private static ValidationReport validationReport(
NetexValidatorsRunner runner
) {
return runner.validate(
TEST_CODESPACE,
TEST_VALIDATION_REPORT_ID,
TEST_FILENAME,
NETEX_FRAGMENT.getBytes(StandardCharsets.UTF_8)
);
}

private static class TestNetexSchemaValidator extends NetexSchemaValidator {

private final List<ValidationIssue> issues;

public TestNetexSchemaValidator(List<ValidationIssue> issues) {
super(0);
this.issues = issues;
}

@Override
public List<ValidationIssue> validate(
NetexSchemaValidationContext validationContext
) {
return issues;
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
package org.entur.netex.validation.validator.schema;

import static org.junit.jupiter.api.Assertions.*;

import java.nio.charset.StandardCharsets;
import java.util.List;
import org.entur.netex.validation.validator.ValidationIssue;
import org.junit.jupiter.api.Test;

class NetexSchemaValidatorTest {

private static final int MAX_VALIDATION_REPORT_ENTRIES = 2;
private static final String TEST_CODESPACE = "ENT";
private static final String TEST_FILENAME = "netex.xml";

private static final String NETEX_FRAGMENT_VALID =
"""
<PublicationDelivery xmlns="http://www.netex.org.uk/netex" xmlns:ns2="http://www.opengis.net/gml/3.2" xmlns:ns3="http://www.siri.org.uk/siri" version="1.15:NO-NeTEx-networktimetable:1.5">
<PublicationTimestamp>2021-10-07T13:40:22.872</PublicationTimestamp>
<ParticipantRef>RB</ParticipantRef>
</PublicationDelivery>
""";

private static final String NETEX_FRAGMENT_INVALID =
"""
<PublicationDelivery xmlns="http://www.netex.org.uk/netex" xmlns:ns2="http://www.opengis.net/gml/3.2" xmlns:ns3="http://www.siri.org.uk/siri" version="1.15:NO-NeTEx-networktimetable:1.5">
<PublicationTimestamp>2021-10-07T13:40:22.872</PublicationTimestamp>
</PublicationDelivery>
""";

private static final String NETEX_FRAGMENT_INVALID_TOO_MANY_ERRORS =
"""
<PublicationDelivery xmlns="http://www.netex.org.uk/netex" xmlns:ns2="http://www.opengis.net/gml/3.2" xmlns:ns3="http://www.siri.org.uk/siri" version="1.15:NO-NeTEx-networktimetable:1.5">
<dataObjects>
<CompositeFrame created="2024-11-28T02:58:39.64" version="1" >
<validityConditions/>
</CompositeFrame>
</dataObjects>
</PublicationDelivery>
""";

@Test
void validateValidDocument() {
List<ValidationIssue> validationIssues = validate(NETEX_FRAGMENT_VALID);
assertTrue(validationIssues.isEmpty());
}

@Test
void validateInvalidDocument() {
List<ValidationIssue> validationIssues = validate(NETEX_FRAGMENT_INVALID);
assertEquals(1, validationIssues.size());
}

@Test
void validateInvalidDocumentTooManyErrors() {
List<ValidationIssue> validationIssues = validate(
NETEX_FRAGMENT_INVALID_TOO_MANY_ERRORS
);
assertEquals(MAX_VALIDATION_REPORT_ENTRIES, validationIssues.size());
}

@Test
void validateMalformedDocument() {
List<ValidationIssue> validationIssues = validate("x");
assertEquals(1, validationIssues.size());
}

private static List<ValidationIssue> validate(String netexFragment) {
NetexSchemaValidator validator = new NetexSchemaValidator(
MAX_VALIDATION_REPORT_ENTRIES
);
NetexSchemaValidationContext validationContext =
new NetexSchemaValidationContext(
TEST_FILENAME,
TEST_CODESPACE,
netexFragment.getBytes(StandardCharsets.UTF_8)
);
return validator.validate(validationContext);
}
}
9 changes: 9 additions & 0 deletions src/test/resources/configuration.test.overloaded.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
validationRuleConfigs:
- code: RULE_1
name: Rule 1
severity: WARNING





9 changes: 9 additions & 0 deletions src/test/resources/configuration.test.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
validationRuleConfigs:
- code: RULE_1
name: Rule 1
severity: ERROR





0 comments on commit 070fb30

Please sign in to comment.