const assert = require('node:assert/strict'); const fs = require('node:fs'); const path = require('node:path'); const test = require('node:test'); const app = fs.readFileSync(path.join(__dirname, '../../data/app.js'), 'utf8'); const page = fs.readFileSync(path.join(__dirname, '../../data/index.html'), 'utf8'); test('recovery UI is unavailable on registration and role-gates the global action', () => { assert.match(app, /name === 'connect' \|\| !token/); assert.match(app, /ui\.recoveryGlobal\.hidden = !isPlayer\(\)/); assert.match(page, /id="recovery-menu-button"[^>]*hidden/); }); test('recovery actions use distinct routes and clear the intended local scope', () => { assert.match(app, /\/api\/session\/leave/); assert.match(app, /\/api\/session\/profile-reset/); assert.match(app, /\/api\/game\/reset/); assert.match(app, /key\.startsWith\('battleship\.'\)/); assert.match(app, /clearLocalProfile\(action !== 'leave'\)/); }); test('global reset needs a timed hold while keyboard confirmation remains available', () => { assert.match(app, /window\.setTimeout\(submitRecovery, 2000\)/); assert.match(app, /pointercancel/); assert.match(app, /event\.detail === 0/); assert.match(app, /event\.key === 'Escape'/); });