Files
healer-man/src/game/partyNavigationPolicy.test.ts
T
2026-09-12 14:25:23 -04:00

100 lines
3.3 KiB
TypeScript

import { describe, expect, it } from "vitest";
import { requireDungeonDefinition } from "./dungeonRegistry";
import {
MAX_SYNCHRONOUS_PARTY_NAVIGATION_TRIANGLES,
partyObjectivesForNavigation,
shouldLoadPartyNavigation,
} from "./partyNavigationPolicy";
import type { DungeonDefinition } from "./dungeonTypes";
import type { ManastormStageAssetPackage } from "./manastormStageAssets";
function manastormPackageWithNavigationTriangles(
triangleCount: number | undefined,
): Pick<ManastormStageAssetPackage, "navigation"> {
return {
navigation: {
id: "navigation",
url: "/navigation.glb",
checksum: "0".repeat(64),
compression: "none",
triangleCount,
},
};
}
function dungeonWithNavigation(
status: DungeonDefinition["validation"]["status"],
triangleCount: number,
navigation?: DungeonDefinition["validation"]["navigation"],
): Pick<DungeonDefinition, "assets" | "validation"> {
return {
assets: {
visual: [],
collision: [],
navigation: { id: "navigation", fileName: "navigation.glb", triangleCount },
},
validation: { status, navigation, blockers: [], warnings: [] },
};
}
describe("party navigation loading policy", () => {
it("keeps reviewed, budgeted dungeon navigation enabled", () => {
const wailingCaverns = requireDungeonDefinition("wailing-caverns");
expect(shouldLoadPartyNavigation("dungeon", wailingCaverns, null)).toBe(true);
});
it("does not schedule Shadowfang Keep's unvalidated oversized navigation graph", () => {
const shadowfangKeep = requireDungeonDefinition("shadowfang-keep");
expect(shadowfangKeep.validation.status).toBe("unvalidated");
expect(shadowfangKeep.assets.navigation?.triangleCount).toBeGreaterThan(
MAX_SYNCHRONOUS_PARTY_NAVIGATION_TRIANGLES,
);
expect(shouldLoadPartyNavigation("dungeon", shadowfangKeep, null)).toBe(false);
});
it("keeps unvalidated regular dungeons on breadcrumb following even under budget", () => {
expect(shouldLoadPartyNavigation(
"dungeon",
dungeonWithNavigation("unvalidated", 1_000),
null,
)).toBe(false);
});
it("loads an independently reviewed dungeon navigation graph", () => {
expect(shouldLoadPartyNavigation(
"dungeon",
dungeonWithNavigation("unvalidated", 1_000, "green"),
null,
)).toBe(true);
});
it("protects Manastorm from oversized or unmeasured synchronous graphs", () => {
const fallbackDungeon = requireDungeonDefinition("wailing-caverns");
expect(shouldLoadPartyNavigation(
"manastorm",
fallbackDungeon,
manastormPackageWithNavigationTriangles(MAX_SYNCHRONOUS_PARTY_NAVIGATION_TRIANGLES),
)).toBe(true);
expect(shouldLoadPartyNavigation(
"manastorm",
fallbackDungeon,
manastormPackageWithNavigationTriangles(MAX_SYNCHRONOUS_PARTY_NAVIGATION_TRIANGLES + 1),
)).toBe(false);
expect(shouldLoadPartyNavigation(
"manastorm",
fallbackDungeon,
manastormPackageWithNavigationTriangles(undefined),
)).toBe(false);
});
it("exposes objectives only after a usable navigation graph is ready", () => {
const objectives = [{ id: "boss", name: "Boss", position: [1, 2, 3] as const }];
expect(partyObjectivesForNavigation(false, objectives)).toEqual([]);
expect(partyObjectivesForNavigation(true, objectives)).toBe(objectives);
});
});