收口认证表单输入组件

迁移登录、重置密码、绑定手机号、邀请码和账号安全表单到 PlatformTextField 与 PlatformFieldLabel

补充认证表单公共输入断言和绑定手机号独立测试

更新 PlatformUiKit 文档和 Hermes 决策记录
This commit is contained in:
2026-06-10 11:37:26 +08:00
parent b601b3b57e
commit 9389f9401f
10 changed files with 193 additions and 75 deletions

View File

@@ -34,12 +34,20 @@ const authMocks = vi.hoisted(() => ({
consumeAuthCallbackResult: vi.fn(),
}));
vi.mock('../../services/apiClient', () => ({
AUTH_STATE_EVENT: 'genarrative-auth-state-changed',
ensureStoredAccessToken: authMocks.ensureStoredAccessToken,
getStoredAccessToken: authMocks.getStoredAccessToken,
refreshStoredAccessToken: authMocks.refreshStoredAccessToken,
}));
vi.mock('../../services/apiClient', async () => {
const actual =
await vi.importActual<typeof import('../../services/apiClient')>(
'../../services/apiClient',
);
return {
...actual,
AUTH_STATE_EVENT: 'genarrative-auth-state-changed',
ensureStoredAccessToken: authMocks.ensureStoredAccessToken,
getStoredAccessToken: authMocks.getStoredAccessToken,
refreshStoredAccessToken: authMocks.refreshStoredAccessToken,
};
});
vi.mock('../../services/authService', () => ({
authEntry: authMocks.authEntry,
@@ -408,8 +416,17 @@ test('auth gate opens a login modal for protected actions and resumes after logi
expect(dialog).toBeTruthy();
expect(screen.queryByText('先登录账号,再同步你的冒险进度。')).toBeNull();
await user.type(within(dialog).getByLabelText('手机号'), '13800000000');
await user.type(within(dialog).getByLabelText('验证码'), '123456');
const phoneInput = within(dialog).getByLabelText(
'手机号',
) as HTMLInputElement;
const codeInput = within(dialog).getByLabelText(
'验证码',
) as HTMLInputElement;
expect(phoneInput.className).toContain('platform-text-field');
expect(codeInput.className).toContain('platform-text-field');
await user.type(phoneInput, '13800000000');
await user.type(codeInput, '123456');
await acceptLegalConsent(user, dialog);
await user.click(within(dialog).getByRole('button', { name: '登录' }));
@@ -592,9 +609,11 @@ test('auth gate hides register entry and opens invite modal for new sms account'
const inviteDialog = await screen.findByRole('dialog', {
name: '请填写邀请码',
});
expect(
(within(inviteDialog).getByLabelText('邀请码') as HTMLInputElement).value,
).toBe('SPRING2026');
const inviteCodeInput = within(inviteDialog).getByLabelText(
'邀请码',
) as HTMLInputElement;
expect(inviteCodeInput.value).toBe('SPRING2026');
expect(inviteCodeInput.className).toContain('platform-text-field');
expect(
within(inviteDialog).getByRole('button', { name: '提交' }),
).toBeTruthy();
@@ -792,7 +811,11 @@ test('login modal resets draft state every time it is reopened', async () => {
).toBeTruthy();
await user.type(within(firstDialog).getByLabelText('验证码'), '123456');
await user.click(within(firstDialog).getByRole('tab', { name: '密码登录' }));
await user.type(within(firstDialog).getByLabelText('密码'), 'passw0rd');
const passwordInput = within(firstDialog).getByLabelText(
'密码',
) as HTMLInputElement;
expect(passwordInput.className).toContain('platform-text-field');
await user.type(passwordInput, 'passw0rd');
await user.click(
within(firstDialog).getByRole('button', { name: '忘记密码' }),
);