1
This commit is contained in:
@@ -6,6 +6,7 @@ import { useState } from 'react';
|
||||
import { beforeEach, expect, test, vi } from 'vitest';
|
||||
|
||||
import type { AuthUser } from '../../services/authService';
|
||||
import { LEGAL_CONSENT_STORAGE_KEY } from '../common/legalDocuments';
|
||||
import { AuthGate } from './AuthGate';
|
||||
import { useAuthUi } from './AuthUiContext';
|
||||
|
||||
@@ -95,6 +96,7 @@ const mockUser: AuthUser = {
|
||||
|
||||
beforeEach(() => {
|
||||
vi.clearAllMocks();
|
||||
window.localStorage.clear();
|
||||
window.history.replaceState(null, '', '/');
|
||||
authMocks.consumeAuthCallbackResult.mockReturnValue(null);
|
||||
authMocks.ensureStoredAccessToken.mockResolvedValue('jwt-existing-token');
|
||||
@@ -141,6 +143,15 @@ beforeEach(() => {
|
||||
authMocks.startWechatLogin.mockResolvedValue(undefined);
|
||||
});
|
||||
|
||||
async function acceptLegalConsent(
|
||||
user: ReturnType<typeof userEvent.setup>,
|
||||
dialog: HTMLElement,
|
||||
) {
|
||||
await user.click(
|
||||
within(dialog).getByRole('switch', { name: '同意法律协议' }),
|
||||
);
|
||||
}
|
||||
|
||||
function ProtectedActionButton({
|
||||
onAuthenticated,
|
||||
}: {
|
||||
@@ -346,6 +357,7 @@ test('auth gate opens a login modal for protected actions and resumes after logi
|
||||
|
||||
await user.type(within(dialog).getByLabelText('手机号'), '13800000000');
|
||||
await user.type(within(dialog).getByLabelText('验证码'), '123456');
|
||||
await acceptLegalConsent(user, dialog);
|
||||
await user.click(within(dialog).getByRole('button', { name: '登录' }));
|
||||
|
||||
await waitFor(() => {
|
||||
@@ -360,6 +372,70 @@ test('auth gate opens a login modal for protected actions and resumes after logi
|
||||
expect(screen.queryByRole('dialog', { name: '账号入口' })).toBeNull();
|
||||
});
|
||||
|
||||
test('login modal requires first-time legal consent before sms login', async () => {
|
||||
const user = userEvent.setup();
|
||||
|
||||
authMocks.getAuthLoginOptions.mockResolvedValue({
|
||||
availableLoginMethods: ['phone'],
|
||||
});
|
||||
|
||||
render(
|
||||
<AuthGate>
|
||||
<ProtectedActionButton onAuthenticated={vi.fn()} />
|
||||
</AuthGate>,
|
||||
);
|
||||
|
||||
await user.click(await screen.findByRole('button', { name: '进入作品' }));
|
||||
|
||||
const dialog = screen.getByRole('dialog', { name: '账号入口' });
|
||||
await user.type(within(dialog).getByLabelText('手机号'), '13800000000');
|
||||
await user.type(within(dialog).getByLabelText('验证码'), '123456');
|
||||
|
||||
const loginButton = within(dialog).getByRole('button', { name: '登录' });
|
||||
const legalSwitch = within(dialog).getByRole('switch', {
|
||||
name: '同意法律协议',
|
||||
});
|
||||
expect((loginButton as HTMLButtonElement).disabled).toBe(true);
|
||||
expect(legalSwitch.getAttribute('aria-checked')).toBe('false');
|
||||
|
||||
await user.click(
|
||||
within(dialog).getByRole('button', { name: '《用户协议》' }),
|
||||
);
|
||||
expect(
|
||||
await screen.findByRole('dialog', { name: '用户协议' }),
|
||||
).toBeTruthy();
|
||||
await user.click(screen.getByRole('button', { name: '我知道了' }));
|
||||
expect(legalSwitch.getAttribute('aria-checked')).toBe('false');
|
||||
|
||||
await user.click(legalSwitch);
|
||||
expect(legalSwitch.getAttribute('aria-checked')).toBe('true');
|
||||
expect(window.localStorage.getItem(LEGAL_CONSENT_STORAGE_KEY)).toBe('true');
|
||||
expect((loginButton as HTMLButtonElement).disabled).toBe(false);
|
||||
});
|
||||
|
||||
test('login modal defaults legal consent to checked after stored confirmation', async () => {
|
||||
const user = userEvent.setup();
|
||||
window.localStorage.setItem(LEGAL_CONSENT_STORAGE_KEY, 'true');
|
||||
|
||||
authMocks.getAuthLoginOptions.mockResolvedValue({
|
||||
availableLoginMethods: ['phone'],
|
||||
});
|
||||
|
||||
render(
|
||||
<AuthGate>
|
||||
<ProtectedActionButton onAuthenticated={vi.fn()} />
|
||||
</AuthGate>,
|
||||
);
|
||||
|
||||
await user.click(await screen.findByRole('button', { name: '进入作品' }));
|
||||
|
||||
const dialog = screen.getByRole('dialog', { name: '账号入口' });
|
||||
const legalSwitch = within(dialog).getByRole('switch', {
|
||||
name: '同意法律协议',
|
||||
});
|
||||
expect(legalSwitch.getAttribute('aria-checked')).toBe('true');
|
||||
});
|
||||
|
||||
test('phone login result is not overwritten by an older guest hydrate', async () => {
|
||||
const user = userEvent.setup();
|
||||
const onAuthenticated = vi.fn();
|
||||
@@ -387,6 +463,7 @@ test('phone login result is not overwritten by an older guest hydrate', async ()
|
||||
const dialog = screen.getByRole('dialog', { name: '账号入口' });
|
||||
await user.type(within(dialog).getByLabelText('手机号'), '13800000000');
|
||||
await user.type(within(dialog).getByLabelText('验证码'), '123456');
|
||||
await acceptLegalConsent(user, dialog);
|
||||
await user.click(within(dialog).getByRole('button', { name: '登录' }));
|
||||
|
||||
expect(await screen.findByText('当前用户:测试玩家')).toBeTruthy();
|
||||
@@ -425,6 +502,7 @@ test('auth gate hides register entry and opens invite modal for new sms account'
|
||||
expect(within(dialog).queryByLabelText('邀请码')).toBeNull();
|
||||
await user.type(within(dialog).getByLabelText('手机号'), '13800000000');
|
||||
await user.type(within(dialog).getByLabelText('验证码'), '123456');
|
||||
await acceptLegalConsent(user, dialog);
|
||||
await user.click(within(dialog).getByRole('button', { name: '登录' }));
|
||||
|
||||
await waitFor(() => {
|
||||
@@ -475,6 +553,7 @@ test('registration invite modal can skip when invite code is empty', async () =>
|
||||
const dialog = screen.getByRole('dialog', { name: '账号入口' });
|
||||
await user.type(within(dialog).getByLabelText('手机号'), '13800000000');
|
||||
await user.type(within(dialog).getByLabelText('验证码'), '123456');
|
||||
await acceptLegalConsent(user, dialog);
|
||||
await user.click(within(dialog).getByRole('button', { name: '登录' }));
|
||||
|
||||
const inviteDialog = await screen.findByRole('dialog', {
|
||||
@@ -700,6 +779,7 @@ test('auth gate separates sms and password login by tabs', async () => {
|
||||
|
||||
await user.type(within(dialog).getByLabelText('手机号'), '13800000000');
|
||||
await user.type(within(dialog).getByLabelText('密码'), 'passw0rd');
|
||||
await acceptLegalConsent(user, dialog);
|
||||
await user.click(within(dialog).getByRole('button', { name: '登录' }));
|
||||
|
||||
await waitFor(() => {
|
||||
|
||||
Reference in New Issue
Block a user