Files
healer-man/src/game/runewakerDungeonRegistry.test.ts
T
2026-09-26 20:27:07 -04:00

61 lines
2.6 KiB
TypeScript

import { describe, expect, it } from "vitest";
import {
DUNGEON_DEFINITIONS,
dungeonCanEnter,
dungeonPackagePassesOfflineGate,
} from "./dungeonRegistry";
import { RUNEWAKER_DUNGEON_DEFINITIONS } from "./generated/runewakerDungeonDefinitions.generated";
import { isBiteSizedDungeonId } from "./dungeonContentSource";
describe("RuneWaker dungeon registry", () => {
it("registers every configured instance exactly once", () => {
expect(RUNEWAKER_DUNGEON_DEFINITIONS).toHaveLength(29);
const runewaker = DUNGEON_DEFINITIONS.filter((definition) => definition.expansion === "runewaker");
expect(runewaker).toHaveLength(33);
expect(runewaker.filter((definition) => !isBiteSizedDungeonId(definition.id))).toHaveLength(30);
expect(new Set(runewaker.map((definition) => definition.id)).size).toBe(33);
expect(runewaker.some((definition) => definition.id === "forsaken-abbey")).toBe(true);
});
it("exposes only green, packaged, offline definitions", () => {
for (const definition of RUNEWAKER_DUNGEON_DEFINITIONS) {
expect(definition.validation.status, definition.id).toBe("green");
expect(definition.assets.visual.length, definition.id).toBeGreaterThan(0);
expect(definition.assets.collision.length, definition.id).toBeGreaterThan(0);
expect(definition.assets.navigation?.fileName, definition.id).toMatch(/-navigation\.glb$/);
expect(dungeonCanEnter(definition.id), definition.id).toBe(true);
expect(JSON.stringify(definition)).not.toMatch(/serverEntry|SqlConnection|mssql/i);
}
});
it("keeps the offline package gate authoritative when generated availability keys are absent", () => {
const definition = RUNEWAKER_DUNGEON_DEFINITIONS[0];
expect(dungeonPackagePassesOfflineGate(definition)).toBe(true);
expect(dungeonPackagePassesOfflineGate({
...definition,
validation: {
...definition.validation,
status: "blocked",
blockers: ["missing packaged asset"],
},
})).toBe(false);
expect(dungeonPackagePassesOfflineGate({
...definition,
availability: "disabled",
})).toBe(false);
});
it("keeps RuneWaker runtime and spawn ids namespaced", () => {
for (const definition of RUNEWAKER_DUNGEON_DEFINITIONS) {
for (const [id, entity] of Object.entries(definition.entities)) {
expect(id, definition.id).toMatch(/^rw-/);
expect(entity.id, definition.id).toBe(id);
}
for (const spawn of definition.staticSpawns) {
expect(spawn.id, definition.id).toMatch(/^rw-/);
expect(spawn.entityId, definition.id).toMatch(/^rw-/);
}
}
});
});