import test from 'brittle'
import { blobCid, blobMime, projectProfile, projectAttachments, blobUrl } from '../lib/blobs.js'
const HOST = 'ap.7rnx.net'
// Older records carry a bare cid string; a profile that failed to project because of a legacy
// shape would silently lose its avatar.
test('blobCid accepts every ref shape atproto has used', (t) => {
t.is(blobCid({ $type: 'blob', ref: { $link: 'bafkreiX' }, mimeType: 'image/jpeg' }), 'bafkreiX')
t.is(blobCid({ ref: 'bafkreiY' }), 'bafkreiY')
t.is(blobCid({ cid: 'bafkreiZ' }), 'bafkreiZ')
t.is(blobCid('bafkreiW'), 'bafkreiW')
t.is(blobCid(null), null)
t.is(blobCid({}), null)
})
test('profile → icon/image/name/summary with our own blob URLs', (t) => {
const out = projectProfile({
host: HOST,
profile: {
displayName: 'tabertron',
description: 'the upstairs device of fleeky',
avatar: { ref: { $link: 'bafkreiA' }, mimeType: 'image/jpeg' },
banner: { ref: { $link: 'bafkreiB' }, mimeType: 'image/webp' }
}
})
t.is(out.name, 'tabertron')
t.is(out.summary, 'the upstairs device of fleeky')
t.is(out.icon.url, blobUrl({ host: HOST, cid: 'bafkreiA' }))
t.is(out.icon.mediaType, 'image/jpeg')
t.is(out.image.url, blobUrl({ host: HOST, cid: 'bafkreiB' }))
t.alike(projectProfile({ profile: null, host: HOST }), {})
})
test('post images → attachments, with alt text and dimensions', (t) => {
const record = {
embed: {
$type: 'app.bsky.embed.images',
images: [{
image: { ref: { $link: 'bafkreiIMG' }, mimeType: 'image/png' },
alt: 'a screenshot',
aspectRatio: { width: 1200, height: 800 }
}]
}
}
const [a] = projectAttachments({ record, host: HOST })
t.is(a.type, 'Document')
t.is(a.mediaType, 'image/png')
t.is(a.url, blobUrl({ host: HOST, cid: 'bafkreiIMG' }))
t.is(a.name, 'a screenshot', 'alt text is an accessibility obligation, not a nicety')
t.is(a.width, 1200)
})
test('images nested under recordWithMedia are found', (t) => {
const record = { embed: { media: { images: [{ image: { ref: { $link: 'bafkreiM' }, mimeType: 'image/gif' } }] } } }
t.is(projectAttachments({ record, host: HOST }).length, 1)
})
// Emitting a broken attachment is worse than emitting none — each unhandled embed type needs its
// own decision, not a guess.
test('unhandled embed types produce no attachment', (t) => {
t.alike(projectAttachments({ record: {}, host: HOST }), [])
t.alike(projectAttachments({ record: { embed: { $type: 'app.bsky.embed.external', external: { uri: 'x' } } }, host: HOST }), [])
t.alike(projectAttachments({ record: { embed: { images: [{ image: null }] } }, host: HOST }), [])
})