commands.test.js
1 import { describe, expect, it } from 'vitest'; 2 import { Strategy, getRegistry } from '@jackwener/opencli/registry'; 3 import './hot.js'; 4 import './posts.js'; 5 import './read.js'; 6 import './search.js'; 7 describe('tieba commands', () => { 8 it('registers all tieba commands as TypeScript adapters', () => { 9 const hot = getRegistry().get('tieba/hot'); 10 const posts = getRegistry().get('tieba/posts'); 11 const search = getRegistry().get('tieba/search'); 12 const read = getRegistry().get('tieba/read'); 13 expect(hot).toBeDefined(); 14 expect(posts).toBeDefined(); 15 expect(search).toBeDefined(); 16 expect(read).toBeDefined(); 17 expect(typeof hot?.func).toBe('function'); 18 expect(typeof posts?.func).toBe('function'); 19 expect(typeof search?.func).toBe('function'); 20 expect(typeof read?.func).toBe('function'); 21 }); 22 it('keeps the intended browser strategies', () => { 23 const hot = getRegistry().get('tieba/hot'); 24 const posts = getRegistry().get('tieba/posts'); 25 const search = getRegistry().get('tieba/search'); 26 const read = getRegistry().get('tieba/read'); 27 expect(hot?.strategy).toBe(Strategy.PUBLIC); 28 expect(posts?.strategy).toBe(Strategy.COOKIE); 29 expect(search?.strategy).toBe(Strategy.COOKIE); 30 expect(read?.strategy).toBe(Strategy.COOKIE); 31 expect(hot?.browser).toBe(true); 32 expect(posts?.browser).toBe(true); 33 expect(search?.browser).toBe(true); 34 expect(read?.browser).toBe(true); 35 }); 36 it('keeps the public limit contract at 20 items for list commands', () => { 37 const hot = getRegistry().get('tieba/hot'); 38 const posts = getRegistry().get('tieba/posts'); 39 const search = getRegistry().get('tieba/search'); 40 expect(hot?.args.find((arg) => arg.name === 'limit')?.default).toBe(20); 41 expect(posts?.args.find((arg) => arg.name === 'limit')?.default).toBe(20); 42 expect(search?.args.find((arg) => arg.name === 'limit')?.default).toBe(20); 43 }); 44 it('rejects tieba read results when navigation lands on the wrong page number', async () => { 45 const read = getRegistry().get('tieba/read'); 46 expect(read).toBeDefined(); 47 expect(typeof read?.func).toBe('function'); 48 const run = read?.func; 49 if (!run) 50 throw new Error('tieba/read did not register a handler'); 51 const page = { 52 goto: async () => undefined, 53 evaluate: async () => ({ 54 pageMeta: { 55 pathname: '/p/10163164720', 56 pn: '1', 57 }, 58 mainPost: { 59 title: '测试帖子', 60 author: '作者', 61 contentText: '正文', 62 structuredText: '', 63 visibleTime: '2026-03-29 12:00', 64 structuredTime: 0, 65 hasMedia: false, 66 }, 67 replies: [], 68 }), 69 }; 70 await expect(run(page, { 71 id: '10163164720', 72 page: 2, 73 limit: 5, 74 })).rejects.toMatchObject({ 75 code: 'EMPTY_RESULT', 76 hint: expect.stringMatching(/requested page/i), 77 }); 78 }); 79 });