test: import app instead of index

This commit is contained in:
DIYgod
2024-03-02 04:50:51 +08:00
parent 91e6fe3d1a
commit 1b0acc996b
10 changed files with 348 additions and 313 deletions
+125 -65
View File
@@ -1,15 +1,11 @@
import { describe, expect, it, jest, afterEach } from '@jest/globals';
import supertest from 'supertest';
import md5 from '@/utils/md5';
import type { serve } from '@hono/node-server';
let server: ReturnType<typeof serve>;
process.env.NODE_NAME = 'mock';
function checkBlock(response) {
async function checkBlock(response) {
expect(response.status).toBe(403);
expect(response.text).toMatch(/Access denied\./);
expect(await response.text()).toMatch(/Access denied\./);
}
afterEach(() => {
@@ -17,7 +13,6 @@ afterEach(() => {
delete process.env.DENYLIST;
delete process.env.ALLOWLIST;
jest.resetModules();
server.close();
});
describe('access-control', () => {
@@ -26,46 +21,77 @@ describe('access-control', () => {
const code = md5('/test/2' + key);
process.env.DENYLIST = 'est/1,233.233.233.,black';
process.env.ACCESS_KEY = key;
server = (await import('@/index')).default;
const request = supertest(server);
const app = (await import('@/app')).default;
const response11 = await request.get('/test/1');
checkBlock(response11);
const response11 = await app.request('/test/1');
await checkBlock(response11);
const response12 = await request.get('/test/1').set('X-Mock-IP', '233.233.233.233');
checkBlock(response12);
const response12 = await app.request('/test/1', {
headers: {
'X-Mock-IP': '233.233.233.233',
},
});
await checkBlock(response12);
const response13 = await request.get('/test/1').set('user-agent', 'blackua');
checkBlock(response13);
const response13 = await app.request('/test/1', {
headers: {
'user-agent': 'blackua',
},
});
await checkBlock(response13);
const response21 = await request.get('/test/2');
const response21 = await app.request('/test/2');
expect(response21.status).toBe(200);
const response22 = await request.get('/test/2').set('X-Mock-IP', '233.233.233.233');
checkBlock(response22);
const response22 = await app.request('/test/2', {
headers: {
'X-Mock-IP': '233.233.233.233',
},
});
await checkBlock(response22);
const response23 = await request.get('/test/2').set('user-agent', 'blackua');
checkBlock(response23);
const response23 = await app.request('/test/2', {
headers: {
'user-agent': 'blackua',
},
});
await checkBlock(response23);
// wrong key/code, not on denylist
const response311 = await request.get(`/test/2?key=wrong+${key}`);
const response311 = await app.request(`/test/2?key=wrong+${key}`);
expect(response311.status).toBe(200);
const response312 = await request.get(`/test/2?code=wrong+${code}`);
const response312 = await app.request(`/test/2?code=wrong+${code}`);
expect(response312.status).toBe(200);
// wrong key/code, on denylist
const response321 = await request.get(`/test/2?key=wrong+${key}`).set('X-Mock-IP', '233.233.233.233');
checkBlock(response321);
const response321 = await app.request(`/test/2?key=wrong+${key}`, {
headers: {
'X-Mock-IP': '233.233.233.233',
},
});
await checkBlock(response321);
const response322 = await request.get(`/test/2?code=wrong+${code}`).set('X-Mock-IP', '233.233.233.233');
checkBlock(response322);
const response322 = await app.request(`/test/2?code=wrong+${code}`, {
headers: {
'X-Mock-IP': '233.233.233.233',
},
});
await checkBlock(response322);
// right key/code, on denylist
const response331 = await request.get(`/test/2?key=${key}`).set('X-Mock-IP', '233.233.233.233');
const response331 = await app.request(`/test/2?key=${key}`, {
headers: {
'X-Mock-IP': '233.233.233.233',
},
});
expect(response331.status).toBe(200);
const response332 = await request.get(`/test/2?code=${code}`).set('X-Mock-IP', '233.233.233.233');
const response332 = await app.request(`/test/2?code=${code}`, {
headers: {
'X-Mock-IP': '233.233.233.233',
},
});
expect(response332.status).toBe(200);
});
@@ -74,61 +100,96 @@ describe('access-control', () => {
const code = md5('/test/2' + key);
process.env.ALLOWLIST = 'est/1,233.233.233.,103.31.4.0/22,white';
process.env.ACCESS_KEY = key;
server = (await import('@/index')).default;
const request = supertest(server);
const app = (await import('@/app')).default;
const response01 = await request.get('/');
const response01 = await app.request('/');
expect(response01.status).toBe(200);
const response02 = await request.get('/robots.txt');
const response02 = await app.request('/robots.txt');
expect(response02.status).toBe(404);
const response11 = await request.get('/test/1');
const response11 = await app.request('/test/1');
expect(response11.status).toBe(200);
const response12 = await request.get('/test/1').set('X-Mock-IP', '233.233.233.233');
const response12 = await app.request('/test/1', {
headers: {
'X-Mock-IP': '233.233.233.233',
},
});
expect(response12.status).toBe(200);
const response13 = await request.get('/test/1').set('user-agent', 'whiteua');
const response13 = await app.request('/test/1', {
headers: {
'user-agent': 'whiteua',
},
});
expect(response13.status).toBe(200);
const response21 = await request.get('/test/2');
checkBlock(response21);
const response21 = await app.request('/test/2');
await checkBlock(response21);
const response22 = await request.get('/test/2').set('X-Mock-IP', '233.233.233.233');
const response22 = await app.request('/test/2', {
headers: {
'X-Mock-IP': '233.233.233.233',
},
});
expect(response22.status).toBe(200);
const response221 = await request.get('/test/2').set('X-Mock-IP', '103.31.4.0');
const response221 = await app.request('/test/2', {
headers: {
'X-Mock-IP': '103.31.4.0',
},
});
expect(response221.status).toBe(200);
const response222 = await request.get('/test/2').set('X-Mock-IP', '103.31.7.255');
const response222 = await app.request('/test/2', {
headers: {
'X-Mock-IP': '103.31.7.255',
},
});
expect(response222.status).toBe(200);
const response223 = await request.get('/test/2').set('X-Mock-IP', '103.31.8.0');
checkBlock(response223);
const response223 = await app.request('/test/2', {
headers: {
'X-Mock-IP': '103.31.8.0',
},
});
await checkBlock(response223);
const response23 = await request.get('/test/2').set('user-agent', 'whiteua');
const response23 = await app.request('/test/2', {
headers: {
'user-agent': 'whiteua',
},
});
expect(response23.status).toBe(200);
// wrong key/code, not on allowlist
const response311 = await request.get(`/test/2?code=wrong+${code}`);
checkBlock(response311);
const response311 = await app.request(`/test/2?code=wrong+${code}`);
await checkBlock(response311);
const response312 = await request.get(`/test/2?key=wrong+${key}`);
checkBlock(response312);
const response312 = await app.request(`/test/2?key=wrong+${key}`);
await checkBlock(response312);
// wrong key/code, on allowlist
const response321 = await request.get(`/test/2?code=wrong+${code}`).set('X-Mock-IP', '233.233.233.233');
const response321 = await app.request(`/test/2?code=wrong+${code}`, {
headers: {
'X-Mock-IP': '233.233.233.233',
},
});
expect(response321.status).toBe(200);
const response322 = await request.get(`/test/2?key=wrong+${key}`).set('X-Mock-IP', '233.233.233.233');
const response322 = await app.request(`/test/2?key=wrong+${key}`, {
headers: {
'X-Mock-IP': '233.233.233.233',
},
});
expect(response322.status).toBe(200);
// right key/code
const response331 = await request.get(`/test/2?code=${code}`);
const response331 = await app.request(`/test/2?code=${code}`);
expect(response331.status).toBe(200);
const response332 = await request.get(`/test/2?key=${key}`);
const response332 = await app.request(`/test/2?key=${key}`);
expect(response332.status).toBe(200);
});
@@ -136,33 +197,32 @@ describe('access-control', () => {
const key = '1L0veRSSHub';
const code = md5('/test/2' + key);
process.env.ACCESS_KEY = key;
server = (await import('@/index')).default;
const request = supertest(server);
const app = (await import('@/app')).default;
const response01 = await request.get('/');
const response01 = await app.request('/');
expect(response01.status).toBe(200);
const response02 = await request.get('/robots.txt');
const response02 = await app.request('/robots.txt');
expect(response02.status).toBe(404);
const response11 = await request.get('/test/1');
checkBlock(response11);
const response11 = await app.request('/test/1');
await checkBlock(response11);
const response21 = await request.get('/test/2');
checkBlock(response21);
const response21 = await app.request('/test/2');
await checkBlock(response21);
// wrong key/code
const response321 = await request.get(`/test/2?key=wrong+${key}`);
checkBlock(response321);
const response321 = await app.request(`/test/2?key=wrong+${key}`);
await checkBlock(response321);
const response322 = await request.get(`/test/2?code=wrong+${code}`);
checkBlock(response322);
const response322 = await app.request(`/test/2?code=wrong+${code}`);
await checkBlock(response322);
// right key/code
const response331 = await request.get(`/test/2?key=${key}`);
const response331 = await app.request(`/test/2?key=${key}`);
expect(response331.status).toBe(200);
const response332 = await request.get(`/test/2?code=${code}`);
const response332 = await app.request(`/test/2?code=${code}`);
expect(response332.status).toBe(200);
});
});
+6 -12
View File
@@ -1,11 +1,8 @@
import { describe, expect, it, jest, afterEach, afterAll } from '@jest/globals';
import supertest from 'supertest';
import Parser from 'rss-parser';
import type { serve } from '@hono/node-server';
const parser = new Parser();
jest.setTimeout(50000);
let server: ReturnType<typeof serve>;
afterAll(() => {
delete process.env.HOTLINK_TEMPLATE;
@@ -19,7 +16,6 @@ afterEach(() => {
delete process.env.HOTLINK_INCLUDE_PATHS;
delete process.env.HOTLINK_EXCLUDE_PATHS;
delete process.env.ALLOW_USER_HOTLINK_TEMPLATE;
server.close();
jest.resetModules();
});
@@ -121,8 +117,7 @@ const expects = {
};
const testAntiHotlink = async (path, expectObj, query?: string | Record<string, any>) => {
server = (await import('@/index')).default;
const request = supertest(server);
const app = (await import('@/app')).default;
let queryStr;
if (query) {
@@ -135,8 +130,8 @@ const testAntiHotlink = async (path, expectObj, query?: string | Record<string,
}
path = path + (queryStr ? `?${queryStr}` : '');
const response = await request.get(path);
const parsed = await parser.parseString(response.text);
const response = await app.request(path);
const parsed = await parser.parseString(await response.text());
expect({
items: parsed.items.slice(0, expectObj.items.length).map((i) => i.content),
desc: parsed.description,
@@ -251,9 +246,8 @@ describe('anti-hotlink', () => {
it('invalid-property', async () => {
process.env.HOTLINK_TEMPLATE = 'https://i3.wp.com/${createObjectURL}';
server = (await import('@/index')).default;
const request = supertest(server);
const response = await request.get('/test/complicated');
expect(response.text).toContain('Error: Invalid URL property: createObjectURL');
const app = (await import('@/app')).default;
const response = await app.request('/test/complicated');
expect(await response.text()).toContain('Error: Invalid URL property: createObjectURL');
});
});
+48 -57
View File
@@ -1,11 +1,8 @@
import { describe, expect, it, jest, afterEach, afterAll, beforeAll } from '@jest/globals';
import supertest from 'supertest';
import Parser from 'rss-parser';
import wait from '@/utils/wait';
import type { serve } from '@hono/node-server';
const parser = new Parser();
let server: ReturnType<typeof serve>;
beforeAll(() => {
process.env.CACHE_EXPIRE = '1';
@@ -15,7 +12,6 @@ beforeAll(() => {
afterEach(() => {
delete process.env.CACHE_TYPE;
jest.resetModules();
server?.close();
});
afterAll(() => {
@@ -25,14 +21,13 @@ afterAll(() => {
describe('cache', () => {
it('memory', async () => {
process.env.CACHE_TYPE = 'memory';
server = (await import('@/index')).default;
const request = supertest(server);
const app = (await import('@/app')).default;
const response1 = await request.get('/test/cache');
const response2 = await request.get('/test/cache');
const response1 = await app.request('/test/cache');
const response2 = await app.request('/test/cache');
const parsed1 = await parser.parseString(response1.text);
const parsed2 = await parser.parseString(response2.text);
const parsed1 = await parser.parseString(await response1.text());
const parsed2 = await parser.parseString(await response2.text());
delete parsed1.lastBuildDate;
delete parsed2.lastBuildDate;
@@ -43,29 +38,29 @@ describe('cache', () => {
expect(parsed2).toMatchObject(parsed1);
expect(response2.status).toBe(200);
expect(response2.headers['rsshub-cache-status']).toBe('HIT');
expect(response2.headers.get('rsshub-cache-status')).toBe('HIT');
await wait(1 * 1000 + 100);
const response3 = await request.get('/test/cache');
const response3 = await app.request('/test/cache');
expect(response3.headers).not.toHaveProperty('rsshub-cache-status');
const parsed3 = await parser.parseString(response3.text);
const parsed3 = await parser.parseString(await response3.text());
await wait(3 * 1000 + 100);
const response4 = await request.get('/test/cache');
const parsed4 = await parser.parseString(response4.text);
const response4 = await app.request('/test/cache');
const parsed4 = await parser.parseString(await response4.text());
expect(parsed1.items[0].content).toBe('Cache1');
expect(parsed2.items[0].content).toBe('Cache1');
expect(parsed3.items[0].content).toBe('Cache1');
expect(parsed4.items[0].content).toBe('Cache2');
await request.get('/test/refreshCache');
await app.request('/test/refreshCache');
await wait(1 * 1000 + 100);
const response5 = await request.get('/test/refreshCache');
const parsed5 = await parser.parseString(response5.text);
const response5 = await app.request('/test/refreshCache');
const parsed5 = await parser.parseString(await response5.text());
await wait(2 * 1000 + 100);
const response6 = await request.get('/test/refreshCache');
const parsed6 = await parser.parseString(response6.text);
const response6 = await app.request('/test/refreshCache');
const parsed6 = await parser.parseString(await response6.text());
expect(parsed5.items[0].content).toBe('1 1');
expect(parsed6.items[0].content).toBe('1 0');
@@ -73,14 +68,14 @@ describe('cache', () => {
it('redis', async () => {
process.env.CACHE_TYPE = 'redis';
server = (await import('@/index')).default;
const request = supertest(server);
const app = (await import('@/app')).default;
const response1 = await request.get('/test/cache');
const response2 = await request.get('/test/cache');
await wait(500);
const response1 = await app.request('/test/cache');
const response2 = await app.request('/test/cache');
const parsed1 = await parser.parseString(response1.text);
const parsed2 = await parser.parseString(response2.text);
const parsed1 = await parser.parseString(await response1.text());
const parsed2 = await parser.parseString(await response2.text());
delete parsed1.lastBuildDate;
delete parsed2.lastBuildDate;
@@ -91,29 +86,29 @@ describe('cache', () => {
expect(parsed2).toMatchObject(parsed1);
expect(response2.status).toBe(200);
expect(response2.headers['rsshub-cache-status']).toBe('HIT');
expect(response2.headers.get('rsshub-cache-status')).toBe('HIT');
await wait(1 * 1000 + 100);
const response3 = await request.get('/test/cache');
const response3 = await app.request('/test/cache');
expect(response3.headers).not.toHaveProperty('rsshub-cache-status');
const parsed3 = await parser.parseString(response3.text);
const parsed3 = await parser.parseString(await response3.text());
await wait(3 * 1000 + 100);
const response4 = await request.get('/test/cache');
const parsed4 = await parser.parseString(response4.text);
const response4 = await app.request('/test/cache');
const parsed4 = await parser.parseString(await response4.text());
expect(parsed1.items[0].content).toBe('Cache1');
expect(parsed2.items[0].content).toBe('Cache1');
expect(parsed3.items[0].content).toBe('Cache1');
expect(parsed4.items[0].content).toBe('Cache2');
await request.get('/test/refreshCache');
await app.request('/test/refreshCache');
await wait(1 * 1000 + 100);
const response5 = await request.get('/test/refreshCache');
const parsed5 = await parser.parseString(response5.text);
const response5 = await app.request('/test/refreshCache');
const parsed5 = await parser.parseString(await response5.text());
await wait(2 * 1000 + 100);
const response6 = await request.get('/test/refreshCache');
const parsed6 = await parser.parseString(response6.text);
const response6 = await app.request('/test/refreshCache');
const parsed6 = await parser.parseString(await response6.text());
expect(parsed5.items[0].content).toBe('1 1');
expect(parsed6.items[0].content).toBe('1 0');
@@ -124,16 +119,15 @@ describe('cache', () => {
it('redis with quit', async () => {
process.env.CACHE_TYPE = 'redis';
server = (await import('@/index')).default;
const cache = (await import('@/utils/cache')).default;
await cache.clients.redisClient!.quit();
const request = supertest(server);
const app = (await import('@/app')).default;
const response1 = await request.get('/test/cache');
const response2 = await request.get('/test/cache');
const response1 = await app.request('/test/cache');
const response2 = await app.request('/test/cache');
const parsed1 = await parser.parseString(response1.text);
const parsed2 = await parser.parseString(response2.text);
const parsed1 = await parser.parseString(await response1.text());
const parsed2 = await parser.parseString(await response2.text());
expect(response2.status).toBe(200);
expect(response2.headers).not.toHaveProperty('rsshub-cache-status');
@@ -145,14 +139,13 @@ describe('cache', () => {
it('redis with error', async () => {
process.env.CACHE_TYPE = 'redis';
process.env.REDIS_URL = 'redis://wrongpath:6379';
server = (await import('@/index')).default;
const request = supertest(server);
const app = (await import('@/app')).default;
const response1 = await request.get('/test/cache');
const response2 = await request.get('/test/cache');
const response1 = await app.request('/test/cache');
const response2 = await app.request('/test/cache');
const parsed1 = await parser.parseString(response1.text);
const parsed2 = await parser.parseString(response2.text);
const parsed1 = await parser.parseString(await response1.text());
const parsed2 = await parser.parseString(await response2.text());
expect(response2.status).toBe(200);
expect(response2.headers).not.toHaveProperty('rsshub-cache-status');
@@ -166,14 +159,13 @@ describe('cache', () => {
it('no cache', async () => {
process.env.CACHE_TYPE = 'NO';
server = (await import('@/index')).default;
const request = supertest(server);
const app = (await import('@/app')).default;
const response1 = await request.get('/test/cache');
const response2 = await request.get('/test/cache');
const response1 = await app.request('/test/cache');
const response2 = await app.request('/test/cache');
const parsed1 = await parser.parseString(response1.text);
const parsed2 = await parser.parseString(response2.text);
const parsed1 = await parser.parseString(await response1.text());
const parsed2 = await parser.parseString(await response2.text());
expect(response2.status).toBe(200);
expect(response2.headers).not.toHaveProperty('rsshub-cache-status');
@@ -184,11 +176,10 @@ describe('cache', () => {
it('throws URL key', async () => {
process.env.CACHE_TYPE = 'memory';
server = (await import('@/index')).default;
const request = supertest(server);
const app = (await import('@/app')).default;
try {
const response = await request.get('/test/cacheUrlKey');
const response = await app.request('/test/cacheUrlKey');
expect(response).toThrow(Error);
} catch (error: any) {
expect(error.message).toContain('Cache key must be a string');
+14 -16
View File
@@ -1,11 +1,9 @@
import { describe, expect, it, afterAll } from '@jest/globals';
import supertest from 'supertest';
import server from '@/index';
import { describe, expect, it } from '@jest/globals';
import app from '@/app';
import { load } from 'cheerio';
process.env.NODE_NAME = 'mock';
const request = supertest(server);
let gitHash;
try {
gitHash = require('git-rev-sync').short();
@@ -13,22 +11,22 @@ try {
gitHash = (process.env.HEROKU_SLUG_COMMIT && process.env.HEROKU_SLUG_COMMIT.slice(0, 7)) || 'unknown';
}
afterAll(() => {
server.close();
});
describe('debug', () => {
it('debug', async () => {
const response1 = await request.get('/test/1');
const etag = response1.headers.etag;
await request.get('/test/1').set('If-None-Match', etag);
await request.get('/test/2');
await request.get('/test/empty');
await request.get('/test/empty');
const response1 = await app.request('/test/1');
const etag = response1.headers.get('etag');
await app.request('/test/1', {
headers: {
'If-None-Match': etag!,
},
});
await app.request('/test/2');
await app.request('/test/empty');
await app.request('/test/empty');
const response = await request.get('/');
const response = await app.request('/');
const $ = load(response.text);
const $ = load(await response.text());
$('.debug-item').each((index, item) => {
const key = $(item).find('.debug-key').html()?.trim();
const value = $(item).find('.debug-value').html()?.trim();
+8 -9
View File
@@ -1,5 +1,4 @@
import { describe, expect, it, afterAll, jest, afterEach } from '@jest/globals';
import supertest from 'supertest';
jest.setTimeout(50000);
@@ -14,29 +13,29 @@ afterEach(() => {
describe('filter-engine', () => {
it(`filter RE2 engine ReDoS attack`, async () => {
const request = supertest((await import('@/index')).default);
const app = (await import('@/app')).default;
const response = await request.get('/test/1?filter=abc(%3F%3Ddef)');
const response = await app.request('/test/1?filter=abc(%3F%3Ddef)');
expect(response.status).toBe(404);
expect(response.text).toMatch(/RE2JSSyntaxException/);
expect(await response.text()).toMatch(/RE2JSSyntaxException/);
});
it(`filter Regexp engine backward compatibility`, async () => {
process.env.FILTER_REGEX_ENGINE = 'regexp';
const request = supertest((await import('@/index')).default);
const app = (await import('@/app')).default;
const response = await request.get('/test/1?filter=abc(%3F%3Ddef)');
const response = await app.request('/test/1?filter=abc(%3F%3Ddef)');
expect(response.status).toBe(200);
});
it(`filter Regexp engine test config`, async () => {
process.env.FILTER_REGEX_ENGINE = 'somethingelse';
const request = supertest((await import('@/index')).default);
const app = (await import('@/app')).default;
const response = await request.get('/test/1?filter=abc(%3F%3Ddef)');
const response = await app.request('/test/1?filter=abc(%3F%3Ddef)');
expect(response.status).toBe(404);
expect(response.text).toMatch(/somethingelse/);
expect(await response.text()).toMatch(/somethingelse/);
});
});
+18 -15
View File
@@ -1,5 +1,4 @@
import { describe, expect, it, afterAll } from '@jest/globals';
import supertest from 'supertest';
process.env.NODE_NAME = 'mock';
process.env.ALLOW_ORIGIN = 'rsshub.mock';
@@ -13,24 +12,28 @@ afterAll(() => {
describe('header', () => {
it(`header`, async () => {
const request = supertest((await import('@/index')).default);
const app = (await import('@/app')).default;
const { config } = await import('@/config');
const response = await request.get('/test/1');
expect(response.headers['access-control-allow-origin']).toBe('rsshub.mock');
expect(response.headers['access-control-allow-methods']).toBe('GET');
expect(response.headers['content-type']).toBe('application/xml; charset=utf-8');
expect(response.headers['cache-control']).toBe(`public, max-age=${config.cache.routeExpire}`);
expect(response.headers['last-modified']).toBe(response.text.match(/<lastBuildDate>(.*)<\/lastBuildDate>/)?.[1]);
expect(response.headers['rsshub-node']).toBe('mock');
expect(response.headers.etag).not.toBe(undefined);
etag = response.headers.etag;
const response = await app.request('/test/1');
expect(response.headers.get('access-control-allow-origin')).toBe('rsshub.mock');
expect(response.headers.get('access-control-allow-methods')).toBe('GET');
expect(response.headers.get('content-type')).toBe('application/xml; charset=utf-8');
expect(response.headers.get('cache-control')).toBe(`public, max-age=${config.cache.routeExpire}`);
expect(response.headers.get('last-modified')).toBe((await response.text()).match(/<lastBuildDate>(.*)<\/lastBuildDate>/)?.[1]);
expect(response.headers.get('rsshub-node')).toBe('mock');
expect(response.headers.get('etag')).not.toBe(undefined);
etag = response.headers.get('etag');
});
it(`etag`, async () => {
const request = supertest((await import('@/index')).default);
const response = await request.get('/test/1').set('If-None-Match', etag);
const app = (await import('@/app')).default;
const response = await app.request('/test/1', {
headers: {
'If-None-Match': etag,
},
});
expect(response.status).toBe(304);
expect(response.text).toBe('');
expect(response.headers['last-modified']).toBe(undefined);
expect(await response.text()).toBe('');
expect(response.headers.get('last-modified')).toBe(null);
});
});
+1 -1
View File
@@ -39,7 +39,7 @@ const middleware: MiddlewareHandler = async (ctx, next) => {
const ifNoneMatch = ctx.req.header('If-None-Match') ?? null;
if (etagMatches(etag, ifNoneMatch)) {
ctx.status(304);
return ctx.body(null);
ctx.set('no-content', true);
} else {
ctx.header('Last-Modified', lastBuildDate);
}
+100 -106
View File
@@ -1,138 +1,132 @@
import { describe, expect, it, afterAll, jest } from '@jest/globals';
import supertest from 'supertest';
import server from '@/index';
import { describe, expect, it, jest } from '@jest/globals';
import app from '@/app';
import Parser from 'rss-parser';
import { config } from '@/config';
import nock from 'nock';
const request = supertest(server);
const parser = new Parser();
afterAll(() => {
server.close();
});
describe('filter', () => {
it(`filter`, async () => {
const response = await request.get('/test/1?filter=Description4|Title5');
const parsed = await parser.parseString(response.text);
const response = await app.request('/test/1?filter=Description4|Title5');
const parsed = await parser.parseString(await response.text());
expect(parsed.items.length).toBe(2);
expect(parsed.items[0].title).toBe('Title4');
expect(parsed.items[1].title).toBe('Title5');
});
it(`filter filter_case_sensitive default`, async () => {
const response = await request.get('/test/1?filter=description4|title5');
const parsed = await parser.parseString(response.text);
const response = await app.request('/test/1?filter=description4|title5');
const parsed = await parser.parseString(await response.text());
expect(parsed.items.length).toBe(0);
});
it(`filter filter_case_sensitive=false`, async () => {
const response = await request.get('/test/1?filter=description4|title5&filter_case_sensitive=false');
const parsed = await parser.parseString(response.text);
const response = await app.request('/test/1?filter=description4|title5&filter_case_sensitive=false');
const parsed = await parser.parseString(await response.text());
expect(parsed.items.length).toBe(2);
expect(parsed.items[0].title).toBe('Title4');
expect(parsed.items[1].title).toBe('Title5');
});
it(`filter_title`, async () => {
const response = await request.get('/test/1?filter_title=Description4|Title5');
const parsed = await parser.parseString(response.text);
const response = await app.request('/test/1?filter_title=Description4|Title5');
const parsed = await parser.parseString(await response.text());
expect(parsed.items.length).toBe(1);
expect(parsed.items[0].title).toBe('Title5');
});
it(`filter_title filter_case_sensitive=false`, async () => {
const response = await request.get('/test/1?filter_title=description4|title5&filter_case_sensitive=false');
const parsed = await parser.parseString(response.text);
const response = await app.request('/test/1?filter_title=description4|title5&filter_case_sensitive=false');
const parsed = await parser.parseString(await response.text());
expect(parsed.items.length).toBe(1);
expect(parsed.items[0].title).toBe('Title5');
});
it(`filter_description`, async () => {
const response = await request.get('/test/1?filter_description=Description4|Title5');
const parsed = await parser.parseString(response.text);
const response = await app.request('/test/1?filter_description=Description4|Title5');
const parsed = await parser.parseString(await response.text());
expect(parsed.items.length).toBe(1);
expect(parsed.items[0].title).toBe('Title4');
});
it(`filter_description filter_case_sensitive=false`, async () => {
const response = await request.get('/test/1?filter_description=description4|title5&filter_case_sensitive=false');
const parsed = await parser.parseString(response.text);
const response = await app.request('/test/1?filter_description=description4|title5&filter_case_sensitive=false');
const parsed = await parser.parseString(await response.text());
expect(parsed.items.length).toBe(1);
expect(parsed.items[0].title).toBe('Title4');
});
it(`filter_author`, async () => {
const response = await request.get('/test/1?filter_author=DIYgod4|DIYgod5');
const parsed = await parser.parseString(response.text);
const response = await app.request('/test/1?filter_author=DIYgod4|DIYgod5');
const parsed = await parser.parseString(await response.text());
expect(parsed.items.length).toBe(2);
expect(parsed.items[0].title).toBe('Title4');
expect(parsed.items[1].title).toBe('Title5');
});
it(`filter_author filter_case_sensitive default`, async () => {
const response = await request.get('/test/1?filter_author=diygod4|diygod5');
const parsed = await parser.parseString(response.text);
const response = await app.request('/test/1?filter_author=diygod4|diygod5');
const parsed = await parser.parseString(await response.text());
expect(parsed.items.length).toBe(0);
});
it(`filter_author filter_case_sensitive=false`, async () => {
const response = await request.get('/test/1?filter_author=diygod4|diygod5&filter_case_sensitive=false');
const parsed = await parser.parseString(response.text);
const response = await app.request('/test/1?filter_author=diygod4|diygod5&filter_case_sensitive=false');
const parsed = await parser.parseString(await response.text());
expect(parsed.items.length).toBe(2);
expect(parsed.items[0].title).toBe('Title4');
expect(parsed.items[1].title).toBe('Title5');
});
it(`filter_category`, async () => {
const response = await request.get('/test/filter?filter_category=Category0|Category1');
const parsed = await parser.parseString(response.text);
const response = await app.request('/test/filter?filter_category=Category0|Category1');
const parsed = await parser.parseString(await response.text());
expect(parsed.items.length).toBe(2);
expect(parsed.items[0].title).toBe('Filter Title1');
expect(parsed.items[1].title).toBe('Filter Title2');
});
it(`filter_category filter_case_sensitive default`, async () => {
const response = await request.get('/test/filter?filter_category=category0|category1');
const parsed = await parser.parseString(response.text);
const response = await app.request('/test/filter?filter_category=category0|category1');
const parsed = await parser.parseString(await response.text());
expect(parsed.items.length).toBe(0);
});
it(`filter_category filter_case_sensitive=false`, async () => {
const response = await request.get('/test/filter?filter_category=category0|category1&filter_case_sensitive=false');
const parsed = await parser.parseString(response.text);
const response = await app.request('/test/filter?filter_category=category0|category1&filter_case_sensitive=false');
const parsed = await parser.parseString(await response.text());
expect(parsed.items.length).toBe(2);
expect(parsed.items[0].title).toBe('Filter Title1');
expect(parsed.items[1].title).toBe('Filter Title2');
});
it(`filter_category filter_case_sensitive=false category string`, async () => {
const response = await request.get('/test/filter?filter_category=category3&filter_case_sensitive=false');
const parsed = await parser.parseString(response.text);
const response = await app.request('/test/filter?filter_category=category3&filter_case_sensitive=false');
const parsed = await parser.parseString(await response.text());
expect(parsed.items.length).toBe(1);
expect(parsed.items[0].title).toBe('Filter Title3');
});
it(`filter_category illegal_category`, async () => {
const response = await request.get('/test/filter-illegal-category?filter_category=CategoryIllegal');
const parsed = await parser.parseString(response.text);
const response = await app.request('/test/filter-illegal-category?filter_category=CategoryIllegal');
const parsed = await parser.parseString(await response.text());
expect(parsed.items.length).toBe(1);
expect(parsed.items[0].categories?.length).toBe(1);
expect(parsed.items[0].categories?.[0]).toBe('CategoryIllegal');
});
it(`filter_time`, async () => {
const response = await request.get('/test/current_time?filter_time=25');
const parsed = await parser.parseString(response.text);
const response = await app.request('/test/current_time?filter_time=25');
const parsed = await parser.parseString(await response.text());
expect(parsed.items.length).toBe(2);
expect(parsed.items[0].title).toBe('Title1');
expect(parsed.items[1].title).toBe('Title2');
});
it(`filterout`, async () => {
const response = await request.get('/test/1?filterout=Description4|Title5');
const parsed = await parser.parseString(response.text);
const response = await app.request('/test/1?filterout=Description4|Title5');
const parsed = await parser.parseString(await response.text());
expect(parsed.items.length).toBe(3);
expect(parsed.items[0].title).toBe('Title1');
expect(parsed.items[1].title).toBe('Title2');
@@ -140,8 +134,8 @@ describe('filter', () => {
});
it(`filterout filter_case_sensitive default`, async () => {
const response = await request.get('/test/1?filterout=description4|title5');
const parsed = await parser.parseString(response.text);
const response = await app.request('/test/1?filterout=description4|title5');
const parsed = await parser.parseString(await response.text());
expect(parsed.items.length).toBe(5);
expect(parsed.items[0].title).toBe('Title1');
expect(parsed.items[1].title).toBe('Title2');
@@ -149,8 +143,8 @@ describe('filter', () => {
});
it(`filterout filter_case_sensitive=false`, async () => {
const response = await request.get('/test/1?filterout=description4|title5&filter_case_sensitive=false');
const parsed = await parser.parseString(response.text);
const response = await app.request('/test/1?filterout=description4|title5&filter_case_sensitive=false');
const parsed = await parser.parseString(await response.text());
expect(parsed.items.length).toBe(3);
expect(parsed.items[0].title).toBe('Title1');
expect(parsed.items[1].title).toBe('Title2');
@@ -158,8 +152,8 @@ describe('filter', () => {
});
it(`filterout_title`, async () => {
const response = await request.get('/test/1?filterout_title=Description4|Title5');
const parsed = await parser.parseString(response.text);
const response = await app.request('/test/1?filterout_title=Description4|Title5');
const parsed = await parser.parseString(await response.text());
expect(parsed.items.length).toBe(4);
expect(parsed.items[0].title).toBe('Title1');
expect(parsed.items[1].title).toBe('Title2');
@@ -168,8 +162,8 @@ describe('filter', () => {
});
it(`filterout_title filter_case_sensitive=false`, async () => {
const response = await request.get('/test/1?filterout_title=description4|title5&filter_case_sensitive=false');
const parsed = await parser.parseString(response.text);
const response = await app.request('/test/1?filterout_title=description4|title5&filter_case_sensitive=false');
const parsed = await parser.parseString(await response.text());
expect(parsed.items.length).toBe(4);
expect(parsed.items[0].title).toBe('Title1');
expect(parsed.items[1].title).toBe('Title2');
@@ -178,8 +172,8 @@ describe('filter', () => {
});
it(`filterout_description`, async () => {
const response = await request.get('/test/1?filterout_description=Description4|Title5');
const parsed = await parser.parseString(response.text);
const response = await app.request('/test/1?filterout_description=Description4|Title5');
const parsed = await parser.parseString(await response.text());
expect(parsed.items.length).toBe(4);
expect(parsed.items[0].title).toBe('Title1');
expect(parsed.items[1].title).toBe('Title2');
@@ -188,8 +182,8 @@ describe('filter', () => {
});
it(`filterout_description filter_case_sensitive=false`, async () => {
const response = await request.get('/test/1?filterout_description=description4|title5&filter_case_sensitive=false');
const parsed = await parser.parseString(response.text);
const response = await app.request('/test/1?filterout_description=description4|title5&filter_case_sensitive=false');
const parsed = await parser.parseString(await response.text());
expect(parsed.items.length).toBe(4);
expect(parsed.items[0].title).toBe('Title1');
expect(parsed.items[1].title).toBe('Title2');
@@ -198,8 +192,8 @@ describe('filter', () => {
});
it(`filterout_author`, async () => {
const response = await request.get('/test/1?filterout_author=DIYgod4|DIYgod5');
const parsed = await parser.parseString(response.text);
const response = await app.request('/test/1?filterout_author=DIYgod4|DIYgod5');
const parsed = await parser.parseString(await response.text());
expect(parsed.items.length).toBe(3);
expect(parsed.items[0].title).toBe('Title1');
expect(parsed.items[1].title).toBe('Title2');
@@ -207,8 +201,8 @@ describe('filter', () => {
});
it(`filterout_author filter_case_sensitive default`, async () => {
const response = await request.get('/test/1?filterout_author=diygod4|diygod5');
const parsed = await parser.parseString(response.text);
const response = await app.request('/test/1?filterout_author=diygod4|diygod5');
const parsed = await parser.parseString(await response.text());
expect(parsed.items.length).toBe(5);
expect(parsed.items[0].title).toBe('Title1');
expect(parsed.items[1].title).toBe('Title2');
@@ -216,8 +210,8 @@ describe('filter', () => {
});
it(`filterout_author filter_case_sensitive=false`, async () => {
const response = await request.get('/test/1?filterout_author=diygod4|diygod5&filter_case_sensitive=false');
const parsed = await parser.parseString(response.text);
const response = await app.request('/test/1?filterout_author=diygod4|diygod5&filter_case_sensitive=false');
const parsed = await parser.parseString(await response.text());
expect(parsed.items.length).toBe(3);
expect(parsed.items[0].title).toBe('Title1');
expect(parsed.items[1].title).toBe('Title2');
@@ -225,8 +219,8 @@ describe('filter', () => {
});
it(`filterout_category`, async () => {
const response = await request.get('/test/filter?filterout_category=Category0|Category1');
const parsed = await parser.parseString(response.text);
const response = await app.request('/test/filter?filterout_category=Category0|Category1');
const parsed = await parser.parseString(await response.text());
expect(parsed.items.length).toBe(6);
expect(parsed.items[0].title).toBe('Filter Title3');
expect(parsed.items[1].title).toBe('Title1');
@@ -234,8 +228,8 @@ describe('filter', () => {
});
it(`filterout_category filter_case_sensitive default`, async () => {
const response = await request.get('/test/filter?filterout_category=category0|category1');
const parsed = await parser.parseString(response.text);
const response = await app.request('/test/filter?filterout_category=category0|category1');
const parsed = await parser.parseString(await response.text());
expect(parsed.items.length).toBe(8);
expect(parsed.items[0].title).toBe('Filter Title1');
expect(parsed.items[1].title).toBe('Filter Title2');
@@ -244,8 +238,8 @@ describe('filter', () => {
});
it(`filterout_category filter_case_sensitive=false`, async () => {
const response = await request.get('/test/filter?filterout_category=category0|category1&filter_case_sensitive=false');
const parsed = await parser.parseString(response.text);
const response = await app.request('/test/filter?filterout_category=category0|category1&filter_case_sensitive=false');
const parsed = await parser.parseString(await response.text());
expect(parsed.items.length).toBe(6);
expect(parsed.items[0].title).toBe('Filter Title3');
expect(parsed.items[1].title).toBe('Title1');
@@ -253,15 +247,15 @@ describe('filter', () => {
});
it(`filter combination`, async () => {
const response = await request.get('/test/filter?filter_title=Filter&filter_description=Description1');
const parsed = await parser.parseString(response.text);
const response = await app.request('/test/filter?filter_title=Filter&filter_description=Description1');
const parsed = await parser.parseString(await response.text());
expect(parsed.items.length).toBe(1);
expect(parsed.items[0].title).toBe('Filter Title1');
});
it(`filterout combination`, async () => {
const response = await request.get('/test/filter?filterout_title=Filter&filterout_description=Description1');
const parsed = await parser.parseString(response.text);
const response = await app.request('/test/filter?filterout_title=Filter&filterout_description=Description1');
const parsed = await parser.parseString(await response.text());
expect(parsed.items.length).toBe(4);
expect(parsed.items[0].title).toBe('Title2');
});
@@ -269,8 +263,8 @@ describe('filter', () => {
describe('limit', () => {
it(`limit`, async () => {
const response = await request.get('/test/1?limit=3');
const parsed = await parser.parseString(response.text);
const response = await app.request('/test/1?limit=3');
const parsed = await parser.parseString(await response.text());
expect(parsed.items.length).toBe(3);
expect(parsed.items[0].title).toBe('Title1');
expect(parsed.items[1].title).toBe('Title2');
@@ -280,9 +274,9 @@ describe('limit', () => {
describe('sorted', () => {
it('sorted', async () => {
const response = await request.get('/test/sort?sorted=false');
const response = await app.request('/test/sort?sorted=false');
expect(response.status).toBe(200);
const parsed = await parser.parseString(response.text);
const parsed = await parser.parseString(await response.text());
expect(parsed.items[0].title).toBe('Sort Title 0');
expect(parsed.items[1].title).toBe('Sort Title 1');
expect(parsed.items[2].title).toBe('Sort Title 2');
@@ -292,8 +286,8 @@ describe('sorted', () => {
describe('tgiv', () => {
it(`tgiv`, async () => {
const response = await request.get('/test/1?tgiv=test');
const parsed = await parser.parseString(response.text);
const response = await app.request('/test/1?tgiv=test');
const parsed = await parser.parseString(await response.text());
expect(parsed.items[0].link).toBe(`https://t.me/iv?url=https%3A%2F%2Fgithub.com%2FDIYgod%2FRSSHub%2Fissues%2F1&rhash=test`);
expect(parsed.items[1].link).toBe(`https://t.me/iv?url=https%3A%2F%2Fgithub.com%2FDIYgod%2FRSSHub%2Fissues%2F2&rhash=test`);
});
@@ -301,49 +295,49 @@ describe('tgiv', () => {
describe('empty', () => {
it(`empty`, async () => {
const response1 = await request.get('/test/empty');
const response1 = await app.request('/test/empty');
expect(response1.status).toBe(404);
expect(response1.text).toMatch(/Error: this route is empty/);
expect(await response1.text()).toMatch(/Error: this route is empty/);
const response2 = await request.get('/test/1?limit=0');
const response2 = await app.request('/test/1?limit=0');
expect(response2.status).toBe(200);
const parsed = await parser.parseString(response2.text);
const parsed = await parser.parseString(await response2.text());
expect(parsed.items.length).toBe(0);
});
});
describe('allow_empty', () => {
it(`allow_empty`, async () => {
const response = await request.get('/test/allow_empty');
const response = await app.request('/test/allow_empty');
expect(response.status).toBe(200);
const parsed = await parser.parseString(response.text);
const parsed = await parser.parseString(await response.text());
expect(parsed.items.length).toBe(0);
});
});
describe('wrong_path', () => {
it(`wrong_path`, async () => {
const response = await request.get('/wrong');
const response = await app.request('/wrong');
expect(response.status).toBe(404);
expect(response.headers['cache-control']).toBe(`public, max-age=${config.cache.routeExpire}`);
expect(response.text).toMatch(/Error message: wrong path/);
expect(response.headers.get('cache-control')).toBe(`public, max-age=${config.cache.routeExpire}`);
expect(await response.text()).toMatch(/Error message: wrong path/);
});
});
describe('fulltext_mode', () => {
it(`fulltext`, async () => {
const response = await request.get('/test/1?mode=fulltext');
const response = await app.request('/test/1?mode=fulltext');
expect(response.status).toBe(200);
const parsed = await parser.parseString(response.text);
const parsed = await parser.parseString(await response.text());
expect(parsed.items[0].content).not.toBe(undefined);
}, 60000);
});
describe('complicated_description', () => {
it(`complicated_description`, async () => {
const response = await request.get('/test/complicated');
const response = await app.request('/test/complicated');
expect(response.status).toBe(200);
const parsed = await parser.parseString(response.text);
const parsed = await parser.parseString(await response.text());
expect(parsed.items[0].content).toBe(`<a href="https://mock.com/DIYgod/RSSHub"></a>
<img src="https://mock.com/DIYgod/RSSHub.jpg" referrerpolicy="no-referrer">
@@ -361,9 +355,9 @@ describe('complicated_description', () => {
describe('multimedia_description', () => {
it(`multimedia_description`, async () => {
const response = await request.get('/test/multimedia');
const response = await app.request('/test/multimedia');
expect(response.status).toBe(200);
const parsed = await parser.parseString(response.text);
const parsed = await parser.parseString(await response.text());
expect(parsed.items[0].content).toBe(`<img src="https://mock.com/DIYgod/RSSHub.jpg" referrerpolicy="no-referrer">
<video src="https://mock.com/DIYgod/RSSHub.mp4"></video>
<video poster="https://mock.com/DIYgod/RSSHub.jpg">
@@ -377,9 +371,9 @@ describe('multimedia_description', () => {
describe('sort', () => {
it(`sort`, async () => {
const response = await request.get('/test/sort');
const response = await app.request('/test/sort');
expect(response.status).toBe(200);
const parsed = await parser.parseString(response.text);
const parsed = await parser.parseString(await response.text());
expect(parsed.items[0].title).toBe('Sort Title 3');
expect(parsed.items.at(-3)?.title).toBe('Sort Title 2');
expect(parsed.items.at(-2)?.title).toBe('Sort Title 0');
@@ -389,9 +383,9 @@ describe('sort', () => {
describe('mess parameter', () => {
it(`date`, async () => {
const response = await request.get('/test/mess');
const response = await app.request('/test/mess');
expect(response.status).toBe(200);
const parsed = await parser.parseString(response.text);
const parsed = await parser.parseString(await response.text());
expect(parsed.items[0].pubDate).toBe('Mon, 31 Dec 2018 16:00:00 GMT');
expect(parsed.items[0].link).toBe('https://github.com/DIYgod/RSSHub/issues/0');
});
@@ -399,8 +393,8 @@ describe('mess parameter', () => {
describe('opencc', () => {
it(`opencc`, async () => {
const response = await request.get('/test/opencc?opencc=t2s');
const parsed = await parser.parseString(response.text);
const response = await app.request('/test/opencc?opencc=t2s');
const parsed = await parser.parseString(await response.text());
expect(parsed.items[0].title).toBe('小可爱');
expect(parsed.items[0].content).toBe('宇宙无敌');
});
@@ -408,8 +402,8 @@ describe('opencc', () => {
describe('brief', () => {
it(`brief`, async () => {
const response = await request.get('/test/brief?brief=100');
const parsed = await parser.parseString(response.text);
const response = await app.request('/test/brief?brief=100');
const parsed = await parser.parseString(await response.text());
expect(parsed.items[0].title).toBe('小可愛');
expect(parsed.items[0].content).toBe(
'<p>宇宙無敵宇宙無敵宇宙無敵宇宙無敵宇宙無敵宇宙無敵宇宙無敵宇宙無敵宇宙無敵宇宙無敵宇宙無敵宇宙無敵宇宙無敵宇宙無敵宇宙無敵宇宙無敵宇宙無敵宇宙無敵宇宙無敵宇宙無敵宇宙無敵宇宙無敵宇宙無敵宇宙無敵宇宙無敵…</p>'
@@ -419,8 +413,8 @@ describe('brief', () => {
describe('multi parameter', () => {
it(`filter before limit`, async () => {
const response = await request.get('/test/filter-limit?filterout_title=2&limit=2');
const parsed = await parser.parseString(response.text);
const response = await app.request('/test/filter-limit?filterout_title=2&limit=2');
const parsed = await parser.parseString(await response.text());
expect(parsed.items.length).toBe(2);
expect(parsed.items[0].title).toBe('Title1');
expect(parsed.items[1].title).toBe('Title3');
@@ -432,7 +426,7 @@ describe('openai', () => {
jest.resetModules();
process.env.OPENAI_API_KEY = 'sk-1234567890';
const request = supertest((await import('@/index')).default);
const app = (await import('@/app')).default;
const { config } = await import('@/config');
nock(config.openai.endpoint)
.post('/chat/completions')
@@ -449,14 +443,14 @@ describe('openai', () => {
},
]);
const responseWithGpt = await request.get('/test/gpt?chatgpt=true');
const responseNormal = await request.get('/test/gpt');
const responseWithGpt = await app.request('/test/gpt?chatgpt=true');
const responseNormal = await app.request('/test/gpt');
expect(responseWithGpt.status).toBe(200);
expect(responseNormal.status).toBe(200);
const parsedGpt = await parser.parseString(responseWithGpt.text);
const parsedNormal = await parser.parseString(responseNormal.text);
const parsedGpt = await parser.parseString(await responseWithGpt.text());
const parsedNormal = await parser.parseString(await responseNormal.text());
expect(parsedGpt.items[0].content).not.toBe(undefined);
expect(parsedGpt.items[0].content).toBe(parsedNormal.items[0].content);
+26 -32
View File
@@ -1,21 +1,15 @@
import { describe, expect, it, afterAll } from '@jest/globals';
import supertest from 'supertest';
import server from '@/index';
import { describe, expect, it } from '@jest/globals';
import app from '@/app';
import Parser from 'rss-parser';
const request = supertest(server);
const parser = new Parser();
afterAll(() => {
server.close();
});
describe('template', () => {
const expectPubDate = new Date(1_546_272_000_000 - 10 * 1000);
it(`.rss`, async () => {
const response1 = await request.get('/test/1?format=rss');
const parsed1 = await parser.parseString(response1.text);
const response1 = await app.request('/test/1?format=rss');
const parsed1 = await parser.parseString(await response1.text());
expect(parsed1).toEqual(expect.any(Object));
expect(parsed1.title).toEqual(expect.any(String));
@@ -33,8 +27,8 @@ describe('template', () => {
expect(parsed1.items[0].content).toEqual(expect.any(String));
expect(parsed1.items[0].guid).toEqual(expect.any(String));
const response2 = await request.get('/test/1');
const parsed2 = await parser.parseString(response2.text);
const response2 = await app.request('/test/1');
const parsed2 = await parser.parseString(await response2.text());
delete parsed1.lastBuildDate;
delete parsed2.lastBuildDate;
delete parsed1.feedUrl;
@@ -45,8 +39,8 @@ describe('template', () => {
});
it(`.atom`, async () => {
const response = await request.get('/test/1?format=atom');
const parsed = await parser.parseString(response.text);
const response = await app.request('/test/1?format=atom');
const parsed = await parser.parseString(await response.text());
expect(parsed).toEqual(expect.any(Object));
expect(parsed.title).toEqual(expect.any(String));
@@ -64,12 +58,12 @@ describe('template', () => {
});
it(`.json`, async () => {
const jsonResponse = await request.get('/test/1?format=json');
const rssResponse = await request.get('/test/1?format=rss');
const jsonParsed = JSON.parse(jsonResponse.text);
const rssParsed = await parser.parseString(rssResponse.text);
const jsonResponse = await app.request('/test/1?format=json');
const rssResponse = await app.request('/test/1?format=rss');
const jsonParsed = JSON.parse(await jsonResponse.text());
const rssParsed = await parser.parseString(await rssResponse.text());
expect(jsonResponse.headers['content-type']).toBe('application/feed+json; charset=UTF-8');
expect(jsonResponse.headers.get('content-type')).toBe('application/feed+json; charset=UTF-8');
expect(jsonParsed.items[0].title).toEqual(rssParsed.items[0].title);
expect(jsonParsed.items[0].url).toEqual(rssParsed.items[0].link);
@@ -81,34 +75,34 @@ describe('template', () => {
});
it('.debug.html', async () => {
const jsonResponse = await request.get('/test/1?format=json');
const jsonParsed = JSON.parse(jsonResponse.text);
const jsonResponse = await app.request('/test/1?format=json');
const jsonParsed = JSON.parse(await jsonResponse.text());
const debugHTMLResponse0 = await request.get('/test/1?format=0.debug.html');
expect(debugHTMLResponse0.headers['content-type']).toBe('text/html; charset=UTF-8');
expect(debugHTMLResponse0.text).toBe(jsonParsed.items[0].content_html);
const debugHTMLResponse0 = await app.request('/test/1?format=0.debug.html');
expect(debugHTMLResponse0.headers.get('content-type')).toBe('text/html; charset=UTF-8');
expect(await debugHTMLResponse0.text()).toBe(jsonParsed.items[0].content_html);
const debugHTMLResponseNotExist = await request.get(`/test/1?format=${jsonParsed.items.length}.debug.html`);
expect(debugHTMLResponseNotExist.text).toBe(`data.item[${jsonParsed.items.length}].description not found`);
const debugHTMLResponseNotExist = await app.request(`/test/1?format=${jsonParsed.items.length}.debug.html`);
expect(await debugHTMLResponseNotExist.text()).toBe(`data.item[${jsonParsed.items.length}].description not found`);
});
it('flatten author object', async () => {
const response = await request.get('/test/json');
const parsed = await parser.parseString(response.text);
const response = await app.request('/test/json');
const parsed = await parser.parseString(await response.text());
expect(parsed.items[2].author).toBe(['DIYgod1', 'DIYgod2'].map((name) => name).join(', '));
expect(parsed.items[3].author).toBe(['DIYgod3', 'DIYgod4', 'DIYgod5'].map((name) => name).join(', '));
expect(parsed.items[4].author).toBeUndefined();
});
it(`long title`, async () => {
const response = await request.get('/test/long');
const parsed = await parser.parseString(response.text);
const response = await app.request('/test/long');
const parsed = await parser.parseString(await response.text());
expect(parsed.items[0].title?.length).toBe(153);
});
it(`enclosure`, async () => {
const response = await request.get('/test/enclosure');
const parsed = await parser.parseString(response.text);
const response = await app.request('/test/enclosure');
const parsed = await parser.parseString(await response.text());
expect(parsed.itunes?.author).toBe('DIYgod');
expect(parsed.items[0].enclosure?.url).toBe('https://github.com/DIYgod/RSSHub/issues/1');
expect(parsed.items[0].enclosure?.length).toBe('3661');
+2
View File
@@ -88,6 +88,8 @@ const middleware: MiddlewareHandler = async (ctx, next) => {
} else if (outputType === 'json') {
ctx.header('Content-Type', 'application/feed+json; charset=UTF-8');
return ctx.body(json(result));
} else if (ctx.get('no-content')) {
return ctx.body(null);
} else {
return ctx.body(art(template, result));
}