From b2608a4a601e5f0021e313f7c8015ad41b0f2d97 Mon Sep 17 00:00:00 2001 From: Florian Egger Date: Sun, 10 May 2026 17:53:19 +0200 Subject: [PATCH] Fix ApiClient mock implementation and update constructor tests --- src/lib/__tests__/wienerlinien-client.test.ts | 126 ++++++++++-------- 1 file changed, 67 insertions(+), 59 deletions(-) diff --git a/src/lib/__tests__/wienerlinien-client.test.ts b/src/lib/__tests__/wienerlinien-client.test.ts index 4f38492..72ce53a 100644 --- a/src/lib/__tests__/wienerlinien-client.test.ts +++ b/src/lib/__tests__/wienerlinien-client.test.ts @@ -1,10 +1,16 @@ import { describe, it, expect, vi, beforeEach } from "vitest"; -vi.mock("@/lib/api-service", () => ({ - ApiClient: vi.fn(() => ({ - get: vi.fn(), - })), -})); +vi.mock("@/lib/api-service", () => { + const MockApiClient = vi.fn(); + MockApiClient.mockImplementation(function () { + return { + get: vi.fn(), + }; + }); + return { + ApiClient: MockApiClient, + }; +}); import { WienerLinienClient } from "@/lib/wienerlinien-client"; import { ApiClient } from "@/lib/api-service"; @@ -21,9 +27,9 @@ describe("WienerLinienClient", () => { { id: "WL:StopPoint:2000002", name: "Karlsplatz", lat: 48.2009, lng: 16.3716 }, ]); - (ApiClient as ReturnType).mockImplementation(() => ({ - get: mockGet, - })); + (ApiClient as ReturnType).mockImplementation(function () { + return { get: mockGet }; + }); const client = new WienerLinienClient(); const stops = await client.findNearbyStops(48.21, 16.37, 500); @@ -46,9 +52,9 @@ describe("WienerLinienClient", () => { it("generates correct cache key and TTL", async () => { const mockGet = vi.fn().mockResolvedValue([]); - (ApiClient as ReturnType).mockImplementation(() => ({ - get: mockGet, - })); + (ApiClient as ReturnType).mockImplementation(function () { + return { get: mockGet }; + }); const client = new WienerLinienClient(); await client.findNearbyStops(48.21, 16.37, 500); @@ -66,9 +72,9 @@ describe("WienerLinienClient", () => { it("returns empty array for non-array response", async () => { const mockGet = vi.fn().mockResolvedValue({ error: "not found" }); - (ApiClient as ReturnType).mockImplementation(() => ({ - get: mockGet, - })); + (ApiClient as ReturnType).mockImplementation(function () { + return { get: mockGet }; + }); const client = new WienerLinienClient(); const stops = await client.findNearbyStops(48.21, 16.37, 500); @@ -79,9 +85,9 @@ describe("WienerLinienClient", () => { it("returns empty array for null response", async () => { const mockGet = vi.fn().mockResolvedValue(null); - (ApiClient as ReturnType).mockImplementation(() => ({ - get: mockGet, - })); + (ApiClient as ReturnType).mockImplementation(function () { + return { get: mockGet }; + }); const client = new WienerLinienClient(); const stops = await client.findNearbyStops(48.21, 16.37, 500); @@ -90,17 +96,19 @@ describe("WienerLinienClient", () => { }); it("filters out malformed stop entries", async () => { - const mockGet = vi.fn().mockResolvedValue([ - { id: "WL:StopPoint:2000001", name: "Valid", lat: 48.21, lng: 16.37 }, - { id: "missing-fields" }, - null, - "string", - { id: 123, name: "wrong-types", lat: "not-a-number", lng: "also-not" }, - ]); + const mockGet = vi + .fn() + .mockResolvedValue([ + { id: "WL:StopPoint:2000001", name: "Valid", lat: 48.21, lng: 16.37 }, + { id: "missing-fields" }, + null, + "string", + { id: 123, name: "wrong-types", lat: "not-a-number", lng: "also-not" }, + ]); - (ApiClient as ReturnType).mockImplementation(() => ({ - get: mockGet, - })); + (ApiClient as ReturnType).mockImplementation(function () { + return { get: mockGet }; + }); const client = new WienerLinienClient(); const stops = await client.findNearbyStops(48.21, 16.37, 500); @@ -117,9 +125,9 @@ describe("WienerLinienClient", () => { it("propagates API errors", async () => { const mockGet = vi.fn().mockRejectedValue(new Error("API timeout")); - (ApiClient as ReturnType).mockImplementation(() => ({ - get: mockGet, - })); + (ApiClient as ReturnType).mockImplementation(function () { + return { get: mockGet }; + }); const client = new WienerLinienClient(); await expect(client.findNearbyStops(48.21, 16.37, 500)).rejects.toThrow("API timeout"); @@ -145,9 +153,9 @@ describe("WienerLinienClient", () => { ], }); - (ApiClient as ReturnType).mockImplementation(() => ({ - get: mockGet, - })); + (ApiClient as ReturnType).mockImplementation(function () { + return { get: mockGet }; + }); const client = new WienerLinienClient(); const response = await client.getMonitor(["WL:StopPoint:2000001"]); @@ -172,9 +180,9 @@ describe("WienerLinienClient", () => { it("generates correct cache key with sorted stop IDs", async () => { const mockGet = vi.fn().mockResolvedValue({}); - (ApiClient as ReturnType).mockImplementation(() => ({ - get: mockGet, - })); + (ApiClient as ReturnType).mockImplementation(function () { + return { get: mockGet }; + }); const client = new WienerLinienClient(); await client.getMonitor(["WL:StopPoint:2000002", "WL:StopPoint:2000001"]); @@ -192,9 +200,9 @@ describe("WienerLinienClient", () => { it("returns empty stops for non-object response", async () => { const mockGet = vi.fn().mockResolvedValue("error"); - (ApiClient as ReturnType).mockImplementation(() => ({ - get: mockGet, - })); + (ApiClient as ReturnType).mockImplementation(function () { + return { get: mockGet }; + }); const client = new WienerLinienClient(); const response = await client.getMonitor(["WL:StopPoint:2000001"]); @@ -205,9 +213,9 @@ describe("WienerLinienClient", () => { it("returns empty stops for null response", async () => { const mockGet = vi.fn().mockResolvedValue(null); - (ApiClient as ReturnType).mockImplementation(() => ({ - get: mockGet, - })); + (ApiClient as ReturnType).mockImplementation(function () { + return { get: mockGet }; + }); const client = new WienerLinienClient(); const response = await client.getMonitor(["WL:StopPoint:2000001"]); @@ -229,9 +237,9 @@ describe("WienerLinienClient", () => { ], }); - (ApiClient as ReturnType).mockImplementation(() => ({ - get: mockGet, - })); + (ApiClient as ReturnType).mockImplementation(function () { + return { get: mockGet }; + }); const client = new WienerLinienClient(); const response = await client.getMonitor(["WL:StopPoint:2000001"]); @@ -252,9 +260,9 @@ describe("WienerLinienClient", () => { ], }); - (ApiClient as ReturnType).mockImplementation(() => ({ - get: mockGet, - })); + (ApiClient as ReturnType).mockImplementation(function () { + return { get: mockGet }; + }); const client = new WienerLinienClient(); const response = await client.getMonitor(["WL:StopPoint:2000001", "WL:StopPoint:2000002"]); @@ -266,9 +274,9 @@ describe("WienerLinienClient", () => { it("propagates API errors", async () => { const mockGet = vi.fn().mockRejectedValue(new Error("503 Service Unavailable")); - (ApiClient as ReturnType).mockImplementation(() => ({ - get: mockGet, - })); + (ApiClient as ReturnType).mockImplementation(function () { + return { get: mockGet }; + }); const client = new WienerLinienClient(); await expect(client.getMonitor(["WL:StopPoint:2000001"])).rejects.toThrow("503 Service Unavailable"); @@ -277,23 +285,23 @@ describe("WienerLinienClient", () => { describe("constructor", () => { it("uses default base URL", () => { - (ApiClient as ReturnType).mockImplementation(() => ({ - get: vi.fn(), - })); + (ApiClient as ReturnType).mockImplementation(function () { + return { get: vi.fn() }; + }); new WienerLinienClient(); - expect(ApiClient).toHaveBeenCalledWith("https://api.wienerlinien.at/darvin-v1"); + expect(ApiClient).toHaveBeenCalledWith({ baseUrl: "https://api.wienerlinien.at/darvin-v1" }); }); it("uses custom base URL when provided", () => { - (ApiClient as ReturnType).mockImplementation(() => ({ - get: vi.fn(), - })); + (ApiClient as ReturnType).mockImplementation(function () { + return { get: vi.fn() }; + }); new WienerLinienClient("https://custom.api.example.com/v1"); - expect(ApiClient).toHaveBeenCalledWith("https://custom.api.example.com/v1"); + expect(ApiClient).toHaveBeenCalledWith({ baseUrl: "https://custom.api.example.com/v1" }); }); }); });