-
Notifications
You must be signed in to change notification settings - Fork 100
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: flex -
forbidden_real_time_booking_field_value
validation not…
…ice (#1845)
- Loading branch information
Showing
3 changed files
with
181 additions
and
1 deletion.
There are no files selected for viewing
86 changes: 86 additions & 0 deletions
86
main/src/main/java/org/mobilitydata/gtfsvalidator/validator/BookingRulesEntityValidator.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,86 @@ | ||
package org.mobilitydata.gtfsvalidator.validator; | ||
|
||
import java.util.ArrayList; | ||
import java.util.List; | ||
import org.mobilitydata.gtfsvalidator.annotation.GtfsValidationNotice; | ||
import org.mobilitydata.gtfsvalidator.annotation.GtfsValidationNotice.FileRefs; | ||
import org.mobilitydata.gtfsvalidator.annotation.GtfsValidator; | ||
import org.mobilitydata.gtfsvalidator.notice.NoticeContainer; | ||
import org.mobilitydata.gtfsvalidator.notice.SeverityLevel; | ||
import org.mobilitydata.gtfsvalidator.notice.ValidationNotice; | ||
import org.mobilitydata.gtfsvalidator.table.GtfsBookingRules; | ||
import org.mobilitydata.gtfsvalidator.table.GtfsBookingRulesSchema; | ||
import org.mobilitydata.gtfsvalidator.table.GtfsBookingType; | ||
|
||
@GtfsValidator | ||
public class BookingRulesEntityValidator extends SingleEntityValidator<GtfsBookingRules> { | ||
|
||
@Override | ||
public void validate(GtfsBookingRules entity, NoticeContainer noticeContainer) { | ||
// Only validate entities with REALTIME booking type | ||
if (entity.bookingType() != GtfsBookingType.REALTIME) { | ||
return; | ||
} | ||
|
||
// Retrieve the list of forbidden fields | ||
List<String> forbiddenFields = findForbiddenRealTimeFields(entity); | ||
|
||
// If there are any forbidden fields, add a validation notice | ||
if (!forbiddenFields.isEmpty()) { | ||
noticeContainer.addValidationNotice( | ||
new ForbiddenRealTimeBookingFieldValueNotice(entity, forbiddenFields)); | ||
} | ||
} | ||
|
||
/** Finds forbidden fields that should not be present for real-time booking rules. */ | ||
public static List<String> findForbiddenRealTimeFields(GtfsBookingRules bookingRule) { | ||
List<String> fields = new ArrayList<>(); | ||
|
||
// Check each field and add its name to the list if it's present | ||
if (bookingRule.hasPriorNoticeDurationMin()) { | ||
fields.add(GtfsBookingRules.PRIOR_NOTICE_DURATION_MIN_FIELD_NAME); | ||
} | ||
if (bookingRule.hasPriorNoticeDurationMax()) { | ||
fields.add(GtfsBookingRules.PRIOR_NOTICE_DURATION_MAX_FIELD_NAME); | ||
} | ||
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.hasPriorNoticeStartDay()) { | ||
fields.add(GtfsBookingRules.PRIOR_NOTICE_START_DAY_FIELD_NAME); | ||
} | ||
if (bookingRule.hasPriorNoticeStartTime()) { | ||
fields.add(GtfsBookingRules.PRIOR_NOTICE_START_TIME_FIELD_NAME); | ||
} | ||
if (bookingRule.hasPriorNoticeServiceId()) { | ||
fields.add(GtfsBookingRules.PRIOR_NOTICE_SERVICE_ID_FIELD_NAME); | ||
} | ||
|
||
return fields; | ||
} | ||
|
||
/** A forbidden field value is present for a real-time booking rule in `booking_rules.txt`. */ | ||
@GtfsValidationNotice( | ||
severity = SeverityLevel.ERROR, | ||
files = @FileRefs(GtfsBookingRulesSchema.class)) | ||
static class ForbiddenRealTimeBookingFieldValueNotice 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; | ||
|
||
ForbiddenRealTimeBookingFieldValueNotice( | ||
GtfsBookingRules bookingRule, List<String> forbiddenFields) { | ||
this.csvRowNumber = bookingRule.csvRowNumber(); | ||
this.bookingRuleId = bookingRule.bookingRuleId(); | ||
this.fieldNames = String.join(", ", forbiddenFields); | ||
} | ||
} | ||
} |
92 changes: 92 additions & 0 deletions
92
...c/test/java/org/mobilitydata/gtfsvalidator/validator/BookingRulesEntityValidatorTest.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,92 @@ | ||
package org.mobilitydata.gtfsvalidator.validator; | ||
|
||
import static com.google.common.truth.Truth.assertThat; | ||
import static org.mobilitydata.gtfsvalidator.table.GtfsBookingType.REALTIME; | ||
|
||
import java.util.List; | ||
import org.junit.Test; | ||
import org.junit.runner.RunWith; | ||
import org.junit.runners.JUnit4; | ||
import org.mobilitydata.gtfsvalidator.notice.NoticeContainer; | ||
import org.mobilitydata.gtfsvalidator.notice.ValidationNotice; | ||
import org.mobilitydata.gtfsvalidator.table.GtfsBookingRules; | ||
import org.mobilitydata.gtfsvalidator.table.GtfsBookingType; | ||
import org.mobilitydata.gtfsvalidator.type.GtfsTime; | ||
import org.mobilitydata.gtfsvalidator.validator.BookingRulesEntityValidator.ForbiddenRealTimeBookingFieldValueNotice; | ||
|
||
@RunWith(JUnit4.class) | ||
public class BookingRulesEntityValidatorTest { | ||
|
||
private static List<ValidationNotice> generateNotices(GtfsBookingRules bookingRule) { | ||
NoticeContainer noticeContainer = new NoticeContainer(); | ||
BookingRulesEntityValidator validator = new BookingRulesEntityValidator(); | ||
validator.validate(bookingRule, noticeContainer); | ||
return noticeContainer.getValidationNotices(); | ||
} | ||
|
||
@Test | ||
public void realTimeBookingWithForbiddenFieldsShouldGenerateNotice() { | ||
GtfsBookingRules bookingRule = | ||
new GtfsBookingRules.Builder() | ||
.setCsvRowNumber(1) | ||
.setBookingRuleId("rule-1") | ||
.setBookingType(REALTIME) | ||
.setPriorNoticeDurationMin(30) // Forbidden field | ||
.setPriorNoticeLastDay(2) // Forbidden field | ||
.build(); | ||
|
||
assertThat(generateNotices(bookingRule)) | ||
.containsExactly( | ||
new ForbiddenRealTimeBookingFieldValueNotice( | ||
bookingRule, | ||
List.of( | ||
GtfsBookingRules.PRIOR_NOTICE_DURATION_MIN_FIELD_NAME, | ||
GtfsBookingRules.PRIOR_NOTICE_LAST_DAY_FIELD_NAME))); | ||
} | ||
|
||
@Test | ||
public void realTimeBookingWithoutForbiddenFieldsShouldNotGenerateNotice() { | ||
GtfsBookingRules bookingRule = | ||
new GtfsBookingRules.Builder() | ||
.setCsvRowNumber(1) | ||
.setBookingRuleId("rule-2") | ||
.setBookingType(REALTIME) | ||
.build(); | ||
|
||
assertThat(generateNotices(bookingRule)).isEmpty(); | ||
} | ||
|
||
@Test | ||
public void scheduledBookingShouldNotGenerateNotice() { | ||
GtfsBookingRules bookingRule = | ||
new GtfsBookingRules.Builder() | ||
.setCsvRowNumber(1) | ||
.setBookingRuleId("rule-3") | ||
.setBookingType(GtfsBookingType.SAMEDAY) | ||
.build(); | ||
|
||
assertThat(generateNotices(bookingRule)).isEmpty(); | ||
} | ||
|
||
@Test | ||
public void realTimeBookingWithMultipleForbiddenFieldsShouldGenerateNotice() { | ||
GtfsBookingRules bookingRule = | ||
new GtfsBookingRules.Builder() | ||
.setCsvRowNumber(1) | ||
.setBookingRuleId("rule-4") | ||
.setBookingType(REALTIME) | ||
.setPriorNoticeDurationMax(60) // Forbidden field | ||
.setPriorNoticeStartTime(GtfsTime.fromSecondsSinceMidnight(2)) // Forbidden field | ||
.setPriorNoticeServiceId("service-1") // Forbidden field | ||
.build(); | ||
|
||
assertThat(generateNotices(bookingRule)) | ||
.containsExactly( | ||
new ForbiddenRealTimeBookingFieldValueNotice( | ||
bookingRule, | ||
List.of( | ||
GtfsBookingRules.PRIOR_NOTICE_DURATION_MAX_FIELD_NAME, | ||
GtfsBookingRules.PRIOR_NOTICE_START_TIME_FIELD_NAME, | ||
GtfsBookingRules.PRIOR_NOTICE_SERVICE_ID_FIELD_NAME))); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters