// ── What core's settings no longer know about ────────────────────────────── // // Phase 3, slice 3. `game_account_signup` policy left core: the mode list, the // derived public flag, the validation and the Site Settings field. The row in // the `settings` table is untouched and module-uo reads it through // `ctx.settings`, which is the whole point — the DATA stays, the SEMANTICS move. // // This file exists because the deletion passed 616 tests without one of them // noticing. Nothing asserted the shape of `getPublic()`, so a field could leave // the public settings payload — which the SPA, the Android app and the Discord // bot all read — and no suite would say a word. That is worth a test in the // direction of "and it is gone", but it is much more worth one in the direction // of "and nothing else went with it". process.env.DB_HOST = '127.0.0.1' process.env.DB_PORT = '59999' const { test, after, afterEach } = require('node:test') const assert = require('node:assert/strict') const settings = require('../src/model/settings/settings.model') const settingsDb = require('../src/model/settings/settings.db') const db = require('../src/utils/db') after(() => db.close()) const originals = { getAll: settingsDb.getAll, get: settingsDb.get } afterEach(() => Object.assign(settingsDb, originals)) // Both readers, because the two halves of this test read different ones: // `getPublic` folds `getAll`, and a module's `ctx.settings.get` is `get`. const withRows = (rows) => { settingsDb.getAll = async () => Object.entries(rows).map(([key, value]) => ({ key, value })) settingsDb.get = async (key) => (key in rows ? rows[key] : null) } test('the public settings payload no longer carries gameAccountSignup', async () => { // Configured as it would be on a live instance that had the feature on. The // row is still there and still readable — it is simply not core's to interpret. withRows({ site_title: 'Test', game_account_signup: 'hybrid' }) const out = await settings.getPublic() assert.equal('gameAccountSignup' in out, false) }) test('and the raw row is still there for the module to read', async () => { // The load-bearing half. Renaming or dropping the key would silently reset // every configured instance to `disabled`, with players reporting that signup // stopped working as the only clue. withRows({ game_account_signup: 'hybrid' }) assert.equal(await settings.get('game_account_signup'), 'hybrid') }) test('the rest of the public payload is unchanged', async () => { // The assertion the deletion actually needed: three clients read this object // and none of them are in this repo. Registration flags are the near // neighbour — same shape, same file, same derived-from-a-mode pattern — and // the one most likely to be taken along by an over-eager edit. withRows({ site_title: 'Test', player_registration: 'both', game_account_signup: 'hybrid', }) const out = await settings.getPublic() assert.deepEqual(out.registration, { password: true, sso: true }) assert.equal(out.site_title, 'Test') }) test('core no longer exports the game-signup policy', () => { // A leftover export is a leftover consumer waiting to happen, and the module // has its own copy now. `ctx.settings` is three functions and never included // these, so nothing outside core could have been using them. for (const name of ['GAME_SIGNUP_KEY', 'GAME_SIGNUP_MODES', 'getGameSignupMode', 'isGameAccountSignupEnabled']) { assert.equal(name in settings, false, `settings still exports ${name}`) } })