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