PPPAIMT-Crest/frontend/src/admin/ReportsPage.test.jsx

94 lines
3.6 KiB
JavaScript

import { cleanup, fireEvent, render, screen, waitFor } from '@testing-library/react';
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
import ReportsPage from './ReportsPage.jsx';
describe('reports page', () => {
const fetchMock = vi.fn();
beforeEach(() => {
fetchMock.mockReset();
fetchMock.mockResolvedValue({ ok: true, status: 200, blob: async () => new Blob(['x']) });
vi.stubGlobal('fetch', fetchMock);
URL.createObjectURL = vi.fn(() => 'blob:export');
URL.revokeObjectURL = vi.fn();
vi.spyOn(HTMLAnchorElement.prototype, 'click').mockImplementation(() => {});
});
afterEach(() => {
cleanup();
vi.restoreAllMocks();
});
it('shows a survey card and an applications card', () => {
render(<ReportsPage />);
expect(screen.getByRole('heading', { name: 'Export Survey Data' })).toBeInTheDocument();
expect(
screen.getByRole('heading', { name: 'Export Applications with consent' }),
).toBeInTheDocument();
expect(screen.getAllByRole('button', { name: 'Export to Excel' })).toHaveLength(2);
});
it('exports applications with the dates chosen in that card only', async () => {
render(<ReportsPage />);
const card = screen.getByRole('form', { name: 'Export Applications with consent' });
const [from, to] = card.querySelectorAll('input[type="date"]');
fireEvent.change(from, { target: { value: '2026-10-01' } });
fireEvent.change(to, { target: { value: '2026-10-23' } });
fireEvent.click(card.querySelector('button'));
await waitFor(() =>
expect(fetchMock).toHaveBeenCalledWith(
'/api/admin/applications/export?from=2026-10-01&to=2026-10-23',
expect.objectContaining({ credentials: 'include' }),
),
);
});
it('shows an unticked Full report checkbox above the dates on the applications card only', () => {
render(<ReportsPage />);
const applications = screen.getByRole('form', { name: 'Export Applications with consent' });
const survey = screen.getByRole('form', { name: 'Export Survey Data' });
const checkbox = screen.getByRole('checkbox', { name: 'Full report' });
expect(applications).toContainElement(checkbox);
expect(survey.querySelector('input[type="checkbox"]')).toBeNull();
expect(checkbox).not.toBeChecked();
expect(checkbox).toHaveAccessibleDescription(/only when you need registration, bank or payment details/);
const fromDate = applications.querySelector('input[type="date"]');
expect(
checkbox.compareDocumentPosition(fromDate) & Node.DOCUMENT_POSITION_FOLLOWING,
).toBeTruthy();
});
it('requests the full report when Full report is ticked', async () => {
render(<ReportsPage />);
const card = screen.getByRole('form', { name: 'Export Applications with consent' });
fireEvent.click(screen.getByRole('checkbox', { name: 'Full report' }));
expect(card).toHaveTextContent('Includes registration details, full PAN and bank account numbers.');
fireEvent.click(card.querySelector('button'));
await waitFor(() =>
expect(fetchMock).toHaveBeenCalledWith(
'/api/admin/applications/export?full=true',
expect.objectContaining({ credentials: 'include' }),
),
);
});
it('keeps the survey export on completed responses', async () => {
render(<ReportsPage />);
const card = screen.getByRole('form', { name: 'Export Survey Data' });
fireEvent.click(card.querySelector('button'));
await waitFor(() =>
expect(fetchMock).toHaveBeenCalledWith(
'/api/admin/survey/export?status=COMPLETED',
expect.objectContaining({ credentials: 'include' }),
),
);
});
});