deadhead-space-freight-tycoon/apps/web/test/attention.test.tsx

69 lines
2.5 KiB
TypeScript

import type { PlayerState, Ship } from "@deadhead/schema";
import { screen, within } from "@testing-library/react";
import { describe, expect, it } from "vitest";
import { tabAttention } from "../src/layout/attention";
import { fakeApi, renderApp, samplePlayerState } from "./render";
const ship = (overrides: Partial<Ship>): Ship => ({
id: "s",
modelId: "courier",
name: "Ship",
status: "idle",
locationId: "earth",
dispatchId: null,
lastArrivalAt: 0,
pilotId: null,
...overrides,
});
const base = samplePlayerState();
const avatar = base.pilots[0]!;
const owner = (overrides: Partial<PlayerState>) =>
samplePlayerState({ tutorial: null, bays: [{ id: "b", locationId: "earth" }], ...overrides });
describe("navigation attention badges (Step 10E.3)", () => {
it("counts ready goals, ships ready for a job and pilots with skill points", () => {
const state = owner({
goals: [
{ id: "a", status: "ready" },
{ id: "b", status: "incomplete" },
{ id: "c", status: "ready" },
],
ships: [
ship({ id: "s1", pilotId: "avatar" }), // ready
ship({ id: "s2", pilotId: "p2" }), // pilot resting
ship({ id: "s3", pilotId: null }), // uncrewed
ship({ id: "s4", pilotId: "p3", status: "in-flight", locationId: null }),
],
pilots: [
{ ...avatar, assignedShipId: "s1", skillPointsAvailable: 2 },
{
...avatar,
id: "p2",
isAvatar: false,
assignedShipId: "s2",
resting: true,
restEndsAt: 1,
},
{ ...avatar, id: "p3", isAvatar: false, assignedShipId: "s4", skillPointsAvailable: 1 },
],
} as Partial<PlayerState>);
expect(tabAttention(state)).toEqual({ "/": 2, "/contracts": 1, "/pilots": 2 });
});
it("nudges toward Jobs during the tutorial until a run is in flight", () => {
expect(tabAttention(base)["/contracts"]).toBe(1);
const flying = samplePlayerState({ tutorial: { ...base.tutorial!, runInFlight: true } });
expect(tabAttention(flying)["/contracts"]).toBe(0);
});
it("shows a badge without changing the tab's accessible name", async () => {
renderApp(fakeApi({ getPlayerState: () => base }));
const nav = await screen.findByRole("navigation", { name: "Main" });
const jobs = within(nav).getByRole("link", { name: "Jobs" });
expect(within(jobs).getByTestId("badge-Jobs")).toHaveTextContent("1");
expect(within(nav).queryByTestId("badge-Pilots")).not.toBeInTheDocument();
});
});