// What the notification says about the node.
//
// ⛔ IT IS THE ONLY ALWAYS-VISIBLE SURFACE THIS APP HAS. Everything else requires opening the app; this
// sits in the shade whenever the node is alive. So it is worth the same care as any other claim the UI
// makes, and it is subject to the same rule: never say more than is known.
//
// The case that motivated it: on 2026-08-18 the node ran for 11 minutes serving ONE identity while its
// owner believed it was serving two, and posted to the wrong one. Nothing on screen — including a
// notification reading "Replicating in the background" — could have corrected that belief.
import test from 'brittle'
import { describeNode } from '../lib/describe.js'
test('no identity at all is stated as read-only, not as replication', (t) => {
// "Replicating in the background" on an unpaired node describes work that cannot be happening: with no
// DID there is nothing of ours to replicate and nothing can be written.
t.is(describeNode([]), 'Read-only — not paired to an identity')
t.is(describeNode(null), 'Read-only — not paired to an identity')
t.is(describeNode(undefined), 'Read-only — not paired to an identity')
})
test('one identity is NAMED, because which one is the question that was got wrong', (t) => {
t.is(describeNode([{ did: 'did:plc:wj62ebbusln6gxo5azo6ogzo', handle: 'wj62.7rnx.net', signing: true }]),
'Serving wj62.7rnx.net')
})
test('a null handle falls back to a short did, never 32 raw characters', (t) => {
// handle is null on every boot of the handset, so this is the branch that actually ships.
const s = describeNode([{ did: 'did:plc:wj62ebbusln6gxo5azo6ogzo', handle: null, signing: true }])
t.is(s, 'Serving wj62ebbu…ogzo')
t.absent(s.includes('did:plc:'), 'the raw did never reaches the shade')
})
test('several identities are counted', (t) => {
const dids = [
{ did: 'did:plc:aaa', handle: 'a.example', signing: true },
{ did: 'did:plc:bbb', handle: 'b.example', signing: true }
]
t.is(describeNode(dids), 'Serving 2 identities')
})
test('an identity it cannot author for says so — reading is not the same as posting', (t) => {
// signing:false means the StateBase never admitted this device. The node is up and replicating and
// every write will be refused, which is exactly the state that looks fine until you try to post.
t.is(describeNode([{ did: 'did:plc:aaa', handle: 'a.example', signing: false }]),
'Serving a.example — read-only')
t.is(describeNode([
{ did: 'did:plc:aaa', handle: 'a.example', signing: false },
{ did: 'did:plc:bbb', handle: 'b.example', signing: false }
]), 'Serving 2 identities — read-only')
})
test('mixed signing is not called read-only — one writable identity is not none', (t) => {
t.is(describeNode([
{ did: 'did:plc:aaa', handle: 'a.example', signing: true },
{ did: 'did:plc:bbb', handle: 'b.example', signing: false }
]), 'Serving 2 identities')
})
test('a malformed entry never throws — the notification must not be able to crash the shell', (t) => {
t.ok(typeof describeNode([{}]) === 'string')
t.ok(typeof describeNode([null]) === 'string')
t.ok(typeof describeNode('nonsense') === 'string')
})