1+ import Parser from 'rss-parser' ;
12import undici from 'undici' ;
23import { describe , expect , it , vi } from 'vitest' ;
34
45import app from '@/app' ;
6+ import { config } from '@/config' ;
57
68describe ( 'index' , ( ) => {
9+ it ( 'exports app entrypoint' , ( ) => {
10+ expect ( typeof app . request ) . toBe ( 'function' ) ;
11+ } ) ;
12+
713 it ( 'serve index' , async ( ) => {
814 const res = await app . request ( '/' ) ;
915 expect ( res . status ) . toBe ( 200 ) ;
@@ -21,3 +27,84 @@ describe('request-rewriter', () => {
2127 expect ( headers . get ( 'user-agent' ) ) . toMatch ( / C h r o m e / ) ;
2228 } ) ;
2329} ) ;
30+
31+ const parser = new Parser ( ) ;
32+
33+ process . env . ALLOW_USER_SUPPLY_UNSAFE_DOMAIN = 'true' ;
34+
35+ const routes = {
36+ '/test/:id' : '/test/1' ,
37+ } ;
38+ if ( process . env . FULL_ROUTES_TEST ) {
39+ const { namespaces } = await import ( '@/registry' ) ;
40+ for ( const namespace in namespaces ) {
41+ for ( const route in namespaces [ namespace ] . routes ) {
42+ const requireConfig = namespaces [ namespace ] . routes [ route ] . features ?. requireConfig ;
43+ let configs ;
44+ if ( typeof requireConfig !== 'boolean' ) {
45+ configs = requireConfig
46+ ?. filter ( ( config ) => ! config . optional )
47+ . map ( ( config ) => config . name )
48+ . filter ( ( name ) => name !== 'ALLOW_USER_SUPPLY_UNSAFE_DOMAIN' ) ;
49+ }
50+ if ( namespaces [ namespace ] . routes [ route ] . example && ! configs ?. length ) {
51+ routes [ `/${ namespace } ${ route } ` ] = namespaces [ namespace ] . routes [ route ] . example ;
52+ }
53+ }
54+ }
55+ }
56+
57+ async function checkRSS ( response ) {
58+ const checkDate = ( date ) => {
59+ expect ( date ) . toEqual ( expect . any ( String ) ) ;
60+ expect ( Date . parse ( date ) ) . toEqual ( expect . any ( Number ) ) ;
61+ expect ( Date . now ( ) - + new Date ( date ) ) . toBeGreaterThan ( - 1000 * 60 * 60 * 24 * 5 ) ;
62+ expect ( Date . now ( ) - + new Date ( date ) ) . toBeLessThan ( 1000 * 60 * 60 * 24 * 30 * 12 * 10 ) ;
63+ } ;
64+
65+ const parsed = await parser . parseString ( await response . text ( ) ) ;
66+
67+ expect ( parsed ) . toEqual ( expect . any ( Object ) ) ;
68+ expect ( parsed . title ) . toEqual ( expect . any ( String ) ) ;
69+ expect ( parsed . title ) . not . toBe ( 'RSSHub' ) ;
70+ expect ( parsed . description ) . toEqual ( expect . any ( String ) ) ;
71+ expect ( parsed . link ) . toEqual ( expect . any ( String ) ) ;
72+ expect ( parsed . lastBuildDate ) . toEqual ( expect . any ( String ) ) ;
73+ expect ( parsed . ttl ) . toEqual ( Math . trunc ( config . cache . routeExpire / 60 ) + '' ) ;
74+ expect ( parsed . items ) . toEqual ( expect . any ( Array ) ) ;
75+ checkDate ( parsed . lastBuildDate ) ;
76+
77+ // check items
78+ const guids : Array < string | undefined > = [ ] ;
79+ for ( const item of parsed . items ) {
80+ expect ( item ) . toEqual ( expect . any ( Object ) ) ;
81+ expect ( item . title ) . toEqual ( expect . any ( String ) ) ;
82+ expect ( item . link ) . toEqual ( expect . any ( String ) ) ;
83+ expect ( item . content ) . toEqual ( expect . any ( String ) ) ;
84+ expect ( item . guid ) . toEqual ( expect . any ( String ) ) ;
85+ if ( item . pubDate ) {
86+ expect ( item . pubDate ) . toEqual ( expect . any ( String ) ) ;
87+ checkDate ( item . pubDate ) ;
88+ }
89+
90+ // guid must be unique
91+ expect ( guids ) . not . toContain ( item . guid ) ;
92+ guids . push ( item . guid ) ;
93+ }
94+ }
95+
96+ describe ( 'routes' , ( ) => {
97+ for ( const route in routes ) {
98+ it . concurrent (
99+ route ,
100+ {
101+ timeout : 60000 ,
102+ } ,
103+ async ( ) => {
104+ const response = await app . request ( routes [ route ] ) ;
105+ expect ( response . status ) . toBe ( 200 ) ;
106+ await checkRSS ( response ) ;
107+ }
108+ ) ;
109+ }
110+ } ) ;
0 commit comments