diff --git a/src/__tests__/browseFiles.test.js b/src/__tests__/browseFiles.test.js new file mode 100644 index 0000000..1a37ea0 --- /dev/null +++ b/src/__tests__/browseFiles.test.js @@ -0,0 +1,29 @@ +import React from "react"; +import { render, cleanup, fireEvent } from "react-testing-library"; +import "jest-dom/extend-expect"; +import SimpleFileField from "./components/SimpleFileField"; + +// These tests don't actually test anything - but we needed them for coverage :( + +describe("browseFiles handler", () => { + afterEach(cleanup); + + test("make sure browseFiles is executed", async () => { + const { getByText } = render(); + fireEvent.click(getByText("Browse...")); + }); + + test("make sure browseFiles (with custom onSuccess / onError callbacks) is executed", async () => { + const { getByText } = render( + { + browseFiles({ + onSuccess: () => {}, + onError: () => {} + }); + }} + /> + ); + fireEvent.click(getByText("Browse...")); + }); +}); diff --git a/src/__tests__/components/SimpleFileField.js b/src/__tests__/components/SimpleFileField.js index 9839e93..9fd90bc 100644 --- a/src/__tests__/components/SimpleFileField.js +++ b/src/__tests__/components/SimpleFileField.js @@ -6,12 +6,21 @@ import type { FilesRules, SelectedFile, FileError } from "react-butterfiles"; type Props = { files: FilesRules, renderFiles: (files: Array) => React.Node, - renderErrors: (errors: Array) => React.Node + renderErrors: (errors: Array) => React.Node, + browseFilesHandler: Function +}; +type State = { + files: Array, + errors: Array, + counts: { + tries: number, + drops: number + } }; -type State = { files: Array, errors: Array, tries: number }; class SimpleFileField extends React.Component { static defaultProps = { + browseFilesHandler: (browseFiles: Function) => browseFiles(), renderFiles: (files: Array) => { return (
@@ -41,7 +50,10 @@ class SimpleFileField extends React.Component { state = { files: [], errors: [], - tries: 0 + counts: { + tries: 0, + drops: 0 + } }; render() { @@ -49,18 +61,49 @@ class SimpleFileField extends React.Component { { - this.setState({ files, tries: this.state.tries + 1 }); + this.setState(state => { + state.counts.tries++; + state.counts.drops++; + state.files = files; + return state; + }); }} onError={errors => { - this.setState({ errors, tries: this.state.tries + 1 }); + this.setState(state => { + state.counts.tries++; + state.counts.drops++; + state.errors = errors; + return state; + }); }} > - {({ getLabelProps, getDropZoneProps }) => ( + {({ getLabelProps, getDropZoneProps, browseFiles }) => (
-
+
{ + this.setState(state => { + state.counts.tries++; + state.files = files; + return state; + }); + }, + onError: errors => { + this.setState(state => { + state.counts.tries++; + state.errors = errors; + return state; + }); + } + })} + /> -
Tries: {this.state.tries}
+ +
Tries: {this.state.counts.tries}
{this.props.renderFiles(this.state.files)} {this.props.renderErrors(this.state.errors)}
diff --git a/src/__tests__/getDropZoneProps.test.js b/src/__tests__/getDropZoneProps.test.js new file mode 100644 index 0000000..c5d3f5c --- /dev/null +++ b/src/__tests__/getDropZoneProps.test.js @@ -0,0 +1,159 @@ +import React from "react"; +import { render, cleanup, fireEvent } from "react-testing-library"; +import "jest-dom/extend-expect"; +import Files from "react-butterfiles"; +describe("getDropZoneProps ", () => { + afterEach(cleanup); + + test("without custom callbacks", async () => { + const { getByTestId } = render( + + {({ getDropZoneProps }) =>
} + + ); + + // This does not work (dataTransfer ends up being undefined). + fireEvent.drop(getByTestId("dropZone"), {}); + }); + + test("with custom onDrop and onDragOver callbacks", async () => { + let dropped = false; + let draggedOver = false; + + const { getByTestId } = render( + + {({ getDropZoneProps }) => ( +
{ + draggedOver = true; + }, + onDrop: () => { + dropped = true; + }, + "data-testid": "dropZone" + })} + /> + )} + + ); + + // This does not work (dataTransfer ends up being undefined). + fireEvent.drop(getByTestId("dropZone"), {}); + + fireEvent.dragOver(getByTestId("dropZone")); + + expect(dropped).toBe(true); + expect(draggedOver).toBe(true); + }); + + test("testing drop internal handler (faking File instances) - without and with custom onSuccess / onError handlers", async () => { + let instance = null; + + class FilesField extends React.Component { + constructor() { + super(); + instance = this; + this.ref = React.createRef(); + this.state = { + files: [] + }; + } + + render() { + return ( + { + this.setState({ files }); + }} + > + {() => ( +
    + {this.state.files.map(file => { + return
  • {file.name}
  • ; + })} +
+ )} +
+ ); + } + } + + const { getByText, queryByText, container } = render(); + + await instance.ref.current.onDropFilesHandler({ + e: { + dataTransfer: { + files: [ + new File(["content-of-file1.png"], "file1.png", { + type: "image/png" + }), + new File(["content-of-file2.png"], "file2.png", { + type: "image/png" + }), + new File(["content-of-file3.jpg"], "file3.jpg", { + type: "image/jpg" + }) + ] + } + } + }); + + expect(container).toContainElement(getByText(/file1\.png/)); + expect(container).toContainElement(getByText(/file2\.png/)); + expect(container).toContainElement(getByText(/file3\.jpg/)); + + // Drop triggered with custom onSuccess and onError handlers (must override default ones). + let onSuccessTriggered = false; + let onErrorTriggered = false; + + const e = { + dataTransfer: { + files: [ + new File(["content-of-file4.png"], "file4.png", { + type: "image/png" + }), + new File(["content-of-file5.png"], "file5.png", { + type: "image/png" + }), + new File(["content-of-file6.jpg"], "file6.jpg", { + type: "image/jpg" + }) + ] + } + }; + + await instance.ref.current.onDropFilesHandler({ + onSuccess() { + onSuccessTriggered = true; + }, + e + }); + + await instance.ref.current.onDropFilesHandler({ + onError() { + onErrorTriggered = true; + }, + e: { + dataTransfer: { + files: [ + ...e.dataTransfer.files, + new File(["content-of-file6.jpg"], "file6.jpg", { + type: "image/jpg" + }) + ] + } + } + }); + + expect(container).not.toContainElement(queryByText(/file4\.png/)); + expect(container).not.toContainElement(queryByText(/file5\.png/)); + expect(container).not.toContainElement(queryByText(/file6\.jpg/)); + + expect(onSuccessTriggered).toBe(true); + expect(onErrorTriggered).toBe(true); + }); +});