deadhead-space-freight-tycoon/apps/web/test/fresh-board.test.tsx

76 lines
2.6 KiB
TypeScript

import type { Contract } from "@deadhead/schema";
import { screen, within } from "@testing-library/react";
import { describe, expect, it } from "vitest";
import { fakeApi, renderApp, samplePlayerState } from "./render";
const job = (id: string, payout: number): Contract => ({
id,
originId: "earth",
destinationId: "moon",
cargoTypeId: "standard",
goodId: "mail",
shipper: "Pacific Orbital Logistics",
priority: false,
deliveryWindowGameHours: null,
tier: 0,
massTonnes: 4,
payout,
requiredSkill: null,
requiredLongHaulLevel: 0,
offeredAt: Date.now(),
expiresAt: Date.now() + 600_000,
firstContact: false,
});
const owner = () => samplePlayerState({ tutorial: null, bays: [{ id: "b", locationId: "earth" }] });
function render(boards: Contract[][], periodMs = 600_000) {
let call = 0;
renderApp(
fakeApi({
getPlayerState: owner,
getContractBoard: () => ({
contracts: boards[Math.min(call++, boards.length - 1)]!,
periodEndsAt: Date.now() + periodMs,
}),
}),
"/contracts?location=earth",
);
}
const remember = (ids: string[]) =>
localStorage.setItem("deadhead:seen-board:earth", JSON.stringify(ids));
const card = async (payout: string) => (await screen.findByText(payout)).closest("li")!;
describe("visible board refresh (CR-008)", () => {
it("tags contracts that weren't on the last board seen here, and says so", async () => {
remember(["old-1", "old-2"]);
render([[job("old-1", 111), job("new-1", 222)]]);
expect(await screen.findByRole("status")).toHaveTextContent("New contracts posted");
expect(within(await card("222 cr")).getByText("New")).toBeInTheDocument();
expect(within(await card("111 cr")).queryByText("New")).not.toBeInTheDocument();
});
it("tags nothing when the board is the one already seen", async () => {
remember(["old-1"]);
render([[job("old-1", 111)]]);
await card("111 cr");
expect(screen.queryByRole("status")).not.toBeInTheDocument();
expect(screen.queryByText("New")).not.toBeInTheDocument();
});
it("tags nothing on a first visit, but remembers the board", async () => {
render([[job("a", 111)]]);
await card("111 cr");
expect(screen.queryByText("New")).not.toBeInTheDocument();
expect(JSON.parse(localStorage.getItem("deadhead:seen-board:earth")!)).toEqual(["a"]);
});
it("announces the new board when the timer rolls over while the page is open", async () => {
render([[job("a", 111)], [job("b", 222)]], 300);
await card("111 cr");
expect(await screen.findByRole("status")).toHaveTextContent("New contracts posted");
expect(within(await card("222 cr")).getByText("New")).toBeInTheDocument();
});
});