diff --git a/src/main/java/pl/agh/transit/DirectConnectionService.java b/src/main/java/pl/agh/transit/DirectConnectionService.java index e616f5f..122c4ed 100644 --- a/src/main/java/pl/agh/transit/DirectConnectionService.java +++ b/src/main/java/pl/agh/transit/DirectConnectionService.java @@ -8,9 +8,6 @@ import pl.agh.transit.dto.TripUpdateDTO; import pl.agh.transit.gtfs_static.model.Stop; import pl.agh.transit.gtfs_static.model.StopTime; -import pl.agh.transit.gtfs_static.repository.RouteRepository; -import pl.agh.transit.gtfs_static.repository.StaticTripRepository; -import pl.agh.transit.gtfs_static.repository.StopRepository; import pl.agh.transit.gtfs_static.repository.StopTimeRepository; import java.time.LocalDate; @@ -18,6 +15,7 @@ import java.time.LocalTime; import java.util.Comparator; import java.util.List; +import java.util.Objects; import java.util.Optional; import java.util.stream.Stream; @@ -25,12 +23,8 @@ @Service @AllArgsConstructor public class DirectConnectionService { - private final StopRepository stopRepository; private final StopTimeRepository stopTimeRepository; - private final RouteRepository routeRepository; - private final StaticTripRepository staticTripRepository; private final TripRepository tripRepository; - private final CalendarService calendarService; private final TripMapper tripMapper; private final ConnectionServiceHelper connectionServiceHelper; @@ -40,8 +34,8 @@ public class DirectConnectionService { * Returns up to 'count' number of connections, sorted by departure time * Uses today's date and current time by default */ - public List findFastestDirectConnection(String fromStopName, String toStopName) { - return findFastestDirectConnection(fromStopName, toStopName, LocalDate.now(), LocalTime.now(), 1); + public List findFastestDirectConnections(String fromStopName, String toStopName, int count) { + return findFastestDirectConnections(fromStopName, toStopName, LocalDate.now(), LocalTime.now(), count); } /** @@ -49,7 +43,7 @@ public List findFastestDirectConnection(String fromStopName, S * Returns up to 'count' number of connections, sorted by departure time * Takes into account delays from GTFS Realtime and service calendar */ - public List findFastestDirectConnection(String fromStopName, String toStopName, LocalDate travelDate, LocalTime travelTime, int count) { + public List findFastestDirectConnections(String fromStopName, String toStopName, LocalDate travelDate, LocalTime travelTime, int count) { log.debug("[1] findFastestDirectConnections START: {} -> {} on {} at {} (count: {})", fromStopName, toStopName, travelDate, travelTime, count); List fromStops = connectionServiceHelper.getStopsForName(fromStopName); @@ -200,7 +194,7 @@ private List findStaticConnection(String fromStopId, List findStaticDestinationStop(fromStopTime, toStopCandidates, fromStopId)) .map(toStopTime -> buildStaticTransportDTO(toStopTime, fromStopId, travelDate)) - .filter(transport -> transport != null) + .filter(Objects::nonNull) .sorted(Comparator.comparing(TransportTypeDTO::getDepartureTime)) .toList(); } diff --git a/src/main/java/pl/agh/transit/StopController.java b/src/main/java/pl/agh/transit/StopController.java index 230f1c2..3dc9aee 100644 --- a/src/main/java/pl/agh/transit/StopController.java +++ b/src/main/java/pl/agh/transit/StopController.java @@ -5,7 +5,6 @@ import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; import pl.agh.transit.dto.PagedResponseDTO; @@ -42,10 +41,10 @@ public ResponseEntity> getNextDepartures( @RequestParam String routeName, @RequestParam(required = false) @DateTimeFormat(iso = DateTimeFormat.ISO.DATE) LocalDate date ) { + //TODO: consider adding time parameter in the future and handling it in the service layer LocalDate travelDate = date != null ? date : LocalDate.now(); List departures = stopService.getNextDeparturesForStopAndRoute( stopName, routeName, travelDate, 5); return ResponseEntity.ok(departures); } - } diff --git a/src/main/java/pl/agh/transit/TripController.java b/src/main/java/pl/agh/transit/TripController.java index fb9bd97..fb0bc51 100644 --- a/src/main/java/pl/agh/transit/TripController.java +++ b/src/main/java/pl/agh/transit/TripController.java @@ -12,7 +12,6 @@ import java.time.LocalDate; import java.time.LocalTime; import java.util.List; -import java.util.Optional; @RestController @AllArgsConstructor @@ -26,7 +25,7 @@ public List getTrips() { return tripService.getTripUpdates(); } - @GetMapping(value = "/trips/random-stop-time", produces = MediaType.APPLICATION_JSON_VALUE) + @GetMapping(value = "/random-stop-time", produces = MediaType.APPLICATION_JSON_VALUE) public StopTimeUpdateDTO getRandomStopTime() { return tripService.getRandomStopTime(); } @@ -36,17 +35,18 @@ public TransportTypeDTO getDirectConnection(@RequestParam String from, @RequestP return tripService.getDirectConnection(from, to); } - - @GetMapping(value = "/fastest-direct-connection/with-date", produces = MediaType.APPLICATION_JSON_VALUE) - public List getDirectConnectionsWithDate( + @GetMapping(value = "/fastest-direct-connections", produces = MediaType.APPLICATION_JSON_VALUE) + public List getFastestConnections( @RequestParam String from, @RequestParam String to, - @RequestParam String travelDate, - @RequestParam String travelTime, + @RequestParam(required = false) LocalDate travelDate, // (YYYY-MM-DD) + @RequestParam(required = false) LocalTime travelTime, // (HH:mm) @RequestParam(defaultValue = "3") int count ) { - LocalDate date = LocalDate.parse(travelDate); - LocalTime time = LocalTime.parse(travelTime); - return directConnectionService.findFastestDirectConnection(from, to, date, time, count); + if (travelDate != null && travelTime != null) { + return directConnectionService.findFastestDirectConnections(from, to, travelDate, travelTime, count); + } else { + return directConnectionService.findFastestDirectConnections(from, to, count); + } } } \ No newline at end of file diff --git a/src/main/java/pl/agh/transit/TripService.java b/src/main/java/pl/agh/transit/TripService.java index 22605bc..2778912 100644 --- a/src/main/java/pl/agh/transit/TripService.java +++ b/src/main/java/pl/agh/transit/TripService.java @@ -39,20 +39,19 @@ public StopTimeUpdateDTO getRandomStopTime(){ .orElseThrow(() -> new ServiceUnavailableException("No stop time updates available")); } - private Optional pickRandom(List list){ - if (list.isEmpty()){ - return Optional.empty(); - } - int randomIndex = random.nextInt(list.size()); - return Optional.of(list.get(randomIndex)); - } - public TransportTypeDTO getDirectConnection(String from , String to){ - List connection = directConnectionService.findFastestDirectConnection(from, to); + List connection = directConnectionService.findFastestDirectConnections(from, to, 1); if (connection.isEmpty()) { throw new ServiceUnavailableException("No connection available from " + from + " to " + to); } return connection.getFirst(); } + private Optional pickRandom(List list){ + if (list.isEmpty()){ + return Optional.empty(); + } + int randomIndex = random.nextInt(list.size()); + return Optional.of(list.get(randomIndex)); + } } diff --git a/src/test/java/pl/agh/transit/DirectConnectionServiceIntegrationTest.java b/src/test/java/pl/agh/transit/DirectConnectionServiceIntegrationTest.java index 0f5c73c..40c281b 100644 --- a/src/test/java/pl/agh/transit/DirectConnectionServiceIntegrationTest.java +++ b/src/test/java/pl/agh/transit/DirectConnectionServiceIntegrationTest.java @@ -24,8 +24,6 @@ import pl.agh.transit.gtfs_static.repository.StopRepository; import pl.agh.transit.gtfs_static.repository.StopTimeRepository; -import java.time.LocalDate; - @SpringBootTest @Transactional @DisplayName("DirectConnectionService Integration Tests") @@ -154,7 +152,7 @@ private void setupTestData() { @DisplayName("Should find fastest direct connection from static data") void findFastestDirectConnection_staticData_returnsFastestRoute() { List result = directConnectionService - .findFastestDirectConnection("Main Station", "City Center", LocalDate.now(), LocalTime.now(), 1); + .findFastestDirectConnections("Main Station", "City Center", LocalDate.now(), LocalTime.now(), 1); assertThat(result).hasSize(1); assertThat(result.get(0).getRouteName()).isEqualTo("1A"); @@ -162,58 +160,58 @@ void findFastestDirectConnection_staticData_returnsFastestRoute() { @Test @DisplayName("Should return empty when no direct connection exists") - void findFastestDirectConnection_noDirectConnection_returnsEmpty() { + void findFastestDirectConnection_noDirectConnections_returnsEmpty() { List result = directConnectionService - .findFastestDirectConnection("Main Station", "Final Stop", LocalDate.now(), LocalTime.now(), 1); + .findFastestDirectConnections("Main Station", "Final Stop", LocalDate.now(), LocalTime.now(), 1); assertThat(result).isEmpty(); } @Test @DisplayName("Should return empty when source stop does not exist") - void findFastestDirectConnection_sourceStopNotFound_returnsEmpty() { + void findFastestDirectConnections_sourceStopNotFound_returnsEmpty() { List result = directConnectionService - .findFastestDirectConnection("Unknown Station", "City Center", LocalDate.now(), LocalTime.now(), 1); + .findFastestDirectConnections("Unknown Station", "City Center", LocalDate.now(), LocalTime.now(), 1); assertThat(result).isEmpty(); } @Test @DisplayName("Should return empty when destination stop does not exist") - void findFastestDirectConnection_destinationStopNotFound_returnsEmpty() { + void findFastestDirectConnections_destinationStopNotFound_returnsEmpty() { List result = directConnectionService - .findFastestDirectConnection("Main Station", "Unknown Station", LocalDate.now(), LocalTime.now(), 1); + .findFastestDirectConnections("Main Station", "Unknown Station", LocalDate.now(), LocalTime.now(), 1); assertThat(result).isEmpty(); } @Test @DisplayName("Should return empty when both stops are the same") - void findFastestDirectConnection_sameSourceAndDestination_returnsEmpty() { + void findFastestDirectConnections_sameSourceAndDestination_returnsEmpty() { List result = directConnectionService - .findFastestDirectConnection("Main Station", "Main Station", LocalDate.now(), LocalTime.now(), 1); + .findFastestDirectConnections("Main Station", "Main Station", LocalDate.now(), LocalTime.now(), 1); assertThat(result).isEmpty(); } @Test @DisplayName("Should return empty when travel date is outside calendar range") - void findFastestDirectConnection_travelDateOutsideCalendar_returnsEmpty() { + void findFastestDirectConnections_travelDateOutsideCalendar_returnsEmpty() { LocalDate futureDate = LocalDate.now().plusYears(1); List result = directConnectionService - .findFastestDirectConnection("Main Station", "City Center", futureDate, LocalTime.now(), 1); + .findFastestDirectConnections("Main Station", "City Center", futureDate, LocalTime.now(), 1); assertThat(result).isEmpty(); } @Test @DisplayName("Should find connection when travel date is within calendar range") - void findFastestDirectConnection_validTravelDate_returnsConnection() { + void findFastestDirectConnection_validTravelDate_returnsConnections() { LocalDate validDate = LocalDate.now(); List result = directConnectionService - .findFastestDirectConnection("Main Station", "City Center", validDate, LocalTime.now(), 1); + .findFastestDirectConnections("Main Station", "City Center", validDate, LocalTime.now(), 1); assertThat(result).hasSize(1); assertThat(result.get(0).getRouteName()).isEqualTo("1A"); @@ -221,13 +219,13 @@ void findFastestDirectConnection_validTravelDate_returnsConnection() { @Test @DisplayName("Should compare departure times and return earliest departure route") - void findFastestDirectConnection_comparesDepartureTimes_returnsEarliestDepartureRoute() { + void findFastestDirectConnections_comparesDepartureTimes_returnsEarliestDepartureRoute() { // Trip 1: Departure 23:01:00, Arrival 23:20:00 // Trip 2: Departure 23:06:00, Arrival 23:10:00 // Should select trip 1 because it departs earliest List result = directConnectionService - .findFastestDirectConnection("Main Station", "City Center", LocalDate.now(), LocalTime.now(), 1); + .findFastestDirectConnections("Main Station", "City Center", LocalDate.now(), LocalTime.now(), 1); assertThat(result).hasSize(1); assertThat(result.get(0).getRouteName()).isEqualTo("1A"); @@ -235,7 +233,7 @@ void findFastestDirectConnection_comparesDepartureTimes_returnsEarliestDeparture @Test @DisplayName("Should ignore trips not active on given date") - void findFastestDirectConnection_inactiveServicesIgnored_returnsActiveRoute() { + void findFastestDirectConnections_inactiveServicesIgnored_returnsActiveRoute() { // Create inactive calendar for today Calendar inactiveCalendar = new Calendar(); inactiveCalendar.setId("service-inactive"); @@ -280,7 +278,7 @@ void findFastestDirectConnection_inactiveServicesIgnored_returnsActiveRoute() { stopTimeRepository.save(stopTime3To); List result = directConnectionService - .findFastestDirectConnection("Main Station", "City Center", LocalDate.now(), LocalTime.now(), 1); + .findFastestDirectConnections("Main Station", "City Center", LocalDate.now(), LocalTime.now(), 1); // Should select route 1A (active, earliest departure), not 3C (inactive) assertThat(result).hasSize(1); @@ -289,7 +287,7 @@ void findFastestDirectConnection_inactiveServicesIgnored_returnsActiveRoute() { @Test @DisplayName("Should handle multiple stops with same name") - void findFastestDirectConnection_multipleStopsSameName_handlesCorrectly() { + void findFastestDirectConnections_multipleStopsSameName_handlesCorrectly() { // Create second stop with same name Stop duplicateStop = new Stop(); duplicateStop.setId("stop-main-2"); @@ -299,7 +297,7 @@ void findFastestDirectConnection_multipleStopsSameName_handlesCorrectly() { stopRepository.save(duplicateStop); List result = directConnectionService - .findFastestDirectConnection("Main Station", "City Center", LocalDate.now(), LocalTime.now(), 1); + .findFastestDirectConnections("Main Station", "City Center", LocalDate.now(), LocalTime.now(), 1); // Should find connection even with multiple stops with same name assertThat(result).hasSize(1); @@ -308,9 +306,9 @@ void findFastestDirectConnection_multipleStopsSameName_handlesCorrectly() { @Test @DisplayName("Should return valid arrival time for connection") - void findFastestDirectConnection_returnsNonNullArrivalTime() { + void findFastestDirectConnections_returnsNonNullArrivalTime() { List result = directConnectionService - .findFastestDirectConnection("Main Station", "City Center", LocalDate.now(), LocalTime.now(), 1); + .findFastestDirectConnections("Main Station", "City Center", LocalDate.now(), LocalTime.now(), 1); assertThat(result).hasSize(1); assertThat(result.get(0).getArrivalTime()).isNotNull(); diff --git a/src/test/java/pl/agh/transit/DirectConnectionServiceTest.java b/src/test/java/pl/agh/transit/DirectConnectionServiceTest.java index 84cf73d..436dc7d 100644 --- a/src/test/java/pl/agh/transit/DirectConnectionServiceTest.java +++ b/src/test/java/pl/agh/transit/DirectConnectionServiceTest.java @@ -14,7 +14,6 @@ import pl.agh.transit.gtfs_static.model.Stop; import pl.agh.transit.gtfs_static.model.StopTime; import pl.agh.transit.gtfs_static.repository.StopTimeRepository; -import pl.agh.transit.gtfs_static.repository.StaticTripRepository; import java.time.LocalDate; import java.time.LocalDateTime; @@ -65,7 +64,7 @@ void setUp() { @Test @DisplayName("Should find fastest direct connection using realtime data") - void findFastestDirectConnection_WithRealtimeData() { + void findFastestDirectConnections_WithRealtimeData() { TripUpdateDTO dto = TripUpdateDTO.builder() .tripId("trip-1") .routeId("route-1") @@ -99,7 +98,7 @@ void findFastestDirectConnection_WithRealtimeData() { when(connectionServiceHelper.parseTimeWithDelay("23:15:00", travelDate, 0)) .thenReturn(travelDate.atStartOfDay().plusHours(23).plusMinutes(15)); - List result = directConnectionService.findFastestDirectConnection("Main Station", "City Center", travelDate, travelTime, 1); + List result = directConnectionService.findFastestDirectConnections("Main Station", "City Center", travelDate, travelTime, 1); assertThat(result).hasSize(1); assertThat(result.get(0).getRouteName()).isEqualTo("1A"); @@ -107,25 +106,25 @@ void findFastestDirectConnection_WithRealtimeData() { @Test @DisplayName("Should return empty when no stops found") - void findFastestDirectConnection_NoStopsFound() { + void findFastestDirectConnections_NoStopsFound() { when(connectionServiceHelper.getStopsForName("Main Station")).thenReturn(List.of()); when(connectionServiceHelper.getStopsForName("City Center")).thenReturn(List.of(toStop)); - List result = directConnectionService.findFastestDirectConnection("Main Station", "City Center", LocalDate.now(), LocalTime.now(), 1); + List result = directConnectionService.findFastestDirectConnections("Main Station", "City Center", LocalDate.now(), LocalTime.now(), 1); assertThat(result).isEmpty(); } @Test @DisplayName("Should return empty when destination stops not found") - void findFastestDirectConnection_NoDestinationStopsFound() { + void findFastestDirectConnections_NoDestinationStopsFound() { when(connectionServiceHelper.getStopsForName("Main Station")).thenReturn(List.of(fromStop)); when(connectionServiceHelper.getStopsForName("Unknown Destination")).thenReturn(List.of()); - List result = directConnectionService.findFastestDirectConnection("Main Station", "Unknown Destination", LocalDate.now(), LocalTime.now(), 1); + List result = directConnectionService.findFastestDirectConnections("Main Station", "Unknown Destination", LocalDate.now(), LocalTime.now(), 1); assertThat(result).isEmpty(); @@ -195,7 +194,7 @@ void findConnectionInTrip_WithMultipleStops() { when(connectionServiceHelper.parseTimeWithDelay("23:15:00", travelDate, 0)) .thenReturn(travelDate.atStartOfDay().plusHours(23).plusMinutes(15)); - List result = directConnectionService.findFastestDirectConnection("Main Station", "City Center", travelDate, travelTime, 1); + List result = directConnectionService.findFastestDirectConnections("Main Station", "City Center", travelDate, travelTime, 1); assertThat(result).hasSize(1); assertThat(result.get(0).getRouteName()).isNotEqualTo("N/A"); @@ -203,7 +202,7 @@ void findConnectionInTrip_WithMultipleStops() { @Test @DisplayName("Should fallback to static data when no realtime data available") - void findFastestDirectConnection_FallbackToStaticData() { + void findFastestDirectConnections_FallbackToStaticData() { LocalDate travelDate = LocalDate.now(); when(connectionServiceHelper.getStopsForName("Main Station")).thenReturn(List.of(fromStop)); @@ -213,7 +212,7 @@ void findFastestDirectConnection_FallbackToStaticData() { when(tripMapper.toDtoList(any())).thenReturn(List.of()); when(stopTimeRepository.findByStopId("stop-1")).thenReturn(List.of()); - List result = directConnectionService.findFastestDirectConnection("Main Station", "City Center", travelDate, LocalTime.now(), 1); + List result = directConnectionService.findFastestDirectConnections("Main Station", "City Center", travelDate, LocalTime.now(), 1); // When no realtime and no static data, should return empty assertThat(result).isEmpty(); @@ -221,7 +220,7 @@ void findFastestDirectConnection_FallbackToStaticData() { @Test @DisplayName("Should filter trips inactive on specific date") - void findFastestDirectConnection_WithSpecificDate() { + void findFastestDirectConnections_WithSpecificDate() { LocalDate travelDate = LocalDate.of(2026, 1, 6); when(connectionServiceHelper.getStopsForName("Main Station")).thenReturn(List.of(fromStop)); @@ -232,7 +231,7 @@ void findFastestDirectConnection_WithSpecificDate() { when(stopTimeRepository.findByStopId("stop-1")).thenReturn(List.of()); - List result = directConnectionService.findFastestDirectConnection("Main Station", "City Center", travelDate, LocalTime.now(), 1); + List result = directConnectionService.findFastestDirectConnections("Main Station", "City Center", travelDate, LocalTime.now(), 1); assertThat(result).isEmpty(); @@ -274,7 +273,7 @@ void findConnectionInTrip_RouteNameFromRealtime() { when(connectionServiceHelper.parseTimeWithDelay("23:15:00", travelDate, 0)) .thenReturn(travelDate.atStartOfDay().plusHours(23).plusMinutes(15)); - List result = directConnectionService.findFastestDirectConnection("Main Station", "City Center", travelDate, travelTime, 1); + List result = directConnectionService.findFastestDirectConnections("Main Station", "City Center", travelDate, travelTime, 1); assertThat(result).hasSize(1); assertThat(result.get(0).getRouteName()).isEqualTo("1A"); @@ -316,7 +315,7 @@ void findConnectionInTrip_RouteNotFound() { when(connectionServiceHelper.parseTimeWithDelay("23:15:00", travelDate, 0)) .thenReturn(travelDate.atStartOfDay().plusHours(23).plusMinutes(15)); - List result = directConnectionService.findFastestDirectConnection("Main Station", "City Center", travelDate, travelTime, 1); + List result = directConnectionService.findFastestDirectConnections("Main Station", "City Center", travelDate, travelTime, 1); assertThat(result).hasSize(1); @@ -363,7 +362,7 @@ void findConnectionInTrip_SkipSameStop() { when(connectionServiceHelper.parseTimeWithDelay("23:15:00", travelDate, 0)) .thenReturn(travelDate.atStartOfDay().plusHours(23).plusMinutes(15)); - List result = directConnectionService.findFastestDirectConnection("Main Station", "City Center", travelDate, travelTime, 1); + List result = directConnectionService.findFastestDirectConnections("Main Station", "City Center", travelDate, travelTime, 1); assertThat(result).hasSize(1); } @@ -405,7 +404,7 @@ void parseGtfsTime() { .thenReturn(travelDate.atStartOfDay().plusHours(23).plusMinutes(15)); - List result = directConnectionService.findFastestDirectConnection("Main Station", "City Center", travelDate, travelTime, 1); + List result = directConnectionService.findFastestDirectConnections("Main Station", "City Center", travelDate, travelTime, 1); assertThat(result).hasSize(1); @@ -414,7 +413,7 @@ void parseGtfsTime() { @Test @DisplayName("Should handle empty trip updates list") - void findFastestDirectConnection_EmptyTripUpdates() { + void findFastestDirectConnections_EmptyTripUpdates() { when(connectionServiceHelper.getStopsForName("Main Station")).thenReturn(List.of(fromStop)); when(connectionServiceHelper.getStopsForName("City Center")).thenReturn(List.of(toStop)); @@ -423,7 +422,7 @@ void findFastestDirectConnection_EmptyTripUpdates() { when(stopTimeRepository.findByStopId("stop-1")).thenReturn(List.of()); - List result = directConnectionService.findFastestDirectConnection("Main Station", "City Center", LocalDate.now(), LocalTime.now(), 1); + List result = directConnectionService.findFastestDirectConnections("Main Station", "City Center", LocalDate.now(), LocalTime.now(), 1); assertThat(result).isEmpty(); @@ -465,14 +464,14 @@ void findFastestDirectConnection_SelectsFastest() { when(connectionServiceHelper.parseTimeWithDelay("23:10:00", travelDate, 0)) .thenReturn(travelDate.atStartOfDay().plusHours(23).plusMinutes(10)); - List result = directConnectionService.findFastestDirectConnection("Main Station", "City Center", travelDate, travelTime, 1); + List result = directConnectionService.findFastestDirectConnections("Main Station", "City Center", travelDate, travelTime, 1); assertThat(result).hasSize(1); } @Test @DisplayName("Should handle multiple destination stops with same name") - void findFastestDirectConnection_MultipleDestinationStops() { + void findFastestDirectConnections_MultipleDestinationStops() { Stop toStop2 = new Stop(); toStop2.setId("stop-3"); toStop2.setStopName("City Center"); @@ -510,7 +509,7 @@ void findFastestDirectConnection_MultipleDestinationStops() { when(connectionServiceHelper.parseTimeWithDelay("23:15:00", travelDate, 0)) .thenReturn(travelDate.atStartOfDay().plusHours(23).plusMinutes(15)); - List result = directConnectionService.findFastestDirectConnection("Main Station", "City Center", travelDate, travelTime, 1); + List result = directConnectionService.findFastestDirectConnections("Main Station", "City Center", travelDate, travelTime, 1); assertThat(result).hasSize(1); } @@ -527,7 +526,7 @@ void findStaticConnection_NoMatchingStopTimes() { when(stopTimeRepository.findByStopId("stop-1")).thenReturn(List.of()); - List result = directConnectionService.findFastestDirectConnection("Main Station", "City Center", LocalDate.now(), LocalTime.now(), 1); + List result = directConnectionService.findFastestDirectConnections("Main Station", "City Center", LocalDate.now(), LocalTime.now(), 1); assertThat(result).isEmpty(); @@ -569,7 +568,7 @@ void parseArrivalTimeWithDelay() { when(connectionServiceHelper.parseTimeWithDelay("23:15:00", travelDate, 0)) .thenReturn(travelDate.atStartOfDay().plusHours(23).plusMinutes(15)); - List result = directConnectionService.findFastestDirectConnection("Main Station", "City Center", travelDate, travelTime, 1); + List result = directConnectionService.findFastestDirectConnections("Main Station", "City Center", travelDate, travelTime, 1); assertThat(result).hasSize(1); assertThat(result.get(0).getArrivalTime()).isNotNull(); @@ -586,7 +585,7 @@ void findConnectionInTrip_FromStopNotInTrip() { when(stopTimeRepository.findByStopId("stop-1")).thenReturn(List.of()); - List result = directConnectionService.findFastestDirectConnection("Main Station", "City Center"); + List result = directConnectionService.findFastestDirectConnections("Main Station", "City Center" ,1); assertThat(result).isEmpty(); @@ -623,7 +622,7 @@ void findStaticConnection_WithComplexTripSequence() { when(tripRepository.getEntitiesOrEmpty()).thenReturn(List.of()); when(stopTimeRepository.findByStopId("stop-1")).thenReturn(List.of(midStop)); - List result = directConnectionService.findFastestDirectConnection("Main Station", "City Center", LocalDate.now(), LocalTime.now(), 1); + List result = directConnectionService.findFastestDirectConnections("Main Station", "City Center", LocalDate.now(), LocalTime.now(), 1); // When no realtime data and static data doesn't match properly, should return empty assertThat(result).isEmpty(); @@ -631,7 +630,7 @@ void findStaticConnection_WithComplexTripSequence() { @Test @DisplayName("findConnectionInTrip should fallback to static trip route when realtime routeId is missing") - void findFastestDirectConnection_routeNameFallbackToStaticTrip_whenRouteIdMissing() { + void findFastestDirectConnections_routeNameFallbackToStaticTrip_whenRouteIdMissing() { // given TripUpdateDTO dtoWithoutRouteId = TripUpdateDTO.builder() .tripId("trip-1") @@ -666,7 +665,7 @@ void findFastestDirectConnection_routeNameFallbackToStaticTrip_whenRouteIdMissin .thenReturn(travelDate.atStartOfDay().plusHours(23).plusMinutes(15)); // when - List result = directConnectionService.findFastestDirectConnection("Main Station", "City Center", travelDate, travelTime, 1); + List result = directConnectionService.findFastestDirectConnections("Main Station", "City Center", travelDate, travelTime, 1); // then assertThat(result).hasSize(1); @@ -675,7 +674,7 @@ void findFastestDirectConnection_routeNameFallbackToStaticTrip_whenRouteIdMissin @Test @DisplayName("findConnectionInTrip should use realtime routeId when present") - void findFastestDirectConnection_routeNameFromRealtime_whenPresent() { + void findFastestDirectConnections_routeNameFromRealtime_whenPresent() { // given TripUpdateDTO dtoWithRouteId = TripUpdateDTO.builder() .tripId("trip-1") @@ -710,7 +709,7 @@ void findFastestDirectConnection_routeNameFromRealtime_whenPresent() { .thenReturn(travelDate.atStartOfDay().plusHours(23).plusMinutes(15)); // when - List result = directConnectionService.findFastestDirectConnection("Main Station", "City Center", travelDate, travelTime, 1); + List result = directConnectionService.findFastestDirectConnections("Main Station", "City Center", travelDate, travelTime, 1); // then assertThat(result).hasSize(1); @@ -719,7 +718,7 @@ void findFastestDirectConnection_routeNameFromRealtime_whenPresent() { @Test @DisplayName("findConnectionInTrip should pick destination stop that appears after fromStop") - void findFastestDirectConnection_destinationMustBeAfterFromStop() { + void findFastestDirectConnections_destinationMustBeAfterFromStop() { // given: destination first, fromStop later, destination again after -> should pick the later one TripUpdateDTO dto = TripUpdateDTO.builder() .tripId("trip-1") @@ -759,7 +758,7 @@ void findFastestDirectConnection_destinationMustBeAfterFromStop() { .thenReturn(travelDate.atStartOfDay().plusHours(23).plusMinutes(15)); // when - List result = directConnectionService.findFastestDirectConnection("Main Station", "City Center", travelDate, travelTime, 1); + List result = directConnectionService.findFastestDirectConnections("Main Station", "City Center", travelDate, travelTime, 1); // then: arrivalTime is computed from *fromStop* arrivalTime in current implementation // so here we just assert connection exists and route resolved. @@ -769,7 +768,7 @@ void findFastestDirectConnection_destinationMustBeAfterFromStop() { @Test @DisplayName("parseArrivalTimeWithDelay should apply arrivalDelay in seconds") - void findFastestDirectConnection_parseArrivalTimeWithDelay_appliesDelay() { + void findFastestDirectConnections_parseArrivalTimeWithDelay_appliesDelay() { // given TripUpdateDTO dto = TripUpdateDTO.builder() .tripId("trip-1") @@ -805,7 +804,7 @@ void findFastestDirectConnection_parseArrivalTimeWithDelay_appliesDelay() { .thenReturn(expectedArrival); // when - List result = directConnectionService.findFastestDirectConnection("Main Station", "City Center", today, travelTime, 1); + List result = directConnectionService.findFastestDirectConnections("Main Station", "City Center", today, travelTime, 1); // then assertThat(result).hasSize(1); @@ -814,7 +813,7 @@ void findFastestDirectConnection_parseArrivalTimeWithDelay_appliesDelay() { @Test @DisplayName("parseArrivalTimeWithDelay should fallback to now when arrivalTime is null") - void findFastestDirectConnection_parseArrivalTimeWithDelay_nullArrivalTime_fallbacksToNow() { + void findFastestDirectConnections_parseArrivalTimeWithDelay_nullArrivalTime_fallbacksToNow() { // given TripUpdateDTO dto = TripUpdateDTO.builder() .tripId("trip-1") @@ -851,7 +850,7 @@ void findFastestDirectConnection_parseArrivalTimeWithDelay_nullArrivalTime_fallb // when LocalDateTime before = LocalDateTime.now(); - List result = directConnectionService.findFastestDirectConnection("Main Station", "City Center", travelDate, travelTime, 1); + List result = directConnectionService.findFastestDirectConnections("Main Station", "City Center", travelDate, travelTime, 1); LocalDateTime after = LocalDateTime.now(); // then @@ -862,7 +861,7 @@ void findFastestDirectConnection_parseArrivalTimeWithDelay_nullArrivalTime_fallb @Test @DisplayName("parseArrivalTimeWithDelay should fallback to now when arrivalTime has invalid format") - void findFastestDirectConnection_parseArrivalTimeWithDelay_invalidFormat_fallbacksToNow() { + void findFastestDirectConnections_parseArrivalTimeWithDelay_invalidFormat_fallbacksToNow() { // given: NumberFormatException from parsing hours TripUpdateDTO dto = TripUpdateDTO.builder() .tripId("trip-1") @@ -899,7 +898,7 @@ void findFastestDirectConnection_parseArrivalTimeWithDelay_invalidFormat_fallbac // when LocalDateTime before = LocalDateTime.now(); - List result = directConnectionService.findFastestDirectConnection("Main Station", "City Center", travelDate, travelTime, 1); + List result = directConnectionService.findFastestDirectConnections("Main Station", "City Center", travelDate, travelTime, 1); LocalDateTime after = LocalDateTime.now(); // then @@ -909,7 +908,7 @@ void findFastestDirectConnection_parseArrivalTimeWithDelay_invalidFormat_fallbac @Test @DisplayName("Should select earliest departure time when multiple connections available") - void findFastestDirectConnection_selectsEarliestDeparture() { + void findFastestDirectConnections_selectsEarliestDeparture() { // given: Trip 1 departs at 23:01, Trip 2 departs at 23:06 // Even though Trip 2 arrives earlier (23:10 vs 23:20), should select Trip 1 (earlier departure) TripUpdateDTO trip1 = TripUpdateDTO.builder() @@ -977,7 +976,7 @@ void findFastestDirectConnection_selectsEarliestDeparture() { .thenReturn(travelDate.atStartOfDay().plusHours(23).plusMinutes(10)); // when - List result = directConnectionService.findFastestDirectConnection("Main Station", "City Center", travelDate, travelTime, 1); + List result = directConnectionService.findFastestDirectConnections("Main Station", "City Center", travelDate, travelTime, 1); // then - should select Trip 1 because it has earliest departure (23:01 < 23:06) assertThat(result).hasSize(1); diff --git a/src/test/java/pl/agh/transit/TripControllerIntegrationTest.java b/src/test/java/pl/agh/transit/TripControllerIntegrationTest.java index 94d89c0..4155b1e 100644 --- a/src/test/java/pl/agh/transit/TripControllerIntegrationTest.java +++ b/src/test/java/pl/agh/transit/TripControllerIntegrationTest.java @@ -46,7 +46,7 @@ void getRandomStopTime_shouldReturnOkWhenData() throws Exception { tripRepository.updateAllTrips(feed); - mockMvc.perform(get("/trips/random-stop-time")) + mockMvc.perform(get("/random-stop-time")) .andExpect(status().isOk()) .andExpect(content().contentType("application/json")) .andExpect(jsonPath("$.stopId").exists()); @@ -63,7 +63,7 @@ void getRandomStopTime_shouldReturnServiceUnavailableWhenNoData() throws Excepti tripRepository.updateAllTrips(emptyFeed); - mockMvc.perform(get("/trips/random-stop-time")) + mockMvc.perform(get("/random-stop-time")) .andExpect(status().isInternalServerError()); } }