// ── PLAN_FIXES §6 step 2, the module's half ─────────────────────────────── // // Each test here is one finding of the first player walk (2026-09-26), held // down so it cannot come back: // // • F13/F14 — a zone that expired in the game is recorded `expired` by core, // through `ctx.events.expired` (D170, D183) // • F8 — a plugin that loads with permissions re-syncs within a tick (D184) // • F7 — nothing is pushed to a game whose world is still loading, or // that the poll saw go away (the step-2 walk) // • D182 — the ZoneManager helper's state reaches the servers page const test = require('node:test') const assert = require('node:assert') const { fakeCtx } = require('./_fakes') /** A core whose `db.query` records every statement and answers from `answer`. */ function withCore(answer = () => []) { const statements = [] const ctx = fakeCtx({ db: { query: (sql, params = []) => { statements.push({ sql, params }) return Promise.resolve(answer(sql, params)) }, pool: {}, }, }) require('../core')._reset() require('../core').init(ctx) return { ctx, statements } } const item = (kind, over = {}) => ({ id: 1, t: 1, kind, frame: { kind, type: 'event', t: 1, serverId: 'main', wipeId: 'w-1', ...over }, }) // ── F13, F14 ─────────────────────────────────────────────────────────────── test('an expired zone is handed to core as the resource the zone step ledgered', async () => { const { ctx } = withCore() const { apply } = require('../ingest') // Protocol 13's frame: the entity's kind is `what`, and the frame keeps its own. await apply('srv-a', item('world.expired', { id: 'rg-13-35875416-1', what: 'zone', runId: '13' })) const calls = ctx.events.expired.calls assert.equal(calls.length, 1) // The same kind and ref `place()` filed it under — `:` — or core // would find no row to close. assert.deepEqual(calls[0][0], { kind: 'world', ref: 'srv-a:rg-13-35875416-1' }) }) test('a world.expired that names nothing is not passed on', async () => { const { ctx } = withCore() const { apply } = require('../ingest') await apply('srv-a', item('world.expired', { what: 'zone' })) assert.equal(ctx.events.expired.calls.length, 0) }) // ── F8 ───────────────────────────────────────────────────────────────────── test('a plugin that loads with permissions marks the permission sync dirty; one without does not', async () => { const { statements } = withCore() const { apply } = require('../ingest') const dirtying = () => statements.filter((s) => /UPDATE\s+rust_perm_sync\s+SET\s+dirty\s*=\s*1/i.test(s.sql)) await apply('srv-a', item('plugin.loaded', { name: 'PopupNotifications', version: '0.2.1', permissions: [] })) assert.equal(dirtying().length, 0, 'a plugin that registers nothing cannot change what a grant resolves to') await apply('srv-a', item('plugin.loaded', { name: 'Kits', version: '4.4.9', permissions: ['kits.admin', 'kits.vip'] })) assert.equal(dirtying().length, 1) assert.deepEqual(dirtying()[0].params, ['srv-a']) await apply('srv-a', item('plugin.unloaded', { name: 'Kits', permissions: ['kits.admin', 'kits.vip'] })) assert.equal(dirtying().length, 2, 'an unload is a reason too: its grants are now unresolved') }) // ── F7 ───────────────────────────────────────────────────────────────────── test('no permission sync goes to a world that is still loading — unless a human asked', () => { withCore() const permSync = require('../permSync') const sync = { state: 'ok', dirty: false, syncedHash: 'h1', bootId: 'boot-1', wipeId: 'w-1', lastAttemptAt: new Date() } const at = (state, force = false) => permSync.reasonToSync({ desiredHash: 'h1', sync, state, force }) // The first walk's restart sync: a new boot id, arriving before the save loaded. assert.equal(at({ bootId: 'boot-2', wipeId: 'w-1', worldReady: false }), null) assert.equal(at({ bootId: 'boot-2', wipeId: 'w-1', worldReady: true }), 'restart') // A plugin that never says is ready, as it always was (§28.6). assert.equal(at({ bootId: 'boot-2', wipeId: 'w-1', worldReady: null }), 'restart') assert.equal(permSync.reasonToSync({ desiredHash: 'h1', sync: null, state: { worldReady: false }, force: false }), null) assert.equal(at({ worldReady: false }, true), 'requested') }) test('no permission sync goes to a game the poll saw go away, however ready its last hello said it was', () => { // The step-2 walk, on Carbon: the sidecar came back and a due audit went out in // the same moment, 80 s before "Server startup complete". The stored hello was the // OLD boot's (same boot id, hence "audit" and not "restart", worldReady true); // only `online: 0` — written by the poll when the server went away — said the // game was not there. withCore() const permSync = require('../permSync') const stale = new Date(Date.now() - permSync.AUDIT_MS - 1000) const sync = { state: 'ok', dirty: false, syncedHash: 'h1', bootId: 'boot-1', wipeId: 'w-1', lastAttemptAt: stale } const at = (state, force = false) => permSync.reasonToSync({ desiredHash: 'h1', sync, state, force }) assert.equal(at({ online: 0, bootId: 'boot-1', wipeId: 'w-1', worldReady: true }), null) assert.equal(at({ online: false, bootId: 'boot-1', wipeId: 'w-1', worldReady: true }), null) // Back, with the new boot's hello still loading: held by worldReady, as before. assert.equal(at({ online: 1, bootId: 'boot-2', wipeId: 'w-1', worldReady: false }), null) // Loaded: the restart sync goes. assert.equal(at({ online: 1, bootId: 'boot-2', wipeId: 'w-1', worldReady: true }), 'restart') // The audit itself still runs for a server that is up. assert.equal(at({ online: 1, bootId: 'boot-1', wipeId: 'w-1', worldReady: true }), 'audit') // A human's "sync now" is not held. assert.equal(at({ online: 0 }, true), 'requested') }) test('no title push goes to a world that is still loading', async () => { withCore() const titleSync = require('../titleSync') const client = require('../sidecarClient') const original = client.titles let pushed = 0 client.titles = async () => { pushed += 1 return { ok: true, data: { kind: 'titles.ok' } } } try { const answer = await titleSync.syncOne( { id: 'srv-a', name: 'A' }, { online: true, protocol: 13, bootId: 'boot-2', wipeId: 'w-1', worldReady: false }, ) assert.equal(answer, null) assert.equal(pushed, 0) } finally { client.titles = original } }) test('worldReady and the zone helper are read out of the stored hello', async () => { withCore((sql) => /FROM rust_server_state/.test(sql) ? [ { serverId: 'a', worldReady: 'false', zoneHelper: '{"state":"missing"}' }, { serverId: 'b', worldReady: 'true', zoneHelper: '{"state":"patched","version":"0.1.0"}' }, { serverId: 'c', worldReady: null, zoneHelper: null }, { serverId: 'd', worldReady: 'true', zoneHelper: '{"state":"unsupported","reason":"no Zone.InitializeZone"}' }, { serverId: 'e', worldReady: 'true', zoneHelper: 'not json' }, ] : [], ) const serversDb = require('../model/servers/servers.db') const rows = await serversDb.listState() const by = Object.fromEntries(rows.map((r) => [r.serverId, r])) assert.equal(by.a.worldReady, false) assert.equal(by.b.worldReady, true) assert.equal(by.c.worldReady, null) assert.deepEqual(by.a.zoneHelper, { state: 'missing' }) assert.deepEqual(by.b.zoneHelper, { state: 'patched', version: '0.1.0' }) assert.equal(by.c.zoneHelper, null) assert.deepEqual(by.d.zoneHelper, { state: 'unsupported', reason: 'no Zone.InitializeZone' }) assert.equal(by.e.zoneHelper, null, 'an unreadable value is no report, not a crash') })