import assert from 'node:assert/strict'; import { test } from 'node:test'; import { mediaFromEmbed, toPost } from '../src/platforms/bluesky.ts'; import { fixture } from './helpers.ts'; const URL_ = 'https://bsky.app/profile/example/post/abc'; test('a text-only post carries no media', () => { const post = toPost(fixture('bluesky/text-only.json'), URL_); assert.equal(post.platform, 'bluesky'); assert.equal(post.textPosition, 'above'); assert.deepEqual(post.media, []); assert.ok(post.text); assert.match(post.author.handle, /^@/); }); test('an image post keeps every image, in order, with alt text', () => { const post = toPost(fixture('bluesky/images.json'), URL_); assert.ok(post.media.length > 1, 'expected a multi-image post'); assert.ok(post.media.every((m) => m.kind === 'image')); assert.ok(post.media.every((m) => m.url.startsWith('https://'))); assert.ok(post.media.some((m) => m.kind === 'image' && m.alt)); }); test('a video post is a direct HLS playlist with a poster', () => { const post = toPost(fixture('bluesky/video.json'), URL_); const [item] = post.media; assert.equal(item?.kind, 'video'); assert.ok(item?.kind === 'video' && item.hls); // Proxying HLS would mean rewriting the manifest, so it is linked direct. assert.ok(item?.direct); assert.ok(item?.kind === 'video' && item.poster); }); test('a quote post with media reaches through the nested embed', () => { const media = mediaFromEmbed({ $type: 'app.bsky.embed.recordWithMedia#view', media: { $type: 'app.bsky.embed.images#view', images: [{ fullsize: 'https://example/i.jpg' }] }, }); assert.deepEqual(media, [{ kind: 'image', url: 'https://example/i.jpg' }]); }); test('a quote post shows the media of the post it quotes', () => { const media = mediaFromEmbed({ $type: 'app.bsky.embed.record#view', record: { embeds: [{ $type: 'app.bsky.embed.images#view', images: [{ fullsize: 'https://cdn/q.jpg' }] }], }, }); assert.deepEqual(media, [{ kind: 'image', url: 'https://cdn/q.jpg' }]); });