Support repeated stopIds and update WienerLinien API URL
This commit is contained in:
@@ -93,6 +93,16 @@ describe("GET /api/wienerlinien/monitor", () => {
|
||||
expect(mockGetMonitor).toHaveBeenCalledWith(["1", "2", "3"]);
|
||||
});
|
||||
|
||||
it("accepts repeated stopIds params from hook (stopIds=a&stopIds=b)", async () => {
|
||||
mockGetMonitor.mockResolvedValue({ stops: [] });
|
||||
const request = new NextRequest(
|
||||
"http://localhost/api/wienerlinien/monitor?stopIds=WL:2000001&stopIds=WL:2000002&stopIds=WL:2000003",
|
||||
);
|
||||
await GET(request);
|
||||
|
||||
expect(mockGetMonitor).toHaveBeenCalledWith(["WL:2000001", "WL:2000002", "WL:2000003"]);
|
||||
});
|
||||
|
||||
it("returns 500 with correlationId when client throws", async () => {
|
||||
mockGetMonitor.mockRejectedValue(new Error("upstream timeout"));
|
||||
|
||||
|
||||
@@ -6,13 +6,12 @@ const client = new WienerLinienClient();
|
||||
|
||||
export async function GET(request: NextRequest) {
|
||||
const { searchParams } = new URL(request.url);
|
||||
const stopIdsParam = searchParams.get("stopIds");
|
||||
|
||||
if (!stopIdsParam || stopIdsParam.trim() === "") {
|
||||
const stopIdsList = searchParams.getAll("stopIds");
|
||||
if (stopIdsList.length === 0 || stopIdsList.every((v) => v.trim() === "")) {
|
||||
return NextResponse.json({ error: "Missing 'stopIds' query parameter" }, { status: 400 });
|
||||
}
|
||||
|
||||
const rawIds = stopIdsParam.split(",");
|
||||
const rawIds = stopIdsList.flatMap((param) => param.split(","));
|
||||
const validStopIds = rawIds
|
||||
.map((id) => id.trim())
|
||||
.filter((id) => id.length > 0)
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
import { format } from "date-fns";
|
||||
import { useJourneys } from "@/hooks/useJourneys";
|
||||
import { useDestinationStation } from "@/hooks/useDestinationStation";
|
||||
import { useBikeRoute } from "@/hooks/useBikeRoute";
|
||||
import { useGeocode } from "@/hooks/useGeocode";
|
||||
import { useClock } from "@/hooks/useClock";
|
||||
@@ -18,11 +19,13 @@ interface EventCardProps {
|
||||
}
|
||||
|
||||
export default function EventCard({ event, originStation }: EventCardProps) {
|
||||
const destStation = useDestinationStation(event.destination);
|
||||
|
||||
const {
|
||||
journeys,
|
||||
loading: journeysLoading,
|
||||
error: journeysError,
|
||||
} = useJourneys(originStation?.extId ?? null, null, event.eventTime, 0);
|
||||
} = useJourneys(originStation?.extId ?? null, destStation.station?.extId ?? null, event.eventTime, 0);
|
||||
|
||||
const destCoords = useGeocode(event.destination);
|
||||
|
||||
|
||||
@@ -7,6 +7,8 @@ interface HafasLocation {
|
||||
type: string;
|
||||
name: string;
|
||||
extId: string;
|
||||
lat: number;
|
||||
lon: number;
|
||||
}
|
||||
|
||||
export function useOriginStation() {
|
||||
@@ -65,7 +67,7 @@ export function useOriginStation() {
|
||||
const match = data?.svcResL?.[0]?.res?.match?.locL ?? [];
|
||||
const stations: Station[] = (match as HafasLocation[])
|
||||
.filter((l) => l.type === "S")
|
||||
.map((l) => ({ name: l.name, extId: l.extId }));
|
||||
.map((l) => ({ name: l.name, extId: l.extId, lat: l.lat, lng: l.lon }));
|
||||
|
||||
if (!isMounted) return;
|
||||
|
||||
|
||||
@@ -291,7 +291,7 @@ describe("WienerLinienClient", () => {
|
||||
|
||||
new WienerLinienClient();
|
||||
|
||||
expect(ApiClient).toHaveBeenCalledWith({ baseUrl: "https://api.wienerlinien.at/darvin-v1" });
|
||||
expect(ApiClient).toHaveBeenCalledWith({ baseUrl: "https://api.wienerlinien.at/darwin-v2" });
|
||||
});
|
||||
|
||||
it("uses custom base URL when provided", () => {
|
||||
|
||||
@@ -1,12 +1,11 @@
|
||||
import { WIENER_LINIEN_API_URL } from "@/lib/constants";
|
||||
import { ApiClient } from "@/lib/api-service";
|
||||
import type { NearbyStop, WienerLinienDeparture, WienerLinienLine, WienerLinienMonitorResponse } from "@/types";
|
||||
|
||||
const DEFAULT_BASE_URL = "https://api.wienerlinien.at/darvin-v1";
|
||||
|
||||
export class WienerLinienClient {
|
||||
private readonly client: ApiClient;
|
||||
|
||||
constructor(baseUrl: string = DEFAULT_BASE_URL) {
|
||||
constructor(baseUrl: string = WIENER_LINIEN_API_URL) {
|
||||
this.client = new ApiClient({ baseUrl });
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user