Skip to content

Commit c969c9d

Browse files
committed
Merge branch 'issue-6475-quick-fix' into dev-2.x
2 parents 23db69c + fd6c9bb commit c969c9d

File tree

6 files changed

+65
-12
lines changed

6 files changed

+65
-12
lines changed

application/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/StoptimeImpl.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,10 @@ public DataFetcher<Integer> stopPositionInPattern() {
8585

8686
@Override
8787
public DataFetcher<Long> serviceDay() {
88-
return environment -> getSource(environment).getServiceDayMidnight();
88+
return environment -> {
89+
Long midnight = getSource(environment).getServiceDayMidnight();
90+
return midnight != TripTimeOnDate.UNDEFINED ? midnight : null;
91+
};
8992
}
9093

9194
@Override

application/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/TripImpl.java

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -252,6 +252,12 @@ public DataFetcher<Iterable<TripTimeOnDate>> stoptimes() {
252252
getTransitService(environment).getScheduledTripTimes(getSource(environment)).orElse(null);
253253
}
254254

255+
/**
256+
* If stoptimesForDate does not have a parameter, and the trip does not run today, we will
257+
* still return a list of TripTimeOnDates, the same list as bare stoptimes() would return.
258+
* This is illogical, but existing UIs depend on this longstanding behavior.
259+
* @return
260+
*/
255261
@Override
256262
public DataFetcher<Iterable<TripTimeOnDate>> stoptimesForDate() {
257263
return environment -> {
@@ -260,11 +266,12 @@ public DataFetcher<Iterable<TripTimeOnDate>> stoptimesForDate() {
260266
var args = new GraphQLTypes.GraphQLTripStoptimesForDateArgs(environment.getArguments());
261267

262268
ZoneId timeZone = transitService.getTimeZone();
263-
LocalDate serviceDate = args.getGraphQLServiceDate() != null
264-
? ServiceDateUtils.parseString(args.getGraphQLServiceDate())
265-
: LocalDate.now(timeZone);
266-
267-
return transitService.getTripTimeOnDates(trip, serviceDate).orElse(null);
269+
if (args.getGraphQLServiceDate() != null) {
270+
LocalDate serviceDate = ServiceDateUtils.parseString(args.getGraphQLServiceDate());
271+
return transitService.getTripTimeOnDates(trip, serviceDate).orElse(null);
272+
} else {
273+
return transitService.getTripTimeOnDates(trip, LocalDate.now(timeZone), true).orElse(null);
274+
}
268275
};
269276
}
270277

application/src/main/java/org/opentripplanner/transit/service/DefaultTransitService.java

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -121,18 +121,28 @@ public Optional<List<TripTimeOnDate>> getScheduledTripTimes(Trip trip) {
121121
}
122122

123123
@Override
124-
public Optional<List<TripTimeOnDate>> getTripTimeOnDates(Trip trip, LocalDate serviceDate) {
124+
public Optional<List<TripTimeOnDate>> getTripTimeOnDates(
125+
Trip trip,
126+
LocalDate serviceDate,
127+
boolean fallbackToPlannedTimetableOnNoServiceDate
128+
) {
125129
TripPattern pattern = findPattern(trip, serviceDate);
126130

127131
Timetable timetable = findTimetable(pattern, serviceDate);
128132

129133
// This check is made here to avoid changing TripTimeOnDate.fromTripTimes
130134
TripTimes times = timetable.getTripTimes(trip);
131-
if (
132-
times == null ||
133-
!this.getServiceCodesRunningForDate(serviceDate).contains(times.getServiceCode())
134-
) {
135+
if (times == null) {
135136
return Optional.empty();
137+
} else if (!this.getServiceCodesRunningForDate(serviceDate).contains(times.getServiceCode())) {
138+
if (fallbackToPlannedTimetableOnNoServiceDate) {
139+
// Technically not returning empty here is incorrect, you should use getScheduledTripTimes
140+
// above instead if you want this, but it has been the behavior for a very long time, and
141+
// at least one longstanding front end will fail without this.
142+
return Optional.ofNullable(TripTimeOnDate.fromTripTimes(timetable, trip));
143+
} else {
144+
return Optional.empty();
145+
}
136146
} else {
137147
Instant midnight = ServiceDateUtils.asStartOfService(
138148
serviceDate,
@@ -142,6 +152,11 @@ public Optional<List<TripTimeOnDate>> getTripTimeOnDates(Trip trip, LocalDate se
142152
}
143153
}
144154

155+
@Override
156+
public Optional<List<TripTimeOnDate>> getTripTimeOnDates(Trip trip, LocalDate serviceDate) {
157+
return getTripTimeOnDates(trip, serviceDate, false);
158+
}
159+
145160
@Override
146161
public Collection<String> listFeedIds() {
147162
return this.timetableRepository.getFeedIds();

application/src/main/java/org/opentripplanner/transit/service/TransitService.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,17 @@ public interface TransitService {
7272
*/
7373
Optional<List<TripTimeOnDate>> getScheduledTripTimes(Trip trip);
7474

75+
/**
76+
* @return if the trip doesn't run on the specified service date, return scheduled trip times,
77+
* unmodified by any realtime data, if fallbackToPlannedTimetableOnNoServiceDate is true, empty
78+
* otherwise. Logically this is confusing, but existing API users depend on this.
79+
*/
80+
Optional<List<TripTimeOnDate>> getTripTimeOnDates(
81+
Trip trip,
82+
LocalDate serviceDate,
83+
boolean fallbackToPlannedTimetableOnNoServiceDate
84+
);
85+
7586
/**
7687
* @return empty if the trip doesn't run on the date specified
7788
*/

application/src/main/resources/org/opentripplanner/apis/gtfs/schema.graphqls

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2495,7 +2495,11 @@ type Trip implements Node {
24952495
"List of times when this trip arrives to or departs from a stop"
24962496
stoptimes: [Stoptime]
24972497
stoptimesForDate(
2498-
"Date for which stoptimes are returned. Format: YYYYMMDD"
2498+
"""
2499+
Date for which stoptimes are returned. Format: YYYYMMDD
2500+
If `serviceDate` is not specified and the trip is not running today, the result is exactly the same
2501+
as for `stoptimes`, i.e. the scheduled stop times are returned.
2502+
"""
24992503
serviceDate: String
25002504
): [Stoptime]
25012505
"Coordinates of the route of this trip in Google polyline encoded format"

application/src/test/java/org/opentripplanner/transit/service/DefaultTransitServiceTest.java

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -241,6 +241,19 @@ void getRealtimeTripTimes() {
241241
);
242242
}
243243

244+
@Test
245+
void getTripTimeOnDateWithNoServiceAndFallbackToPlannedTimetable() {
246+
assertEquals(
247+
Optional.of(
248+
List.of(
249+
new TripTimeOnDate(SCHEDULED_TRIP_TIMES, 0, RAIL_PATTERN),
250+
new TripTimeOnDate(SCHEDULED_TRIP_TIMES, 1, RAIL_PATTERN)
251+
)
252+
),
253+
service.getTripTimeOnDates(TRIP, NO_SERVICE_DATE, true)
254+
);
255+
}
256+
244257
@Test
245258
void getTripTimesOnNoServiceDay() {
246259
assertEquals(Optional.empty(), service.getTripTimeOnDates(TRIP, NO_SERVICE_DATE));

0 commit comments

Comments
 (0)