Files
galaxy-game/ui/frontend/tests/game-shell-stubs.test.ts
T
Ilia Denisov 785c3483f8 ui/phase-17: ship-class CRUD without calc
Phase 17 lights up the ship-class table and designer active views,
extends the order-draft pipeline with createShipClass and
removeShipClass commands, and projects pending Save/Delete actions
through applyOrderOverlay so the table reflects the player's
intent before auto-sync lands. The plan is corrected in the same
patch: per game/rules.txt, ship classes are designed once and
cannot be edited — the engine has no Update command, so the UI
exposes only Create + Delete.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-09 21:44:21 +02:00

91 lines
3.7 KiB
TypeScript

// Component tests for the remaining Phase 10 active-view stubs. Each
// stub renders the localised view title plus the `coming soon` body
// copy and exposes a stable `data-testid` so later phases can replace
// the content without renaming the test hook. Phase 17 lit up the
// ship-classes table and the ship-class designer, so the assertions
// for those slugs / components moved to the dedicated suites
// (`table-ship-classes.test.ts`, `designer-ship-class.test.ts`); the
// `table.svelte` router still falls back to the stub for the
// not-yet-implemented entities (planets, ship-groups, fleets,
// sciences, races) and that fallback is exercised here.
import "@testing-library/jest-dom/vitest";
import { render } from "@testing-library/svelte";
import { beforeEach, describe, expect, test } from "vitest";
import { i18n } from "../src/lib/i18n/index.svelte";
import MapView from "../src/lib/active-view/map.svelte";
import TableView from "../src/lib/active-view/table.svelte";
import ReportView from "../src/lib/active-view/report.svelte";
import BattleView from "../src/lib/active-view/battle.svelte";
import MailView from "../src/lib/active-view/mail.svelte";
import DesignerScience from "../src/lib/active-view/designer-science.svelte";
beforeEach(() => {
i18n.resetForTests("en");
});
describe("active-view stubs", () => {
test("map view renders loading overlay when no game-state context is provided", () => {
// The live integration in `lib/active-view/map.svelte` (Phase 11)
// reads its data from a `GameStateStore` provided through context
// by `routes/games/[id]/+layout.svelte`. Without the context the
// store reference is `undefined` and the view stays in the
// `idle` branch, surfacing the localised loading overlay so the
// shell never renders an empty active-view slot.
const ui = render(MapView);
const node = ui.getByTestId("active-view-map");
expect(node).toHaveAttribute("data-status", "idle");
expect(ui.getByTestId("map-loading")).toBeInTheDocument();
expect(ui.getByTestId("map-canvas-wrap")).toBeInTheDocument();
});
test("table stub falls back for not-yet-implemented entities", () => {
const ui = render(TableView, { props: { entity: "planets" } });
const node = ui.getByTestId("active-view-table");
expect(node).toHaveAttribute("data-entity", "planets");
expect(node).toHaveTextContent("planets");
expect(node).toHaveTextContent("coming soon");
});
test("table stub also handles multi-word entities", () => {
const ui = render(TableView, { props: { entity: "ship-groups" } });
const node = ui.getByTestId("active-view-table");
expect(node).toHaveAttribute("data-entity", "ship-groups");
expect(node).toHaveTextContent("ship groups");
});
test("report / mail / designer-science stubs render their localised titles", () => {
const r = render(ReportView);
expect(r.getByTestId("active-view-report")).toHaveTextContent(
"turn report",
);
const m = render(MailView);
expect(m.getByTestId("active-view-mail")).toHaveTextContent(
"diplomatic mail",
);
const sci = render(DesignerScience);
expect(
sci.getByTestId("active-view-designer-science"),
).toHaveTextContent("science designer");
});
test("battle stub stamps the battleId on the host element", () => {
const ui = render(BattleView, { props: { battleId: "b-42" } });
const node = ui.getByTestId("active-view-battle");
expect(node).toHaveAttribute("data-battle-id", "b-42");
expect(node).toHaveTextContent("battle log");
});
test("battle stub accepts an empty battleId for the list URL", () => {
const ui = render(BattleView, { props: { battleId: "" } });
expect(ui.getByTestId("active-view-battle")).toHaveAttribute(
"data-battle-id",
"",
);
});
});