OverviewFilesCommitsIssuesDocsReleasesPeers

hyper-proto-peer / test / label-uds.test.mjs

96 lines · javascript ref:
// label-intent / label-list — the local surface a projector uses to label (member labels, hyper-social #80).
//
// The gateway's member projector calls label-intent for each roster member (and with neg:true when one
// leaves) on the labeler DID's local control socket. It re-asserts the whole set on every roster change,
// so the verb must be idempotent: an unchanged state writes nothing (LabelRoom.ensure). A DID that is not
// a labeler answers with an error that says so, not an unknown-method error.
//
// Run: bare test/label-uds.test.mjs
import '../lib/bare-globals.js'
import test from 'brittle'
import fs from 'bare-fs'
import { join } from 'bare-path'
import { Client } from 'hyper-svc'
import { serveDeviceUds } from '../lib/serve-device-uds.js'
import { LabelRoom } from 'atproto-room/lib/label-room.js'

const SRC = 'did:plc:wqnwulql7ndcz6xmtvaovl6u'
const WJ = 'did:plc:wj62ebbusln6gxo5azo6ogzo'
const KEY = new Uint8Array(32).fill(44)
const tmp = () => { const d = '/tmp/hpp-lu-' + Math.floor(Math.random() * 1e9); fs.mkdirSync(d, { recursive: true }); return d }
const device = { state: () => ({ ok: true }), membersDiag: async () => ({}), did: SRC }

function mockSb () {
  const m = new Map()
  let writes = 0
  return {
    writes: () => writes,
    async set (k, v) { writes++; m.set(k, v) },
    async del (k) { m.delete(k) },
    async get (k) { return m.has(k) ? m.get(k) : null },
    async list (prefix) { const o = {}; for (const [k, v] of m) if (k.startsWith(prefix)) o[k] = v; return o }
  }
}

async function serve (t, labels) {
  const uds = join(tmp(), 'c.sock')
  const s = await serveDeviceUds(device, { uds, labels })
  const c = await Client.connectUds(uds)
  t.teardown(async () => { try { await c.close() } catch {} ; try { await s.close() } catch {} })
  return c
}

test('★ label-intent is idempotent; label-list shows intents and how many are signed', async (t) => {
  const sb = mockSb()
  const room = new LabelRoom(sb, { src: SRC, privateKey: KEY, holds: () => true, ns: '__labelintent__' })
  const c = await serve(t, room)

  const a = await c.call('label-intent', { uri: WJ, val: 'loser-club-member' })
  t.is(a.changed, true, 'a new label is written')
  const n = sb.writes()
  const b = await c.call('label-intent', { uri: WJ, val: 'loser-club-member' })
  t.is(b.changed, false, 'the same label again is not')
  t.is(sb.writes(), n, 'and writes nothing')

  await room.tick()
  const l = await c.call('label-list', {})
  t.is(l.intents.length, 1)
  t.alike({ uri: l.intents[0].uri, val: l.intents[0].val, neg: l.intents[0].neg }, { uri: WJ, val: 'loser-club-member', neg: false })
  t.is(l.signed, 1, 'one label in the signed log')

  const g = await c.call('label-intent', { uri: WJ, val: 'loser-club-member', neg: true })
  t.is(g.changed, true, 'a negation is a change')
})

// ⛔ DIAGNOSE WHAT THE GATE SEES. 2026-10-14: loser-club's member labels were never re-signed with `ver`, both
// co-owners logged nothing, and get-state's holdsSigner (asked WITHOUT the network head) said stortron while the
// label gate asks WITH it. label-list now answers both questions on the device itself: would this device's label
// tick sign right now (the same holds() the tick calls), and what is actually in the signed log, ver included.
test('label-list reports the label gate and each signed label with its ver', async (t) => {
  const sb = mockSb()
  let gate = true
  const room = new LabelRoom(sb, { src: SRC, privateKey: KEY, holds: () => gate, ns: '__labelintent__' })
  const c = await serve(t, room)
  await c.call('label-intent', { uri: WJ, val: 'loser-club-member' })
  await room.tick()
  const l = await c.call('label-list', {})
  t.is(l.holds, true, 'holds: the gate the tick asks')
  t.is(l.labels.length, 1)
  t.alike({ uri: l.labels[0].uri, val: l.labels[0].val, ver: l.labels[0].ver, neg: l.labels[0].neg }, { uri: WJ, val: 'loser-club-member', ver: 1, neg: false })
  t.ok(typeof l.labels[0].cts === 'string', 'with its cts')
  t.is(l.projection, null, 'projection: null until the label room has projected into a core')
  gate = false
  t.is((await c.call('label-list', {})).holds, false, 'and it follows the election')
})

test('label-intent checks its input', async (t) => {
  const c = await serve(t, new LabelRoom(mockSb(), { src: SRC, privateKey: KEY, holds: () => true, ns: '__labelintent__' }))
  await t.exception(() => c.call('label-intent', { uri: WJ }), /val/)
})

test('a DID that is not a labeler says so', async (t) => {
  const c = await serve(t, null)
  await t.exception(() => c.call('label-intent', { uri: WJ, val: 'x' }), /not a labeler/)
  await t.exception(() => c.call('label-list', {}), /not a labeler/)
})