Files
Tony f5dd404b1e perf(template): speed up atom & rss rendering (#23629)
* perf(template): speed up atom&rss rendering

* test: add regression test
2026-10-20 03:20:15 +08:00

96 lines
3.9 KiB
TypeScript

import { raw } from 'hono/html';
import { renderToString } from 'hono/jsx/dom/server';
import { describe, expect, it } from 'vitest';
import Atom from '@/views/atom';
describe('Atom view', () => {
it('renders optional fields and media extensions', () => {
const html = renderToString(
<Atom
data={{
title: 'Atom Feed',
link: 'https://example.com',
description: 'Atom Description',
language: 'zh',
lastBuildDate: '2024-01-01T00:00:00Z',
icon: 'https://example.com/icon.png',
logo: 'https://example.com/logo.png',
item: [
{
title: 'Item One',
link: 'https://example.com/one',
description: 'Entry One',
pubDate: '2024-01-01T00:00:00Z',
updated: '2024-01-02T00:00:00Z',
summary: 'Entry One',
author: 'Author One',
category: 'News',
media: {
content: {
url: 'https://example.com/video.mp4',
},
},
upvotes: 12,
downvotes: 1,
comments: 3,
},
{
title: 'Item Two',
link: 'https://example.com/two',
description: 'Entry Two',
category: ['Tech', 'AI'],
guid: 'guid-2',
},
],
}}
/>
);
expect(html).toContain('<icon>https://example.com/icon.png</icon>');
expect(html).toContain('<logo>https://example.com/logo.png</logo>');
expect(html).toContain('media:content');
expect(html).toContain('term="News"');
expect(html).toContain('term="Tech"');
expect(html).toContain('rsshub:upvotes');
expect(html).toContain('rsshub:downvotes');
expect(html).toContain('rsshub:comments');
});
it('renders multiple enclosure links with known sizes and deduplicates the legacy enclosure', () => {
const html = renderToString(
<Atom
data={{
title: 'Attachments',
item: [
{
title: 'Episode',
link: 'https://example.com/episode',
enclosure_url: 'https://example.com/audio.mp3',
enclosure_type: 'audio/mpeg',
attachments: [
{ url: 'https://example.com/audio.mp3', mime_type: 'audio/mpeg', size_in_bytes: 123, title: 'Audio & notes' },
{ url: 'https://example.com/cover.png', mime_type: 'image/png' },
],
},
],
}}
/>
);
expect(html.match(/rel="enclosure"/g)).toHaveLength(2);
expect(html).toContain('href="https://example.com/audio.mp3" type="audio/mpeg" length="123" title="Audio &amp; notes"');
expect(html).toContain('href="https://example.com/cover.png" type="image/png"');
});
it('does not let hono hoist feed titles and links as document metadata', () => {
const html = String(
<probe>
{raw('</head>')}
<Atom data={{ title: 'Feed', item: [{ title: 'Item', link: 'https://example.com/item' }] }} />
</probe>
);
expect(html).toMatch(/^<probe><\/head><feed/);
});
});