import React from 'react';
import { fireEvent, createEvent } from '@testing-library/react';
import renderWithTheme from '../../../../testUtils/renderWithTheme';
import FileDnD from '..';
const fireDropFileEvent = (
element: HTMLElement,
files: {
name: string;
size: number;
type: string;
}[]
): void => {
const mockFiles = files.map(file => {
const mockFile = new File([file.name], file.name, {
type: file.type,
});
Object.defineProperty(mockFile, 'size', {
value: file.size,
});
return mockFile;
});
const fileDropEvent = createEvent.drop(element, {
dataTransfer: { files: mockFiles },
});
fireEvent(element, fileDropEvent);
};
describe('rendering', () => {
it('shows dropzone content', () => {
const { getByText } = renderWithTheme(
);
expect(getByText('Drap and Drop files here')).toBeInTheDocument();
expect(
getByText(
'Please only use these following file formats: .JPG, .JPEG, .PNG'
)
).toBeInTheDocument();
});
});
describe('interaction', () => {
describe('dropping valid files', () => {
it('allows to drop valid files into the dropzone', () => {
const onAccept = jest.fn();
const onReject = jest.fn();
const { getByText } = renderWithTheme(
);
fireDropFileEvent(getByText('Drap and Drop files here'), [
{
name: 'test.png',
type: 'image/png',
size: 100 * 1024,
},
]);
expect(onAccept).toHaveBeenCalledWith([expect.any(File)]);
expect(onReject).not.toHaveBeenCalled();
});
it('allows to drop MULTIPLE valid files into the dropzone', () => {
const onAccept = jest.fn();
const onReject = jest.fn();
const { getByText } = renderWithTheme(
);
fireDropFileEvent(getByText('Drap and Drop files here'), [
{
name: 'test1.png',
type: 'image/jpg',
size: 100 * 1024,
},
{
name: 'test2.png',
type: 'image/jpg',
size: 200 * 1024,
},
]);
expect(onAccept).toHaveBeenCalledWith([
expect.any(File),
expect.any(File),
]);
expect(onReject).not.toHaveBeenCalled();
});
it('selects ONE file when dropping multiple files into single dropzone file input', () => {
const onAccept = jest.fn();
const onReject = jest.fn();
const { getByText } = renderWithTheme(
);
fireDropFileEvent(getByText('Drap and Drop files here'), [
{
name: 'test1.png',
type: 'image/jpg',
size: 100 * 1024,
},
{
name: 'test2.png',
type: 'image/jpg',
size: 200 * 1024,
},
]);
expect(onAccept).toHaveBeenCalledWith([expect.any(File)]);
expect(onReject).not.toHaveBeenCalled();
});
});
describe('dropping invalid files', () => {
it('DOES NOT allow to drop invalid file type into the dropzone', () => {
const onAccept = jest.fn();
const onReject = jest.fn();
const { getByText } = renderWithTheme(
);
fireDropFileEvent(getByText('Drap and Drop files here'), [
{
name: 'test.gzip',
type: 'application/gzip',
size: 100 * 1024,
},
]);
expect(onReject).toHaveBeenCalledWith([
expect.objectContaining({
file: expect.any(File),
reason: 'format-not-allowed',
}),
]);
expect(onAccept).not.toHaveBeenCalled();
});
it('DOES NOT allow to drop invalid file size into the dropzone', () => {
const onAccept = jest.fn();
const onReject = jest.fn();
const { getByText } = renderWithTheme(
);
fireDropFileEvent(getByText('Drap and Drop files here'), [
{
name: 'test.png',
type: 'image/png',
size: 1025,
},
]);
expect(onReject).toHaveBeenCalledWith([
expect.objectContaining({
file: expect.any(File),
reason: 'size-limit-exceeded',
}),
]);
expect(onAccept).not.toHaveBeenCalled();
});
});
describe('dropping mixing invalid & valid files', () => {
it('allows to drop valid files but NOT invalid ones type into the dropzone', () => {
const onAccept = jest.fn();
const onReject = jest.fn();
const { getByText } = renderWithTheme(
);
fireDropFileEvent(getByText('Drap and Drop files here'), [
{
name: 'test.gzip',
type: 'application/gzip',
size: 1024,
},
{
name: 'test.jpg',
type: 'image/jpg',
size: 1024,
},
{
name: 'test.gzip',
type: 'application/gzip',
size: 1025,
},
{
name: 'test.png',
type: 'image/png',
size: 1025,
},
]);
expect(onReject).toHaveBeenCalledWith([
expect.objectContaining({
file: expect.any(File),
reason: 'format-not-allowed',
}),
expect.objectContaining({
file: expect.any(File),
reason: 'format-not-allowed',
}),
expect.objectContaining({
file: expect.any(File),
reason: 'size-limit-exceeded',
}),
]);
expect(onAccept).toHaveBeenCalledWith([expect.any(File)]);
});
});
});