62 lines
2.1 KiB
TypeScript
62 lines
2.1 KiB
TypeScript
|
|
import { describe, it, expect, afterEach } from 'vitest';
|
||
|
|
import { screen, waitFor } from '@testing-library/react';
|
||
|
|
import { EngagementsPage } from './EngagementsPage';
|
||
|
|
import { installFetchMock, renderWithProviders } from '@/test/testUtils';
|
||
|
|
|
||
|
|
describe('EngagementsPage', () => {
|
||
|
|
let fetchMock: ReturnType<typeof installFetchMock>;
|
||
|
|
|
||
|
|
afterEach(() => {
|
||
|
|
fetchMock?.restore();
|
||
|
|
});
|
||
|
|
|
||
|
|
it('shows the loading row while the engagements query is pending', () => {
|
||
|
|
fetchMock = installFetchMock([]); // never resolve in this test
|
||
|
|
// Replace with a long-lived promise so the query sits in pending state.
|
||
|
|
const pending: typeof fetch = () => new Promise(() => null);
|
||
|
|
globalThis.fetch = pending;
|
||
|
|
renderWithProviders(<EngagementsPage />);
|
||
|
|
expect(screen.getByText(/fetching engagements/i)).toBeInTheDocument();
|
||
|
|
});
|
||
|
|
|
||
|
|
it('renders the empty state when the list is empty', async () => {
|
||
|
|
fetchMock = installFetchMock([{ status: 200, body: [] }]);
|
||
|
|
renderWithProviders(<EngagementsPage />);
|
||
|
|
await screen.findByText(/no engagements yet/i);
|
||
|
|
});
|
||
|
|
|
||
|
|
it('renders the error state on 500', async () => {
|
||
|
|
fetchMock = installFetchMock([{ status: 500, body: { detail: 'internal_error' } }]);
|
||
|
|
renderWithProviders(<EngagementsPage />);
|
||
|
|
await waitFor(() => {
|
||
|
|
expect(screen.getByText(/fetch failed/i)).toBeInTheDocument();
|
||
|
|
});
|
||
|
|
expect(screen.getByRole('button', { name: /retry/i })).toBeInTheDocument();
|
||
|
|
});
|
||
|
|
|
||
|
|
it('renders rows when the backend returns engagements', async () => {
|
||
|
|
fetchMock = installFetchMock([
|
||
|
|
{
|
||
|
|
status: 200,
|
||
|
|
body: [
|
||
|
|
{
|
||
|
|
id: 'eng_1',
|
||
|
|
name: 'OPERATION ALPHA',
|
||
|
|
client_name: 'Acme',
|
||
|
|
description: null,
|
||
|
|
status: 'active',
|
||
|
|
c2_type: 'mythic',
|
||
|
|
start_date: '2026-05-20',
|
||
|
|
end_date: '2026-05-30',
|
||
|
|
created_at: '2026-05-20T10:00:00Z',
|
||
|
|
},
|
||
|
|
],
|
||
|
|
},
|
||
|
|
]);
|
||
|
|
renderWithProviders(<EngagementsPage />);
|
||
|
|
await screen.findByText('OPERATION ALPHA');
|
||
|
|
expect(screen.getByText('Acme')).toBeInTheDocument();
|
||
|
|
expect(screen.getByText('MYTHIC')).toBeInTheDocument();
|
||
|
|
});
|
||
|
|
});
|