94 lines
3.6 KiB
JavaScript
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' }),
|
|
),
|
|
);
|
|
});
|
|
});
|