Files
floci-ui/packages/frontend/src/pages/DiagnosticsPage.test.tsx
T
Zakaria 8b166d86d4
CI / checks (pull_request) Failing after 12m12s
feat(frontend): collapse responding services on the diagnostics page
Failing console services stay visible; responding ones are behind a toggle.
2026-10-23 12:00:10 -04:00

117 lines
6.1 KiB
TypeScript

import {QueryClient, QueryClientProvider} from '@tanstack/react-query'
import {render, screen, within} from '@testing-library/react'
import userEvent from '@testing-library/user-event'
import {MemoryRouter, Route, Routes} from 'react-router-dom'
import {expect, test, vi} from 'vitest'
import {DiagnosticsPage} from './DiagnosticsPage'
import type {RuntimeDiagnostics} from '@/types/cloud'
const api = vi.hoisted(() => ({getCloudDiagnostics: vi.fn()}))
vi.mock('@/api/cloudProxyClient', () => api)
const healthy: RuntimeDiagnostics = {
cloud: 'aws',
checkedAt: new Date().toISOString(),
runtime: {status: 'reachable', endpoint: 'http://floci:4566', latencyMs: 12, error: null, version: '1.9.0', edition: 'community'},
emulatedServices: [
{name: 'route53', state: 'running', consolePages: []},
{name: 's3', state: 'running', consolePages: [{service: 'storage', displayName: 'S3', route: '/cloud-explorer/aws/storage'}]},
{name: 'sqs', state: 'stopped', consolePages: [{service: 'messaging', displayName: 'SQS', route: '/cloud-explorer/aws/messaging'}]},
],
consoleServices: [
{cloud: 'aws', service: 'storage', adapterRegistered: true, runtime: 'reachable', endpoint: 'http://floci:4566', checkedAt: '', latencyMs: 4, error: null, errorCode: null},
{cloud: 'aws', service: 'messaging', adapterRegistered: true, runtime: 'unavailable', endpoint: 'http://floci:4566', checkedAt: '', latencyMs: 9, error: 'Service is not running', errorCode: 'RUNTIME_UNAVAILABLE'},
],
containers: [{kind: 'ec2-instance', resourceId: 'i-0abc', status: 'running', sshHost: 'localhost', sshPort: 2201}],
console: {startedAt: '2026-10-23T08:00:00.000Z', uptimeSeconds: 9_015, authMode: 'oidc', activeSessions: 2},
}
function renderPage(path = '/diagnostics/aws') {
const client = new QueryClient({defaultOptions: {queries: {retry: false}}})
return render(
<QueryClientProvider client={client}>
<MemoryRouter initialEntries={[path]}>
<Routes><Route path="/diagnostics/:cloud" element={<DiagnosticsPage/>}/></Routes>
</MemoryRouter>
</QueryClientProvider>,
)
}
test('summarises the runtime and lists failing console services first', async () => {
api.getCloudDiagnostics.mockResolvedValue(healthy)
renderPage()
const summary = await screen.findByRole('region', {name: 'Runtime summary'})
expect(within(summary).getByText('Reachable')).toBeInTheDocument()
expect(screen.getByText('http://floci:4566 · 12 ms')).toBeInTheDocument()
expect(screen.getByText('1.9.0')).toBeInTheDocument()
expect(screen.getByText('1 not running')).toBeInTheDocument()
expect(screen.getByText('2 / 3')).toBeInTheDocument()
const consoleServices = screen.getByRole('region', {name: 'Console services'})
const rows = within(consoleServices).getAllByRole('row')
expect(rows).toHaveLength(2)
expect(rows[1]).toHaveTextContent('messaging')
expect(rows[1]).toHaveTextContent('Service is not running (RUNTIME_UNAVAILABLE)')
expect(screen.getByRole('link', {name: 'i-0abc'})).toHaveAttribute('href', '/cloud-explorer/aws/compute?resource=i-0abc')
expect(screen.getByText('localhost:2201')).toBeInTheDocument()
expect(screen.getByText('2 h 30 min')).toBeInTheDocument()
expect(screen.getByText('OIDC single sign-on')).toBeInTheDocument()
})
test('keeps responding console services behind a toggle', async () => {
const user = userEvent.setup()
api.getCloudDiagnostics.mockResolvedValue({
...healthy,
consoleServices: healthy.consoleServices.map((service) => ({...service, runtime: 'reachable', error: null, errorCode: null})),
} satisfies RuntimeDiagnostics)
renderPage()
const consoleServices = await screen.findByRole('region', {name: 'Console services'})
expect(within(consoleServices).getByText('All 2 responding')).toBeInTheDocument()
expect(within(consoleServices).queryByRole('table')).not.toBeInTheDocument()
await user.click(within(consoleServices).getByRole('button', {name: 'Show 2 responding'}))
expect(within(consoleServices).getAllByRole('row')).toHaveLength(3)
await user.click(within(consoleServices).getByRole('button', {name: 'Hide responding'}))
expect(within(consoleServices).queryByRole('table')).not.toBeInTheDocument()
})
test('filters emulated services by console coverage and state', async () => {
const user = userEvent.setup()
api.getCloudDiagnostics.mockResolvedValue(healthy)
renderPage()
const section = await screen.findByRole('region', {name: 'Emulated services'})
await user.click(within(section).getByRole('button', {name: 'No console page'}))
expect(within(section).getAllByRole('listitem').map((item) => item.textContent)).toEqual(['route53'])
await user.click(within(section).getByRole('button', {name: 'Not running'}))
expect(within(section).getByRole('link', {name: 'SQS'})).toHaveAttribute('href', '/cloud-explorer/aws/messaging')
expect(within(section).getAllByRole('listitem')).toHaveLength(1)
await user.click(within(section).getByRole('button', {name: 'All'}))
await user.type(within(section).getByRole('searchbox'), 's3')
expect(within(section).getAllByRole('listitem').map((item) => item.textContent)).toEqual(['s3S3'])
})
test('shows what is known when the runtime is down', async () => {
api.getCloudDiagnostics.mockResolvedValue({
...healthy,
runtime: {status: 'unavailable', endpoint: 'http://floci:4566', latencyMs: null, error: 'Cannot reach Floci core at http://floci:4566', version: null, edition: null},
emulatedServices: null,
consoleServices: [],
containers: null,
} satisfies RuntimeDiagnostics)
renderPage()
expect(await screen.findByText('Unavailable')).toBeInTheDocument()
expect(screen.getByText('Cannot reach Floci core at http://floci:4566')).toBeInTheDocument()
expect(screen.getAllByText('Not reported by the runtime')).toHaveLength(2)
expect(screen.queryByRole('region', {name: 'Emulated services'})).not.toBeInTheDocument()
expect(screen.getByText('This runtime does not publish container diagnostics.')).toBeInTheDocument()
})