Files
Genarrative/apps/ai-game-creator-shell/tests/clientAuthError.test.ts
T
k88936 f435d48399 AGC 认证错误改为每个变体一个具名载荷类型
- auth_error.rs:枚举改为 newtype 变体,每个变体持有一个同名 `#[ts(export)]` 载荷结构体
- auth_session.rs:41 处构造点改为 `ClientAuthError::X(X { .. })` 并导入载荷类型
- 重新生成 services/generated:ClientAuthError.ts 变成 `{ type } & 具名类型`,新增 19 个载荷类型文件
- tests/clientAuthError.test.ts:新增编译期用例,switch (error.type) 分支里错误窄化成具名载荷类型
2026-10-01 18:08:18 +08:00

78 lines
2.7 KiB
TypeScript

import { describe, expect, it } from 'vitest';
import { isClientAuthError } from '../src/services/clientAuthError';
import type { AuthServiceUnavailable } from '../src/services/generated/AuthServiceUnavailable';
import type { ClientAuthError } from '../src/services/generated/ClientAuthError';
import type { PhoneNumberInvalid } from '../src/services/generated/PhoneNumberInvalid';
/**
* 编译期用例:每个变体在 `type` 上判别后都能落到一个**具名载荷类型**,
* 等价于 Java 的 `catch (PhoneNumberInvalid e)`;类型不匹配时 `tsc` 会直接报错。
*/
function handleByNamedType(error: ClientAuthError) {
switch (error.type) {
case 'phoneNumberInvalid': {
const payload: PhoneNumberInvalid = error;
return payload.message;
}
case 'authServiceUnavailable': {
const payload: AuthServiceUnavailable = error;
return `${payload.status}:${payload.message}`;
}
default:
return '';
}
}
describe('AGC 认证命令错误的形状读取', () => {
it('判别后按具名载荷类型分支处理', () => {
expect(
handleByNamedType({
type: 'phoneNumberInvalid',
message: '请输入正确的手机号',
}),
).toBe('请输入正确的手机号');
expect(
handleByNamedType({
type: 'authServiceUnavailable',
status: 503,
message: '登录服务暂时不可用',
}),
).toBe('503:登录服务暂时不可用');
});
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('未知变体也算形状合法,由调用方按 default 交给错误池', () => {
expect(
isClientAuthError({ type: 'brandNewRejection', message: '新变体' }),
).toEqual({ type: 'brandNewRejection', message: '新变体' });
});
it('status 故意不校验:缺 status 但 message 可用的拒绝仍可读', () => {
expect(
isClientAuthError({
type: 'authServiceUnavailable',
message: '登录服务暂时不可用',
}),
).toEqual({
type: 'authServiceUnavailable',
message: '登录服务暂时不可用',
});
});
});