import { describe, it, expect, vi, beforeEach } from 'vitest'; import { render, screen, waitFor, cleanup } from '@testing-library/react'; import { QueryClient, QueryClientProvider } from '@tanstack/react-query'; import { MemoryRouter } from 'react-router-dom'; import type { ReactNode } from 'react'; // ----------------------------------------------------------------------------- // M-029 Pass 3 (Audit M-026): ObservabilityPage XSS-hardening + render coverage. // // ObservabilityPage renders server health + metrics. The Prometheus text // payload (getPrometheusMetrics) is operator-facing free-form text; the // existing implementation renders it inside a controlled
{text}
// surface, which React's text-interpolation escapes automatically. This test
// pins that contract so a future refactor that switched to
// dangerouslySetInnerHTML for "rich" rendering wouldn't slip past CI.
//
// Pins:
// 1. Page renders.
// 2. health.status / metrics fields containing literal ';
describe('ObservabilityPage — render + XSS hardening (M-026 / M-029 Pass 3)', () => {
beforeEach(() => {
vi.clearAllMocks();
cleanup();
delete (window as unknown as { __xss_pwned__?: number }).__xss_pwned__;
});
it('renders the page header when metrics + health resolve', async () => {
vi.mocked(client.getMetrics).mockResolvedValue({
gauge: {
certificate_total: 0,
certificate_active: 0,
certificate_expiring_soon: 0,
certificate_expired: 0,
certificate_revoked: 0,
agent_total: 0,
agent_online: 0,
job_pending: 0,
},
counter: { job_completed_total: 0, job_failed_total: 0 },
uptime: { uptime_seconds: 3600, server_started: new Date().toISOString(), measured_at: new Date().toISOString() },
} as never);
vi.mocked(client.getHealth).mockResolvedValue({ status: 'ok' } as never);
vi.mocked(client.getPrometheusMetrics).mockResolvedValue('# HELP up The current up state\nup 1\n' as never);
renderWithQuery(