const { test, beforeEach } = require('node:test') const assert = require('node:assert/strict') const shardIngest = require('../src/utils/shardIngest') // Protocol 3.0 points.board routing. Same shape as shardIngest.ruleset.test.js: // stubbed deps, asserting where the dispatcher sends the frame and whether it is // appended to the event log. function makeDeps() { const calls = { boards: [], appended: [], broadcast: [] } const noop = async () => {} return { calls, shardEvents: { append: async (row) => { calls.appended.push(row); return true } }, shardState: { upsertPointsBoard: async (ev) => { calls.boards.push(ev) }, // Present so any stray routing is a harmless no-op. clearOnline: noop, upsertOnline: noop, setOffline: noop, upsertHouse: noop, addEconomySample: noop, setRuleset: noop, }, shardLinks: { removeByAccount: noop }, uoLinkConfig: { recordStatus: noop }, broadcast: (ev) => { calls.broadcast.push(ev) }, pushDispatch: async () => {}, log: { warn() {}, info() {}, error() {} }, } } const FRAME = { kind: 'points.board', t: 1000, system: 'QueensLoyalty', nameString: "Queen's Loyalty", nameNumber: 1114938, maxPoints: 30000, showOnGump: true, players: 842, top: [ { rank: 1, serial: '0x1A2B', name: 'Darrow', points: 29500 }, { rank: 2, serial: '0x1A2C', name: 'Mireille', points: 21000 }, ], } beforeEach(() => shardIngest.reset()) test('points.board routes to upsertPointsBoard with the whole frame', async () => { const deps = makeDeps() await shardIngest.ingest(FRAME, deps) assert.equal(deps.calls.boards.length, 1) const stored = deps.calls.boards[0] assert.equal(stored.system, 'QueensLoyalty') assert.equal(stored.nameNumber, 1114938) assert.equal(stored.players, 842) // The ranked list must survive intact — the read model serves it from the payload. assert.equal(stored.top.length, 2) assert.equal(stored.top[0].name, 'Darrow') }) // A board is state, not an event. The shard emits a frame every time anyone's // score moves the top ten, so logging would grow shard_events without bound for // something whose only interesting value is its latest version — the same call // guild.update already makes. test('points.board is NOT appended to the event log', async () => { const deps = makeDeps() const r = await shardIngest.ingest(FRAME, deps) assert.equal(r.logged, false) assert.equal(deps.calls.appended.length, 0) assert.equal(shardIngest.LOGGED_KINDS.has('points.board'), false) }) test('points.board is broadcast (the leaderboards page updates live)', async () => { const deps = makeDeps() await shardIngest.ingest(FRAME, deps) assert.equal(deps.calls.broadcast.length, 1) assert.equal(deps.calls.broadcast[0].kind, 'points.board') }) test('a backfilled points.board still stores but does not broadcast', async () => { const deps = makeDeps() await shardIngest.ingest(FRAME, { ...deps, fromBackfill: true }) assert.equal(deps.calls.boards.length, 1) assert.equal(deps.calls.broadcast.length, 0) }) // Each system is its own row, so two systems must not collide — this is the whole // reason the frame is per-system rather than one board of everything. test('two systems are stored independently', async () => { const deps = makeDeps() await shardIngest.ingest(FRAME, deps) await shardIngest.ingest({ ...FRAME, system: 'CleanUpBritannia', nameString: null }, deps) assert.deepEqual(deps.calls.boards.map((b) => b.system), ['QueensLoyalty', 'CleanUpBritannia']) }) // A re-emitted board is an overwrite of one row, never an append. test('a repeated points.board overwrites rather than accumulating', async () => { const deps = makeDeps() await shardIngest.ingest(FRAME, deps) await shardIngest.ingest({ ...FRAME, t: 2000, players: 843 }, deps) assert.equal(deps.calls.appended.length, 0) assert.equal(deps.calls.boards.length, 2) // two writes... assert.equal(deps.calls.boards[1].system, 'QueensLoyalty') // ...of the same row }) // A model write that throws must not kill the feed. test('an upsertPointsBoard failure does not throw or stop the broadcast', async () => { const deps = makeDeps() deps.shardState.upsertPointsBoard = async () => { throw new Error('db down') } const r = await shardIngest.ingest(FRAME, deps) assert.equal(r.logged, false) assert.equal(deps.calls.broadcast.length, 1) })