import { describe, expect, it } from 'vitest'; import { clientAuthErrorKind, clientAuthErrorNotice, isClientAuthError, } from '../src/services/clientAuthError'; describe('AGC 认证命令错误分流', () => { it('只按形状读取 Rust 的结构化拒绝,裸字符串与 Error 都不算', () => { expect( isClientAuthError({ type: 'phoneOrPasswordMismatch', message: '手机号或密码错误', }), ).toEqual({ type: 'phoneOrPasswordMismatch', message: '手机号或密码错误' }); expect(isClientAuthError('手机号或密码错误')).toBeNull(); expect(isClientAuthError(new Error('手机号或密码错误'))).toBeNull(); expect( isClientAuthError({ type: '', message: '手机号或密码错误' }), ).toBeNull(); expect(isClientAuthError({ type: 'phoneNumberInvalid' })).toBeNull(); expect(isClientAuthError(null)).toBeNull(); }); it('业务输入给提示、会话变体按未登录、系统与未识别变体交给错误池', () => { expect( clientAuthErrorKind({ type: 'passwordEntryInputRejected', message: '密码长度需要在 6 到 128 位之间', }), ).toBe('input'); expect( clientAuthErrorKind({ type: 'phoneOrPasswordMismatch', message: '手机号或密码错误', }), ).toBe('input'); expect( clientAuthErrorKind({ type: 'sessionAuthorityRejected', message: '登录已失效,请重新登录', }), ).toBe('session'); expect( clientAuthErrorKind({ type: 'authNetworkUnavailable', message: '无法连接登录服务', }), ).toBe('fault'); expect( clientAuthErrorKind({ type: 'runtimeSessionInstallFailed', message: '本机运行时会话安装失败', }), ).toBe('fault'); // 未识别变体按 fault 处理:Rust 加了变体但界面没接,属于缺陷,必须进池。 expect( clientAuthErrorKind( isClientAuthError({ type: 'brandNewRejection', message: '新变体' })!, ), ).toBe('fault'); }); it('input / session 原样使用 Rust 文案,fault 与空文案不给提示', () => { expect( clientAuthErrorNotice({ type: 'phoneOrPasswordMismatch', message: '手机号或密码错误', }), ).toBe('手机号或密码错误'); expect( clientAuthErrorNotice({ type: 'sessionAuthorityRejected', message: '登录已失效,请重新登录', }), ).toBe('登录已失效,请重新登录'); expect( clientAuthErrorNotice({ type: 'authServiceUnavailable', status: 503, message: '登录服务暂时不可用', }), ).toBeNull(); expect( clientAuthErrorNotice({ type: 'phoneNumberInvalid', message: ' ' }), ).toBeNull(); }); });