OverviewFilesCommitsIssuesDocsReleasesPeers

favela-community / test / cli.test.mjs

75 lines · javascript ref:
// favela-community CLI — drives run() against a temp storage: the local owner flow (create → manage →
// read) + the mod-not-admitted guard + arg/error handling. Cross-machine admission/replication is proven
// by community-room.test.mjs. Bare-native. Run: bare test/cli.test.mjs
import { run } from '../lib/cli.js'

const assert = (c, m) => { if (!c) { console.error('FAIL:', m); process.exit(1) } console.log('  ok -', m) }
const stamp = Date.now()
const STORE = 'data/cli-' + stamp + '/store'    // owner storage
const STORE2 = 'data/cli2-' + stamp + '/store'  // a separate mod's storage
const DID = 'did:plc:member2222222222222222222'

// capture out/err; return the parsed JSON of the last out line (commands use --json)
function cap () {
  const out = []; const err = []
  return { io: { out: (s) => out.push(String(s)), err: (s) => err.push(String(s)) }, out, err }
}
async function cli (args) {
  const c = cap()
  const code = await run(args, c.io)
  let json = null
  try { json = JSON.parse(c.out[c.out.length - 1]) } catch {}
  return { code, out: c.out, err: c.err, json }
}

// ── create (owner) ──
const created = await cli(['create', '--name', 'Test Community', '--storage', STORE, '--json'])
assert(created.code === 0 && created.json && /^[0-9a-f]{64}$/.test(created.json.roomKey), 'create → roomKey + exit 0')
assert(created.json.role === 'owner' && /^[0-9a-f]{64}$/.test(created.json.localKey), 'create reports owner + localKey')
const KEY = created.json.roomKey

// ── read: empty roster, meta from create ──
const m0 = await cli(['members', KEY, '--storage', STORE, '--json'])
assert(m0.code === 0 && Array.isArray(m0.json.members) && m0.json.members.length === 0, 'members (fresh) = []')
const meta0 = await cli(['meta', KEY, '--storage', STORE, '--json'])
assert(meta0.json.meta && meta0.json.meta.name === 'Test Community', 'meta.name set at create')

// ── owner writes: add-member, then read it back (writer identity persists via the namespace index) ──
const add = await cli(['add-member', KEY, DID, '--storage', STORE, '--json'])
assert(add.code === 0, 'add-member → exit 0 (owner is still writable on reopen)')
const m1 = await cli(['members', KEY, '--storage', STORE, '--json'])
assert(m1.json.members.length === 1 && m1.json.members[0] === DID, 'members now = [DID]')

// ── moderation: ban removes from roster ──
await cli(['ban', KEY, DID, '--storage', STORE, '--json'])
const m2 = await cli(['members', KEY, '--storage', STORE, '--json'])
assert(m2.json.members.length === 0, 'ban removes DID from the roster')

// ── set-meta update ──
await cli(['set-meta', KEY, 'name', 'Renamed', '--storage', STORE, '--json'])
const meta1 = await cli(['meta', KEY, '--storage', STORE, '--json'])
assert(meta1.json.meta.name === 'Renamed', 'set-meta updates name')

// ── mod (separate storage): join prints a localKey; writing without admission is refused ──
const join = await cli(['join', KEY, '--storage', STORE2, '--json'])
assert(join.code === 0 && /^[0-9a-f]{64}$/.test(join.json.localKey) && join.json.writable === false, 'join → mod localKey, not yet writable')
const badWrite = await cli(['add-member', KEY, DID, '--storage', STORE2, '--json'])
assert(badWrite.code === 1 && badWrite.err.some((e) => /not a writer/.test(e)), 'un-admitted mod CANNOT write (add-member refused)')

// ── local-key is stable for the mod (same as join) ──
const lk = await cli(['local-key', KEY, '--storage', STORE2, '--json'])
assert(lk.json.localKey === join.json.localKey, 'local-key is stable for a joined mod (namespace index)')

// ── errors / help ──
const bad = await cli(['members', 'not-a-key', '--storage', STORE, '--json'])
assert(bad.code === 1 && bad.err.some((e) => /64-hex roomKey/.test(e)), 'bad roomKey → exit 1 + message')
const help = await cli(['help'])
assert(help.code === 0 && help.out.some((l) => /favela-community/.test(l) && /create/.test(l)), 'help prints usage')
assert(help.out.some((l) => /discover/.test(l)), 'help lists the discover command')
const discNoArg = await cli(['discover', '--json'])
assert(discNoArg.code === 1 && discNoArg.err.some((e) => /usage: discover/.test(e)), 'discover with no query → exit 1 + usage (no DHT touched)')
const none = await cli([])
assert(none.code === 1, 'no command → exit 1 (usage)')

console.log('\nFAVELA-COMMUNITY CLI OK (Bare-native): owner create/manage/read + mod-not-admitted guard + errors')