diff --git a/application/src/main/java/org/opentripplanner/apis/transmodel/mapping/BookingInfoMapper.java b/application/src/main/java/org/opentripplanner/apis/transmodel/mapping/BookingInfoMapper.java new file mode 100644 index 00000000000..de59794ea18 --- /dev/null +++ b/application/src/main/java/org/opentripplanner/apis/transmodel/mapping/BookingInfoMapper.java @@ -0,0 +1,38 @@ +package org.opentripplanner.apis.transmodel.mapping; + +import org.opentripplanner.transit.model.timetable.booking.BookingInfo; +import org.opentripplanner.transit.model.timetable.booking.BookingTime; + +/** + * Maps the {@link BookingInfo} to enum value (as a string) returned by the API. + */ +public class BookingInfoMapper { + + public static String mapToBookWhen(BookingInfo bookingInfo) { + if (bookingInfo.getMinimumBookingNotice().isPresent()) { + return null; + } + BookingTime latestBookingTime = bookingInfo.getLatestBookingTime(); + BookingTime earliestBookingTime = bookingInfo.getEarliestBookingTime(); + + // Try to deduce the original enum from stored values + if (earliestBookingTime == null) { + if (latestBookingTime == null) { + return "timeOfTravelOnly"; + } else if (latestBookingTime.getDaysPrior() == 1) { + return "untilPreviousDay"; + } else if (latestBookingTime.getDaysPrior() == 0) { + return "advanceAndDayOfTravel"; + } else { + return "other"; + } + } else if ( + earliestBookingTime.getDaysPrior() == 0 && + (latestBookingTime == null || latestBookingTime.getDaysPrior() == 0) + ) { + return "dayOfTravelOnly"; + } else { + return "other"; + } + } +} diff --git a/application/src/main/java/org/opentripplanner/apis/transmodel/model/timetable/BookingArrangementType.java b/application/src/main/java/org/opentripplanner/apis/transmodel/model/timetable/BookingArrangementType.java index 911ec8d9b0c..097fa92baca 100644 --- a/application/src/main/java/org/opentripplanner/apis/transmodel/model/timetable/BookingArrangementType.java +++ b/application/src/main/java/org/opentripplanner/apis/transmodel/model/timetable/BookingArrangementType.java @@ -6,6 +6,7 @@ import graphql.schema.GraphQLList; import graphql.schema.GraphQLObjectType; import graphql.schema.GraphQLOutputType; +import org.opentripplanner.apis.transmodel.mapping.BookingInfoMapper; import org.opentripplanner.apis.transmodel.model.EnumTypes; import org.opentripplanner.apis.transmodel.model.framework.TransmodelScalars; import org.opentripplanner.transit.model.organization.ContactInfo; @@ -107,34 +108,7 @@ public static GraphQLObjectType create() { .name("bookWhen") .description("Time constraints for booking") .type(EnumTypes.PURCHASE_WHEN) - .dataFetcher(environment -> { - BookingInfo bookingInfo = bookingInfo(environment); - if (bookingInfo.getMinimumBookingNotice().isPresent()) { - return null; - } - BookingTime latestBookingTime = bookingInfo.getLatestBookingTime(); - BookingTime earliestBookingTime = bookingInfo.getEarliestBookingTime(); - - // Try to deduce the original enum from stored values - if (earliestBookingTime == null) { - if (latestBookingTime == null) { - return "timeOfTravelOnly"; - } else if (latestBookingTime.getDaysPrior() == 1) { - return "untilPreviousDay"; - } else if (latestBookingTime.getDaysPrior() == 0) { - return "advanceAndDayOfTravel"; - } else { - return "other"; - } - } else if ( - earliestBookingTime.getDaysPrior() == 0 && - (latestBookingTime == null || latestBookingTime.getDaysPrior() == 0) - ) { - return "dayOfTravelOnly"; - } else { - return "other"; - } - }) + .dataFetcher(environment -> BookingInfoMapper.mapToBookWhen(bookingInfo(environment))) .build() ) .field( diff --git a/application/src/test/java/org/opentripplanner/apis/transmodel/mapping/BookingInfoMapperTest.java b/application/src/test/java/org/opentripplanner/apis/transmodel/mapping/BookingInfoMapperTest.java new file mode 100644 index 00000000000..f78f24d63b5 --- /dev/null +++ b/application/src/test/java/org/opentripplanner/apis/transmodel/mapping/BookingInfoMapperTest.java @@ -0,0 +1,83 @@ +package org.opentripplanner.apis.transmodel.mapping; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.opentripplanner.apis.transmodel.mapping.BookingInfoMapper.mapToBookWhen; + +import java.time.Duration; +import java.time.LocalTime; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.ValueSource; +import org.opentripplanner.transit.model.timetable.booking.BookingInfo; +import org.opentripplanner.transit.model.timetable.booking.BookingTime; + +class BookingInfoMapperTest { + + private static final Duration TEN_MINUTES = Duration.ofMinutes(10); + private static final BookingTime BOOKING_TIME_ZERO_DAYS_PRIOR = new BookingTime( + LocalTime.of(10, 0), + 0 + ); + + @Test + void bookingNotice() { + assertNull(mapToBookWhen(BookingInfo.of().withMinimumBookingNotice(TEN_MINUTES).build())); + } + + @Test + void timeOfTravelOnly() { + assertEquals("timeOfTravelOnly", mapToBookWhen(BookingInfo.of().build())); + } + + @Test + void untilPreviousDay() { + var info = daysPrior(1); + assertEquals("untilPreviousDay", mapToBookWhen(info)); + } + + @Test + void advanceAndDayOfTravel() { + var info = daysPrior(0); + assertEquals("advanceAndDayOfTravel", mapToBookWhen(info)); + } + + @ParameterizedTest + @ValueSource(ints = { 2, 3, 4, 14, 28 }) + void other(int days) { + var info = daysPrior(days); + assertEquals("other", mapToBookWhen(info)); + } + + @Test + void dayOfTravelOnly() { + var info = BookingInfo.of().withEarliestBookingTime(BOOKING_TIME_ZERO_DAYS_PRIOR).build(); + assertEquals("dayOfTravelOnly", mapToBookWhen(info)); + } + + @Test + void foo() { + var info = BookingInfo + .of() + .withEarliestBookingTime(BOOKING_TIME_ZERO_DAYS_PRIOR) + .withLatestBookingTime(BOOKING_TIME_ZERO_DAYS_PRIOR) + .build(); + assertEquals("dayOfTravelOnly", mapToBookWhen(info)); + } + + @Test + void earliestBookingTimeZero() { + var info = BookingInfo + .of() + .withEarliestBookingTime(new BookingTime(LocalTime.of(10, 0), 10)) + .build(); + assertEquals("other", mapToBookWhen(info)); + } + + private static BookingInfo daysPrior(int daysPrior) { + return BookingInfo + .of() + .withLatestBookingTime(new BookingTime(LocalTime.of(10, 0), daysPrior)) + .build(); + } +}