Files
watermaps/apps/web/tests/marine-data-hook.test.tsx
T
2026-07-24 11:29:24 +02:00

69 lines
2.4 KiB
TypeScript

import { cleanup, renderHook, waitFor } from "@testing-library/react";
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
const apiMocks = vi.hoisted(() => ({
getMarineForecast: vi.fn(),
getNearestTide: vi.fn()
}));
vi.mock("../src/api", () => apiMocks);
import { useMarineData } from "../src/hooks/useMarineData";
beforeEach(() => {
apiMocks.getMarineForecast.mockResolvedValue({ source: "test", updatedAt: new Date().toISOString() });
apiMocks.getNearestTide.mockResolvedValue({
station: "test",
distanceKm: 1,
nextHigh: null,
nextLow: null,
waterLevelCurve: [],
source: "test",
updatedAt: new Date().toISOString()
});
});
afterEach(() => {
cleanup();
vi.clearAllMocks();
});
describe("useMarineData", () => {
it("does not refetch weather and tide for every GPS jitter inside the same rounded cell", async () => {
const { result, rerender } = renderHook(
({ position }) => useMarineData(position),
{ initialProps: { position: { lat: 53.201, lon: 7.101 } } }
);
await waitFor(() => expect(result.current.loading).toBe(false));
expect(apiMocks.getMarineForecast).toHaveBeenCalledTimes(1);
expect(apiMocks.getNearestTide).toHaveBeenCalledTimes(1);
rerender({ position: { lat: 53.203, lon: 7.103 } });
await Promise.resolve();
expect(apiMocks.getMarineForecast).toHaveBeenCalledTimes(1);
expect(apiMocks.getNearestTide).toHaveBeenCalledTimes(1);
rerender({ position: { lat: 53.216, lon: 7.116 } });
await waitFor(() => expect(apiMocks.getMarineForecast).toHaveBeenCalledTimes(2));
expect(apiMocks.getNearestTide).toHaveBeenCalledTimes(2);
});
it("keeps partial data visible and exposes the failed source separately", async () => {
apiMocks.getMarineForecast.mockRejectedValueOnce(new Error("forecast offline"));
const { result } = renderHook(() =>
useMarineData({ lat: 53.2159, lon: 6.5766 })
);
await waitFor(() => expect(result.current.loading).toBe(false));
expect(result.current.forecast).toBeNull();
expect(result.current.tide?.station).toBe("test");
expect(result.current.forecastError).toBe("Wetterdaten nicht erreichbar");
expect(result.current.tideError).toBeNull();
expect(result.current.error).toBeNull();
expect(result.current.queryPosition).toEqual({ lat: 53.22, lon: 6.58 });
expect(result.current.refreshedAt).toEqual(expect.any(String));
});
});