// bsky-inbound.test.js — a Spacedust link on a bound DID's post becomes an observation (hyper-social #82, I2b).
//
// ⛔ THE SAME OBSERVATION SHAPE AS THE FEDIVERSE (I1), so nothing on the node changes: kind, actor, subject (kept as
// observed), target (inverted to the identity's own favela post), activity (the identity the observation is undone
// by — here the linking record's at:// URI, which is what a Spacedust `delete` names).
//
// ⚠ The favela post behind an at:// rkey is found by recomputing tidFor over the identity's posts — tidFor is
// one-way (favela-bridge tid.js), so the caller supplies `postName(rkey)`.
import test from 'brittle'
import { linkToObservation, SOURCES } from '../lib/bsky-inbound.js'
const DID = 'did:plc:fleekyfleekyfleeky'
const FEED = 'd2'.repeat(32)
const ALICE = 'did:plc:alicealicealice'
const POST = `at://${DID}/app.bsky.feed.post/3mrhxnkbhv622`
const postName = (rkey) => (rkey === '3mrhxnkbhv622' ? '01k4qspvquliq9js01m6c5658b' : null)
const link = (source, over = {}) => ({ operation: 'create', source, subject: POST, did: ALICE, collection: source.split(':')[0], rkey: '3abc', ...over })
test('★ like / repost / reply on the identity\'s own post → observations aimed at the favela post', (t) => {
const ctx = { did: DID, feed: FEED, postName }
const like = linkToObservation(link(SOURCES.LIKE), ctx)
t.alike(like, {
op: 'note',
obs: { kind: 'like', actor: ALICE, subject: POST, target: { feed: FEED, collection: 'post', name: '01k4qspvquliq9js01m6c5658b' }, activity: `at://${ALICE}/app.bsky.feed.like/3abc` }
})
t.is(linkToObservation(link(SOURCES.REPOST), ctx).obs.kind, 'repost')
const reply = linkToObservation(link(SOURCES.REPLY_PARENT, { collection: 'app.bsky.feed.post' }), ctx)
t.is(reply.obs.kind, 'reply')
t.is(reply.obs.activity, `at://${ALICE}/app.bsky.feed.post/3abc`, 'the reply post itself — its text is fetched for display')
})
test('★ a follow of the DID is a follow, aimed at nobody\'s post', (t) => {
const r = linkToObservation(link(SOURCES.FOLLOW, { subject: DID, collection: 'app.bsky.graph.follow' }), { did: DID, feed: FEED, postName })
t.alike({ kind: r.obs.kind, subject: r.obs.subject, target: r.obs.target }, { kind: 'follow', subject: DID, target: null })
})
test('a delete removes what the create added', (t) => {
const r = linkToObservation(link(SOURCES.LIKE, { operation: 'delete' }), { did: DID, feed: FEED, postName })
t.alike(r, { op: 'remove', activity: `at://${ALICE}/app.bsky.feed.like/3abc` })
})
test('⛔ not ours, not mapped, or not a kind we have words for → nothing', (t) => {
const ctx = { did: DID, feed: FEED, postName }
t.is(linkToObservation(link(SOURCES.LIKE, { subject: 'at://did:plc:other/app.bsky.feed.post/3x' }), ctx), null, 'someone else\'s post')
t.is(linkToObservation(link(SOURCES.LIKE, { subject: `at://${DID}/app.bsky.feed.post/3unknown` }), ctx), null, 'a post with no favela original')
t.is(linkToObservation(link(SOURCES.REPLY_ROOT, { collection: 'app.bsky.feed.post' }), ctx), null, 'a root-only reply is not a reply to this post')
t.is(linkToObservation(link(SOURCES.QUOTE, { collection: 'app.bsky.feed.post' }), ctx), null, 'quotes come later, with their own kind')
t.is(linkToObservation(link(SOURCES.LIKE, { did: DID }), ctx), null, 'the identity liking its own post is not news')
})