import { userEvent } from '@testing-library/user-event'; import { Status } from '../../common'; import { render, screen } from '../../test-utils'; import UploadItem, { UploadItemProps } from './UploadItem'; describe('UploadItem', () => { const props: UploadItemProps = { file: { id: 1, filename: 'purchase-receipt.pdf', status: Status.SUCCEEDED, url: 'https://wise.com', }, canDelete: true, onDelete: jest.fn(), singleFileUpload: true, onFocus: jest.fn(), }; const renderComponent = (customProps = props) => render(); describe('filename', () => { it('should display the filename', () => { renderComponent(); expect(screen.getByText(props.file.filename!)).toBeInTheDocument(); }); it('should display the default filename when it is missing', () => { renderComponent({ ...props, file: { ...props.file, filename: undefined }, }); expect(screen.getByText('Uploaded file')).toBeInTheDocument(); }); }); describe('description', () => { it('should display the default uploading copy while file upload is in progress', () => { renderComponent({ ...props, file: { ...props.file, status: Status.PENDING }, }); expect(screen.getByText('Uploading...')).toBeInTheDocument(); }); it('should display the default deleting copy while file deletion is in progress', () => { renderComponent({ ...props, file: { ...props.file, status: Status.PROCESSING }, }); expect(screen.getByText('Deleting...')).toBeInTheDocument(); }); it('should display the default success copy when file upload is complete', () => { renderComponent({ ...props, file: { ...props.file, status: Status.SUCCEEDED }, }); expect(screen.getByText('Uploaded')).toBeInTheDocument(); }); }); describe('failed uploads', () => { it('should display the error.message from an API response', () => { const errorMessage = 'An API error object with message field'; renderComponent({ ...props, file: { ...props.file, status: Status.FAILED, error: { message: errorMessage } }, }); expect(screen.getByText(errorMessage)).toBeInTheDocument(); }); it('should display the error if it is supplied as a string', () => { const errorMessage = 'An API error string'; renderComponent({ ...props, file: { ...props.file, status: Status.FAILED, error: errorMessage }, }); expect(screen.getByText(errorMessage)).toBeInTheDocument(); }); it('should display default error message when error is missing but status is FAILED', () => { renderComponent({ ...props, file: { ...props.file, status: Status.FAILED }, }); expect(screen.getByText('Uploading failed')).toBeInTheDocument(); }); it('should display the error even if status is missing', () => { const errorMessage = 'An API error string without status'; renderComponent({ ...props, file: { ...props.file, error: errorMessage }, }); expect(screen.getByText(errorMessage)).toBeInTheDocument(); }); }); describe('file deletion', () => { it('should render the remove file button when deleteFile prop is supplied', () => { renderComponent(); expect(screen.getByLabelText('Remove file ', { exact: false })).toBeInTheDocument(); }); it('should not render the remove file button when canDelete prop is false', () => { renderComponent({ ...props, canDelete: false }); expect(screen.queryByLabelText('Remove file ', { exact: false })).not.toBeInTheDocument(); }); }); describe('manual file download handler', () => { it('calls onDownload handler provided through props', async () => { const onDownload = jest.fn(); renderComponent({ ...props, onDownload }); await userEvent.click(screen.getAllByRole('link')[0]); expect(onDownload).toHaveBeenCalledTimes(1); expect(onDownload).toHaveBeenCalledWith(props.file); }); }); });