This commit is contained in:
2026-04-22 22:01:07 +08:00
parent d8716d70b0
commit b317c2a8ea
37 changed files with 1821 additions and 515 deletions

View File

@@ -9,6 +9,7 @@ import { AuthGate } from './AuthGate';
import { useAuthUi } from './AuthUiContext';
const authMocks = vi.hoisted(() => ({
ensureStoredAccessToken: vi.fn(),
ensureAutoAuthUser: vi.fn(),
getAuthLoginOptions: vi.fn(),
getCurrentAuthUser: vi.fn(),
@@ -20,6 +21,7 @@ const authMocks = vi.hoisted(() => ({
vi.mock('../../services/apiClient', () => ({
AUTH_STATE_EVENT: 'genarrative-auth-state-changed',
ensureStoredAccessToken: authMocks.ensureStoredAccessToken,
}));
vi.mock('../../services/authService', () => ({
@@ -76,6 +78,7 @@ const mockUser: AuthUser = {
beforeEach(() => {
vi.clearAllMocks();
authMocks.consumeAuthCallbackResult.mockReturnValue(null);
authMocks.ensureStoredAccessToken.mockResolvedValue('jwt-existing-token');
authMocks.getCurrentAuthUser.mockResolvedValue({
user: null,
availableLoginMethods: ['phone'],
@@ -127,6 +130,33 @@ test('auth gate keeps platform content visible when phone login is available', a
expect(authMocks.ensureAutoAuthUser).not.toHaveBeenCalled();
});
test('auth gate waits for access token refresh before exposing restored user content', async () => {
let resolveToken!: (token: string) => void;
const tokenPromise = new Promise<string>((resolve) => {
resolveToken = resolve;
});
authMocks.ensureStoredAccessToken.mockReturnValue(tokenPromise);
authMocks.getCurrentAuthUser.mockResolvedValue({
user: mockUser,
availableLoginMethods: ['phone'],
});
render(
<AuthGate>
<div></div>
</AuthGate>,
);
expect(screen.getByText('正在校验登录状态...')).toBeTruthy();
expect(authMocks.getCurrentAuthUser).not.toHaveBeenCalled();
resolveToken('jwt-restored-token');
expect(await screen.findByText('应用内容')).toBeTruthy();
expect(authMocks.ensureStoredAccessToken).toHaveBeenCalledTimes(1);
expect(authMocks.getCurrentAuthUser).toHaveBeenCalledTimes(1);
});
test('auth gate does not auto-create a guest account when dev guest switch is not explicitly enabled', async () => {
authMocks.getAuthLoginOptions.mockResolvedValue({
availableLoginMethods: [],
@@ -171,6 +201,7 @@ test('auth gate opens a login modal for protected actions and resumes after logi
'13800000000',
'123456',
);
expect(authMocks.getCurrentAuthUser).toHaveBeenCalledTimes(1);
expect(onAuthenticated).toHaveBeenCalledTimes(1);
});