Skip to content

Commit

Permalink
BHBC-964: Update tests
Browse files Browse the repository at this point in the history
  • Loading branch information
NickPhura committed Apr 15, 2021
1 parent e77e86c commit dffc46f
Show file tree
Hide file tree
Showing 4 changed files with 213 additions and 1,583 deletions.
156 changes: 31 additions & 125 deletions app/src/components/attachments/FileUpload.test.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { fireEvent, render, waitFor } from '@testing-library/react';
import { APIError } from 'hooks/api/useAxios';
import { useBiohubApi } from 'hooks/useBioHubApi';
import React from 'react';
import FileUpload from './FileUpload';
Expand Down Expand Up @@ -27,154 +26,61 @@ describe('FileUpload', () => {
mockBiohubApi().project.uploadProjectAttachments.mockClear();
});

it('matches the snapshot', () => {
const { asFragment } = renderContainer();
it('renders the dropZone component', async () => {
const { getByText } = renderContainer();

expect(asFragment()).toMatchSnapshot();
expect(getByText('Drag your files here', { exact: false })).toBeVisible();
});

it('handles file upload success', async () => {
let resolveRef: (value: unknown) => void;
it('renders an item in the list for each file added', async () => {
mockBiohubApi().project.uploadProjectAttachments.mockReturnValue(Promise.resolve());

const mockUploadPromise = new Promise(function (resolve: any, reject: any) {
resolveRef = resolve;
});

mockBiohubApi().project.uploadProjectAttachments.mockReturnValue(mockUploadPromise);

const { asFragment, getByTestId, getByText } = renderContainer();

const testFile = new File(['test png content'], 'testpng.txt', { type: 'text/plain' });
const { getByTestId, getByText } = renderContainer();

const dropZoneInput = getByTestId('drop-zone-input');

fireEvent.change(dropZoneInput, { target: { files: [testFile] } });

await waitFor(() => {
expect(mockBiohubApi().project.uploadProjectAttachments).toHaveBeenCalledWith(
projectId,
[testFile],
expect.any(Object),
expect.any(Function)
);

expect(getByText('testpng.txt')).toBeVisible();

expect(getByText('Uploading')).toBeVisible();
fireEvent.change(dropZoneInput, {
target: {
files: [
new File([`test png content`], `testpng0.txt`, { type: 'text/plain' }),
new File([`test png content`], `testpng1.txt`, { type: 'text/plain' }),
new File([`test png content`], `testpng2.txt`, { type: 'text/plain' }),
new File([`test png content`], `testpng3.txt`, { type: 'text/plain' }),
new File([`test png content`], `testpng4.txt`, { type: 'text/plain' })
]
}
});

// Manually trigger the upload resolve to simulate a successful upload
// @ts-ignore
resolveRef(null);

await waitFor(() => {
expect(getByText('Complete')).toBeVisible();
expect(getByText('testpng0.txt')).toBeVisible();
expect(getByText('testpng1.txt')).toBeVisible();
expect(getByText('testpng2.txt')).toBeVisible();
expect(getByText('testpng3.txt')).toBeVisible();
expect(getByText('testpng4.txt')).toBeVisible();
});

// expect file list item to show complete state
expect(asFragment()).toMatchSnapshot();
});

it('handles file upload API rejection', async () => {
let rejectRef: (reason: unknown) => void;

const mockUploadPromise = new Promise(function (resolve: any, reject: any) {
rejectRef = reject;
});

mockBiohubApi().project.uploadProjectAttachments.mockReturnValue(mockUploadPromise);

const { asFragment, getByTestId, getByText, getByTitle } = renderContainer();
it('removes an item from the list when the onCancel callback is triggered', async () => {
mockBiohubApi().project.uploadProjectAttachments.mockReturnValue(new Promise(() => {}));

const testFile = new File(['test png content'], 'testpng.txt', { type: 'text/plain' });
const { getByTestId, getByText, getByTitle, queryByText } = renderContainer();

const dropZoneInput = getByTestId('drop-zone-input');

fireEvent.change(dropZoneInput, { target: { files: [testFile] } });

await waitFor(() => {
expect(mockBiohubApi().project.uploadProjectAttachments).toHaveBeenCalledWith(
projectId,
[testFile],
expect.any(Object),
expect.any(Function)
);

expect(getByText('testpng.txt')).toBeVisible();

expect(getByText('Uploading')).toBeVisible();
});

// Manually trigger the upload reject to simulate an unsuccessful upload
// @ts-ignore
rejectRef(new APIError({ response: { data: { message: 'File was evil!' } } } as any));

await waitFor(() => {
expect(getByText('File was evil!')).toBeVisible();
});

// expect file list item to show error state
expect(asFragment()).toMatchSnapshot();

const removeButton = getByTitle('Clear File');

await waitFor(() => {
expect(removeButton).toBeVisible();
fireEvent.change(dropZoneInput, {
target: {
files: [new File([`test png content`], `testpng0.txt`, { type: 'text/plain' })]
}
});

fireEvent.click(removeButton);

// expect file list item to be removed
expect(asFragment()).toMatchSnapshot();
});

it('handles file upload DropZone rejection for file too large', async () => {
const { asFragment, getByTestId, getByText } = renderContainer();

const testFile = new File(['test png content'], 'testpng.txt', { type: 'text/plain' });
// force file size to be 500MB
Object.defineProperty(testFile, 'size', { value: 1024 * 1024 * 500 }); // 500MB file

const dropZoneInput = getByTestId('drop-zone-input');

fireEvent.change(dropZoneInput, { target: { files: [testFile] } });

await waitFor(() => {
expect(getByText('testpng.txt')).toBeVisible();

expect(getByText('File size exceeds maximum')).toBeVisible();
expect(getByText('testpng0.txt')).toBeVisible();
});

// expect file list item to show error state
expect(asFragment()).toMatchSnapshot();
});

it('handles file upload DropZone rejection for too many files uploaded at once', async () => {
const { asFragment, getByTestId, getByText, getAllByText } = renderContainer();

const getTestFiles = (num: number): File[] => {
const files = [];
for (let i = 0; i < num; i++) {
files.push(new File([`test png ${i} content`], `testpng${i}.txt`, { type: 'text/plain' }));
}
return files;
};

const dropZoneInput = getByTestId('drop-zone-input');

fireEvent.change(dropZoneInput, { target: { files: getTestFiles(11) } });
fireEvent.click(getByTitle('Cancel Upload'));

await waitFor(() => {
const errorMessages = getAllByText('Number of files uploaded at once exceeds maximum');
expect(errorMessages.length).toEqual(11);
expect(queryByText('testpng0.txt')).not.toBeInTheDocument();
});

expect(getByText('testpng1.txt')).toBeVisible();
expect(getByText('testpng3.txt')).toBeVisible();
expect(getByText('testpng7.txt')).toBeVisible();
expect(getByText('testpng10.txt')).toBeVisible();

// expect file list item to show error state
expect(asFragment()).toMatchSnapshot();
});
});
172 changes: 172 additions & 0 deletions app/src/components/attachments/FileUploadItem.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,172 @@
import { fireEvent, render, waitFor } from '@testing-library/react';
import { APIError } from 'hooks/api/useAxios';
import { useBiohubApi } from 'hooks/useBioHubApi';
import React from 'react';
import FileUploadItem, { IFileUploadItemProps } from './FileUploadItem';

jest.mock('../../hooks/useBioHubApi');
const mockUseBiohubApi = {
project: {
uploadProjectAttachments: jest.fn<Promise<any>, []>()
}
};

const mockBiohubApi = ((useBiohubApi as unknown) as jest.Mock<typeof mockUseBiohubApi>).mockReturnValue(
mockUseBiohubApi
);

const projectId = 1;
const onCancel = jest.fn();

const renderContainer = (props: IFileUploadItemProps) => {
return render(<FileUploadItem {...props} />);
};

describe('FileUploadItem', () => {
beforeEach(() => {
// clear mocks before each test
mockBiohubApi().project.uploadProjectAttachments.mockClear();
});

it('calls props.onCancel when the `X` button is clicked', async () => {
let rejectRef: (value: unknown) => void;

const mockUploadPromise = new Promise(function (resolve: any, reject: any) {
rejectRef = reject;
});

mockBiohubApi().project.uploadProjectAttachments.mockReturnValue(mockUploadPromise);

const testFile = new File(['test png content'], 'testpng.txt', { type: 'text/plain' });

const { getByText, getByTitle } = renderContainer({
projectId,
file: testFile,
error: '',
onCancel: () => onCancel()
});

await waitFor(() => {
expect(mockBiohubApi().project.uploadProjectAttachments).toHaveBeenCalledWith(
projectId,
[testFile],
expect.any(Object),
expect.any(Function)
);

expect(getByText('testpng.txt')).toBeVisible();

expect(getByText('Uploading')).toBeVisible();
});

const cancelButton = getByTitle('Cancel Upload');

expect(cancelButton).toBeVisible();

fireEvent.click(cancelButton);

// Manually trigger the upload reject to simulate a cancelled request
// @ts-ignore
rejectRef({ message: '' });

await waitFor(() => {
expect(onCancel).toBeCalledTimes(1);
});
});

it('handles file upload success', async () => {
let resolveRef: (value: unknown) => void;

const mockUploadPromise = new Promise(function (resolve: any, reject: any) {
resolveRef = resolve;
});

mockBiohubApi().project.uploadProjectAttachments.mockReturnValue(mockUploadPromise);

const testFile = new File(['test png content'], 'testpng.txt', { type: 'text/plain' });

const { getByText } = renderContainer({
projectId,
file: testFile,
error: '',
onCancel: () => onCancel()
});

await waitFor(() => {
expect(mockBiohubApi().project.uploadProjectAttachments).toHaveBeenCalledWith(
projectId,
[testFile],
expect.any(Object),
expect.any(Function)
);

expect(getByText('testpng.txt')).toBeVisible();

expect(getByText('Uploading')).toBeVisible();
});

// Manually trigger the upload resolve to simulate a successful upload
// @ts-ignore
resolveRef(null);

await waitFor(() => {
expect(getByText('Complete')).toBeVisible();
});
});

it('handles file upload API rejection', async () => {
let rejectRef: (reason: unknown) => void;

const mockUploadPromise = new Promise(function (resolve: any, reject: any) {
rejectRef = reject;
});

mockBiohubApi().project.uploadProjectAttachments.mockReturnValue(mockUploadPromise);

const testFile = new File(['test png content'], 'testpng.txt', { type: 'text/plain' });

const { getByText } = renderContainer({
projectId,
file: testFile,
error: '',
onCancel: () => onCancel()
});

await waitFor(() => {
expect(mockBiohubApi().project.uploadProjectAttachments).toHaveBeenCalledWith(
projectId,
[testFile],
expect.any(Object),
expect.any(Function)
);

expect(getByText('testpng.txt')).toBeVisible();

expect(getByText('Uploading')).toBeVisible();
});

// Manually trigger the upload reject to simulate an unsuccessful upload
// @ts-ignore
rejectRef(new APIError({ response: { data: { message: 'api error message' } } } as any));

await waitFor(() => {
expect(getByText('api error message')).toBeVisible();
});
});

it('shows an error message if the component initially receives an error', async () => {
const testFile = new File(['test png content'], 'testpng.txt', { type: 'text/plain' });

const { getByText } = renderContainer({
projectId,
file: testFile,
error: 'initial error message',
onCancel: () => onCancel()
});

await waitFor(() => {
expect(getByText('testpng.txt')).toBeVisible();
expect(getByText('initial error message')).toBeVisible();
});
});
});
Loading

0 comments on commit dffc46f

Please sign in to comment.