test: router

This commit is contained in:
DIYgod
2024-02-01 01:43:53 +08:00
parent 04647e122b
commit f289568899
8 changed files with 109 additions and 140 deletions
+3 -3
View File
@@ -88,12 +88,12 @@ const middleware: MiddlewareHandler = async (ctx, next) => {
if (outputType === 'ums') {
ctx.header('Content-Type', 'application/json; charset=UTF-8');
return ctx.body(render.rss3Ums(data));
return ctx.body(render.rss3Ums(result));
} else if (outputType === 'json') {
ctx.header('Content-Type', 'application/feed+json; charset=UTF-8');
return ctx.body(render.json(data));
return ctx.body(render.json(result));
} else {
return ctx.body(render.art(template, data));
return ctx.body(render.art(template, result));
}
};
+1 -1
View File
@@ -2,7 +2,7 @@ const dayjs = require('dayjs');
const { constructTopicEntry } = require('./utils');
module.exports = async (ctx) => {
const id = ctx.params.id;
const id = ctx.req.param('id');
const topicUrl = `https://m.okjike.com/topics/${id}`;
const data = await constructTopicEntry(ctx, topicUrl);
+3 -3
View File
@@ -3,7 +3,7 @@ const cheerio = require('cheerio');
const { parseDate } = require('@/utils/parse-date');
module.exports = async (ctx) => {
const id = ctx.params.id;
const id = ctx.req.param('id');
const response = await got({
method: 'get',
@@ -148,11 +148,11 @@ module.exports = async (ctx) => {
})
);
ctx.state.data = {
ctx.set('data', {
title: `${data.user.screenName}的即刻动态`,
description: data.user.bio,
link: `https://m.okjike.com/users/${id}`,
image: data.user.avatarImage.picUrl,
item: items,
};
});
};
+19 -18
View File
@@ -1,21 +1,21 @@
const config = require('@/config').value;
const got = require('@/utils/got');
const wait = require('@/utils/wait');
import { config } from '@/config';
import got from '@/utils/got';
import wait from '@/utils/wait';
let cacheIndex = 0;
module.exports = async (ctx) => {
if (ctx.params.id === 'error') {
if (ctx.req.param('id') === 'error') {
throw new Error('Error test');
}
if (ctx.params.id === 'httperror') {
if (ctx.req.param('id') === 'httperror') {
await got({
method: 'get',
url: 'https://httpbingo.org/status/404',
});
}
let item = [];
switch (ctx.params.id) {
switch (ctx.req.param('id')) {
case 'filter':
item = [
{
@@ -331,21 +331,21 @@ module.exports = async (ctx) => {
item.push({
title: `Title${i}`,
description: `Description${i}`,
pubDate: new Date((ctx.params.id === 'current_time' ? new Date() : 1_546_272_000_000) - i * 10 * 1000).toUTCString(),
pubDate: new Date((ctx.req.param('id') === 'current_time' ? new Date() : 1_546_272_000_000) - i * 10 * 1000).toUTCString(),
link: `https://github.com/DIYgod/RSSHub/issues/${i}`,
author: `DIYgod${i}`,
});
}
if (ctx.params.id === 'empty') {
if (ctx.req.param('id') === 'empty') {
item = null;
}
if (ctx.params.id === 'allow_empty') {
if (ctx.req.param('id') === 'allow_empty') {
item = null;
}
if (ctx.params.id === 'enclosure') {
if (ctx.req.param('id') === 'enclosure') {
item = [
{
title: '',
@@ -357,11 +357,11 @@ module.exports = async (ctx) => {
];
}
if (ctx.params.id === 'slow') {
if (ctx.req.param('id') === 'slow') {
await wait(1000);
}
if (ctx.query.mode === 'fulltext') {
if (ctx.req.query('mode') === 'fulltext') {
item = [
{
title: '',
@@ -370,12 +370,13 @@ module.exports = async (ctx) => {
];
}
ctx.state.data = {
title: `Test ${ctx.params.id}`,
itunes_author: ctx.params.id === 'enclosure' ? 'DIYgod' : null,
ctx.set('data', {
title: `Test ${ctx.req.param('id')}`,
itunes_author: ctx.req.param('id') === 'enclosure' ? 'DIYgod' : null,
link: 'https://github.com/DIYgod/RSSHub',
item,
allowEmpty: ctx.params.id === 'allow_empty',
description: ctx.params.id === 'complicated' ? '<img src="http://mock.com/DIYgod/DIYgod/RSSHub">' : ctx.params.id === 'multimedia' ? '<video src="http://mock.com/DIYgod/DIYgod/RSSHub"></video>' : 'A test route for RSSHub',
};
allowEmpty: ctx.req.param('id') === 'allow_empty',
description:
ctx.req.param('id') === 'complicated' ? '<img src="http://mock.com/DIYgod/DIYgod/RSSHub">' : ctx.req.param('id') === 'multimedia' ? '<video src="http://mock.com/DIYgod/DIYgod/RSSHub"></video>' : 'A test route for RSSHub',
});
};
-115
View File
@@ -1,115 +0,0 @@
process.env.SOCKET = 'socket';
const supertest = require('supertest');
jest.mock('request-promise-native');
const server = require('../lib/index');
const request = supertest(server);
const Parser = require('rss-parser');
const parser = new Parser();
const config = require('../lib/config').value;
afterAll(() => {
delete process.env.SOCKET;
});
async function checkRSS(response) {
const checkDate = (date) => {
expect(date).toEqual(expect.any(String));
expect(Date.parse(date)).toEqual(expect.any(Number));
expect(Date.now() - new Date(date)).toBeGreaterThan(-1000 * 60 * 60 * 24 * 5);
expect(Date.now() - new Date(date)).toBeLessThan(1000 * 60 * 60 * 24 * 30 * 12 * 10);
};
const parsed = await parser.parseString(response.text);
expect(parsed).toEqual(expect.any(Object));
expect(parsed.title).toEqual(expect.any(String));
expect(parsed.title).not.toBe('RSSHub');
expect(parsed.description).toEqual(expect.any(String));
expect(parsed.link).toEqual(expect.any(String));
expect(parsed.lastBuildDate).toEqual(expect.any(String));
expect(parsed.ttl).toEqual(Math.trunc(config.cache.routeExpire / 60) + '');
expect(parsed.items).toEqual(expect.any(Array));
checkDate(parsed.lastBuildDate);
// check items
const guids = [];
for (const item of parsed.items) {
expect(item).toEqual(expect.any(Object));
expect(item.title).toEqual(expect.any(String));
expect(item.link).toEqual(expect.any(String));
expect(item.content).toEqual(expect.any(String));
expect(item.guid).toEqual(expect.any(String));
if (item.pubDate) {
expect(item.pubDate).toEqual(expect.any(String));
checkDate(item.pubDate);
}
// guid must be unique
expect(guids).not.toContain(item.guid);
guids.push(item.guid);
}
}
afterAll(() => {
server.close();
});
describe('router', () => {
// root
it(`/`, async () => {
const response = await request.get('/');
expect(response.status).toBe(200);
expect(response.headers['content-type']).toBe('text/html; charset=UTF-8');
expect(response.headers['cache-control']).toBe('no-cache');
});
// route
it(`/test/1`, async () => {
const response = await request.get('/test/1');
expect(response.status).toBe(200);
await checkRSS(response);
});
// robots.txt
it('/robots.txt', async () => {
config.disallowRobot = false;
const response404 = await request.get('/robots.txt');
expect(response404.status).toBe(404);
config.disallowRobot = true;
const response = await request.get('/robots.txt');
expect(response.status).toBe(200);
expect(response.text).toBe('User-agent: *\nDisallow: /');
expect(response.headers['content-type']).toBe('text/plain');
});
// api
it(`/api/routes/test`, async () => {
const response = await request.get('/api/routes/test');
expect(response.status).toBe(200);
expect(response.body).toEqual({
status: 0,
data: {
test: {
routes: ['/test/:id'],
},
},
message: 'request returned 1 route',
});
}, 60000);
it(`/api/routes`, async () => {
const response = await request.get('/api/routes');
expect(response.status).toBe(200);
expect(response.body).toMatchObject({
status: 0,
data: {
test: {
routes: ['/test/:id'],
},
},
message: expect.stringMatching(/request returned (\d+) routes/),
});
});
});
+83
View File
@@ -0,0 +1,83 @@
import { describe, expect, it, afterAll, jest } from '@jest/globals';
process.env.SOCKET = 'socket';
jest.mock('request-promise-native');
import app from '../lib/app';
import Parser from 'rss-parser';
const parser = new Parser();
import { config } from '../lib/config';
afterAll(() => {
delete process.env.SOCKET;
});
async function checkRSS(response) {
const checkDate = (date) => {
expect(date).toEqual(expect.any(String));
expect(Date.parse(date)).toEqual(expect.any(Number));
expect(Date.now() - +new Date(date)).toBeGreaterThan(-1000 * 60 * 60 * 24 * 5);
expect(Date.now() - +new Date(date)).toBeLessThan(1000 * 60 * 60 * 24 * 30 * 12 * 10);
};
const parsed = await parser.parseString(await response.text());
expect(parsed).toEqual(expect.any(Object));
expect(parsed.title).toEqual(expect.any(String));
expect(parsed.title).not.toBe('RSSHub');
expect(parsed.description).toEqual(expect.any(String));
expect(parsed.link).toEqual(expect.any(String));
expect(parsed.lastBuildDate).toEqual(expect.any(String));
expect(parsed.ttl).toEqual(Math.trunc(config.cache.routeExpire / 60) + '');
expect(parsed.items).toEqual(expect.any(Array));
checkDate(parsed.lastBuildDate);
// check items
const guids: (string | undefined)[] = [];
for (const item of parsed.items) {
expect(item).toEqual(expect.any(Object));
expect(item.title).toEqual(expect.any(String));
expect(item.link).toEqual(expect.any(String));
expect(item.content).toEqual(expect.any(String));
expect(item.guid).toEqual(expect.any(String));
if (item.pubDate) {
expect(item.pubDate).toEqual(expect.any(String));
checkDate(item.pubDate);
}
// guid must be unique
expect(guids).not.toContain(item.guid);
guids.push(item.guid);
}
}
describe('router', () => {
// root
it(`/`, async () => {
const response = await app.request('/');
expect(response.status).toBe(200);
expect(response.headers.get('content-type')).toBe('text/html; charset=UTF-8');
expect(response.headers.get('cache-control')).toBe('no-cache');
});
// route
it(`/test/1`, async () => {
const response = await app.request('/test/1');
expect(response.status).toBe(200);
await checkRSS(response);
});
// robots.txt
// TODO
// it('/robots.txt', async () => {
// config.disallowRobot = false;
// const response404 = await app.request('/robots.txt');
// expect(response404.status).toBe(404);
// config.disallowRobot = true;
// const response = await app.request('/robots.txt');
// expect(response.status).toBe(200);
// expect(await response.text()).toBe('User-agent: *\nDisallow: /');
// expect(response.headers.get('content-type')).toBe('text/plain');
// });
});