OverviewFilesCommitsIssuesDocsReleasesPeers

favela-web / test / strongref.test.mjs

47 lines · javascript ref:
// strongRef — { uri, cid } for a referenced record. Run: node test/strongref.test.mjs
//
// A like written as `subject: { uri }` indexes perfectly in favela and is INVALID to bsky:
// app.bsky.feed.like.subject is a strongRef where uri AND cid are both required, so the relay's lexicon
// validation drops it. It federates as nothing while the local UI shows a like. Shipped in 0.2.41 and
// caught only because the likes never appeared on bsky — so these tests exist to make that shape
// impossible to ship again.
import { parseAtUri, strongRef } from '../lib/strongref.js'
import { cidForBytesSync } from 'atproto-repo/lib/cid.js'
import * as dagCbor from '@ipld/dag-cbor'
import b4a from 'b4a'

let pass = 0
const ok = (c, m) => { if (!c) { console.error('FAIL:', m); process.exit(1) } console.log('  ok -', m); pass++ }

// Strict parsing: a malformed uri must not half-parse into a lookup against the wrong record.
ok(JSON.stringify(parseAtUri('at://did:plc:a/app.bsky.feed.post/r1')) === JSON.stringify({ did: 'did:plc:a', collection: 'app.bsky.feed.post', rkey: 'r1' }), 'a well-formed at:// uri parses')
ok(parseAtUri('at://did:plc:a/app.bsky.feed.post') === null, 'a uri missing the rkey is refused')
ok(parseAtUri('at://did:plc:a/app.bsky.feed.post/r1/extra') === null, 'a uri with too many segments is refused')
ok(parseAtUri('https://example.com/x/y') === null, 'a non-at:// uri is refused')
ok(parseAtUri('at://notadid/app.bsky.feed.post/r1') === null, 'a subject that is not a did is refused')
ok(parseAtUri('at://did:plc:a/nodots/r1') === null, 'a collection that is not an nsid is refused')
ok(parseAtUri(null) === null, 'null is refused')

// The cid must be of the EXACT stored bytes, never a re-encode.
const record = { $type: 'app.bsky.feed.post', text: 'hi', createdAt: '2026-07-20T00:00:00.000Z' }
const bytes = b4a.from(dagCbor.encode(record))
const expected = String(cidForBytesSync(bytes))
const store = { getRaw: async (c, r) => (c === 'app.bsky.feed.post' && r === 'r1') ? { bytes, record } : null }
const getRecordStore = async (did) => (did === 'did:plc:a' ? store : null)

const ref = await strongRef('at://did:plc:a/app.bsky.feed.post/r1', getRecordStore)
ok(ref && ref.uri === 'at://did:plc:a/app.bsky.feed.post/r1', 'the ref carries the uri')
ok(ref && ref.cid === expected, 'and the cid of the exact stored bytes')
ok(ref && String(ref.cid).startsWith('bafyrei'), 'which is a dag-cbor cid (bafyrei…), matching the fleet\'s existing like records')

// Every "cannot resolve" path must return NULL, so the caller refuses to write rather than writing a
// uri-only subject. Returning a partial ref would recreate the original bug.
ok((await strongRef('at://did:plc:a/app.bsky.feed.post/missing', getRecordStore)) === null, 'an absent record yields null, never a uri-only ref')
ok((await strongRef('at://did:plc:unknown/app.bsky.feed.post/r1', getRecordStore)) === null, 'an unknown did yields null')
ok((await strongRef('garbage', getRecordStore)) === null, 'a malformed uri yields null')
ok((await strongRef('at://did:plc:a/app.bsky.feed.post/r1', null)) === null, 'no store yields null')
ok((await strongRef('at://did:plc:a/app.bsky.feed.post/r1', async () => ({}))) === null, 'a store without getRaw yields null rather than throwing')
ok((await strongRef('at://did:plc:a/app.bsky.feed.post/r1', async () => { throw new Error('boom') })) === null, 'a throwing store yields null rather than propagating')

console.log(`\nSTRONGREF OK: ${pass} assertions`)