import { describe, expect, it } from 'vitest'; import { extractStoryMediaLinks, parseBloombergRss, renderStoryBody } from './utils.js'; describe('Bloomberg utils', () => { it('parses Bloomberg RSS items with summary, link, and deduped media links', () => { const xml = ` <![CDATA[Headline One]]> One & more]]> https://www.bloomberg.com/news/articles/2026-03-19/example-one Headline Two Summary Two https://www.bloomberg.com/news/articles/2026-03-19/example-two `; const items = parseBloombergRss(xml); expect(items).toHaveLength(2); expect(items[0]).toEqual({ title: 'Headline One', summary: 'Summary One & more', link: 'https://www.bloomberg.com/news/articles/2026-03-19/example-one', mediaLinks: ['https://assets.bwbx.io/example-one.jpg'], }); expect(items[1]).toEqual({ title: 'Headline Two', summary: 'Summary Two', link: 'https://www.bloomberg.com/news/articles/2026-03-19/example-two', mediaLinks: ['https://assets.bwbx.io/example-two.png'], }); }); it('renders Bloomberg story rich-text body into readable text', () => { const body = { type: 'document', content: [ { type: 'inline-newsletter', data: { position: 'top' }, content: [] }, { type: 'paragraph', data: {}, content: [ { type: 'text', value: 'Lead paragraph with ' }, { type: 'entity', content: [{ type: 'text', value: 'linked text' }] }, { type: 'text', value: '.' }, ], }, { type: 'heading', data: { level: 2 }, content: [{ type: 'text', value: 'Key Points' }], }, { type: 'list', data: { style: 'unordered' }, content: [ { type: 'list-item', content: [ { type: 'paragraph', content: [{ type: 'text', value: 'Point one' }] }, ], }, { type: 'list-item', content: [ { type: 'paragraph', content: [{ type: 'text', value: 'Point two' }] }, ], }, ], }, { type: 'blockquote', content: [{ type: 'text', value: 'Quoted line' }], }, { type: 'media', data: { attachment: { caption: '

Chart caption

', }, }, }, { type: 'ad', data: { num: 1 }, content: [] }, ], }; expect(renderStoryBody(body)).toBe([ 'Lead paragraph with linked text.', '## Key Points', '- Point one\n- Point two', '> Quoted line', 'Chart caption', ].join('\n\n')); }); it('collects deduped story media links from lede, attachments, and body media', () => { const story = { ledeImageUrl: 'https://assets.bwbx.io/lede.webp', lede: { url: 'https://assets.bwbx.io/lede.webp' }, socialImageUrl: 'https://assets.bwbx.io/social.png', imageAttachments: { one: { url: 'https://assets.bwbx.io/figure.jpg' }, }, body: { content: [ { type: 'media', data: { chart: { src: 'https://resource.bloomberg.com/images/chart.png', fallback: 'https://assets.bwbx.io/chart-fallback.png', }, }, }, ], }, }; expect(extractStoryMediaLinks(story)).toEqual([ 'https://assets.bwbx.io/lede.webp', 'https://assets.bwbx.io/social.png', 'https://assets.bwbx.io/figure.jpg', 'https://resource.bloomberg.com/images/chart.png', 'https://assets.bwbx.io/chart-fallback.png', ]); }); });