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(38); expect(runewaker.filter((definition) => !isBiteSizedDungeonId(definition.id))).toHaveLength(30); expect(new Set(runewaker.map((definition) => definition.id)).size).toBe(38); 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-/); } } }); });