69 lines
2.4 KiB
TypeScript
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));
|
|
});
|
|
});
|