修复推荐页封面遮罩与登录态刷新
推荐页运行态封面增加加载条并隔离层级,避免 runtime 内容穿透封面 登录态从未登录到已登录或退出后刷新当前页面,退出等待 token 清理完成后再刷新 补充推荐页封面、认证刷新与样式回归测试 同步平台链路、项目基线和 Hermes 决策文档
This commit is contained in:
@@ -3,11 +3,11 @@
|
||||
import { act, render, screen, waitFor, within } from '@testing-library/react';
|
||||
import userEvent from '@testing-library/user-event';
|
||||
import { useState } from 'react';
|
||||
import { beforeEach, expect, test, vi } from 'vitest';
|
||||
import { afterEach, beforeEach, expect, test, vi } from 'vitest';
|
||||
|
||||
import type { AuthSessionSummary, AuthUser } from '../../services/authService';
|
||||
import { LEGAL_CONSENT_STORAGE_KEY } from '../common/legalDocuments';
|
||||
import { AuthGate } from './AuthGate';
|
||||
import { AuthGate, setAuthGateReloadForTest } from './AuthGate';
|
||||
import { useAuthUi } from './AuthUiContext';
|
||||
|
||||
const authMocks = vi.hoisted(() => ({
|
||||
@@ -107,6 +107,7 @@ beforeEach(() => {
|
||||
vi.clearAllMocks();
|
||||
window.localStorage.clear();
|
||||
window.history.replaceState(null, '', '/');
|
||||
setAuthGateReloadForTest(vi.fn());
|
||||
authMocks.consumeAuthCallbackResult.mockReturnValue(null);
|
||||
authMocks.ensureStoredAccessToken.mockResolvedValue('jwt-existing-token');
|
||||
authMocks.getStoredAccessToken.mockReturnValue('');
|
||||
@@ -158,6 +159,10 @@ beforeEach(() => {
|
||||
authMocks.requestWechatMiniProgramPhoneLogin.mockResolvedValue(true);
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
setAuthGateReloadForTest(null);
|
||||
});
|
||||
|
||||
async function acceptLegalConsent(
|
||||
user: ReturnType<typeof userEvent.setup>,
|
||||
dialog: HTMLElement,
|
||||
@@ -382,6 +387,8 @@ test('auth gate keeps sms and password entries available when login options requ
|
||||
test('auth gate opens a login modal for protected actions and resumes after login', async () => {
|
||||
const user = userEvent.setup();
|
||||
const onAuthenticated = vi.fn();
|
||||
const reload = vi.fn();
|
||||
setAuthGateReloadForTest(reload);
|
||||
|
||||
authMocks.getAuthLoginOptions.mockResolvedValue({
|
||||
availableLoginMethods: ['phone'],
|
||||
@@ -411,6 +418,7 @@ test('auth gate opens a login modal for protected actions and resumes after logi
|
||||
);
|
||||
expect(authMocks.getCurrentAuthUser).toHaveBeenCalledTimes(1);
|
||||
expect(onAuthenticated).toHaveBeenCalledTimes(1);
|
||||
expect(reload).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
|
||||
expect(screen.queryByRole('dialog', { name: '账号入口' })).toBeNull();
|
||||
@@ -636,6 +644,8 @@ test('registration invite modal can skip when invite code is empty', async () =>
|
||||
|
||||
test('auth state refresh keeps mounted platform content and local tab state', async () => {
|
||||
const user = userEvent.setup();
|
||||
const reload = vi.fn();
|
||||
setAuthGateReloadForTest(reload);
|
||||
authMocks.getCurrentAuthUser.mockResolvedValue({
|
||||
user: mockUser,
|
||||
availableLoginMethods: ['phone'],
|
||||
@@ -674,10 +684,13 @@ test('auth state refresh keeps mounted platform content and local tab state', as
|
||||
expect(authMocks.getCurrentAuthUser).toHaveBeenCalledTimes(2);
|
||||
});
|
||||
expect(screen.getByText('当前Tab:创作')).toBeTruthy();
|
||||
expect(reload).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
test('logout withdraws user context before backend request finishes', async () => {
|
||||
const user = userEvent.setup();
|
||||
const reload = vi.fn();
|
||||
setAuthGateReloadForTest(reload);
|
||||
authMocks.getCurrentAuthUser.mockResolvedValue({
|
||||
user: mockUser,
|
||||
availableLoginMethods: ['phone'],
|
||||
@@ -703,11 +716,14 @@ test('logout withdraws user context before backend request finishes', async () =
|
||||
expect(await screen.findByText('当前用户:未登录')).toBeTruthy();
|
||||
expect(screen.getByText('私有数据:不可读取')).toBeTruthy();
|
||||
expect(authMocks.logoutAuthUser).toHaveBeenCalledTimes(1);
|
||||
expect(reload).not.toHaveBeenCalled();
|
||||
|
||||
await act(async () => {
|
||||
resolveLogout();
|
||||
await logoutPromise;
|
||||
});
|
||||
|
||||
expect(reload).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
|
||||
test('auth gate shows sms send feedback in the login modal', async () => {
|
||||
|
||||
Reference in New Issue
Block a user