57 lines
3.4 KiB
TypeScript
57 lines
3.4 KiB
TypeScript
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
|
|
import { cleanup, fireEvent, render, screen } from '@testing-library/react';
|
|
import { afterEach, expect, test, vi } from 'vitest';
|
|
import OperationsPage from './OperationsPage';
|
|
|
|
const mocks = vi.hoisted(() => ({ opsHealth: vi.fn(), sourceReadiness: vi.fn() }));
|
|
vi.mock('../../api/client', () => ({ api: mocks }));
|
|
|
|
afterEach(() => { cleanup(); mocks.opsHealth.mockReset(); mocks.sourceReadiness.mockReset(); });
|
|
|
|
test('reconciles service identities with bound and identity-required vehicles', async () => {
|
|
mocks.opsHealth.mockResolvedValue({
|
|
linkHealth: [], kafkaLag: 0, activeConnections: 10, capacityFindings: [], redisOnlineKeys: 5,
|
|
tdengineWritable: true, mysqlWritable: true,
|
|
runtime: { platformRelease: 'test-release', dataMode: 'production', requestTimeoutMs: 5000, amapSecurityProxyEnabled: true, amapSecurityCodeExposed: false }
|
|
});
|
|
mocks.sourceReadiness.mockResolvedValue({
|
|
totalVehicles: 1035, boundVehicles: 1024, identityRequiredVehicles: 11, onlineVehicles: 234,
|
|
kafkaLag: 0, activeConnections: 10, redisOnlineKeys: 5, platformRelease: 'test-release', sources: []
|
|
});
|
|
const client = new QueryClient({ defaultOptions: { queries: { retry: false } } });
|
|
render(<QueryClientProvider client={client}><OperationsPage /></QueryClientProvider>);
|
|
|
|
expect(await screen.findByText('1035 / 234')).toBeInTheDocument();
|
|
for (const key of [['ops-health-v2'], ['ops-source-readiness-v2']]) {
|
|
const query = client.getQueryCache().find({ queryKey: key });
|
|
const liveOptions = query?.options as { refetchIntervalInBackground?: boolean; refetchOnWindowFocus?: boolean };
|
|
expect(liveOptions.refetchIntervalInBackground).toBe(false);
|
|
expect(liveOptions.refetchOnWindowFocus).toBe(true);
|
|
}
|
|
expect(screen.getByText('服务身份 / 在线')).toBeInTheDocument();
|
|
expect(screen.getByText('已绑定 1024 · 待绑定 11')).toBeInTheDocument();
|
|
expect(screen.queryByText('统一车辆视角')).not.toBeInTheDocument();
|
|
});
|
|
|
|
test('keeps health evidence visible when source readiness fails and retries that section', async () => {
|
|
mocks.opsHealth.mockResolvedValue({
|
|
linkHealth: [], kafkaLag: 0, activeConnections: 10, capacityFindings: [], redisOnlineKeys: 5,
|
|
tdengineWritable: true, mysqlWritable: true,
|
|
runtime: { platformRelease: 'test-release', dataMode: 'production', requestTimeoutMs: 5000, amapSecurityProxyEnabled: true, amapSecurityCodeExposed: false }
|
|
});
|
|
mocks.sourceReadiness.mockRejectedValueOnce(new Error('来源就绪度暂时不可用')).mockResolvedValueOnce({
|
|
totalVehicles: 1035, boundVehicles: 1024, identityRequiredVehicles: 11, onlineVehicles: 234,
|
|
kafkaLag: 0, activeConnections: 10, redisOnlineKeys: 5, platformRelease: 'test-release', sources: []
|
|
});
|
|
const client = new QueryClient({ defaultOptions: { queries: { retry: false } } });
|
|
render(<QueryClientProvider client={client}><OperationsPage /></QueryClientProvider>);
|
|
|
|
expect(await screen.findByText('来源就绪度暂时不可用')).toBeInTheDocument();
|
|
expect(screen.getByText('test-release')).toBeInTheDocument();
|
|
fireEvent.click(screen.getByRole('button', { name: /重试/ }));
|
|
|
|
expect(await screen.findByText('1035 / 234')).toBeInTheDocument();
|
|
expect(screen.queryByText('来源就绪度暂时不可用')).not.toBeInTheDocument();
|
|
expect(mocks.sourceReadiness).toHaveBeenCalledTimes(2);
|
|
});
|