diff --git a/tests/game-engine.test.mjs b/tests/game-engine.test.mjs index babe299..492842d 100644 --- a/tests/game-engine.test.mjs +++ b/tests/game-engine.test.mjs @@ -11,6 +11,7 @@ import { reset, validateLevel, } from '../game-engine.js'; +import { LEVELS } from '../levels.js'; const ONE_RELAY = [ '#########', @@ -117,3 +118,18 @@ test('two independent echoes can sustain a staged two-gate extraction route', () assert.equal(state.status, 'won'); assert.deepEqual(state.player, { x: 11, y: 1 }); }); + +test('three independent echoes sustain the cathedral-null extraction route end-to-end', () => { + const tripleRelay = LEVELS.find((level) => level.id === 'cathedral-null'); + let state = createGame(tripleRelay.map, { maxEchoes: 3 }); + + state = anchor(drive(state, 'DDRRRRR')); + state = anchor(drive(state, 'DDDDRRRRR')); + state = anchor(drive(state, 'RRR')); + + assert.deepEqual(getActiveGateIds(state), ['A', 'B', 'C']); + + state = drive(state, 'RRRRRRRRRRRR'); + assert.equal(state.status, 'won'); + assert.deepEqual(state.player, { x: 13, y: 1 }); +}); diff --git a/tests/shell.test.mjs b/tests/shell.test.mjs index 69ea0c6..d9d1ff6 100644 --- a/tests/shell.test.mjs +++ b/tests/shell.test.mjs @@ -12,6 +12,8 @@ test('the playable shell uses a local canvas entry point and no external runtime assert.match(html, /<\/script>/); assert.match(html, /data-action="anchor"/); assert.doesNotMatch(html, /<(?:script|link|img)\b[^>]+(?:src|href)\s*=\s*["']https?:\/\//i); + assert.doesNotMatch(html, /@import\s+(?:url\()?\s*["']?https?:\/\//i); + assert.doesNotMatch(html, /url\(\s*["']?https?:\/\//i); }); test('the runtime exposes a narrow smoke-test surface without network calls', () => {