diff --git a/main/src/main/java/org/mobilitydata/gtfsvalidator/validator/BookingRulesEntityValidator.java b/main/src/main/java/org/mobilitydata/gtfsvalidator/validator/BookingRulesEntityValidator.java index 0c7983b2c6..52cbd1a575 100644 --- a/main/src/main/java/org/mobilitydata/gtfsvalidator/validator/BookingRulesEntityValidator.java +++ b/main/src/main/java/org/mobilitydata/gtfsvalidator/validator/BookingRulesEntityValidator.java @@ -17,6 +17,12 @@ public class BookingRulesEntityValidator extends SingleEntityValidator forbiddenFields = findForbiddenSameDayFields(entity); + + // If there are any forbidden fields, add a validation notice + if (!forbiddenFields.isEmpty()) { + noticeContainer.addValidationNotice( + new ForbiddenSameDayBookingFieldValueNotice(entity, forbiddenFields)); + } + } + + private static List findForbiddenSameDayFields(GtfsBookingRules bookingRule) { + List fields = new ArrayList<>(); + + // Check each forbidden field and add its name to the list if it's present + if (bookingRule.hasPriorNoticeLastDay()) { + fields.add(GtfsBookingRules.PRIOR_NOTICE_LAST_DAY_FIELD_NAME); + } + if (bookingRule.hasPriorNoticeLastTime()) { + fields.add(GtfsBookingRules.PRIOR_NOTICE_LAST_TIME_FIELD_NAME); + } + if (bookingRule.hasPriorNoticeServiceId()) { + fields.add(GtfsBookingRules.PRIOR_NOTICE_SERVICE_ID_FIELD_NAME); + } + return fields; + } + /** Finds forbidden fields that should not be present for real-time booking rules. */ public static List findForbiddenRealTimeFields(GtfsBookingRules bookingRule) { List fields = new ArrayList<>(); - // Check each field and add its name to the list if it's present + // Check each forbidden field and add its name to the list if it's present if (bookingRule.hasPriorNoticeDurationMin()) { fields.add(GtfsBookingRules.PRIOR_NOTICE_DURATION_MIN_FIELD_NAME); } @@ -83,4 +122,26 @@ static class ForbiddenRealTimeBookingFieldValueNotice extends ValidationNotice { this.fieldNames = String.join(", ", forbiddenFields); } } + + /** A forbidden field value is present for a same-day booking rule in `booking_rules.txt`. */ + @GtfsValidationNotice( + severity = SeverityLevel.ERROR, + files = @FileRefs(GtfsBookingRulesSchema.class)) + static class ForbiddenSameDayBookingFieldValueNotice extends ValidationNotice { + /** The row number of the faulty record. */ + private final int csvRowNumber; + + /** The `booking_rules.booking_rule_id` of the faulty record. */ + private final String bookingRuleId; + + /** The names of the forbidden fields comma-separated. */ + private final String fieldNames; + + ForbiddenSameDayBookingFieldValueNotice( + GtfsBookingRules bookingRule, List forbiddenFields) { + this.csvRowNumber = bookingRule.csvRowNumber(); + this.bookingRuleId = bookingRule.bookingRuleId(); + this.fieldNames = String.join(", ", forbiddenFields); + } + } } diff --git a/main/src/test/java/org/mobilitydata/gtfsvalidator/validator/BookingRulesEntityValidatorTest.java b/main/src/test/java/org/mobilitydata/gtfsvalidator/validator/BookingRulesEntityValidatorTest.java index 98ba39b459..085d601d31 100644 --- a/main/src/test/java/org/mobilitydata/gtfsvalidator/validator/BookingRulesEntityValidatorTest.java +++ b/main/src/test/java/org/mobilitydata/gtfsvalidator/validator/BookingRulesEntityValidatorTest.java @@ -89,4 +89,33 @@ public void realTimeBookingWithMultipleForbiddenFieldsShouldGenerateNotice() { GtfsBookingRules.PRIOR_NOTICE_START_TIME_FIELD_NAME, GtfsBookingRules.PRIOR_NOTICE_SERVICE_ID_FIELD_NAME))); } + + @Test + public void sameDayBookingWithForbiddenFieldsShouldGenerateNotice() { + GtfsBookingRules bookingRule = + new GtfsBookingRules.Builder() + .setCsvRowNumber(1) + .setBookingRuleId("rule-5") + .setBookingType(GtfsBookingType.SAMEDAY) + .setPriorNoticeLastDay(2) // Forbidden field + .setPriorNoticeStartTime(GtfsTime.fromSecondsSinceMidnight(5000)) // Forbidden field + .build(); + + assertThat(generateNotices(bookingRule)) + .containsExactly( + new BookingRulesEntityValidator.ForbiddenSameDayBookingFieldValueNotice( + bookingRule, List.of(GtfsBookingRules.PRIOR_NOTICE_LAST_DAY_FIELD_NAME))); + } + + @Test + public void sameDayBookingWithoutForbiddenFieldsShouldNotGenerateNotice() { + GtfsBookingRules bookingRule = + new GtfsBookingRules.Builder() + .setCsvRowNumber(1) + .setBookingRuleId("rule-6") + .setBookingType(GtfsBookingType.SAMEDAY) + .build(); + + assertThat(generateNotices(bookingRule)).isEmpty(); + } }