feat(platform): harden telemetry pipeline and unify Semi UI workspaces

This commit is contained in:
lingniu
2026-07-18 00:26:36 +08:00
parent 65b4e4f055
commit 159c80b0ae
136 changed files with 21616 additions and 1785 deletions

View File

@@ -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');
});