// 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();
});
});