// Vitest coverage for the pending-Send overlay. The overlay // renders a green dashed line from the source group's orbit // planet to the chosen destination for every wire-valid // `sendShipGroup` command in the order draft. import { describe, expect, test } from "vitest"; import type { GameReport, ReportLocalShipGroup, ReportPlanet, } from "../src/api/game-state"; import type { OrderCommand } from "../src/sync/order-types"; import { buildPendingSendLines } from "../src/map/pending-send-routes"; function planet(overrides: Partial & Pick): ReportPlanet { return { name: `P${overrides.number}`, kind: "uninhabited", owner: null, size: 1, resources: 1, industryStockpile: 0, materialsStockpile: 0, industry: 0, population: 0, colonists: 0, production: null, freeIndustry: 0, ...overrides, }; } function localGroup(overrides: Partial & Pick): ReportLocalShipGroup { return { count: 1, class: "Cruiser", tech: { drive: 1, weapons: 0, shields: 0, cargo: 0 }, cargo: "NONE", load: 0, origin: null, range: null, speed: 0, mass: 1, state: "In_Orbit", fleet: null, ...overrides, }; } function makeReport( overrides: Partial & Pick, ): GameReport { return { turn: 1, mapWidth: 200, mapHeight: 200, planetCount: overrides.planets.length, race: "Earthlings", localShipClass: [], localScience: [], routes: [], localPlayerDrive: 0, localPlayerWeapons: 0, localPlayerShields: 0, localPlayerCargo: 0, otherShipGroups: [], incomingShipGroups: [], unidentifiedShipGroups: [], localFleets: [], otherRaces: [], races: [], myVotes: 0, myVoteFor: "", ...overrides, }; } const SOURCE_PLANET = planet({ number: 1, x: 100, y: 100, kind: "local" }); const DEST_PLANET = planet({ number: 2, x: 110, y: 100, kind: "uninhabited" }); const GROUP_ID = "11111111-1111-1111-1111-111111111111"; describe("buildPendingSendLines", () => { test("emits a dashed line from the orbit planet to the destination", () => { const report = makeReport({ planets: [SOURCE_PLANET, DEST_PLANET], localShipGroups: [localGroup({ id: GROUP_ID, destination: 1 })], }); const cmd: OrderCommand = { kind: "sendShipGroup", id: "cmd-1", groupId: GROUP_ID, destinationPlanetNumber: 2, }; const lines = buildPendingSendLines(report, [cmd], { "cmd-1": "valid" }); expect(lines).toHaveLength(1); const line = lines[0]!; expect(line.kind).toBe("line"); expect(line.x1).toBe(100); expect(line.y1).toBe(100); expect(line.x2).toBe(110); expect(line.y2).toBe(100); expect(line.style.strokeDashPx).toBeGreaterThan(0); expect(line.style.strokeColor).toBe(0x66bb6a); }); test("uses the torus-shortest path across the seam", () => { const report = makeReport({ mapWidth: 100, mapHeight: 100, planets: [ planet({ number: 1, x: 95, y: 50, kind: "local" }), planet({ number: 2, x: 5, y: 50 }), ], localShipGroups: [localGroup({ id: GROUP_ID, destination: 1 })], }); const cmd: OrderCommand = { kind: "sendShipGroup", id: "cmd-1", groupId: GROUP_ID, destinationPlanetNumber: 2, }; const lines = buildPendingSendLines(report, [cmd], { "cmd-1": "valid" }); expect(lines).toHaveLength(1); expect(lines[0]!.x1).toBe(95); expect(lines[0]!.x2).toBe(105); // 95 + (+10) wrap delta }); test("ignores commands targeting groups missing from the report", () => { const report = makeReport({ planets: [SOURCE_PLANET, DEST_PLANET], localShipGroups: [], }); const cmd: OrderCommand = { kind: "sendShipGroup", id: "cmd-1", groupId: GROUP_ID, destinationPlanetNumber: 2, }; expect(buildPendingSendLines(report, [cmd], { "cmd-1": "valid" })).toEqual( [], ); }); test("ignores commands when the source group is in hyperspace", () => { const report = makeReport({ planets: [SOURCE_PLANET, DEST_PLANET], localShipGroups: [ localGroup({ id: GROUP_ID, destination: 1, origin: 2, range: 5, state: "In_Space", }), ], }); const cmd: OrderCommand = { kind: "sendShipGroup", id: "cmd-1", groupId: GROUP_ID, destinationPlanetNumber: 2, }; expect(buildPendingSendLines(report, [cmd], { "cmd-1": "valid" })).toEqual( [], ); }); test("skips rejected and invalid commands", () => { const report = makeReport({ planets: [SOURCE_PLANET, DEST_PLANET], localShipGroups: [localGroup({ id: GROUP_ID, destination: 1 })], }); const cmd: OrderCommand = { kind: "sendShipGroup", id: "cmd-1", groupId: GROUP_ID, destinationPlanetNumber: 2, }; expect( buildPendingSendLines(report, [cmd], { "cmd-1": "rejected" }), ).toEqual([]); expect( buildPendingSendLines(report, [cmd], { "cmd-1": "invalid" }), ).toEqual([]); }); test("ignores non-sendShipGroup commands", () => { const report = makeReport({ planets: [SOURCE_PLANET, DEST_PLANET], localShipGroups: [localGroup({ id: GROUP_ID, destination: 1 })], }); const cmd: OrderCommand = { kind: "dismantleShipGroup", id: "cmd-1", groupId: GROUP_ID, }; expect(buildPendingSendLines(report, [cmd], { "cmd-1": "valid" })).toEqual( [], ); }); });