Files
KVideo/tests/douban-image-fallback.test.ts
T

55 lines
2.0 KiB
TypeScript

import assert from 'node:assert/strict';
import test from 'node:test';
import { GET } from '@/app/api/douban/image/route';
import { buildDoubanImageCandidates } from '@/lib/server/douban-image';
test('Douban image candidates preserve the path and try reachable mirrors', () => {
const candidates = buildDoubanImageCandidates(
'https://img1.doubanio.com/view/photo/s_ratio_poster/public/p123.webp?x=1',
);
assert.deepEqual(candidates, [
'https://img1.doubanio.com/view/photo/s_ratio_poster/public/p123.webp?x=1',
'https://img9.doubanio.com/view/photo/s_ratio_poster/public/p123.webp?x=1',
'https://img3.doubanio.com/view/photo/s_ratio_poster/public/p123.webp?x=1',
'https://img2.doubanio.com/view/photo/s_ratio_poster/public/p123.webp?x=1',
]);
});
test('non-Douban and malformed URLs are attempted only once', () => {
assert.deepEqual(buildDoubanImageCandidates('https://example.com/poster.jpg'), [
'https://example.com/poster.jpg',
]);
assert.deepEqual(buildDoubanImageCandidates('not a url'), ['not a url']);
});
test('image proxy falls back after a mirror network failure', async (context) => {
const requested: string[] = [];
context.mock.method(globalThis, 'fetch', async (input: string | URL | Request) => {
const url = input.toString();
requested.push(url);
if (url.includes('img1.doubanio.com')) {
throw new TypeError('fetch failed');
}
return new Response('image-bytes', {
status: 200,
headers: { 'content-type': 'image/webp' },
});
});
const target = encodeURIComponent('https://img1.doubanio.com/poster.webp');
const response = await GET(new Request(`https://kvideo.test/api/douban/image?url=${target}`));
assert.equal(response.status, 200);
assert.equal(response.headers.get('content-type'), 'image/webp');
assert.equal(await response.text(), 'image-bytes');
assert.deepEqual(requested, [
'https://img1.doubanio.com/poster.webp',
'https://img9.doubanio.com/poster.webp',
]);
});