// REQ-USR-004: AppLayout 注册 401 登出处理(壳层接线,BR10) import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest'; import { screen, act } from '@testing-library/react'; import { Routes, Route, useLocation } from 'react-router-dom'; import { renderShell } from './renderShell'; import AppLayout from '../../src/layouts/AppLayout/AppLayout'; import { registerUnauthorizedHandler, TOKEN_STORAGE_KEY, } from '../../src/api/request'; import { SESSION_EXPIRED_TEXT } from '../../src/layouts/AppLayout/shellMessages'; import type { AuthUser } from '../../src/api/types'; const ADMIN: AuthUser = { id: 1, sUserName: '朱子纯', sUserType: '超级管理员', sLanguage: '中文' }; function LocProbe() { const loc = useLocation(); return
{loc.pathname}
; } describe('AppLayout 401 登出接线', () => { let captured: (() => void) | null = null; beforeEach(() => { captured = null; }); afterEach(() => { registerUnauthorizedHandler(null); vi.restoreAllMocks(); }); it('registers onUnauthorized on mount; invoking it clears auth + warns + navigates /login', async () => { localStorage.setItem(TOKEN_STORAGE_KEY, 't'); // 拦截真实注册:把回调存进 captured,同时透传给真实单例 const origRegister = registerUnauthorizedHandler; const restore = vi .spyOn(await import('../../src/api/request'), 'registerUnauthorizedHandler') .mockImplementation((fn) => { if (fn) captured = fn as () => void; origRegister(fn); }); const { getState } = renderShell( }> } /> } /> , { initialEntries: ['/'], preloadedAuth: { token: 't', user: ADMIN } }, ); expect(captured).toBeTypeOf('function'); await act(async () => { captured!(); }); expect(getState().auth.token).toBeNull(); expect(localStorage.getItem(TOKEN_STORAGE_KEY)).toBeNull(); expect(await screen.findByText(SESSION_EXPIRED_TEXT)).toBeInTheDocument(); expect(screen.getByTestId('loc').textContent).toBe('/login'); restore.mockRestore(); }); });