utils.test.js
1 import { describe, expect, it, vi } from 'vitest'; 2 import { AuthRequiredError, CommandExecutionError } from '@jackwener/opencli/errors'; 3 import { apiGet, apiPost, extractPwdId, getShareList, getToken } from './utils.js'; 4 function makePage(evaluateImpl) { 5 return { 6 evaluate: vi.fn(evaluateImpl), 7 }; 8 } 9 describe('quark utils', () => { 10 it('extractPwdId accepts share URLs and raw ids', () => { 11 expect(extractPwdId('https://pan.quark.cn/s/abc123')).toBe('abc123'); 12 expect(extractPwdId('abc123')).toBe('abc123'); 13 }); 14 it('maps JSON auth failures to AuthRequiredError', async () => { 15 const page = makePage(async () => ({ 16 status: 401, 17 code: 401, 18 message: '未登录', 19 data: null, 20 })); 21 await expect(apiGet(page, 'https://drive-pc.quark.cn/test')).rejects.toBeInstanceOf(AuthRequiredError); 22 }); 23 it('maps non-JSON auth pages to AuthRequiredError', async () => { 24 const page = makePage(async () => { 25 const error = Object.assign(new Error('Non-JSON response: <html><title>登录</title></html>'), { status: 401 }); 26 throw error; 27 }); 28 await expect(apiPost(page, 'https://drive-pc.quark.cn/test', {})).rejects.toBeInstanceOf(AuthRequiredError); 29 }); 30 it('keeps generic API failures as CommandExecutionError', async () => { 31 const page = makePage(async () => ({ 32 status: 500, 33 code: 500, 34 message: 'server busy', 35 data: null, 36 })); 37 await expect(apiGet(page, 'https://drive-pc.quark.cn/test')).rejects.toBeInstanceOf(CommandExecutionError); 38 }); 39 it('unwraps successful token responses', async () => { 40 const page = makePage(async () => ({ 41 status: 200, 42 code: 0, 43 message: 'ok', 44 data: { stoken: 'token123' }, 45 })); 46 await expect(getToken(page, 'abc123')).resolves.toBe('token123'); 47 }); 48 it('maps share-tree detail auth failures to AuthRequiredError', async () => { 49 const page = makePage(async () => ({ 50 status: 401, 51 code: 401, 52 message: '请先登录', 53 data: null, 54 metadata: { _total: 0 }, 55 })); 56 await expect(getShareList(page, 'abc123', 'token123')).rejects.toBeInstanceOf(AuthRequiredError); 57 }); 58 });