Fix ApiClient mock implementation and update constructor tests

This commit is contained in:
2026-05-10 17:53:19 +02:00
parent 7901368971
commit b2608a4a60
+67 -59
View File
@@ -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<typeof vi.fn>).mockImplementation(() => ({
get: mockGet,
}));
(ApiClient as ReturnType<typeof vi.fn>).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<typeof vi.fn>).mockImplementation(() => ({
get: mockGet,
}));
(ApiClient as ReturnType<typeof vi.fn>).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<typeof vi.fn>).mockImplementation(() => ({
get: mockGet,
}));
(ApiClient as ReturnType<typeof vi.fn>).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<typeof vi.fn>).mockImplementation(() => ({
get: mockGet,
}));
(ApiClient as ReturnType<typeof vi.fn>).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<typeof vi.fn>).mockImplementation(() => ({
get: mockGet,
}));
(ApiClient as ReturnType<typeof vi.fn>).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<typeof vi.fn>).mockImplementation(() => ({
get: mockGet,
}));
(ApiClient as ReturnType<typeof vi.fn>).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<typeof vi.fn>).mockImplementation(() => ({
get: mockGet,
}));
(ApiClient as ReturnType<typeof vi.fn>).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<typeof vi.fn>).mockImplementation(() => ({
get: mockGet,
}));
(ApiClient as ReturnType<typeof vi.fn>).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<typeof vi.fn>).mockImplementation(() => ({
get: mockGet,
}));
(ApiClient as ReturnType<typeof vi.fn>).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<typeof vi.fn>).mockImplementation(() => ({
get: mockGet,
}));
(ApiClient as ReturnType<typeof vi.fn>).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<typeof vi.fn>).mockImplementation(() => ({
get: mockGet,
}));
(ApiClient as ReturnType<typeof vi.fn>).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<typeof vi.fn>).mockImplementation(() => ({
get: mockGet,
}));
(ApiClient as ReturnType<typeof vi.fn>).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<typeof vi.fn>).mockImplementation(() => ({
get: mockGet,
}));
(ApiClient as ReturnType<typeof vi.fn>).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<typeof vi.fn>).mockImplementation(() => ({
get: vi.fn(),
}));
(ApiClient as ReturnType<typeof vi.fn>).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<typeof vi.fn>).mockImplementation(() => ({
get: vi.fn(),
}));
(ApiClient as ReturnType<typeof vi.fn>).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" });
});
});
});