// The step that actually publishes, and why the card needs a fourth one.
//
// ⛔ CONSENT IS NOT AUTHORSHIP. Step 3's switch records that posts MAY go to Bluesky. Nothing about it
// writes a record. The fediverse bridge HOLDS the feed and projects from it server-side, so for that
// network the switch really is the last step — but Bluesky's membrane is keyless and serves only what
// the device SIGNED, so until the device authors them the repo stays empty.
//
// Measured on a handset, with every visible step reporting success: identity correct, handle
// resolving, relay active, switch on — and an atproto repo holding one bootstrap record and no
// profile. The card had no way to say "nothing has been published", because it had nothing to press.
import test from 'brittle'
import { blueskySection, projectResult } from '../lib/pages.js'
const DID = { did: 'did:plc:example', handle: 'fleeky.7rnx.net', pdsUrl: 'https://pds.7rnx.net', sealed: true }
const ON = { networks: ['bsky'], credential: 'did:plc:example' }
test('★★★ the publish step appears once there is somewhere for it to go', (t) => {
const html = blueskySection(DID, ON)
t.ok(/4\. Publish what you have written/.test(html), 'the step is offered')
t.ok(/action="\/did\/project"/.test(html), 'and posts to the verb that authors')
t.ok(/name="send" value="1"/.test(html), 'with an explicit send')
t.ok(/name="send" value=""/.test(html), 'and a dry run beside it, because this cannot be recalled')
})
test('★★★ it is NOT offered when nothing could resolve what was published', (t) => {
// ⛔ Publishing into an identity nobody carries writes records no one can resolve.
const uncarried = blueskySection({ ...DID, handle: null }, ON)
t.absent(/4\. Publish what you have written/.test(uncarried), 'no bridge carries it yet')
// ⛔ And never against withheld consent — the button would be publishing something the switch says
// must not be published.
const off = blueskySection(DID, { networks: [], credential: 'did:plc:example' })
t.absent(/4\. Publish what you have written/.test(off), 'the switch is off')
})
test('★★ it says that existing posts go too, not only new ones', (t) => {
const html = blueskySection(DID, ON)
t.ok(/existing posts, not just new ones/.test(html),
'a person pressing this is publishing their history, and must be told so before they do')
})
test('★★★ the result shows the daemon\'s own lines, not a count', (t) => {
// The withheld lines are the interesting half: "too long for bsky", "a members room reaches
// nothing". A summary cannot answer "what happened to the one I meant".
const html = projectResult({
sent: 1,
skipped: 2,
withheld: 1,
log: [' 1788 [favela,bsky] bsky: SENT 3mvb36hp7mc22', ' 1789 [favela] bsky: withheld — too long for bsky']
})
t.ok(/1<\/strong> published/.test(html))
t.ok(/already there/.test(html))
t.ok(/withheld — too long for bsky/.test(html), 'the reason survives to the page')
})
test('★★ a refusal is reported as publishing nothing, not as a zero', (t) => {
// ⛔ "could not read what the repo holds" and "there was nothing to send" are different facts, and
// reporting the first as `0 published` invites pressing it again until it duplicates everything.
const html = projectResult({ refused: 'could not read what the bsky sink already holds', log: [] })
t.ok(/Nothing was published/.test(html))
t.ok(/could not read what the bsky sink already holds/.test(html))
})