158 lines
5.4 KiB
TypeScript
158 lines
5.4 KiB
TypeScript
import { describe, expect, it } from 'vitest';
|
|
|
|
process.env.OPENAI_API_KEY = 'sk-1234567890';
|
|
process.env.OPENAI_API_ENDPOINT = 'https://api.openai.mock/v1';
|
|
|
|
const { config } = await import('@/config');
|
|
const { default: parameter } = await import('@/middleware/parameter');
|
|
|
|
const runMiddleware = async (data: any, query: Record<string, string | undefined>) => {
|
|
const store = new Map<string, unknown>([['data', data]]);
|
|
const ctx = {
|
|
req: {
|
|
query: (key: string) => query[key],
|
|
},
|
|
get: (key: string) => store.get(key),
|
|
set: (key: string, value: unknown) => store.set(key, value),
|
|
};
|
|
await parameter(ctx as any, async () => {});
|
|
return store.get('data') as any;
|
|
};
|
|
|
|
describe('parameter middleware branches', () => {
|
|
it('normalizes base urls and updates quote links', async () => {
|
|
const data = {
|
|
link: 'example.com/base',
|
|
item: [
|
|
{
|
|
title: 'Item 1',
|
|
link: '/relative',
|
|
description: '<div class="rsshub-quote">Quote</div><a href="/foo">Foo</a>',
|
|
_extra: {
|
|
links: [{ href: 'https://example.com' }],
|
|
},
|
|
},
|
|
{
|
|
title: 'Item 2',
|
|
description: '<img src="/img.png" />',
|
|
},
|
|
],
|
|
allowEmpty: true,
|
|
};
|
|
|
|
const result = await runMiddleware(data, {});
|
|
expect(result.item[0].link).toBe('http://example.com/relative');
|
|
expect(result.item[1].description).toContain('http://example.com/img.png');
|
|
expect(result.item[0]._extra.links[0].content_html).toContain('rsshub-quote');
|
|
});
|
|
|
|
it('filters with RegExp engine', async () => {
|
|
const originalEngine = config.feature.filter_regex_engine;
|
|
config.feature.filter_regex_engine = 'regexp';
|
|
|
|
const data = {
|
|
link: 'https://example.com',
|
|
item: [
|
|
{ title: 'Keep', description: 'A' },
|
|
{ title: 'Drop', description: 'B' },
|
|
],
|
|
};
|
|
|
|
const result = await runMiddleware(data, { filter: 'Keep' });
|
|
expect(result.item).toHaveLength(1);
|
|
expect(result.item[0].title).toBe('Keep');
|
|
|
|
config.feature.filter_regex_engine = originalEngine;
|
|
});
|
|
|
|
it('filters by category when title and description do not match', async () => {
|
|
const originalEngine = config.feature.filter_regex_engine;
|
|
config.feature.filter_regex_engine = 'regexp';
|
|
|
|
const data = {
|
|
link: 'https://example.com',
|
|
item: [
|
|
{
|
|
title: 'Nope',
|
|
description: 'Also nope',
|
|
author: 'Still nope',
|
|
category: ['Match'],
|
|
},
|
|
],
|
|
};
|
|
|
|
const result = await runMiddleware(data, { filter: 'Match' });
|
|
expect(result.item).toHaveLength(1);
|
|
expect(result.item[0].category).toContain('Match');
|
|
|
|
config.feature.filter_regex_engine = originalEngine;
|
|
});
|
|
|
|
it('keeps items without link in tgiv mode', async () => {
|
|
const data = {
|
|
link: 'https://example.com',
|
|
item: [{ title: 'NoLink' }],
|
|
};
|
|
|
|
const result = await runMiddleware(data, { tgiv: 'hash' });
|
|
expect(result.item[0].link).toBeUndefined();
|
|
});
|
|
|
|
it('rewrites links for scihub', async () => {
|
|
const data = {
|
|
link: 'https://example.com',
|
|
item: [
|
|
{ title: 'With DOI', doi: '10.1000/xyz' },
|
|
{ title: 'With link', link: 'https://example.com/paper' },
|
|
],
|
|
};
|
|
|
|
const result = await runMiddleware(data, { scihub: '1' });
|
|
expect(result.item[0].link).toBe(`${config.scihub.host}10.1000/xyz`);
|
|
expect(result.item[1].link).toBe(`${config.scihub.host}https://example.com/paper`);
|
|
});
|
|
|
|
it('throws on invalid brief value', async () => {
|
|
const data = {
|
|
link: 'https://example.com',
|
|
item: [{ title: 'Item', description: 'Desc' }],
|
|
};
|
|
|
|
await expect(runMiddleware(data, { brief: '10' })).rejects.toThrow('Invalid parameter brief');
|
|
});
|
|
|
|
it('processes openai description and title', async () => {
|
|
const originalInput = config.openai.inputOption;
|
|
|
|
const descriptionData = {
|
|
link: 'https://example.com',
|
|
item: [
|
|
{
|
|
title: 'Title',
|
|
description: 'Description',
|
|
link: `https://example.com/${Date.now()}/desc`,
|
|
},
|
|
],
|
|
};
|
|
config.openai.inputOption = 'description';
|
|
const descriptionResult = await runMiddleware(descriptionData, { chatgpt: 'true' });
|
|
expect(descriptionResult.item[0].description).toContain('AI processed content.');
|
|
|
|
const titleData = {
|
|
link: 'https://example.com',
|
|
item: [
|
|
{
|
|
title: 'Title',
|
|
description: 'Description',
|
|
link: `https://example.com/${Date.now()}/title`,
|
|
},
|
|
],
|
|
};
|
|
config.openai.inputOption = 'title';
|
|
const titleResult = await runMiddleware(titleData, { chatgpt: 'true' });
|
|
expect(titleResult.item[0].title).toContain('AI processed content.');
|
|
|
|
config.openai.inputOption = originalInput;
|
|
});
|
|
});
|