132 lines
4.2 KiB
TypeScript
132 lines
4.2 KiB
TypeScript
import "@testing-library/jest-dom/vitest";
|
||
import { cleanup, fireEvent, render, screen } from "@testing-library/react";
|
||
import { afterEach, describe, expect, it, vi } from "vitest";
|
||
import { calculateRouteGuidance } from "@watermaps/shared";
|
||
import { CourseAssistantPanel } from "../src/components/CourseAssistantPanel";
|
||
|
||
afterEach(cleanup);
|
||
|
||
describe("CourseAssistantPanel", () => {
|
||
it("shows the continuously calculated target course and correction", () => {
|
||
const guidance = calculateRouteGuidance({
|
||
route: [[0, 0], [0.02, 0]],
|
||
position: { lon: 0.001, lat: 0 },
|
||
headingDeg: 80,
|
||
speedKn: 6,
|
||
accuracyM: 5
|
||
});
|
||
const onStop = vi.fn();
|
||
|
||
render(
|
||
<CourseAssistantPanel
|
||
guidance={guidance}
|
||
gpsStatus="tracking"
|
||
headingDeg={80}
|
||
headingSource="COG"
|
||
accuracyM={5}
|
||
fixStale={false}
|
||
onStop={onStop}
|
||
/>
|
||
);
|
||
|
||
expect(screen.getByRole("complementary", { name: "Kursassistent" })).toHaveTextContent("090°T");
|
||
expect(screen.getByText("10° nach Steuerbord")).toBeVisible();
|
||
expect(screen.getByText("Auf Route – Sollkurs wird mit jedem GPS-Fix angepasst.")).toBeVisible();
|
||
expect(screen.getByText("IST COG").parentElement).toHaveTextContent("080°T");
|
||
fireEvent.click(screen.getByRole("button", { name: "Kursassistent stoppen" }));
|
||
expect(onStop).toHaveBeenCalledTimes(1);
|
||
});
|
||
|
||
it("suppresses steering advice while GPS accuracy is insufficient", () => {
|
||
const guidance = calculateRouteGuidance({
|
||
route: [[0, 0], [0.02, 0]],
|
||
position: { lon: 0.001, lat: 0 },
|
||
headingDeg: 80,
|
||
speedKn: 6,
|
||
accuracyM: 250
|
||
});
|
||
|
||
render(
|
||
<CourseAssistantPanel
|
||
guidance={guidance}
|
||
gpsStatus="tracking"
|
||
headingDeg={80}
|
||
headingSource="COG"
|
||
accuracyM={250}
|
||
fixStale={false}
|
||
onStop={vi.fn()}
|
||
/>
|
||
);
|
||
|
||
expect(guidance?.status).toBe("gps-unreliable");
|
||
expect(screen.getByText("Keine verlässliche Steueranweisung")).toBeVisible();
|
||
expect(screen.getByText(/GPS zu ungenau/)).toBeVisible();
|
||
expect(screen.getByRole("complementary", { name: "Kursassistent" })).toHaveAttribute("data-alert", "true");
|
||
});
|
||
|
||
it("pauses when the latest GPS fix is stale", () => {
|
||
render(
|
||
<CourseAssistantPanel
|
||
guidance={null}
|
||
gpsStatus="tracking"
|
||
headingDeg={null}
|
||
headingSource="--"
|
||
accuracyM={null}
|
||
fixStale
|
||
onStop={vi.fn()}
|
||
/>
|
||
);
|
||
|
||
expect(screen.getByText(/GPS-Fix ist veraltet/)).toBeVisible();
|
||
expect(screen.getByText("---")).toBeVisible();
|
||
});
|
||
|
||
it("keeps every open route warning visible while guidance is active", () => {
|
||
render(
|
||
<CourseAssistantPanel
|
||
guidance={null}
|
||
gpsStatus="tracking"
|
||
headingDeg={null}
|
||
headingSource="--"
|
||
accuracyM={null}
|
||
fixStale={false}
|
||
routeWarnings={[
|
||
{
|
||
code: "ROUTING_SOURCE",
|
||
severity: "info",
|
||
message: "Routingquelle: lokaler Graph."
|
||
},
|
||
{
|
||
code: "BRIDGE_TOO_LOW",
|
||
severity: "caution",
|
||
message: "Eine Brücke ist zu niedrig."
|
||
},
|
||
{
|
||
code: "ROUTE_SEARCH_LIMITED",
|
||
severity: "caution",
|
||
message: "Die Snap-Suche wurde begrenzt."
|
||
},
|
||
{
|
||
code: "START_SNAP_TOO_FAR",
|
||
severity: "caution",
|
||
message: "Der Startpunkt liegt weit vom Fahrwasser entfernt."
|
||
},
|
||
{
|
||
code: "DESTINATION_SNAP_TOO_FAR",
|
||
severity: "caution",
|
||
message: "Der Zielpunkt liegt weit vom Fahrwasser entfernt."
|
||
}
|
||
]}
|
||
onStop={vi.fn()}
|
||
/>
|
||
);
|
||
|
||
expect(screen.getByText("Hinweise (4)")).toBeVisible();
|
||
expect(screen.getByText("Eine Brücke ist zu niedrig.")).toBeVisible();
|
||
expect(screen.getByText("Die Snap-Suche wurde begrenzt.")).toBeVisible();
|
||
expect(screen.getByText("Der Startpunkt liegt weit vom Fahrwasser entfernt.")).toBeVisible();
|
||
expect(screen.getByText("Der Zielpunkt liegt weit vom Fahrwasser entfernt.")).toBeVisible();
|
||
expect(screen.getByText("Routingdetails (1)")).toBeVisible();
|
||
});
|
||
});
|