OverviewFilesCommitsIssuesDocsReleasesPeers

favela-node / test / publish.test.mjs

55 lines · javascript ref:
// favela-node phase 3 — publish the lens-export records into the community DID's co-owned repo:
//   app.bsky.feed.generator (did = the community DID = its own service) + app.bsky.labeler.service.
// Single-node (co-signing across admins is proven in community.test.mjs); here we assert the records are
// written + read back with the correct atproto shape. Run: bare test/publish.test.mjs
import '../lib/bare-globals.js'
import Corestore from 'corestore'
import { createCommunity, publishFeedGenerator, publishLabelerService } from '../index.js'

const assert = (c, m) => { if (!c) { console.error('FAIL:', m); process.exit(1) } console.log('  ok -', m) }
const stamp = Date.now()
const tmp = (s) => `data/fn-pub-${s}-${stamp}`
const ROOT = 'abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about'
const FOUNDER = 'legal winner thank year wave sausage worth useful legal winner thank yellow'
const CTS = '2026-07-15T00:00:00.000Z'

const roomStore = new Corestore(tmp('room'))
const c = await createCommunity({
  rootMnemonic: ROOT, founderDeviceMnemonic: FOUNDER, name: 'Cat Lovers',
  roomStore, repoStorage: tmp('repo'), handle: 'catlovers.test', network: false
})
assert(/^did:plc:/.test(c.did), 'community minted a did:plc (single-node, no network)')

// ── phase 2: the community DID declares its feed-generator + labeler services at GENESIS ──
const op = c.identity.signedOp
assert(op.services.bsky_fg && op.services.bsky_fg.type === 'BskyFeedGenerator', 'genesis declares #bsky_fg (feed generator) → the membrane')
assert(op.services.atproto_labeler && op.services.atproto_labeler.type === 'AtprotoLabeler', 'genesis declares #atproto_labeler → the membrane')
assert(op.verificationMethods.atproto_label === op.verificationMethods.atproto, '#atproto_label VM = the shared #atproto signing key (labels co-signed by it)')

// ── app.bsky.feed.generator — the group OWNS the record; the record's `did` = a did:web SERVICE ──
const SERVICE = 'did:web:favela.example.net'
const gen = await publishFeedGenerator(c.repo, c.did, { rkey: 'catlovers', displayName: 'Cat Lovers', description: 'meow', service: SERVICE, createdAt: CTS })
assert(gen.did === SERVICE, 'feed.generator.did = the did:web SERVICE (favela-web), NOT the group DID — group is the OWNER, did:web is the invisible engine (like graze.social)')
const genBack = await c.repo.getRecord('app.bsky.feed.generator', 'catlovers')
assert(genBack && genBack.$type === 'app.bsky.feed.generator' && genBack.did === SERVICE, 'feed.generator read back: $type + did:web service')
assert(genBack.displayName === 'Cat Lovers' && genBack.description === 'meow' && genBack.createdAt === CTS, 'feed.generator carries displayName/description/createdAt')
// the record lives in c.repo (= the group's repo) → the group is the CREATOR/owner; only the service is the did:web
const legacy = await publishFeedGenerator(c.repo, c.did, { rkey: 'legacyfeed', displayName: 'Legacy', createdAt: CTS })
assert(legacy.did === c.did, 'legacy fallback: no service → did = communityDid (back-compat for old callers)')

// ── app.bsky.labeler.service (rkey self) ──
const lab = await publishLabelerService(c.repo, { labelValues: ['spam', '!hide'], createdAt: CTS })
assert(lab.$type === 'app.bsky.labeler.service', 'labeler.service $type')
const labBack = await c.repo.getRecord('app.bsky.labeler.service', 'self')
assert(labBack && labBack.$type === 'app.bsky.labeler.service' && Array.isArray(labBack.policies.labelValues), 'labeler.service read back (rkey self) with policies.labelValues')
assert(labBack.policies.labelValues.includes('spam') && labBack.policies.labelValues.includes('!hide'), 'labeler.service declares its label values')

// ── both records coexist in the repo ──
const all = await c.repo.listRecords()
const has = (coll, rk) => all.some((r) => r.collection === coll && r.rkey === rk)
assert(has('app.bsky.feed.generator', 'catlovers') && has('app.bsky.labeler.service', 'self'), 'both records present in the community repo (listRecords)')

console.log('\nFAVELA-NODE PUBLISH OK: feed.generator + labeler.service written into the co-owned community repo (correct atproto shape)')
await c.sb.close(); await c.room.close()
try { await roomStore.close() } catch {}