fix: clear creation hub cache on logout

This commit is contained in:
2026-04-26 00:05:19 +08:00
parent c5d783d3e6
commit c9a59f9edb
6 changed files with 295 additions and 18 deletions

View File

@@ -17,6 +17,8 @@ const authMocks = vi.hoisted(() => ({
getAuthLoginOptions: vi.fn(),
getCurrentAuthUser: vi.fn(),
loginWithPhoneCode: vi.fn(),
logoutAllAuthSessions: vi.fn(),
logoutAuthUser: vi.fn(),
resetPassword: vi.fn(),
sendPhoneLoginCode: vi.fn(),
startWechatLogin: vi.fn(),
@@ -44,8 +46,8 @@ vi.mock('../../services/authService', () => ({
getCaptchaChallengeFromError: vi.fn(() => null),
liftAuthRiskBlock: vi.fn(),
loginWithPhoneCode: authMocks.loginWithPhoneCode,
logoutAllAuthSessions: vi.fn(),
logoutAuthUser: vi.fn(),
logoutAllAuthSessions: authMocks.logoutAllAuthSessions,
logoutAuthUser: authMocks.logoutAuthUser,
resetPassword: authMocks.resetPassword,
revokeAuthSession: vi.fn(),
sendPhoneLoginCode: authMocks.sendPhoneLoginCode,
@@ -96,6 +98,8 @@ beforeEach(() => {
authMocks.loginWithPhoneCode.mockResolvedValue(mockUser);
authMocks.authEntry.mockResolvedValue(mockUser);
authMocks.changePassword.mockResolvedValue(mockUser);
authMocks.logoutAllAuthSessions.mockResolvedValue(undefined);
authMocks.logoutAuthUser.mockResolvedValue(undefined);
authMocks.resetPassword.mockResolvedValue(mockUser);
authMocks.sendPhoneLoginCode.mockResolvedValue({
cooldownSeconds: 60,
@@ -139,6 +143,27 @@ function PlatformTabStateProbe() {
);
}
function LogoutStateProbe() {
const authUi = useAuthUi();
return (
<div>
<div>{authUi?.user?.displayName ?? '未登录'}</div>
<div>
{authUi?.canAccessProtectedData ? '可读取' : '不可读取'}
</div>
<button
type="button"
onClick={() => {
void authUi?.logout();
}}
>
退
</button>
</div>
);
}
test('auth gate keeps platform content visible when phone login is available', async () => {
authMocks.getAuthLoginOptions.mockResolvedValue({
availableLoginMethods: ['phone'],
@@ -276,6 +301,40 @@ test('auth state refresh keeps mounted platform content and local tab state', as
expect(screen.getByText('当前Tab创作')).toBeTruthy();
});
test('logout withdraws user context before backend request finishes', async () => {
const user = userEvent.setup();
authMocks.getCurrentAuthUser.mockResolvedValue({
user: mockUser,
availableLoginMethods: ['phone'],
});
let resolveLogout!: () => void;
const logoutPromise = new Promise<void>((resolve) => {
resolveLogout = resolve;
});
authMocks.logoutAuthUser.mockReturnValueOnce(logoutPromise);
render(
<AuthGate>
<LogoutStateProbe />
</AuthGate>,
);
expect(await screen.findByText('当前用户:测试玩家')).toBeTruthy();
expect(screen.getByText('私有数据:可读取')).toBeTruthy();
await user.click(screen.getByRole('button', { name: '退出登录' }));
expect(await screen.findByText('当前用户:未登录')).toBeTruthy();
expect(screen.getByText('私有数据:不可读取')).toBeTruthy();
expect(authMocks.logoutAuthUser).toHaveBeenCalledTimes(1);
await act(async () => {
resolveLogout();
await logoutPromise;
});
});
test('auth gate shows sms send feedback in the login modal', async () => {
const user = userEvent.setup();