diff --git a/lib/middleware/template.ts b/lib/middleware/template.ts index 0808b25bea..7fdae70978 100644 --- a/lib/middleware/template.ts +++ b/lib/middleware/template.ts @@ -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)); } }; diff --git a/lib/v3/jike/topic-text.js b/lib/v3/jike/topic-text.js index 06ee45a096..f243428f3c 100644 --- a/lib/v3/jike/topic-text.js +++ b/lib/v3/jike/topic-text.js @@ -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); diff --git a/lib/v3/jike/user.js b/lib/v3/jike/user.js index 87e4c56a41..bef1798231 100644 --- a/lib/v3/jike/user.js +++ b/lib/v3/jike/user.js @@ -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, - }; + }); }; diff --git a/lib/v2/test/index.js b/lib/v3/test/index.js similarity index 92% rename from lib/v2/test/index.js rename to lib/v3/test/index.js index c79739db21..449c233407 100644 --- a/lib/v2/test/index.js +++ b/lib/v3/test/index.js @@ -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' ? '' : ctx.params.id === 'multimedia' ? '' : 'A test route for RSSHub', - }; + allowEmpty: ctx.req.param('id') === 'allow_empty', + description: + ctx.req.param('id') === 'complicated' ? '' : ctx.req.param('id') === 'multimedia' ? '' : 'A test route for RSSHub', + }); }; diff --git a/lib/v2/test/maintainer.js b/lib/v3/test/maintainer.js similarity index 100% rename from lib/v2/test/maintainer.js rename to lib/v3/test/maintainer.js diff --git a/lib/v2/test/router.js b/lib/v3/test/router.js similarity index 100% rename from lib/v2/test/router.js rename to lib/v3/test/router.js diff --git a/test/router.js b/test/router.js deleted file mode 100644 index 9ee9c74b96..0000000000 --- a/test/router.js +++ /dev/null @@ -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/), - }); - }); -}); diff --git a/test/router.ts b/test/router.ts new file mode 100644 index 0000000000..62f5de1681 --- /dev/null +++ b/test/router.ts @@ -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'); + // }); +});