62 lines
2.0 KiB
TypeScript
62 lines
2.0 KiB
TypeScript
import { act, cleanup, renderHook } from "@testing-library/react";
|
|
import { afterEach, describe, expect, it, vi } from "vitest";
|
|
import { useGeolocation } from "../src/hooks/useGeolocation";
|
|
|
|
const originalGeolocation = Object.getOwnPropertyDescriptor(navigator, "geolocation");
|
|
|
|
afterEach(() => {
|
|
cleanup();
|
|
if (originalGeolocation) Object.defineProperty(navigator, "geolocation", originalGeolocation);
|
|
else Reflect.deleteProperty(navigator, "geolocation");
|
|
});
|
|
|
|
describe("useGeolocation", () => {
|
|
it("derives COG only after movement exceeds GPS noise and clears the watch on stop", () => {
|
|
let success: PositionCallback | undefined;
|
|
const watchPosition = vi.fn((callback: PositionCallback) => {
|
|
success = callback;
|
|
return 23;
|
|
});
|
|
const clearWatch = vi.fn();
|
|
Object.defineProperty(navigator, "geolocation", {
|
|
configurable: true,
|
|
value: { watchPosition, clearWatch, getCurrentPosition: vi.fn() }
|
|
});
|
|
const { result } = renderHook(() => useGeolocation());
|
|
|
|
act(() => result.current.start());
|
|
act(() => success?.(positionAt(53, 7, 5, 1_000)));
|
|
expect(result.current.courseDeg).toBeNull();
|
|
|
|
act(() => success?.(positionAt(53, 7.00001, 5, 2_000)));
|
|
expect(result.current.courseDeg).toBeNull();
|
|
|
|
const receivedAtMs = Date.now();
|
|
act(() => success?.(positionAt(53, 7.0001, 5, 3_000)));
|
|
expect(result.current.courseDeg).toBeCloseTo(90, 0);
|
|
expect(result.current.timestampMs).toBeGreaterThanOrEqual(receivedAtMs);
|
|
|
|
act(() => result.current.stop());
|
|
expect(clearWatch).toHaveBeenCalledWith(23);
|
|
expect(result.current.status).toBe("idle");
|
|
expect(result.current.position).toBeNull();
|
|
});
|
|
});
|
|
|
|
function positionAt(lat: number, lon: number, accuracy: number, timestamp: number): GeolocationPosition {
|
|
return {
|
|
coords: {
|
|
latitude: lat,
|
|
longitude: lon,
|
|
accuracy,
|
|
altitude: null,
|
|
altitudeAccuracy: null,
|
|
heading: null,
|
|
speed: 3,
|
|
toJSON: () => ({})
|
|
},
|
|
timestamp,
|
|
toJSON: () => ({})
|
|
};
|
|
}
|