search.test.js
1 import { beforeEach, describe, expect, it, vi } from 'vitest'; 2 import { getRegistry } from '@jackwener/opencli/registry'; 3 import './search.js'; 4 describe('ctrip search', () => { 5 const command = getRegistry().get('ctrip/search'); 6 beforeEach(() => { 7 vi.unstubAllGlobals(); 8 }); 9 it('maps live endpoint results into ranked rows', async () => { 10 vi.stubGlobal('fetch', vi.fn().mockResolvedValue(new Response(JSON.stringify({ 11 Response: { 12 searchResults: [ 13 { 14 displayName: '苏州, 江苏, 中国', 15 displayType: '城市', 16 commentScore: 0, 17 price: '', 18 }, 19 { 20 word: '姑苏区', 21 type: '行政区', 22 cStar: 4.8, 23 minPrice: 320, 24 }, 25 ], 26 }, 27 }), { status: 200 }))); 28 const result = await command.func(null, { query: '苏州', limit: 3 }); 29 expect(result).toEqual([ 30 { 31 rank: 1, 32 name: '苏州, 江苏, 中国', 33 type: '城市', 34 score: 0, 35 price: '', 36 url: '', 37 }, 38 { 39 rank: 2, 40 name: '姑苏区', 41 type: '行政区', 42 score: 4.8, 43 price: 320, 44 url: '', 45 }, 46 ]); 47 }); 48 it('rejects empty queries', async () => { 49 await expect(command.func(null, { query: ' ', limit: 3 })).rejects.toThrow('Search keyword cannot be empty'); 50 }); 51 it('surfaces fetch failures as CliError', async () => { 52 vi.stubGlobal('fetch', vi.fn().mockResolvedValue(new Response('{}', { status: 503 }))); 53 await expect(command.func(null, { query: '苏州', limit: 3 })).rejects.toMatchObject({ 54 code: 'FETCH_ERROR', 55 message: 'ctrip search failed with status 503', 56 }); 57 }); 58 it('surfaces empty results as EmptyResultError', async () => { 59 vi.stubGlobal('fetch', vi.fn().mockResolvedValue(new Response(JSON.stringify({ 60 Response: { searchResults: [] }, 61 }), { status: 200 }))); 62 await expect(command.func(null, { query: '苏州', limit: 3 })).rejects.toThrow('ctrip search returned no data'); 63 }); 64 });