const { test, beforeEach } = require('node:test') const assert = require('node:assert/strict') // Term capture lives in the model (shardState.model.upsertGovernor → // recordGovernorTransition) and talks to the db module. We exercise the real // logic against an in-memory fake by monkeypatching the shared db module object // (same instance the model require()s) — no DB, no mocking library. const db = require('../src/model/shardState/shardState.db') const model = require('../src/model/shardState/shardState.model') let terms // in-memory shard_governor_terms let nextId const saved = {} beforeEach(() => { terms = [] nextId = 1 for (const k of ['currentGovernorTerm', 'closeGovernorTerm', 'openGovernorTerm', 'upsertGovernor']) { saved[k] = db[k] } db.currentGovernorTerm = async (city) => terms.find((t) => t.city === city && t.ended_at === null) || null db.closeGovernorTerm = async (id, endedAt) => { const row = terms.find((t) => t.id === id) if (row) row.ended_at = endedAt } db.openGovernorTerm = async ({ city, serial, name, acct, webId, startedAt }) => { terms.push({ id: nextId++, city, governor_serial: serial, governor_name: name, governor_acct: acct, governor_web_id: webId, started_at: startedAt, ended_at: null }) } db.upsertGovernor = async () => {} // snapshot write — irrelevant to term capture }) function restore() { for (const k of Object.keys(saved)) db[k] = saved[k] } test('a repeated city.update with the same governor does NOT open a second term', async () => { await model.upsertGovernor({ city: 'Britain', governor: { serial: '0x1', name: 'Darrow' }, t: 100 }) await model.upsertGovernor({ city: 'Britain', governor: { serial: '0x1', name: 'Darrow' }, t: 200 }) const open = terms.filter((t) => t.ended_at === null) assert.equal(terms.length, 1) assert.equal(open.length, 1) assert.equal(open[0].governor_serial, '0x1') assert.equal(open[0].started_at, 100) restore() }) test('a governor change closes the old term and opens a new one', async () => { await model.upsertGovernor({ city: 'Britain', governor: { serial: '0x1', name: 'Darrow' }, t: 100 }) await model.upsertGovernor({ city: 'Britain', governor: { serial: '0x2', name: 'Mira' }, t: 300 }) assert.equal(terms.length, 2) const [first, second] = terms assert.equal(first.governor_serial, '0x1') assert.equal(first.ended_at, 300) // closed at the transition time assert.equal(second.governor_serial, '0x2') assert.equal(second.ended_at, null) // now current assert.equal(second.started_at, 300) restore() }) test('a seat going vacant closes the term without opening a new one', async () => { await model.upsertGovernor({ city: 'Britain', governor: { serial: '0x1', name: 'Darrow' }, t: 100 }) await model.upsertGovernor({ city: 'Britain', governor: null, t: 400 }) assert.equal(terms.length, 1) assert.equal(terms[0].ended_at, 400) restore() }) test('terms are tracked independently per city', async () => { await model.upsertGovernor({ city: 'Britain', governor: { serial: '0x1' }, t: 100 }) await model.upsertGovernor({ city: 'Minoc', governor: { serial: '0x9' }, t: 120 }) await model.upsertGovernor({ city: 'Britain', governor: { serial: '0x1' }, t: 200 }) // dup, no-op assert.equal(terms.length, 2) assert.equal(terms.filter((t) => t.ended_at === null).length, 2) restore() })