feat(platform): harden telemetry pipeline and unify Semi UI workspaces
This commit is contained in:
@@ -8,19 +8,23 @@ const routing = vi.hoisted(() => ({
|
||||
scheduleIdleRoutePreloads: vi.fn(() => vi.fn()),
|
||||
shouldPreloadRouteOnIntent: vi.fn(() => true)
|
||||
}));
|
||||
const auth = vi.hoisted(() => ({ session: { name: 'test-user', role: 'viewer' as const } as any }));
|
||||
const auth = vi.hoisted(() => ({
|
||||
session: { name: 'test-user', username: 'test-user', role: 'viewer' as const } as any,
|
||||
logout: vi.fn()
|
||||
}));
|
||||
|
||||
vi.mock('../routing/routeModules', () => routing);
|
||||
vi.mock('../auth/AuthGate', () => ({
|
||||
usePlatformSession: () => ({ session: auth.session, logout: vi.fn() })
|
||||
usePlatformSession: () => ({ session: auth.session, logout: auth.logout })
|
||||
}));
|
||||
|
||||
import { AppShell } from './AppShell';
|
||||
|
||||
afterEach(() => {
|
||||
cleanup();
|
||||
vi.restoreAllMocks();
|
||||
vi.clearAllMocks();
|
||||
auth.session = { name: 'test-user', role: 'viewer' };
|
||||
auth.session = { name: 'test-user', username: 'test-user', role: 'viewer' };
|
||||
});
|
||||
|
||||
test('renders only explicitly assigned customer menus', () => {
|
||||
@@ -61,6 +65,22 @@ test('reschedules likely route preloads when the active module changes', async (
|
||||
expect(secondCleanup).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
|
||||
test('marks the content as a full-height track workspace after sidebar navigation', async () => {
|
||||
const scrollTo = vi.fn();
|
||||
Object.defineProperty(HTMLElement.prototype, 'scrollTo', { configurable: true, value: scrollTo });
|
||||
render(<MemoryRouter future={ROUTER_FUTURE} initialEntries={['/monitor']}>
|
||||
<Routes><Route element={<AppShell />}><Route path="*" element={<span>页面内容</span>} /></Route></Routes>
|
||||
</MemoryRouter>);
|
||||
|
||||
expect(document.querySelector('.v2-content')).not.toHaveClass('is-track-workspace');
|
||||
scrollTo.mockClear();
|
||||
fireEvent.click(screen.getByRole('link', { name: '轨迹回放' }));
|
||||
|
||||
await waitFor(() => expect(document.querySelector('.v2-content')).toHaveClass('is-track-workspace'));
|
||||
expect(scrollTo).toHaveBeenCalledWith({ top: 0, left: 0, behavior: 'auto' });
|
||||
expect(screen.getByRole('heading', { name: '轨迹回放' })).toBeInTheDocument();
|
||||
});
|
||||
|
||||
test('opens contextual help for the active module and closes it without navigating', () => {
|
||||
render(<MemoryRouter future={ROUTER_FUTURE} initialEntries={['/monitor']}>
|
||||
<Routes><Route element={<AppShell />}><Route path="*" element={<span>页面内容</span>} /></Route></Routes>
|
||||
@@ -72,7 +92,87 @@ test('opens contextual help for the active module and closes it without navigati
|
||||
|
||||
expect(screen.getByRole('dialog', { name: '全局监控' })).toHaveTextContent('筛选会自动生效');
|
||||
expect(help).toHaveAttribute('aria-expanded', 'true');
|
||||
fireEvent.click(screen.getByRole('button', { name: '关闭帮助' }));
|
||||
expect(screen.queryByRole('dialog')).not.toBeInTheDocument();
|
||||
fireEvent.click(screen.getByLabelText('关闭帮助'));
|
||||
expect(help).toHaveAttribute('aria-expanded', 'false');
|
||||
expect(document.body.style.overflow).not.toBe('hidden');
|
||||
expect(screen.getByText('页面内容')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
test('uses one Semi account menu for identity, password and logout actions', async () => {
|
||||
render(<MemoryRouter future={ROUTER_FUTURE} initialEntries={['/monitor']}>
|
||||
<Routes><Route element={<AppShell />}><Route path="*" element={<span>页面内容</span>} /></Route></Routes>
|
||||
</MemoryRouter>);
|
||||
|
||||
const trigger = screen.getByRole('button', { name: '账号菜单,test-user' });
|
||||
expect(trigger).toHaveAttribute('aria-expanded', 'false');
|
||||
fireEvent.click(trigger);
|
||||
|
||||
expect(await screen.findByText('@test-user')).toBeInTheDocument();
|
||||
await waitFor(() => expect(screen.getByRole('button', { name: '账号菜单,test-user' })).toHaveAttribute('aria-expanded', 'true'));
|
||||
fireEvent.click(screen.getByText('修改登录密码'));
|
||||
|
||||
expect(screen.getByRole('dialog', { name: '修改登录密码' })).toBeInTheDocument();
|
||||
fireEvent.click(screen.getByRole('button', { name: '取消' }));
|
||||
|
||||
fireEvent.click(trigger);
|
||||
fireEvent.click(await screen.findByText('退出登录'));
|
||||
expect(auth.logout).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
|
||||
test('uses the compact mobile navigation and opens secondary modules in a Semi SideSheet', () => {
|
||||
vi.spyOn(window, 'matchMedia').mockReturnValue({
|
||||
matches: true,
|
||||
media: '(max-width: 680px)',
|
||||
onchange: null,
|
||||
addListener: vi.fn(),
|
||||
removeListener: vi.fn(),
|
||||
addEventListener: vi.fn(),
|
||||
removeEventListener: vi.fn(),
|
||||
dispatchEvent: vi.fn()
|
||||
});
|
||||
|
||||
render(<MemoryRouter future={ROUTER_FUTURE} initialEntries={['/monitor']}>
|
||||
<Routes><Route element={<AppShell />}><Route path="*" element={<span>页面内容</span>} /></Route></Routes>
|
||||
</MemoryRouter>);
|
||||
|
||||
expect(screen.getByRole('link', { name: '全局监控' })).toBeInTheDocument();
|
||||
expect(screen.getByRole('link', { name: '车辆查询' })).toBeInTheDocument();
|
||||
expect(screen.getByRole('link', { name: '轨迹回放' })).toBeInTheDocument();
|
||||
expect(screen.getByRole('link', { name: '里程查询' })).toBeInTheDocument();
|
||||
expect(screen.queryByRole('link', { name: '历史数据' })).not.toBeInTheDocument();
|
||||
|
||||
fireEvent.click(screen.getByRole('button', { name: '更多功能' }));
|
||||
|
||||
const moreSheet = screen.getByRole('dialog', { name: '更多功能' });
|
||||
expect(moreSheet).toHaveTextContent('数据分析与系统管理');
|
||||
expect(screen.getByRole('link', { name: '历史数据' })).toBeInTheDocument();
|
||||
expect(screen.getByRole('link', { name: '告警中心' })).toBeInTheDocument();
|
||||
expect(screen.getByRole('link', { name: '接入管理' })).toBeInTheDocument();
|
||||
expect(screen.getByRole('link', { name: '账号管理' })).toBeInTheDocument();
|
||||
expect(screen.getByRole('link', { name: '运维质量' })).toBeInTheDocument();
|
||||
|
||||
fireEvent.click(screen.getByLabelText('关闭更多功能'));
|
||||
expect(screen.getByRole('button', { name: '更多功能' })).toHaveAttribute('aria-expanded', 'false');
|
||||
expect(document.body.style.overflow).not.toBe('hidden');
|
||||
});
|
||||
|
||||
test('automatically collapses the Semi sidebar at tablet width', () => {
|
||||
vi.spyOn(window, 'matchMedia').mockImplementation((query) => ({
|
||||
matches: query === '(max-width: 900px)',
|
||||
media: query,
|
||||
onchange: null,
|
||||
addListener: vi.fn(),
|
||||
removeListener: vi.fn(),
|
||||
addEventListener: vi.fn(),
|
||||
removeEventListener: vi.fn(),
|
||||
dispatchEvent: vi.fn()
|
||||
}));
|
||||
|
||||
render(<MemoryRouter future={ROUTER_FUTURE} initialEntries={['/monitor']}>
|
||||
<Routes><Route element={<AppShell />}><Route path="*" element={<span>页面内容</span>} /></Route></Routes>
|
||||
</MemoryRouter>);
|
||||
|
||||
expect(screen.getByRole('link', { name: '全局监控' })).toHaveAttribute('title', '全局监控');
|
||||
expect(screen.queryByRole('button', { name: '收起侧栏' })).not.toBeInTheDocument();
|
||||
expect(document.querySelector('.v2-sidebar')).toHaveClass('is-collapsed');
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user