// @vitest-environment jsdom
/**
* S-5.4 — Page Component Smoke Tests
*
* Verifies pages render without crashing with mocked API data.
*/
import React from 'react';
import { describe, it, expect, vi, beforeEach } from 'vitest';
import { render } from '@testing-library/react';
// ─── Mock react-router-dom ──────────────────────────────────────
vi.mock('react-router-dom', () => ({
useParams: () => ({}),
useNavigate: () => vi.fn(),
useSearchParams: () => [new URLSearchParams(), vi.fn()],
Link: ({ children, to, ...props }: any) => {children},
NavLink: ({ children, to, ...props }: any) => {children},
}));
// ─── Mock useApi hook ───────────────────────────────────────────
vi.mock('../../hooks/useApi', () => ({
useApi: () => ({
data: null,
loading: false,
error: null,
refetch: vi.fn(),
}),
}));
// ─── Mock useSSE hook ───────────────────────────────────────────
vi.mock('../../hooks/useSSE', () => ({
useSSE: () => ({
data: [],
error: null,
connected: false,
}),
}));
// ─── Mock recharts (avoid SVG rendering issues in jsdom) ────────
vi.mock('recharts', () => {
const Noop = ({ children }: any) =>
{children}
;
return {
ResponsiveContainer: Noop,
LineChart: Noop,
Line: () => null,
BarChart: Noop,
Bar: () => null,
AreaChart: Noop,
Area: () => null,
PieChart: Noop,
Pie: () => null,
Cell: () => null,
XAxis: () => null,
YAxis: () => null,
Tooltip: () => null,
CartesianGrid: () => null,
Legend: () => null,
};
});
// ─── Mock API client (prevent actual fetch calls) ───────────────
vi.mock('../../api/client', () => {
const noop = () => Promise.resolve({});
const noopArr = () => Promise.resolve([]);
return {
getKeys: noopArr,
createKey: noop,
revokeKey: noop,
getStats: () => Promise.resolve({ totalEvents: 0, totalSessions: 0, totalAgents: 0 }),
getConfig: () => Promise.resolve({ retentionDays: 30, agentGateUrl: '', agentGateSecret: '', formBridgeUrl: '', formBridgeSecret: '' }),
updateConfig: noop,
getEvents: () => Promise.resolve({ events: [], total: 0, hasMore: false }),
getSessions: () => Promise.resolve({ sessions: [], total: 0, hasMore: false }),
getAgents: noopArr,
getAnalytics: () => Promise.resolve({ buckets: [], totals: {} }),
getCostAnalytics: () => Promise.resolve({ byAgent: [], overTime: [], totals: {} }),
getToolAnalytics: () => Promise.resolve({ tools: [] }),
getAlertRules: noopArr,
getAlertHistory: () => Promise.resolve({ entries: [], total: 0, hasMore: false }),
createAlertRule: noop,
updateAlertRule: noop,
deleteAlertRule: noop,
getGuardrailRules: () => Promise.resolve({ rules: [] }),
getGuardrailHistory: () => Promise.resolve({ triggers: [], total: 0 }),
updateGuardrailRule: noop,
deleteGuardrailRule: noop,
getOverviewStats: () => Promise.resolve({}),
getSession: noop,
getSessionTimeline: () => Promise.resolve({ events: [], chainValid: true }),
getSessionReplay: () => Promise.resolve({ session: {}, events: [], chainValid: true }),
getAgent: noop,
getAgentAnalytics: () => Promise.resolve({ agents: [] }),
getLlmAnalytics: () => Promise.resolve({ summary: {}, byModel: [], byTime: [] }),
getHealthOverview: () => Promise.resolve({ agents: [], window: 24 }),
getOptimizationRecommendations: () => Promise.resolve({ recommendations: [], period: 30, totalPotentialSavings: 0 }),
getBenchmarks: () => Promise.resolve({ benchmarks: [], total: 0, hasMore: false }),
getMemories: () => Promise.resolve({ memories: [], total: 0 }),
recall: () => Promise.resolve({ results: [], query: '', totalResults: 0 }),
reflect: noop,
getCapabilities: () => Promise.resolve({ capabilities: [] }),
getDelegations: () => Promise.resolve({ delegations: [], total: 0 }),
verifyAuditChain: () => Promise.resolve({ verified: true, sessionsVerified: 0, brokenChains: [] }),
generateComplianceReport: noop,
getExportEventsUrl: () => '/api/compliance/export/events',
ApiError: class ApiError extends Error { status: number; constructor(s: number, m: string) { super(m); this.status = s; this.name = 'ApiError'; } },
diagnoseAgent: noop,
diagnoseSession: noop,
getPrompts: () => Promise.resolve({ templates: [], total: 0 }),
getPrompt: noop,
createPrompt: noop,
getPromptFingerprints: noopArr,
getPromptAnalytics: noopArr,
getPromptDiff: noop,
createPromptVersion: noop,
deletePrompt: noop,
linkFingerprintToTemplate: noop,
};
});
// ─── Tests ──────────────────────────────────────────────────────
describe('Page smoke tests', () => {
it('Settings renders without crashing', async () => {
const { default: Settings } = await import('../Settings');
expect(() => render()).not.toThrow();
});
it('Analytics renders without crashing', async () => {
const { Analytics } = await import('../Analytics');
expect(() => render()).not.toThrow();
});
it('EventsExplorer renders without crashing', async () => {
const { EventsExplorer } = await import('../EventsExplorer');
expect(() => render()).not.toThrow();
});
it('Alerts renders without crashing', async () => {
const { Alerts } = await import('../Alerts');
expect(() => render()).not.toThrow();
});
it('GuardrailList renders without crashing', async () => {
const { default: GuardrailList } = await import('../GuardrailList');
expect(() => render()).not.toThrow();
});
it('Compliance renders without crashing', async () => {
const { default: Compliance } = await import('../Compliance');
expect(() => render()).not.toThrow();
});
it('Sessions renders without crashing', async () => {
const { Sessions } = await import('../Sessions');
expect(() => render()).not.toThrow();
});
});