react-dropzone 11.5.3 → 12.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.eslintignore +1 -3
- package/.eslintrc +2 -4
- package/.husky/commit-msg +5 -0
- package/.husky/pre-commit +5 -0
- package/.nvmrc +1 -1
- package/README.md +78 -29
- package/commitlint.config.js +1 -1
- package/dist/es/index.js +195 -151
- package/dist/es/utils/index.js +53 -17
- package/dist/index.js +16 -2
- package/examples/events/README.md +3 -1
- package/examples/no-jsx/README.md +32 -0
- package/package.json +80 -76
- package/rollup.config.js +22 -19
- package/src/.eslintrc +7 -4
- package/src/__snapshots__/index.spec.js.snap +1 -1
- package/src/index.js +372 -288
- package/src/index.spec.js +1837 -1369
- package/src/utils/index.js +117 -56
- package/src/utils/index.spec.js +414 -254
- package/styleguide.config.js +57 -50
- package/testSetup.js +1 -1
- package/typings/.eslintrc +28 -0
- package/typings/react-dropzone.d.ts +24 -14
- package/typings/tests/accept.tsx +10 -9
- package/typings/tests/all.tsx +6 -5
- package/typings/tests/basic.tsx +8 -7
- package/typings/tests/events.tsx +8 -6
- package/typings/tests/file-dialog.tsx +4 -3
- package/typings/tests/hook.tsx +6 -6
- package/typings/tests/plugin.tsx +11 -22
- package/typings/tests/refs.tsx +4 -4
- package/tslint.json +0 -101
package/src/index.spec.js
CHANGED
|
@@ -1,24 +1,33 @@
|
|
|
1
1
|
/* eslint react/prop-types: 0, jsx-a11y/label-has-for: 0 */
|
|
2
|
-
import React, { createRef } from
|
|
3
|
-
import {
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
2
|
+
import React, { createRef } from "react";
|
|
3
|
+
import {
|
|
4
|
+
act,
|
|
5
|
+
cleanup,
|
|
6
|
+
fireEvent,
|
|
7
|
+
render,
|
|
8
|
+
waitFor,
|
|
9
|
+
} from "@testing-library/react";
|
|
10
|
+
import { renderHook } from "@testing-library/react-hooks";
|
|
11
|
+
import { fromEvent } from "file-selector";
|
|
12
|
+
import * as utils from "./utils";
|
|
13
|
+
import Dropzone, { useDropzone } from "./index";
|
|
14
|
+
|
|
15
|
+
describe("useDropzone() hook", () => {
|
|
16
|
+
let files;
|
|
17
|
+
let images;
|
|
12
18
|
|
|
13
19
|
beforeEach(() => {
|
|
14
|
-
files = [createFile(
|
|
15
|
-
images = [
|
|
16
|
-
|
|
20
|
+
files = [createFile("file1.pdf", 1111, "application/pdf")];
|
|
21
|
+
images = [
|
|
22
|
+
createFile("cats.gif", 1234, "image/gif"),
|
|
23
|
+
createFile("dogs.gif", 2345, "image/jpeg"),
|
|
24
|
+
];
|
|
25
|
+
});
|
|
17
26
|
|
|
18
|
-
afterEach(cleanup)
|
|
27
|
+
afterEach(cleanup);
|
|
19
28
|
|
|
20
|
-
describe(
|
|
21
|
-
it(
|
|
29
|
+
describe("behavior", () => {
|
|
30
|
+
it("renders the root and input nodes with the necessary props", () => {
|
|
22
31
|
const { container } = render(
|
|
23
32
|
<Dropzone>
|
|
24
33
|
{({ getRootProps, getInputProps }) => (
|
|
@@ -27,12 +36,12 @@ describe('useDropzone() hook', () => {
|
|
|
27
36
|
</div>
|
|
28
37
|
)}
|
|
29
38
|
</Dropzone>
|
|
30
|
-
)
|
|
31
|
-
expect(container.innerHTML).toMatchSnapshot()
|
|
32
|
-
})
|
|
39
|
+
);
|
|
40
|
+
expect(container.innerHTML).toMatchSnapshot();
|
|
41
|
+
});
|
|
33
42
|
|
|
34
|
-
it(
|
|
35
|
-
const accept =
|
|
43
|
+
it("sets {accept} prop on the <input>", () => {
|
|
44
|
+
const accept = "image/jpeg";
|
|
36
45
|
const { container } = render(
|
|
37
46
|
<Dropzone accept={accept}>
|
|
38
47
|
{({ getRootProps, getInputProps }) => (
|
|
@@ -41,14 +50,14 @@ describe('useDropzone() hook', () => {
|
|
|
41
50
|
</div>
|
|
42
51
|
)}
|
|
43
52
|
</Dropzone>
|
|
44
|
-
)
|
|
53
|
+
);
|
|
45
54
|
|
|
46
|
-
const input = container.querySelector(
|
|
55
|
+
const input = container.querySelector("input");
|
|
47
56
|
|
|
48
|
-
expect(input).toHaveAttribute(
|
|
49
|
-
})
|
|
57
|
+
expect(input).toHaveAttribute("accept", accept);
|
|
58
|
+
});
|
|
50
59
|
|
|
51
|
-
it(
|
|
60
|
+
it("updates {multiple} prop on the <input> when it changes", () => {
|
|
52
61
|
const { container, rerender } = render(
|
|
53
62
|
<Dropzone accept="image/jpeg">
|
|
54
63
|
{({ getRootProps, getInputProps }) => (
|
|
@@ -57,9 +66,12 @@ describe('useDropzone() hook', () => {
|
|
|
57
66
|
</div>
|
|
58
67
|
)}
|
|
59
68
|
</Dropzone>
|
|
60
|
-
)
|
|
69
|
+
);
|
|
61
70
|
|
|
62
|
-
expect(container.querySelector(
|
|
71
|
+
expect(container.querySelector("input")).toHaveAttribute(
|
|
72
|
+
"accept",
|
|
73
|
+
"image/jpeg"
|
|
74
|
+
);
|
|
63
75
|
|
|
64
76
|
rerender(
|
|
65
77
|
<Dropzone accept="image/png">
|
|
@@ -69,12 +81,15 @@ describe('useDropzone() hook', () => {
|
|
|
69
81
|
</div>
|
|
70
82
|
)}
|
|
71
83
|
</Dropzone>
|
|
72
|
-
)
|
|
84
|
+
);
|
|
73
85
|
|
|
74
|
-
expect(container.querySelector(
|
|
75
|
-
|
|
86
|
+
expect(container.querySelector("input")).toHaveAttribute(
|
|
87
|
+
"accept",
|
|
88
|
+
"image/png"
|
|
89
|
+
);
|
|
90
|
+
});
|
|
76
91
|
|
|
77
|
-
it(
|
|
92
|
+
it("sets {multiple} prop on the <input>", () => {
|
|
78
93
|
const { container } = render(
|
|
79
94
|
<Dropzone multiple>
|
|
80
95
|
{({ getRootProps, getInputProps }) => (
|
|
@@ -83,13 +98,13 @@ describe('useDropzone() hook', () => {
|
|
|
83
98
|
</div>
|
|
84
99
|
)}
|
|
85
100
|
</Dropzone>
|
|
86
|
-
)
|
|
101
|
+
);
|
|
87
102
|
|
|
88
|
-
const input = container.querySelector(
|
|
89
|
-
expect(input).toHaveAttribute(
|
|
90
|
-
})
|
|
103
|
+
const input = container.querySelector("input");
|
|
104
|
+
expect(input).toHaveAttribute("multiple");
|
|
105
|
+
});
|
|
91
106
|
|
|
92
|
-
it(
|
|
107
|
+
it("updates {multiple} prop on the <input> when it changes", () => {
|
|
93
108
|
const { container, rerender } = render(
|
|
94
109
|
<Dropzone multiple={false}>
|
|
95
110
|
{({ getRootProps, getInputProps }) => (
|
|
@@ -98,9 +113,9 @@ describe('useDropzone() hook', () => {
|
|
|
98
113
|
</div>
|
|
99
114
|
)}
|
|
100
115
|
</Dropzone>
|
|
101
|
-
)
|
|
116
|
+
);
|
|
102
117
|
|
|
103
|
-
expect(container.querySelector(
|
|
118
|
+
expect(container.querySelector("input")).not.toHaveAttribute("multiple");
|
|
104
119
|
|
|
105
120
|
rerender(
|
|
106
121
|
<Dropzone multiple>
|
|
@@ -110,13 +125,13 @@ describe('useDropzone() hook', () => {
|
|
|
110
125
|
</div>
|
|
111
126
|
)}
|
|
112
127
|
</Dropzone>
|
|
113
|
-
)
|
|
128
|
+
);
|
|
114
129
|
|
|
115
|
-
expect(container.querySelector(
|
|
116
|
-
})
|
|
130
|
+
expect(container.querySelector("input")).toHaveAttribute("multiple");
|
|
131
|
+
});
|
|
117
132
|
|
|
118
|
-
it(
|
|
119
|
-
const name =
|
|
133
|
+
it("sets any props passed to the input props getter on the <input>", () => {
|
|
134
|
+
const name = "dropzone-input";
|
|
120
135
|
const { container } = render(
|
|
121
136
|
<Dropzone multiple>
|
|
122
137
|
{({ getRootProps, getInputProps }) => (
|
|
@@ -125,31 +140,31 @@ describe('useDropzone() hook', () => {
|
|
|
125
140
|
</div>
|
|
126
141
|
)}
|
|
127
142
|
</Dropzone>
|
|
128
|
-
)
|
|
143
|
+
);
|
|
129
144
|
|
|
130
|
-
const input = container.querySelector(
|
|
131
|
-
expect(input).toHaveAttribute(
|
|
132
|
-
})
|
|
145
|
+
const input = container.querySelector("input");
|
|
146
|
+
expect(input).toHaveAttribute("name", name);
|
|
147
|
+
});
|
|
133
148
|
|
|
134
|
-
it(
|
|
135
|
-
const ariaLabel =
|
|
149
|
+
it("sets any props passed to the root props getter on the root node", () => {
|
|
150
|
+
const ariaLabel = "Dropzone area";
|
|
136
151
|
const { container } = render(
|
|
137
152
|
<Dropzone multiple>
|
|
138
153
|
{({ getRootProps, getInputProps }) => (
|
|
139
|
-
<div {...getRootProps({
|
|
154
|
+
<div {...getRootProps({ "aria-label": ariaLabel })}>
|
|
140
155
|
<input {...getInputProps()} />
|
|
141
156
|
</div>
|
|
142
157
|
)}
|
|
143
158
|
</Dropzone>
|
|
144
|
-
)
|
|
159
|
+
);
|
|
145
160
|
|
|
146
|
-
const dropzone = container.querySelector(
|
|
161
|
+
const dropzone = container.querySelector("div");
|
|
147
162
|
|
|
148
|
-
expect(dropzone).toHaveAttribute(
|
|
149
|
-
})
|
|
163
|
+
expect(dropzone).toHaveAttribute("aria-label", ariaLabel);
|
|
164
|
+
});
|
|
150
165
|
|
|
151
|
-
it(
|
|
152
|
-
const event = createDtWithFiles(files)
|
|
166
|
+
it("runs the custom callback handlers provided to the root props getter", async () => {
|
|
167
|
+
const event = createDtWithFiles(files);
|
|
153
168
|
|
|
154
169
|
const rootProps = {
|
|
155
170
|
onClick: jest.fn(),
|
|
@@ -159,8 +174,8 @@ describe('useDropzone() hook', () => {
|
|
|
159
174
|
onDragEnter: jest.fn(),
|
|
160
175
|
onDragOver: jest.fn(),
|
|
161
176
|
onDragLeave: jest.fn(),
|
|
162
|
-
onDrop: jest.fn()
|
|
163
|
-
}
|
|
177
|
+
onDrop: jest.fn(),
|
|
178
|
+
};
|
|
164
179
|
|
|
165
180
|
const ui = (
|
|
166
181
|
<Dropzone>
|
|
@@ -170,43 +185,43 @@ describe('useDropzone() hook', () => {
|
|
|
170
185
|
</div>
|
|
171
186
|
)}
|
|
172
187
|
</Dropzone>
|
|
173
|
-
)
|
|
188
|
+
);
|
|
174
189
|
|
|
175
|
-
const { container, rerender } = render(ui)
|
|
190
|
+
const { container, rerender } = render(ui);
|
|
176
191
|
|
|
177
|
-
const dropzone = container.querySelector(
|
|
192
|
+
const dropzone = container.querySelector("div");
|
|
178
193
|
|
|
179
|
-
fireEvent.click(dropzone)
|
|
180
|
-
expect(rootProps.onClick).toHaveBeenCalled()
|
|
194
|
+
fireEvent.click(dropzone);
|
|
195
|
+
expect(rootProps.onClick).toHaveBeenCalled();
|
|
181
196
|
|
|
182
|
-
fireEvent.focus(dropzone)
|
|
183
|
-
fireEvent.keyDown(dropzone)
|
|
184
|
-
expect(rootProps.onFocus).toHaveBeenCalled()
|
|
185
|
-
expect(rootProps.onKeyDown).toHaveBeenCalled()
|
|
197
|
+
fireEvent.focus(dropzone);
|
|
198
|
+
fireEvent.keyDown(dropzone);
|
|
199
|
+
expect(rootProps.onFocus).toHaveBeenCalled();
|
|
200
|
+
expect(rootProps.onKeyDown).toHaveBeenCalled();
|
|
186
201
|
|
|
187
|
-
fireEvent.blur(dropzone)
|
|
188
|
-
expect(rootProps.onBlur).toHaveBeenCalled()
|
|
202
|
+
fireEvent.blur(dropzone);
|
|
203
|
+
expect(rootProps.onBlur).toHaveBeenCalled();
|
|
189
204
|
|
|
190
|
-
fireEvent.dragEnter(dropzone, event)
|
|
191
|
-
await flushPromises(rerender, ui)
|
|
192
|
-
expect(rootProps.onDragEnter).toHaveBeenCalled()
|
|
205
|
+
fireEvent.dragEnter(dropzone, event);
|
|
206
|
+
await flushPromises(rerender, ui);
|
|
207
|
+
expect(rootProps.onDragEnter).toHaveBeenCalled();
|
|
193
208
|
|
|
194
|
-
fireEvent.dragOver(dropzone, event)
|
|
195
|
-
expect(rootProps.onDragOver).toHaveBeenCalled()
|
|
209
|
+
fireEvent.dragOver(dropzone, event);
|
|
210
|
+
expect(rootProps.onDragOver).toHaveBeenCalled();
|
|
196
211
|
|
|
197
|
-
fireEvent.dragLeave(dropzone, event)
|
|
198
|
-
expect(rootProps.onDragLeave).toHaveBeenCalled()
|
|
212
|
+
fireEvent.dragLeave(dropzone, event);
|
|
213
|
+
expect(rootProps.onDragLeave).toHaveBeenCalled();
|
|
199
214
|
|
|
200
|
-
fireEvent.drop(dropzone, event)
|
|
201
|
-
await flushPromises(rerender, ui)
|
|
202
|
-
expect(rootProps.onDrop).toHaveBeenCalled()
|
|
203
|
-
})
|
|
215
|
+
fireEvent.drop(dropzone, event);
|
|
216
|
+
await flushPromises(rerender, ui);
|
|
217
|
+
expect(rootProps.onDrop).toHaveBeenCalled();
|
|
218
|
+
});
|
|
204
219
|
|
|
205
|
-
it(
|
|
220
|
+
it("runs the custom callback handlers provided to the input props getter", async () => {
|
|
206
221
|
const inputProps = {
|
|
207
222
|
onClick: jest.fn(),
|
|
208
|
-
onChange: jest.fn()
|
|
209
|
-
}
|
|
223
|
+
onChange: jest.fn(),
|
|
224
|
+
};
|
|
210
225
|
|
|
211
226
|
const ui = (
|
|
212
227
|
<Dropzone>
|
|
@@ -216,23 +231,23 @@ describe('useDropzone() hook', () => {
|
|
|
216
231
|
</div>
|
|
217
232
|
)}
|
|
218
233
|
</Dropzone>
|
|
219
|
-
)
|
|
234
|
+
);
|
|
220
235
|
|
|
221
|
-
const { container, rerender } = render(ui)
|
|
236
|
+
const { container, rerender } = render(ui);
|
|
222
237
|
|
|
223
|
-
const input = container.querySelector(
|
|
238
|
+
const input = container.querySelector("input");
|
|
224
239
|
|
|
225
|
-
fireEvent.click(input)
|
|
226
|
-
await flushPromises(rerender, ui)
|
|
227
|
-
expect(inputProps.onClick).toHaveBeenCalled()
|
|
240
|
+
fireEvent.click(input);
|
|
241
|
+
await flushPromises(rerender, ui);
|
|
242
|
+
expect(inputProps.onClick).toHaveBeenCalled();
|
|
228
243
|
|
|
229
|
-
fireEvent.change(input)
|
|
230
|
-
await flushPromises(rerender, ui)
|
|
231
|
-
expect(inputProps.onChange).toHaveBeenCalled()
|
|
232
|
-
})
|
|
244
|
+
fireEvent.change(input);
|
|
245
|
+
await flushPromises(rerender, ui);
|
|
246
|
+
expect(inputProps.onChange).toHaveBeenCalled();
|
|
247
|
+
});
|
|
233
248
|
|
|
234
|
-
it(
|
|
235
|
-
const event = createDtWithFiles(files)
|
|
249
|
+
it("runs no callback handlers if {disabled} is true", () => {
|
|
250
|
+
const event = createDtWithFiles(files);
|
|
236
251
|
|
|
237
252
|
const rootProps = {
|
|
238
253
|
onClick: jest.fn(),
|
|
@@ -242,13 +257,13 @@ describe('useDropzone() hook', () => {
|
|
|
242
257
|
onDragEnter: jest.fn(),
|
|
243
258
|
onDragOver: jest.fn(),
|
|
244
259
|
onDragLeave: jest.fn(),
|
|
245
|
-
onDrop: jest.fn()
|
|
246
|
-
}
|
|
260
|
+
onDrop: jest.fn(),
|
|
261
|
+
};
|
|
247
262
|
|
|
248
263
|
const inputProps = {
|
|
249
264
|
onClick: jest.fn(),
|
|
250
|
-
onChange: jest.fn()
|
|
251
|
-
}
|
|
265
|
+
onChange: jest.fn(),
|
|
266
|
+
};
|
|
252
267
|
|
|
253
268
|
const { container } = render(
|
|
254
269
|
<Dropzone disabled>
|
|
@@ -258,59 +273,59 @@ describe('useDropzone() hook', () => {
|
|
|
258
273
|
</div>
|
|
259
274
|
)}
|
|
260
275
|
</Dropzone>
|
|
261
|
-
)
|
|
276
|
+
);
|
|
262
277
|
|
|
263
|
-
const dropzone = container.querySelector(
|
|
278
|
+
const dropzone = container.querySelector("div");
|
|
264
279
|
|
|
265
|
-
fireEvent.click(dropzone)
|
|
266
|
-
expect(rootProps.onClick).not.toHaveBeenCalled()
|
|
280
|
+
fireEvent.click(dropzone);
|
|
281
|
+
expect(rootProps.onClick).not.toHaveBeenCalled();
|
|
267
282
|
|
|
268
|
-
fireEvent.focus(dropzone)
|
|
269
|
-
fireEvent.keyDown(dropzone)
|
|
270
|
-
expect(rootProps.onFocus).not.toHaveBeenCalled()
|
|
271
|
-
expect(rootProps.onKeyDown).not.toHaveBeenCalled()
|
|
283
|
+
fireEvent.focus(dropzone);
|
|
284
|
+
fireEvent.keyDown(dropzone);
|
|
285
|
+
expect(rootProps.onFocus).not.toHaveBeenCalled();
|
|
286
|
+
expect(rootProps.onKeyDown).not.toHaveBeenCalled();
|
|
272
287
|
|
|
273
|
-
fireEvent.blur(dropzone)
|
|
274
|
-
expect(rootProps.onBlur).not.toHaveBeenCalled()
|
|
288
|
+
fireEvent.blur(dropzone);
|
|
289
|
+
expect(rootProps.onBlur).not.toHaveBeenCalled();
|
|
275
290
|
|
|
276
|
-
fireEvent.dragEnter(dropzone, event)
|
|
277
|
-
expect(rootProps.onDragEnter).not.toHaveBeenCalled()
|
|
291
|
+
fireEvent.dragEnter(dropzone, event);
|
|
292
|
+
expect(rootProps.onDragEnter).not.toHaveBeenCalled();
|
|
278
293
|
|
|
279
|
-
fireEvent.dragOver(dropzone, event)
|
|
280
|
-
expect(rootProps.onDragOver).not.toHaveBeenCalled()
|
|
294
|
+
fireEvent.dragOver(dropzone, event);
|
|
295
|
+
expect(rootProps.onDragOver).not.toHaveBeenCalled();
|
|
281
296
|
|
|
282
|
-
fireEvent.dragLeave(dropzone, event)
|
|
283
|
-
expect(rootProps.onDragLeave).not.toHaveBeenCalled()
|
|
297
|
+
fireEvent.dragLeave(dropzone, event);
|
|
298
|
+
expect(rootProps.onDragLeave).not.toHaveBeenCalled();
|
|
284
299
|
|
|
285
|
-
fireEvent.drop(dropzone, event)
|
|
286
|
-
expect(rootProps.onDrop).not.toHaveBeenCalled()
|
|
300
|
+
fireEvent.drop(dropzone, event);
|
|
301
|
+
expect(rootProps.onDrop).not.toHaveBeenCalled();
|
|
287
302
|
|
|
288
|
-
const input = container.querySelector(
|
|
303
|
+
const input = container.querySelector("input");
|
|
289
304
|
|
|
290
|
-
fireEvent.click(input)
|
|
291
|
-
expect(inputProps.onClick).not.toHaveBeenCalled()
|
|
305
|
+
fireEvent.click(input);
|
|
306
|
+
expect(inputProps.onClick).not.toHaveBeenCalled();
|
|
292
307
|
|
|
293
|
-
fireEvent.change(input)
|
|
294
|
-
expect(inputProps.onChange).not.toHaveBeenCalled()
|
|
295
|
-
})
|
|
308
|
+
fireEvent.change(input);
|
|
309
|
+
expect(inputProps.onChange).not.toHaveBeenCalled();
|
|
310
|
+
});
|
|
296
311
|
|
|
297
|
-
test(
|
|
298
|
-
const { result } = renderHook(() => useDropzone())
|
|
299
|
-
const { rootRef, inputRef, getRootProps, getInputProps } = result.current
|
|
312
|
+
test("{rootRef, inputRef} are exposed", () => {
|
|
313
|
+
const { result } = renderHook(() => useDropzone());
|
|
314
|
+
const { rootRef, inputRef, getRootProps, getInputProps } = result.current;
|
|
300
315
|
|
|
301
316
|
const { container } = render(
|
|
302
317
|
<div {...getRootProps()}>
|
|
303
318
|
<input {...getInputProps()} />
|
|
304
319
|
</div>
|
|
305
|
-
)
|
|
320
|
+
);
|
|
306
321
|
|
|
307
|
-
expect(container.querySelector(
|
|
308
|
-
expect(container.querySelector(
|
|
309
|
-
})
|
|
322
|
+
expect(container.querySelector("div")).toEqual(rootRef.current);
|
|
323
|
+
expect(container.querySelector("input")).toEqual(inputRef.current);
|
|
324
|
+
});
|
|
310
325
|
|
|
311
|
-
test(
|
|
312
|
-
const dropzoneRef = createRef()
|
|
313
|
-
const onClickSpy = jest.spyOn(HTMLInputElement.prototype,
|
|
326
|
+
test("<Dropzone> exposes and sets the ref if using a ref object", () => {
|
|
327
|
+
const dropzoneRef = createRef();
|
|
328
|
+
const onClickSpy = jest.spyOn(HTMLInputElement.prototype, "click");
|
|
314
329
|
|
|
315
330
|
const ui = (
|
|
316
331
|
<Dropzone ref={dropzoneRef}>
|
|
@@ -321,25 +336,25 @@ describe('useDropzone() hook', () => {
|
|
|
321
336
|
</div>
|
|
322
337
|
)}
|
|
323
338
|
</Dropzone>
|
|
324
|
-
)
|
|
339
|
+
);
|
|
325
340
|
|
|
326
|
-
const { rerender } = render(ui)
|
|
341
|
+
const { rerender } = render(ui);
|
|
327
342
|
|
|
328
|
-
expect(dropzoneRef.current).not.toBeNull()
|
|
329
|
-
expect(typeof dropzoneRef.current.open).toEqual(
|
|
343
|
+
expect(dropzoneRef.current).not.toBeNull();
|
|
344
|
+
expect(typeof dropzoneRef.current.open).toEqual("function");
|
|
330
345
|
|
|
331
|
-
act(() => dropzoneRef.current.open())
|
|
332
|
-
expect(onClickSpy).toHaveBeenCalled()
|
|
346
|
+
act(() => dropzoneRef.current.open());
|
|
347
|
+
expect(onClickSpy).toHaveBeenCalled();
|
|
333
348
|
|
|
334
|
-
rerender(null)
|
|
349
|
+
rerender(null);
|
|
335
350
|
|
|
336
|
-
expect(dropzoneRef.current).toBeNull()
|
|
337
|
-
})
|
|
351
|
+
expect(dropzoneRef.current).toBeNull();
|
|
352
|
+
});
|
|
338
353
|
|
|
339
|
-
test(
|
|
340
|
-
let dropzoneRef
|
|
341
|
-
const setRef = ref => (dropzoneRef = ref)
|
|
342
|
-
const onClickSpy = jest.spyOn(HTMLInputElement.prototype,
|
|
354
|
+
test("<Dropzone> exposes and sets the ref if using a ref fn", () => {
|
|
355
|
+
let dropzoneRef;
|
|
356
|
+
const setRef = (ref) => (dropzoneRef = ref);
|
|
357
|
+
const onClickSpy = jest.spyOn(HTMLInputElement.prototype, "click");
|
|
343
358
|
|
|
344
359
|
const ui = (
|
|
345
360
|
<Dropzone ref={setRef}>
|
|
@@ -350,22 +365,22 @@ describe('useDropzone() hook', () => {
|
|
|
350
365
|
</div>
|
|
351
366
|
)}
|
|
352
367
|
</Dropzone>
|
|
353
|
-
)
|
|
368
|
+
);
|
|
354
369
|
|
|
355
|
-
const { rerender } = render(ui)
|
|
370
|
+
const { rerender } = render(ui);
|
|
356
371
|
|
|
357
|
-
expect(dropzoneRef).not.toBeNull()
|
|
358
|
-
expect(typeof dropzoneRef.open).toEqual(
|
|
372
|
+
expect(dropzoneRef).not.toBeNull();
|
|
373
|
+
expect(typeof dropzoneRef.open).toEqual("function");
|
|
359
374
|
|
|
360
|
-
act(() => dropzoneRef.open())
|
|
361
|
-
expect(onClickSpy).toHaveBeenCalled()
|
|
375
|
+
act(() => dropzoneRef.open());
|
|
376
|
+
expect(onClickSpy).toHaveBeenCalled();
|
|
362
377
|
|
|
363
|
-
rerender(null)
|
|
364
|
-
expect(dropzoneRef).toBeNull()
|
|
365
|
-
})
|
|
378
|
+
rerender(null);
|
|
379
|
+
expect(dropzoneRef).toBeNull();
|
|
380
|
+
});
|
|
366
381
|
|
|
367
382
|
test("<Dropzone> doesn't invoke the ref fn if it hasn't changed", () => {
|
|
368
|
-
const setRef = jest.fn()
|
|
383
|
+
const setRef = jest.fn();
|
|
369
384
|
|
|
370
385
|
const { rerender } = render(
|
|
371
386
|
<Dropzone ref={setRef}>
|
|
@@ -375,16 +390,18 @@ describe('useDropzone() hook', () => {
|
|
|
375
390
|
</div>
|
|
376
391
|
)}
|
|
377
392
|
</Dropzone>
|
|
378
|
-
)
|
|
393
|
+
);
|
|
379
394
|
|
|
380
395
|
rerender(
|
|
381
|
-
<Dropzone ref={setRef}>
|
|
382
|
-
|
|
396
|
+
<Dropzone ref={setRef}>
|
|
397
|
+
{({ getRootProps }) => <div {...getRootProps()} />}
|
|
398
|
+
</Dropzone>
|
|
399
|
+
);
|
|
383
400
|
|
|
384
|
-
expect(setRef).toHaveBeenCalledTimes(1)
|
|
385
|
-
})
|
|
401
|
+
expect(setRef).toHaveBeenCalledTimes(1);
|
|
402
|
+
});
|
|
386
403
|
|
|
387
|
-
it(
|
|
404
|
+
it("sets {isFocused} to false if {disabled} is true", () => {
|
|
388
405
|
const { container, rerender } = render(
|
|
389
406
|
<Dropzone>
|
|
390
407
|
{({ getRootProps, getInputProps, isFocused }) => (
|
|
@@ -394,12 +411,12 @@ describe('useDropzone() hook', () => {
|
|
|
394
411
|
</div>
|
|
395
412
|
)}
|
|
396
413
|
</Dropzone>
|
|
397
|
-
)
|
|
414
|
+
);
|
|
398
415
|
|
|
399
|
-
const dropzone = container.querySelector(
|
|
416
|
+
const dropzone = container.querySelector("div");
|
|
400
417
|
|
|
401
|
-
fireEvent.focus(dropzone)
|
|
402
|
-
expect(dropzone.querySelector(
|
|
418
|
+
fireEvent.focus(dropzone);
|
|
419
|
+
expect(dropzone.querySelector("#focus")).not.toBeNull();
|
|
403
420
|
|
|
404
421
|
rerender(
|
|
405
422
|
<Dropzone disabled>
|
|
@@ -410,12 +427,12 @@ describe('useDropzone() hook', () => {
|
|
|
410
427
|
</div>
|
|
411
428
|
)}
|
|
412
429
|
</Dropzone>
|
|
413
|
-
)
|
|
430
|
+
);
|
|
414
431
|
|
|
415
|
-
expect(dropzone.querySelector(
|
|
416
|
-
})
|
|
432
|
+
expect(dropzone.querySelector("#focus")).toBeNull();
|
|
433
|
+
});
|
|
417
434
|
|
|
418
|
-
test(
|
|
435
|
+
test("{tabindex} is 0 if {disabled} is false", () => {
|
|
419
436
|
const { container } = render(
|
|
420
437
|
<Dropzone>
|
|
421
438
|
{({ getRootProps, getInputProps }) => (
|
|
@@ -424,11 +441,11 @@ describe('useDropzone() hook', () => {
|
|
|
424
441
|
</div>
|
|
425
442
|
)}
|
|
426
443
|
</Dropzone>
|
|
427
|
-
)
|
|
428
|
-
expect(container.querySelector(
|
|
429
|
-
})
|
|
444
|
+
);
|
|
445
|
+
expect(container.querySelector("div")).toHaveAttribute("tabindex", "0");
|
|
446
|
+
});
|
|
430
447
|
|
|
431
|
-
test(
|
|
448
|
+
test("{tabindex} is not set if {disabled} is true", () => {
|
|
432
449
|
const { container, rerender } = render(
|
|
433
450
|
<Dropzone>
|
|
434
451
|
{({ getRootProps, getInputProps }) => (
|
|
@@ -437,9 +454,9 @@ describe('useDropzone() hook', () => {
|
|
|
437
454
|
</div>
|
|
438
455
|
)}
|
|
439
456
|
</Dropzone>
|
|
440
|
-
)
|
|
457
|
+
);
|
|
441
458
|
|
|
442
|
-
expect(container.querySelector(
|
|
459
|
+
expect(container.querySelector("div")).toHaveAttribute("tabindex", "0");
|
|
443
460
|
|
|
444
461
|
rerender(
|
|
445
462
|
<Dropzone disabled>
|
|
@@ -449,12 +466,12 @@ describe('useDropzone() hook', () => {
|
|
|
449
466
|
</div>
|
|
450
467
|
)}
|
|
451
468
|
</Dropzone>
|
|
452
|
-
)
|
|
469
|
+
);
|
|
453
470
|
|
|
454
|
-
expect(container.querySelector(
|
|
455
|
-
})
|
|
471
|
+
expect(container.querySelector("div")).not.toHaveAttribute("tabindex");
|
|
472
|
+
});
|
|
456
473
|
|
|
457
|
-
test(
|
|
474
|
+
test("{tabindex} is not set if {noKeyboard} is true", () => {
|
|
458
475
|
const { container, rerender } = render(
|
|
459
476
|
<Dropzone>
|
|
460
477
|
{({ getRootProps, getInputProps }) => (
|
|
@@ -463,9 +480,9 @@ describe('useDropzone() hook', () => {
|
|
|
463
480
|
</div>
|
|
464
481
|
)}
|
|
465
482
|
</Dropzone>
|
|
466
|
-
)
|
|
483
|
+
);
|
|
467
484
|
|
|
468
|
-
expect(container.querySelector(
|
|
485
|
+
expect(container.querySelector("div")).toHaveAttribute("tabindex", "0");
|
|
469
486
|
|
|
470
487
|
rerender(
|
|
471
488
|
<Dropzone noKeyboard>
|
|
@@ -475,51 +492,51 @@ describe('useDropzone() hook', () => {
|
|
|
475
492
|
</div>
|
|
476
493
|
)}
|
|
477
494
|
</Dropzone>
|
|
478
|
-
)
|
|
495
|
+
);
|
|
479
496
|
|
|
480
|
-
expect(container.querySelector(
|
|
481
|
-
})
|
|
497
|
+
expect(container.querySelector("div")).not.toHaveAttribute("tabindex");
|
|
498
|
+
});
|
|
482
499
|
|
|
483
|
-
test(
|
|
484
|
-
const data = createDtWithFiles(files)
|
|
500
|
+
test("refs are set when {refKey} is set to a different value", (done) => {
|
|
501
|
+
const data = createDtWithFiles(files);
|
|
485
502
|
|
|
486
503
|
class MyView extends React.Component {
|
|
487
504
|
render() {
|
|
488
|
-
const { children, innerRef, ...rest } = this.props
|
|
505
|
+
const { children, innerRef, ...rest } = this.props;
|
|
489
506
|
return (
|
|
490
507
|
<div id="dropzone" ref={innerRef} {...rest}>
|
|
491
508
|
<div>{children}</div>
|
|
492
509
|
</div>
|
|
493
|
-
)
|
|
510
|
+
);
|
|
494
511
|
}
|
|
495
512
|
}
|
|
496
513
|
|
|
497
514
|
const ui = (
|
|
498
515
|
<Dropzone>
|
|
499
516
|
{({ getRootProps }) => (
|
|
500
|
-
<MyView {...getRootProps({ refKey:
|
|
517
|
+
<MyView {...getRootProps({ refKey: "innerRef" })}>
|
|
501
518
|
<span>Drop some files here ...</span>
|
|
502
519
|
</MyView>
|
|
503
520
|
)}
|
|
504
521
|
</Dropzone>
|
|
505
|
-
)
|
|
522
|
+
);
|
|
506
523
|
|
|
507
|
-
const { container, rerender } = render(ui)
|
|
508
|
-
const dropzone = container.querySelector(
|
|
524
|
+
const { container, rerender } = render(ui);
|
|
525
|
+
const dropzone = container.querySelector("#dropzone");
|
|
509
526
|
|
|
510
527
|
const fn = async () => {
|
|
511
|
-
fireDrop(dropzone, data)
|
|
512
|
-
await flushPromises(rerender, ui)
|
|
513
|
-
done()
|
|
514
|
-
}
|
|
528
|
+
fireDrop(dropzone, data);
|
|
529
|
+
await flushPromises(rerender, ui);
|
|
530
|
+
done();
|
|
531
|
+
};
|
|
515
532
|
|
|
516
|
-
expect(fn).not.toThrow()
|
|
517
|
-
})
|
|
533
|
+
expect(fn).not.toThrow();
|
|
534
|
+
});
|
|
518
535
|
|
|
519
|
-
test(
|
|
520
|
-
const activeRef = createRef()
|
|
521
|
-
const active = <span ref={activeRef}>I am active</span
|
|
522
|
-
const onClickSpy = jest.spyOn(HTMLInputElement.prototype,
|
|
536
|
+
test("click events originating from <label> should not trigger file dialog open twice", () => {
|
|
537
|
+
const activeRef = createRef();
|
|
538
|
+
const active = <span ref={activeRef}>I am active</span>;
|
|
539
|
+
const onClickSpy = jest.spyOn(HTMLInputElement.prototype, "click");
|
|
523
540
|
|
|
524
541
|
const { container } = render(
|
|
525
542
|
<Dropzone>
|
|
@@ -530,35 +547,35 @@ describe('useDropzone() hook', () => {
|
|
|
530
547
|
</label>
|
|
531
548
|
)}
|
|
532
549
|
</Dropzone>
|
|
533
|
-
)
|
|
550
|
+
);
|
|
534
551
|
|
|
535
|
-
const dropzone = container.querySelector(
|
|
552
|
+
const dropzone = container.querySelector("label");
|
|
536
553
|
|
|
537
|
-
const event = new Event(
|
|
554
|
+
const event = new Event("click", { bubbles: true, cancelable: true });
|
|
538
555
|
|
|
539
|
-
fireEvent(dropzone, event)
|
|
556
|
+
fireEvent(dropzone, event);
|
|
540
557
|
|
|
541
|
-
const ref = activeRef.current
|
|
542
|
-
expect(ref).not.toBeNull()
|
|
543
|
-
expect(dropzone).toContainElement(ref)
|
|
544
|
-
expect(onClickSpy).toHaveBeenCalledTimes(1)
|
|
545
|
-
})
|
|
546
|
-
})
|
|
558
|
+
const ref = activeRef.current;
|
|
559
|
+
expect(ref).not.toBeNull();
|
|
560
|
+
expect(dropzone).toContainElement(ref);
|
|
561
|
+
expect(onClickSpy).toHaveBeenCalledTimes(1);
|
|
562
|
+
});
|
|
563
|
+
});
|
|
547
564
|
|
|
548
|
-
describe(
|
|
549
|
-
const addEventListenerSpy = jest.spyOn(document,
|
|
550
|
-
const removeEventListenerSpy = jest.spyOn(document,
|
|
565
|
+
describe("document drop protection", () => {
|
|
566
|
+
const addEventListenerSpy = jest.spyOn(document, "addEventListener");
|
|
567
|
+
const removeEventListenerSpy = jest.spyOn(document, "removeEventListener");
|
|
551
568
|
// Collect the list of addEventListener/removeEventListener spy calls into an object keyed by event name
|
|
552
|
-
const collectEventListenerCalls = spy =>
|
|
569
|
+
const collectEventListenerCalls = (spy) =>
|
|
553
570
|
spy.mock.calls.reduce(
|
|
554
571
|
(acc, [eventName, ...rest]) => ({
|
|
555
572
|
...acc,
|
|
556
|
-
[eventName]: rest
|
|
573
|
+
[eventName]: rest,
|
|
557
574
|
}),
|
|
558
575
|
{}
|
|
559
|
-
)
|
|
576
|
+
);
|
|
560
577
|
|
|
561
|
-
it(
|
|
578
|
+
it("installs hooks to prevent stray drops from taking over the browser window", () => {
|
|
562
579
|
render(
|
|
563
580
|
<Dropzone>
|
|
564
581
|
{({ getRootProps, getInputProps }) => (
|
|
@@ -567,24 +584,24 @@ describe('useDropzone() hook', () => {
|
|
|
567
584
|
</div>
|
|
568
585
|
)}
|
|
569
586
|
</Dropzone>
|
|
570
|
-
)
|
|
587
|
+
);
|
|
571
588
|
|
|
572
|
-
expect(addEventListenerSpy).toHaveBeenCalledTimes(2)
|
|
589
|
+
expect(addEventListenerSpy).toHaveBeenCalledTimes(2);
|
|
573
590
|
|
|
574
|
-
const addEventCalls = collectEventListenerCalls(addEventListenerSpy)
|
|
575
|
-
const events = Object.keys(addEventCalls)
|
|
591
|
+
const addEventCalls = collectEventListenerCalls(addEventListenerSpy);
|
|
592
|
+
const events = Object.keys(addEventCalls);
|
|
576
593
|
|
|
577
|
-
expect(events).toContain(
|
|
578
|
-
expect(events).toContain(
|
|
594
|
+
expect(events).toContain("dragover");
|
|
595
|
+
expect(events).toContain("drop");
|
|
579
596
|
|
|
580
|
-
events.forEach(eventName => {
|
|
581
|
-
const [fn, options] = addEventCalls[eventName]
|
|
582
|
-
expect(fn).toBeDefined()
|
|
583
|
-
expect(options).toBe(false)
|
|
584
|
-
})
|
|
585
|
-
})
|
|
597
|
+
events.forEach((eventName) => {
|
|
598
|
+
const [fn, options] = addEventCalls[eventName];
|
|
599
|
+
expect(fn).toBeDefined();
|
|
600
|
+
expect(options).toBe(false);
|
|
601
|
+
});
|
|
602
|
+
});
|
|
586
603
|
|
|
587
|
-
it(
|
|
604
|
+
it("removes document hooks when unmounted", () => {
|
|
588
605
|
const { unmount } = render(
|
|
589
606
|
<Dropzone>
|
|
590
607
|
{({ getRootProps, getInputProps }) => (
|
|
@@ -593,27 +610,29 @@ describe('useDropzone() hook', () => {
|
|
|
593
610
|
</div>
|
|
594
611
|
)}
|
|
595
612
|
</Dropzone>
|
|
596
|
-
)
|
|
613
|
+
);
|
|
597
614
|
|
|
598
|
-
unmount()
|
|
615
|
+
unmount();
|
|
599
616
|
|
|
600
|
-
expect(removeEventListenerSpy).toHaveBeenCalledTimes(2)
|
|
617
|
+
expect(removeEventListenerSpy).toHaveBeenCalledTimes(2);
|
|
601
618
|
|
|
602
|
-
const addEventCalls = collectEventListenerCalls(addEventListenerSpy)
|
|
603
|
-
const removeEventCalls = collectEventListenerCalls(
|
|
604
|
-
|
|
619
|
+
const addEventCalls = collectEventListenerCalls(addEventListenerSpy);
|
|
620
|
+
const removeEventCalls = collectEventListenerCalls(
|
|
621
|
+
removeEventListenerSpy
|
|
622
|
+
);
|
|
623
|
+
const events = Object.keys(removeEventCalls);
|
|
605
624
|
|
|
606
|
-
expect(events).toContain(
|
|
607
|
-
expect(events).toContain(
|
|
625
|
+
expect(events).toContain("dragover");
|
|
626
|
+
expect(events).toContain("drop");
|
|
608
627
|
|
|
609
|
-
events.forEach(eventName => {
|
|
610
|
-
const [a] = addEventCalls[eventName]
|
|
611
|
-
const [b] = removeEventCalls[eventName]
|
|
612
|
-
expect(a).toEqual(b)
|
|
613
|
-
})
|
|
614
|
-
})
|
|
628
|
+
events.forEach((eventName) => {
|
|
629
|
+
const [a] = addEventCalls[eventName];
|
|
630
|
+
const [b] = removeEventCalls[eventName];
|
|
631
|
+
expect(a).toEqual(b);
|
|
632
|
+
});
|
|
633
|
+
});
|
|
615
634
|
|
|
616
|
-
it(
|
|
635
|
+
it("terminates drags and drops on elements outside our dropzone", () => {
|
|
617
636
|
render(
|
|
618
637
|
<Dropzone>
|
|
619
638
|
{({ getRootProps, getInputProps }) => (
|
|
@@ -622,20 +641,20 @@ describe('useDropzone() hook', () => {
|
|
|
622
641
|
</div>
|
|
623
642
|
)}
|
|
624
643
|
</Dropzone>
|
|
625
|
-
)
|
|
644
|
+
);
|
|
626
645
|
|
|
627
|
-
const dragEvt = new Event(
|
|
628
|
-
const dragEvtPreventDefaultSpy = jest.spyOn(dragEvt,
|
|
629
|
-
fireEvent(document.body, dragEvt)
|
|
630
|
-
expect(dragEvtPreventDefaultSpy).toHaveBeenCalled()
|
|
646
|
+
const dragEvt = new Event("dragover", { bubbles: true });
|
|
647
|
+
const dragEvtPreventDefaultSpy = jest.spyOn(dragEvt, "preventDefault");
|
|
648
|
+
fireEvent(document.body, dragEvt);
|
|
649
|
+
expect(dragEvtPreventDefaultSpy).toHaveBeenCalled();
|
|
631
650
|
|
|
632
|
-
const dropEvt = new Event(
|
|
633
|
-
const dropEvtPreventDefaultSpy = jest.spyOn(dropEvt,
|
|
634
|
-
fireEvent(document.body, dropEvt)
|
|
635
|
-
expect(dropEvtPreventDefaultSpy).toHaveBeenCalled()
|
|
636
|
-
})
|
|
651
|
+
const dropEvt = new Event("drop", { bubbles: true });
|
|
652
|
+
const dropEvtPreventDefaultSpy = jest.spyOn(dropEvt, "preventDefault");
|
|
653
|
+
fireEvent(document.body, dropEvt);
|
|
654
|
+
expect(dropEvtPreventDefaultSpy).toHaveBeenCalled();
|
|
655
|
+
});
|
|
637
656
|
|
|
638
|
-
it(
|
|
657
|
+
it("permits drags and drops on elements inside our dropzone", () => {
|
|
639
658
|
const { container } = render(
|
|
640
659
|
<Dropzone>
|
|
641
660
|
{({ getRootProps, getInputProps }) => (
|
|
@@ -644,19 +663,19 @@ describe('useDropzone() hook', () => {
|
|
|
644
663
|
</div>
|
|
645
664
|
)}
|
|
646
665
|
</Dropzone>
|
|
647
|
-
)
|
|
648
|
-
const dropzone = container.querySelector(
|
|
666
|
+
);
|
|
667
|
+
const dropzone = container.querySelector("div");
|
|
649
668
|
|
|
650
|
-
const dropEvt = new Event(
|
|
651
|
-
const dropEvtPreventDefaultSpy = jest.spyOn(dropEvt,
|
|
669
|
+
const dropEvt = new Event("drop", { bubbles: true });
|
|
670
|
+
const dropEvtPreventDefaultSpy = jest.spyOn(dropEvt, "preventDefault");
|
|
652
671
|
|
|
653
|
-
fireEvent(dropzone, dropEvt)
|
|
672
|
+
fireEvent(dropzone, dropEvt);
|
|
654
673
|
// A call is from the onDrop handler for the dropzone,
|
|
655
674
|
// but there should be no more than 1
|
|
656
|
-
expect(dropEvtPreventDefaultSpy).toHaveBeenCalled()
|
|
657
|
-
})
|
|
675
|
+
expect(dropEvtPreventDefaultSpy).toHaveBeenCalled();
|
|
676
|
+
});
|
|
658
677
|
|
|
659
|
-
it(
|
|
678
|
+
it("does not prevent stray drops when {preventDropOnDocument} is false", () => {
|
|
660
679
|
render(
|
|
661
680
|
<Dropzone preventDropOnDocument={false}>
|
|
662
681
|
{({ getRootProps, getInputProps }) => (
|
|
@@ -665,25 +684,25 @@ describe('useDropzone() hook', () => {
|
|
|
665
684
|
</div>
|
|
666
685
|
)}
|
|
667
686
|
</Dropzone>
|
|
668
|
-
)
|
|
687
|
+
);
|
|
669
688
|
|
|
670
|
-
const dropEvt = new Event(
|
|
671
|
-
const dropEvtPreventDefaultSpy = jest.spyOn(dropEvt,
|
|
672
|
-
fireEvent(document.body, dropEvt)
|
|
673
|
-
expect(dropEvtPreventDefaultSpy).toHaveBeenCalledTimes(0)
|
|
674
|
-
})
|
|
675
|
-
})
|
|
689
|
+
const dropEvt = new Event("drop", { bubbles: true });
|
|
690
|
+
const dropEvtPreventDefaultSpy = jest.spyOn(dropEvt, "preventDefault");
|
|
691
|
+
fireEvent(document.body, dropEvt);
|
|
692
|
+
expect(dropEvtPreventDefaultSpy).toHaveBeenCalledTimes(0);
|
|
693
|
+
});
|
|
694
|
+
});
|
|
676
695
|
|
|
677
|
-
describe(
|
|
678
|
-
const data = createDtWithFiles(files)
|
|
696
|
+
describe("event propagation", () => {
|
|
697
|
+
const data = createDtWithFiles(files);
|
|
679
698
|
|
|
680
|
-
test(
|
|
699
|
+
test("drag events propagate from the inner dropzone to parents", async () => {
|
|
681
700
|
const innerProps = {
|
|
682
701
|
onDragEnter: jest.fn(),
|
|
683
702
|
onDragOver: jest.fn(),
|
|
684
703
|
onDragLeave: jest.fn(),
|
|
685
|
-
onDrop: jest.fn()
|
|
686
|
-
}
|
|
704
|
+
onDrop: jest.fn(),
|
|
705
|
+
};
|
|
687
706
|
|
|
688
707
|
const InnerDropzone = () => (
|
|
689
708
|
<Dropzone {...innerProps}>
|
|
@@ -693,14 +712,14 @@ describe('useDropzone() hook', () => {
|
|
|
693
712
|
</div>
|
|
694
713
|
)}
|
|
695
714
|
</Dropzone>
|
|
696
|
-
)
|
|
715
|
+
);
|
|
697
716
|
|
|
698
717
|
const parentProps = {
|
|
699
718
|
onDragEnter: jest.fn(),
|
|
700
719
|
onDragOver: jest.fn(),
|
|
701
720
|
onDragLeave: jest.fn(),
|
|
702
|
-
onDrop: jest.fn()
|
|
703
|
-
}
|
|
721
|
+
onDrop: jest.fn(),
|
|
722
|
+
};
|
|
704
723
|
|
|
705
724
|
const ui = (
|
|
706
725
|
<Dropzone {...parentProps}>
|
|
@@ -711,45 +730,45 @@ describe('useDropzone() hook', () => {
|
|
|
711
730
|
</div>
|
|
712
731
|
)}
|
|
713
732
|
</Dropzone>
|
|
714
|
-
)
|
|
733
|
+
);
|
|
715
734
|
|
|
716
|
-
const { container, rerender } = render(ui)
|
|
735
|
+
const { container, rerender } = render(ui);
|
|
717
736
|
|
|
718
|
-
const innerDropzone = container.querySelector(
|
|
737
|
+
const innerDropzone = container.querySelector("#inner-dropzone");
|
|
719
738
|
|
|
720
|
-
fireDragEnter(innerDropzone, data)
|
|
721
|
-
await flushPromises(rerender, ui)
|
|
722
|
-
expect(innerProps.onDragEnter).toHaveBeenCalled()
|
|
723
|
-
expect(parentProps.onDragEnter).toHaveBeenCalled()
|
|
739
|
+
fireDragEnter(innerDropzone, data);
|
|
740
|
+
await flushPromises(rerender, ui);
|
|
741
|
+
expect(innerProps.onDragEnter).toHaveBeenCalled();
|
|
742
|
+
expect(parentProps.onDragEnter).toHaveBeenCalled();
|
|
724
743
|
|
|
725
|
-
fireDragOver(innerDropzone, data)
|
|
726
|
-
expect(innerProps.onDragOver).toHaveBeenCalled()
|
|
727
|
-
expect(parentProps.onDragOver).toHaveBeenCalled()
|
|
744
|
+
fireDragOver(innerDropzone, data);
|
|
745
|
+
expect(innerProps.onDragOver).toHaveBeenCalled();
|
|
746
|
+
expect(parentProps.onDragOver).toHaveBeenCalled();
|
|
728
747
|
|
|
729
|
-
fireDragLeave(innerDropzone, data)
|
|
730
|
-
expect(innerProps.onDragLeave).toHaveBeenCalled()
|
|
731
|
-
expect(parentProps.onDragLeave).toHaveBeenCalled()
|
|
748
|
+
fireDragLeave(innerDropzone, data);
|
|
749
|
+
expect(innerProps.onDragLeave).toHaveBeenCalled();
|
|
750
|
+
expect(parentProps.onDragLeave).toHaveBeenCalled();
|
|
732
751
|
|
|
733
|
-
fireDrop(innerDropzone, data)
|
|
734
|
-
await flushPromises(rerender, ui)
|
|
735
|
-
expect(innerProps.onDrop).toHaveBeenCalled()
|
|
736
|
-
expect(parentProps.onDrop).toHaveBeenCalled()
|
|
737
|
-
})
|
|
752
|
+
fireDrop(innerDropzone, data);
|
|
753
|
+
await flushPromises(rerender, ui);
|
|
754
|
+
expect(innerProps.onDrop).toHaveBeenCalled();
|
|
755
|
+
expect(parentProps.onDrop).toHaveBeenCalled();
|
|
756
|
+
});
|
|
738
757
|
|
|
739
|
-
test(
|
|
758
|
+
test("drag events do not propagate from the inner dropzone to parent dropzone if user invoked stopPropagation() on the events", async () => {
|
|
740
759
|
const innerProps = {
|
|
741
760
|
onDragEnter: jest.fn(),
|
|
742
761
|
onDragOver: jest.fn(),
|
|
743
762
|
onDragLeave: jest.fn(),
|
|
744
|
-
onDrop: jest.fn()
|
|
745
|
-
}
|
|
763
|
+
onDrop: jest.fn(),
|
|
764
|
+
};
|
|
746
765
|
|
|
747
|
-
Object.keys(innerProps).forEach(prop =>
|
|
766
|
+
Object.keys(innerProps).forEach((prop) =>
|
|
748
767
|
innerProps[prop].mockImplementation((...args) => {
|
|
749
|
-
const event = prop ===
|
|
750
|
-
event.stopPropagation()
|
|
768
|
+
const event = prop === "onDrop" ? args.pop() : args.shift();
|
|
769
|
+
event.stopPropagation();
|
|
751
770
|
})
|
|
752
|
-
)
|
|
771
|
+
);
|
|
753
772
|
|
|
754
773
|
const InnerDropzone = () => (
|
|
755
774
|
<Dropzone {...innerProps}>
|
|
@@ -759,14 +778,14 @@ describe('useDropzone() hook', () => {
|
|
|
759
778
|
</div>
|
|
760
779
|
)}
|
|
761
780
|
</Dropzone>
|
|
762
|
-
)
|
|
781
|
+
);
|
|
763
782
|
|
|
764
783
|
const parentProps = {
|
|
765
784
|
onDragEnter: jest.fn(),
|
|
766
785
|
onDragOver: jest.fn(),
|
|
767
786
|
onDragLeave: jest.fn(),
|
|
768
|
-
onDrop: jest.fn()
|
|
769
|
-
}
|
|
787
|
+
onDrop: jest.fn(),
|
|
788
|
+
};
|
|
770
789
|
|
|
771
790
|
const ui = (
|
|
772
791
|
<Dropzone {...parentProps}>
|
|
@@ -777,38 +796,38 @@ describe('useDropzone() hook', () => {
|
|
|
777
796
|
</div>
|
|
778
797
|
)}
|
|
779
798
|
</Dropzone>
|
|
780
|
-
)
|
|
799
|
+
);
|
|
781
800
|
|
|
782
|
-
const { container, rerender } = render(ui)
|
|
801
|
+
const { container, rerender } = render(ui);
|
|
783
802
|
|
|
784
|
-
const innerDropzone = container.querySelector(
|
|
803
|
+
const innerDropzone = container.querySelector("#inner-dropzone");
|
|
785
804
|
|
|
786
|
-
fireDragEnter(innerDropzone, data)
|
|
787
|
-
await flushPromises(rerender, ui)
|
|
788
|
-
expect(innerProps.onDragEnter).toHaveBeenCalled()
|
|
789
|
-
expect(parentProps.onDragEnter).not.toHaveBeenCalled()
|
|
805
|
+
fireDragEnter(innerDropzone, data);
|
|
806
|
+
await flushPromises(rerender, ui);
|
|
807
|
+
expect(innerProps.onDragEnter).toHaveBeenCalled();
|
|
808
|
+
expect(parentProps.onDragEnter).not.toHaveBeenCalled();
|
|
790
809
|
|
|
791
|
-
fireDragOver(innerDropzone, data)
|
|
792
|
-
expect(innerProps.onDragOver).toHaveBeenCalled()
|
|
793
|
-
expect(parentProps.onDragOver).not.toHaveBeenCalled()
|
|
810
|
+
fireDragOver(innerDropzone, data);
|
|
811
|
+
expect(innerProps.onDragOver).toHaveBeenCalled();
|
|
812
|
+
expect(parentProps.onDragOver).not.toHaveBeenCalled();
|
|
794
813
|
|
|
795
|
-
fireDragLeave(innerDropzone, data)
|
|
796
|
-
expect(innerProps.onDragLeave).toHaveBeenCalled()
|
|
797
|
-
expect(parentProps.onDragLeave).not.toHaveBeenCalled()
|
|
814
|
+
fireDragLeave(innerDropzone, data);
|
|
815
|
+
expect(innerProps.onDragLeave).toHaveBeenCalled();
|
|
816
|
+
expect(parentProps.onDragLeave).not.toHaveBeenCalled();
|
|
798
817
|
|
|
799
|
-
fireDrop(innerDropzone, data)
|
|
800
|
-
await flushPromises(rerender, ui)
|
|
801
|
-
expect(innerProps.onDrop).toHaveBeenCalled()
|
|
802
|
-
expect(parentProps.onDrop).not.toHaveBeenCalled()
|
|
803
|
-
})
|
|
818
|
+
fireDrop(innerDropzone, data);
|
|
819
|
+
await flushPromises(rerender, ui);
|
|
820
|
+
expect(innerProps.onDrop).toHaveBeenCalled();
|
|
821
|
+
expect(parentProps.onDrop).not.toHaveBeenCalled();
|
|
822
|
+
});
|
|
804
823
|
|
|
805
|
-
test(
|
|
824
|
+
test("drag events do not propagate from the inner dropzone to parent dropzone if {noDragEventsBubbling} is true", async () => {
|
|
806
825
|
const innerProps = {
|
|
807
826
|
onDragEnter: jest.fn(),
|
|
808
827
|
onDragOver: jest.fn(),
|
|
809
828
|
onDragLeave: jest.fn(),
|
|
810
|
-
onDrop: jest.fn()
|
|
811
|
-
}
|
|
829
|
+
onDrop: jest.fn(),
|
|
830
|
+
};
|
|
812
831
|
|
|
813
832
|
const InnerDropzone = () => (
|
|
814
833
|
<Dropzone {...innerProps} noDragEventsBubbling>
|
|
@@ -818,14 +837,14 @@ describe('useDropzone() hook', () => {
|
|
|
818
837
|
</div>
|
|
819
838
|
)}
|
|
820
839
|
</Dropzone>
|
|
821
|
-
)
|
|
840
|
+
);
|
|
822
841
|
|
|
823
842
|
const parentProps = {
|
|
824
843
|
onDragEnter: jest.fn(),
|
|
825
844
|
onDragOver: jest.fn(),
|
|
826
845
|
onDragLeave: jest.fn(),
|
|
827
|
-
onDrop: jest.fn()
|
|
828
|
-
}
|
|
846
|
+
onDrop: jest.fn(),
|
|
847
|
+
};
|
|
829
848
|
|
|
830
849
|
const ui = (
|
|
831
850
|
<Dropzone {...parentProps}>
|
|
@@ -836,38 +855,38 @@ describe('useDropzone() hook', () => {
|
|
|
836
855
|
</div>
|
|
837
856
|
)}
|
|
838
857
|
</Dropzone>
|
|
839
|
-
)
|
|
858
|
+
);
|
|
840
859
|
|
|
841
|
-
const { container, rerender } = render(ui)
|
|
860
|
+
const { container, rerender } = render(ui);
|
|
842
861
|
|
|
843
|
-
const outerDropzone = container.querySelector(
|
|
844
|
-
const innerDropzone = container.querySelector(
|
|
862
|
+
const outerDropzone = container.querySelector("#outer-dropzone");
|
|
863
|
+
const innerDropzone = container.querySelector("#inner-dropzone");
|
|
845
864
|
|
|
846
865
|
// Sets drag targets on the outer dropzone
|
|
847
|
-
fireDragEnter(outerDropzone, data)
|
|
848
|
-
await flushPromises(rerender, ui)
|
|
849
|
-
|
|
850
|
-
fireDragEnter(innerDropzone, data)
|
|
851
|
-
await flushPromises(rerender, ui)
|
|
852
|
-
expect(innerProps.onDragEnter).toHaveBeenCalled()
|
|
853
|
-
expect(parentProps.onDragEnter).toHaveBeenCalledTimes(1)
|
|
854
|
-
|
|
855
|
-
fireDragOver(innerDropzone, data)
|
|
856
|
-
expect(innerProps.onDragOver).toHaveBeenCalled()
|
|
857
|
-
expect(parentProps.onDragOver).not.toHaveBeenCalled()
|
|
858
|
-
|
|
859
|
-
fireDragLeave(innerDropzone, data)
|
|
860
|
-
expect(innerProps.onDragLeave).toHaveBeenCalled()
|
|
861
|
-
expect(parentProps.onDragLeave).not.toHaveBeenCalled()
|
|
862
|
-
|
|
863
|
-
fireDrop(innerDropzone, data)
|
|
864
|
-
await flushPromises(rerender, ui)
|
|
865
|
-
expect(innerProps.onDrop).toHaveBeenCalled()
|
|
866
|
-
expect(parentProps.onDrop).not.toHaveBeenCalled()
|
|
867
|
-
})
|
|
868
|
-
|
|
869
|
-
test(
|
|
870
|
-
const innerDragLeave = jest.fn()
|
|
866
|
+
fireDragEnter(outerDropzone, data);
|
|
867
|
+
await flushPromises(rerender, ui);
|
|
868
|
+
|
|
869
|
+
fireDragEnter(innerDropzone, data);
|
|
870
|
+
await flushPromises(rerender, ui);
|
|
871
|
+
expect(innerProps.onDragEnter).toHaveBeenCalled();
|
|
872
|
+
expect(parentProps.onDragEnter).toHaveBeenCalledTimes(1);
|
|
873
|
+
|
|
874
|
+
fireDragOver(innerDropzone, data);
|
|
875
|
+
expect(innerProps.onDragOver).toHaveBeenCalled();
|
|
876
|
+
expect(parentProps.onDragOver).not.toHaveBeenCalled();
|
|
877
|
+
|
|
878
|
+
fireDragLeave(innerDropzone, data);
|
|
879
|
+
expect(innerProps.onDragLeave).toHaveBeenCalled();
|
|
880
|
+
expect(parentProps.onDragLeave).not.toHaveBeenCalled();
|
|
881
|
+
|
|
882
|
+
fireDrop(innerDropzone, data);
|
|
883
|
+
await flushPromises(rerender, ui);
|
|
884
|
+
expect(innerProps.onDrop).toHaveBeenCalled();
|
|
885
|
+
expect(parentProps.onDrop).not.toHaveBeenCalled();
|
|
886
|
+
});
|
|
887
|
+
|
|
888
|
+
test("onDragLeave is not invoked for the parent dropzone if it was invoked for an inner dropzone", async () => {
|
|
889
|
+
const innerDragLeave = jest.fn();
|
|
871
890
|
const InnerDropzone = () => (
|
|
872
891
|
<Dropzone onDragLeave={innerDragLeave}>
|
|
873
892
|
{({ getRootProps, getInputProps }) => (
|
|
@@ -876,9 +895,9 @@ describe('useDropzone() hook', () => {
|
|
|
876
895
|
</div>
|
|
877
896
|
)}
|
|
878
897
|
</Dropzone>
|
|
879
|
-
)
|
|
898
|
+
);
|
|
880
899
|
|
|
881
|
-
const parentDragLeave = jest.fn()
|
|
900
|
+
const parentDragLeave = jest.fn();
|
|
882
901
|
const ui = (
|
|
883
902
|
<Dropzone onDragLeave={parentDragLeave}>
|
|
884
903
|
{({ getRootProps, getInputProps }) => (
|
|
@@ -888,36 +907,38 @@ describe('useDropzone() hook', () => {
|
|
|
888
907
|
</div>
|
|
889
908
|
)}
|
|
890
909
|
</Dropzone>
|
|
891
|
-
)
|
|
910
|
+
);
|
|
892
911
|
|
|
893
|
-
const { container, rerender } = render(ui)
|
|
912
|
+
const { container, rerender } = render(ui);
|
|
894
913
|
|
|
895
|
-
const parentDropzone = container.querySelector(
|
|
914
|
+
const parentDropzone = container.querySelector("#parent-dropzone");
|
|
896
915
|
|
|
897
|
-
fireDragEnter(parentDropzone, data)
|
|
898
|
-
await flushPromises(rerender, ui)
|
|
916
|
+
fireDragEnter(parentDropzone, data);
|
|
917
|
+
await flushPromises(rerender, ui);
|
|
899
918
|
|
|
900
|
-
const innerDropzone = container.querySelector(
|
|
901
|
-
fireDragEnter(innerDropzone, data)
|
|
902
|
-
await flushPromises(rerender, ui)
|
|
919
|
+
const innerDropzone = container.querySelector("#inner-dropzone");
|
|
920
|
+
fireDragEnter(innerDropzone, data);
|
|
921
|
+
await flushPromises(rerender, ui);
|
|
903
922
|
|
|
904
|
-
fireDragLeave(innerDropzone, data)
|
|
905
|
-
expect(innerDragLeave).toHaveBeenCalled()
|
|
906
|
-
expect(parentDragLeave).not.toHaveBeenCalled()
|
|
907
|
-
})
|
|
908
|
-
})
|
|
923
|
+
fireDragLeave(innerDropzone, data);
|
|
924
|
+
expect(innerDragLeave).toHaveBeenCalled();
|
|
925
|
+
expect(parentDragLeave).not.toHaveBeenCalled();
|
|
926
|
+
});
|
|
927
|
+
});
|
|
909
928
|
|
|
910
|
-
describe(
|
|
911
|
-
it(
|
|
912
|
-
const data = createDtWithFiles(files)
|
|
929
|
+
describe("plugin integration", () => {
|
|
930
|
+
it("uses provided getFilesFromEvent()", async () => {
|
|
931
|
+
const data = createDtWithFiles(files);
|
|
913
932
|
|
|
914
933
|
const props = {
|
|
915
|
-
getFilesFromEvent: jest
|
|
934
|
+
getFilesFromEvent: jest
|
|
935
|
+
.fn()
|
|
936
|
+
.mockImplementation((event) => fromEvent(event)),
|
|
916
937
|
onDragEnter: jest.fn(),
|
|
917
938
|
onDragOver: jest.fn(),
|
|
918
939
|
onDragLeave: jest.fn(),
|
|
919
|
-
onDrop: jest.fn()
|
|
920
|
-
}
|
|
940
|
+
onDrop: jest.fn(),
|
|
941
|
+
};
|
|
921
942
|
|
|
922
943
|
const ui = (
|
|
923
944
|
<Dropzone {...props}>
|
|
@@ -927,30 +948,30 @@ describe('useDropzone() hook', () => {
|
|
|
927
948
|
</div>
|
|
928
949
|
)}
|
|
929
950
|
</Dropzone>
|
|
930
|
-
)
|
|
931
|
-
const { container, rerender } = render(ui)
|
|
932
|
-
const dropzone = container.querySelector(
|
|
951
|
+
);
|
|
952
|
+
const { container, rerender } = render(ui);
|
|
953
|
+
const dropzone = container.querySelector("div");
|
|
933
954
|
|
|
934
|
-
fireDragEnter(dropzone, data)
|
|
935
|
-
await flushPromises(rerender, ui)
|
|
936
|
-
expect(props.onDragEnter).toHaveBeenCalled()
|
|
955
|
+
fireDragEnter(dropzone, data);
|
|
956
|
+
await flushPromises(rerender, ui);
|
|
957
|
+
expect(props.onDragEnter).toHaveBeenCalled();
|
|
937
958
|
|
|
938
|
-
fireDragOver(dropzone, data)
|
|
939
|
-
expect(props.onDragOver).toHaveBeenCalled()
|
|
959
|
+
fireDragOver(dropzone, data);
|
|
960
|
+
expect(props.onDragOver).toHaveBeenCalled();
|
|
940
961
|
|
|
941
|
-
fireDragLeave(dropzone, data)
|
|
942
|
-
expect(props.onDragLeave).toHaveBeenCalled()
|
|
962
|
+
fireDragLeave(dropzone, data);
|
|
963
|
+
expect(props.onDragLeave).toHaveBeenCalled();
|
|
943
964
|
|
|
944
|
-
fireDrop(dropzone, data)
|
|
945
|
-
await flushPromises(rerender, ui)
|
|
946
|
-
expect(props.onDrop).toHaveBeenCalled()
|
|
965
|
+
fireDrop(dropzone, data);
|
|
966
|
+
await flushPromises(rerender, ui);
|
|
967
|
+
expect(props.onDrop).toHaveBeenCalled();
|
|
947
968
|
|
|
948
|
-
expect(props.getFilesFromEvent).toHaveBeenCalledTimes(2)
|
|
949
|
-
})
|
|
950
|
-
})
|
|
969
|
+
expect(props.getFilesFromEvent).toHaveBeenCalledTimes(2);
|
|
970
|
+
});
|
|
971
|
+
});
|
|
951
972
|
|
|
952
|
-
describe(
|
|
953
|
-
it(
|
|
973
|
+
describe("onFocus", () => {
|
|
974
|
+
it("sets focus state", () => {
|
|
954
975
|
const { container } = render(
|
|
955
976
|
<Dropzone>
|
|
956
977
|
{({ getRootProps, getInputProps, isFocused }) => (
|
|
@@ -960,33 +981,35 @@ describe('useDropzone() hook', () => {
|
|
|
960
981
|
</div>
|
|
961
982
|
)}
|
|
962
983
|
</Dropzone>
|
|
963
|
-
)
|
|
984
|
+
);
|
|
964
985
|
|
|
965
|
-
const dropzone = container.querySelector(
|
|
986
|
+
const dropzone = container.querySelector("div");
|
|
966
987
|
|
|
967
|
-
fireEvent.focus(dropzone)
|
|
968
|
-
expect(dropzone.querySelector(
|
|
969
|
-
})
|
|
988
|
+
fireEvent.focus(dropzone);
|
|
989
|
+
expect(dropzone.querySelector("#focus")).not.toBeNull();
|
|
990
|
+
});
|
|
970
991
|
|
|
971
|
-
it(
|
|
992
|
+
it("does not set focus state if user stopped event propagation", () => {
|
|
972
993
|
const { container } = render(
|
|
973
994
|
<Dropzone>
|
|
974
995
|
{({ getRootProps, getInputProps, isFocused }) => (
|
|
975
|
-
<div
|
|
996
|
+
<div
|
|
997
|
+
{...getRootProps({ onFocus: (event) => event.stopPropagation() })}
|
|
998
|
+
>
|
|
976
999
|
<input {...getInputProps()} />
|
|
977
1000
|
{isFocused && <div id="focus" />}
|
|
978
1001
|
</div>
|
|
979
1002
|
)}
|
|
980
1003
|
</Dropzone>
|
|
981
|
-
)
|
|
1004
|
+
);
|
|
982
1005
|
|
|
983
|
-
const dropzone = container.querySelector(
|
|
1006
|
+
const dropzone = container.querySelector("div");
|
|
984
1007
|
|
|
985
|
-
fireEvent.focus(dropzone)
|
|
986
|
-
expect(dropzone.querySelector(
|
|
987
|
-
})
|
|
1008
|
+
fireEvent.focus(dropzone);
|
|
1009
|
+
expect(dropzone.querySelector("#focus")).toBeNull();
|
|
1010
|
+
});
|
|
988
1011
|
|
|
989
|
-
it(
|
|
1012
|
+
it("does not set focus state if {noKeyboard} is true", () => {
|
|
990
1013
|
const { container } = render(
|
|
991
1014
|
<Dropzone noKeyboard>
|
|
992
1015
|
{({ getRootProps, getInputProps, isFocused }) => (
|
|
@@ -996,15 +1019,15 @@ describe('useDropzone() hook', () => {
|
|
|
996
1019
|
</div>
|
|
997
1020
|
)}
|
|
998
1021
|
</Dropzone>
|
|
999
|
-
)
|
|
1022
|
+
);
|
|
1000
1023
|
|
|
1001
|
-
const dropzone = container.querySelector(
|
|
1024
|
+
const dropzone = container.querySelector("div");
|
|
1002
1025
|
|
|
1003
|
-
fireEvent.focus(dropzone)
|
|
1004
|
-
expect(dropzone.querySelector(
|
|
1005
|
-
})
|
|
1026
|
+
fireEvent.focus(dropzone);
|
|
1027
|
+
expect(dropzone.querySelector("#focus")).toBeNull();
|
|
1028
|
+
});
|
|
1006
1029
|
|
|
1007
|
-
it(
|
|
1030
|
+
it("restores focus behavior if {noKeyboard} is set back to false", () => {
|
|
1008
1031
|
const { container, rerender } = render(
|
|
1009
1032
|
<Dropzone noKeyboard>
|
|
1010
1033
|
{({ getRootProps, getInputProps, isFocused }) => (
|
|
@@ -1014,12 +1037,12 @@ describe('useDropzone() hook', () => {
|
|
|
1014
1037
|
</div>
|
|
1015
1038
|
)}
|
|
1016
1039
|
</Dropzone>
|
|
1017
|
-
)
|
|
1040
|
+
);
|
|
1018
1041
|
|
|
1019
|
-
const dropzone = container.querySelector(
|
|
1042
|
+
const dropzone = container.querySelector("div");
|
|
1020
1043
|
|
|
1021
|
-
fireEvent.focus(dropzone)
|
|
1022
|
-
expect(dropzone.querySelector(
|
|
1044
|
+
fireEvent.focus(dropzone);
|
|
1045
|
+
expect(dropzone.querySelector("#focus")).toBeNull();
|
|
1023
1046
|
|
|
1024
1047
|
rerender(
|
|
1025
1048
|
<Dropzone noKeyboard={false}>
|
|
@@ -1030,15 +1053,15 @@ describe('useDropzone() hook', () => {
|
|
|
1030
1053
|
</div>
|
|
1031
1054
|
)}
|
|
1032
1055
|
</Dropzone>
|
|
1033
|
-
)
|
|
1056
|
+
);
|
|
1034
1057
|
|
|
1035
|
-
fireEvent.focus(dropzone)
|
|
1036
|
-
expect(dropzone.querySelector(
|
|
1037
|
-
})
|
|
1038
|
-
})
|
|
1058
|
+
fireEvent.focus(dropzone);
|
|
1059
|
+
expect(dropzone.querySelector("#focus")).not.toBeNull();
|
|
1060
|
+
});
|
|
1061
|
+
});
|
|
1039
1062
|
|
|
1040
|
-
describe(
|
|
1041
|
-
it(
|
|
1063
|
+
describe("onBlur", () => {
|
|
1064
|
+
it("unsets focus state", () => {
|
|
1042
1065
|
const { container } = render(
|
|
1043
1066
|
<Dropzone>
|
|
1044
1067
|
{({ getRootProps, getInputProps, isFocused }) => (
|
|
@@ -1048,38 +1071,40 @@ describe('useDropzone() hook', () => {
|
|
|
1048
1071
|
</div>
|
|
1049
1072
|
)}
|
|
1050
1073
|
</Dropzone>
|
|
1051
|
-
)
|
|
1074
|
+
);
|
|
1052
1075
|
|
|
1053
|
-
const dropzone = container.querySelector(
|
|
1076
|
+
const dropzone = container.querySelector("div");
|
|
1054
1077
|
|
|
1055
|
-
fireEvent.focus(dropzone)
|
|
1056
|
-
expect(dropzone.querySelector(
|
|
1078
|
+
fireEvent.focus(dropzone);
|
|
1079
|
+
expect(dropzone.querySelector("#focus")).not.toBeNull();
|
|
1057
1080
|
|
|
1058
|
-
fireEvent.blur(dropzone)
|
|
1059
|
-
expect(dropzone.querySelector(
|
|
1060
|
-
})
|
|
1081
|
+
fireEvent.blur(dropzone);
|
|
1082
|
+
expect(dropzone.querySelector("#focus")).toBeNull();
|
|
1083
|
+
});
|
|
1061
1084
|
|
|
1062
|
-
it(
|
|
1085
|
+
it("does not unset focus state if user stopped event propagation", () => {
|
|
1063
1086
|
const { container } = render(
|
|
1064
1087
|
<Dropzone>
|
|
1065
1088
|
{({ getRootProps, getInputProps, isFocused }) => (
|
|
1066
|
-
<div
|
|
1089
|
+
<div
|
|
1090
|
+
{...getRootProps({ onBlur: (event) => event.stopPropagation() })}
|
|
1091
|
+
>
|
|
1067
1092
|
<input {...getInputProps()} />
|
|
1068
1093
|
{isFocused && <div id="focus" />}
|
|
1069
1094
|
</div>
|
|
1070
1095
|
)}
|
|
1071
1096
|
</Dropzone>
|
|
1072
|
-
)
|
|
1097
|
+
);
|
|
1073
1098
|
|
|
1074
|
-
const dropzone = container.querySelector(
|
|
1099
|
+
const dropzone = container.querySelector("div");
|
|
1075
1100
|
|
|
1076
|
-
fireEvent.focus(dropzone)
|
|
1077
|
-
expect(dropzone.querySelector(
|
|
1078
|
-
fireEvent.blur(dropzone)
|
|
1079
|
-
expect(dropzone.querySelector(
|
|
1080
|
-
})
|
|
1101
|
+
fireEvent.focus(dropzone);
|
|
1102
|
+
expect(dropzone.querySelector("#focus")).not.toBeNull();
|
|
1103
|
+
fireEvent.blur(dropzone);
|
|
1104
|
+
expect(dropzone.querySelector("#focus")).not.toBeNull();
|
|
1105
|
+
});
|
|
1081
1106
|
|
|
1082
|
-
it(
|
|
1107
|
+
it("does not unset focus state if {noKeyboard} is true", () => {
|
|
1083
1108
|
const { container, rerender } = render(
|
|
1084
1109
|
<Dropzone>
|
|
1085
1110
|
{({ getRootProps, getInputProps, isFocused }) => (
|
|
@@ -1089,12 +1114,12 @@ describe('useDropzone() hook', () => {
|
|
|
1089
1114
|
</div>
|
|
1090
1115
|
)}
|
|
1091
1116
|
</Dropzone>
|
|
1092
|
-
)
|
|
1117
|
+
);
|
|
1093
1118
|
|
|
1094
|
-
const dropzone = container.querySelector(
|
|
1119
|
+
const dropzone = container.querySelector("div");
|
|
1095
1120
|
|
|
1096
|
-
fireEvent.focus(dropzone)
|
|
1097
|
-
expect(dropzone.querySelector(
|
|
1121
|
+
fireEvent.focus(dropzone);
|
|
1122
|
+
expect(dropzone.querySelector("#focus")).not.toBeNull();
|
|
1098
1123
|
|
|
1099
1124
|
rerender(
|
|
1100
1125
|
<Dropzone noKeyboard>
|
|
@@ -1105,13 +1130,13 @@ describe('useDropzone() hook', () => {
|
|
|
1105
1130
|
</div>
|
|
1106
1131
|
)}
|
|
1107
1132
|
</Dropzone>
|
|
1108
|
-
)
|
|
1133
|
+
);
|
|
1109
1134
|
|
|
1110
|
-
fireEvent.blur(dropzone)
|
|
1111
|
-
expect(dropzone.querySelector(
|
|
1112
|
-
})
|
|
1135
|
+
fireEvent.blur(dropzone);
|
|
1136
|
+
expect(dropzone.querySelector("#focus")).not.toBeNull();
|
|
1137
|
+
});
|
|
1113
1138
|
|
|
1114
|
-
it(
|
|
1139
|
+
it("restores blur behavior if {noKeyboard} is set back to false", () => {
|
|
1115
1140
|
const { container, rerender } = render(
|
|
1116
1141
|
<Dropzone>
|
|
1117
1142
|
{({ getRootProps, getInputProps, isFocused }) => (
|
|
@@ -1121,12 +1146,12 @@ describe('useDropzone() hook', () => {
|
|
|
1121
1146
|
</div>
|
|
1122
1147
|
)}
|
|
1123
1148
|
</Dropzone>
|
|
1124
|
-
)
|
|
1149
|
+
);
|
|
1125
1150
|
|
|
1126
|
-
const dropzone = container.querySelector(
|
|
1151
|
+
const dropzone = container.querySelector("div");
|
|
1127
1152
|
|
|
1128
|
-
fireEvent.focus(dropzone)
|
|
1129
|
-
expect(dropzone.querySelector(
|
|
1153
|
+
fireEvent.focus(dropzone);
|
|
1154
|
+
expect(dropzone.querySelector("#focus")).not.toBeNull();
|
|
1130
1155
|
|
|
1131
1156
|
rerender(
|
|
1132
1157
|
<Dropzone noKeyboard>
|
|
@@ -1137,10 +1162,10 @@ describe('useDropzone() hook', () => {
|
|
|
1137
1162
|
</div>
|
|
1138
1163
|
)}
|
|
1139
1164
|
</Dropzone>
|
|
1140
|
-
)
|
|
1165
|
+
);
|
|
1141
1166
|
|
|
1142
|
-
fireEvent.blur(dropzone)
|
|
1143
|
-
expect(dropzone.querySelector(
|
|
1167
|
+
fireEvent.blur(dropzone);
|
|
1168
|
+
expect(dropzone.querySelector("#focus")).not.toBeNull();
|
|
1144
1169
|
|
|
1145
1170
|
rerender(
|
|
1146
1171
|
<Dropzone noKeyboard={false}>
|
|
@@ -1151,18 +1176,32 @@ describe('useDropzone() hook', () => {
|
|
|
1151
1176
|
</div>
|
|
1152
1177
|
)}
|
|
1153
1178
|
</Dropzone>
|
|
1154
|
-
)
|
|
1179
|
+
);
|
|
1180
|
+
|
|
1181
|
+
fireEvent.blur(dropzone);
|
|
1182
|
+
expect(dropzone.querySelector("#focus")).toBeNull();
|
|
1183
|
+
});
|
|
1184
|
+
});
|
|
1185
|
+
|
|
1186
|
+
describe("onClick", () => {
|
|
1187
|
+
let currentShowOpenFilePicker;
|
|
1155
1188
|
|
|
1156
|
-
|
|
1157
|
-
|
|
1158
|
-
})
|
|
1159
|
-
|
|
1189
|
+
beforeEach(() => {
|
|
1190
|
+
currentShowOpenFilePicker = window.showOpenFilePicker;
|
|
1191
|
+
});
|
|
1192
|
+
|
|
1193
|
+
afterEach(() => {
|
|
1194
|
+
if (currentShowOpenFilePicker) {
|
|
1195
|
+
window.showOpenFilePicker = currentShowOpenFilePicker;
|
|
1196
|
+
} else {
|
|
1197
|
+
delete window.showOpenFilePicker;
|
|
1198
|
+
}
|
|
1199
|
+
});
|
|
1160
1200
|
|
|
1161
|
-
|
|
1162
|
-
|
|
1163
|
-
const
|
|
1164
|
-
const
|
|
1165
|
-
const onClickSpy = jest.spyOn(HTMLInputElement.prototype, 'click')
|
|
1201
|
+
it("should proxy the click event to the input", () => {
|
|
1202
|
+
const activeRef = createRef();
|
|
1203
|
+
const active = <span ref={activeRef}>I am active</span>;
|
|
1204
|
+
const onClickSpy = jest.spyOn(HTMLInputElement.prototype, "click");
|
|
1166
1205
|
|
|
1167
1206
|
const { container } = render(
|
|
1168
1207
|
<Dropzone>
|
|
@@ -1173,37 +1212,39 @@ describe('useDropzone() hook', () => {
|
|
|
1173
1212
|
</div>
|
|
1174
1213
|
)}
|
|
1175
1214
|
</Dropzone>
|
|
1176
|
-
)
|
|
1215
|
+
);
|
|
1177
1216
|
|
|
1178
|
-
const dropzone = container.querySelector(
|
|
1217
|
+
const dropzone = container.querySelector("div");
|
|
1179
1218
|
|
|
1180
|
-
fireEvent.click(dropzone)
|
|
1181
|
-
const ref = activeRef.current
|
|
1182
|
-
expect(ref).not.toBeNull()
|
|
1183
|
-
expect(dropzone).toContainElement(ref)
|
|
1184
|
-
expect(onClickSpy).toHaveBeenCalled()
|
|
1185
|
-
})
|
|
1219
|
+
fireEvent.click(dropzone);
|
|
1220
|
+
const ref = activeRef.current;
|
|
1221
|
+
expect(ref).not.toBeNull();
|
|
1222
|
+
expect(dropzone).toContainElement(ref);
|
|
1223
|
+
expect(onClickSpy).toHaveBeenCalled();
|
|
1224
|
+
});
|
|
1186
1225
|
|
|
1187
|
-
it(
|
|
1188
|
-
const onClickSpy = jest.spyOn(HTMLInputElement.prototype,
|
|
1226
|
+
it("should not not proxy the click event to the input if event propagation was stopped", () => {
|
|
1227
|
+
const onClickSpy = jest.spyOn(HTMLInputElement.prototype, "click");
|
|
1189
1228
|
const { container } = render(
|
|
1190
1229
|
<Dropzone>
|
|
1191
1230
|
{({ getRootProps, getInputProps }) => (
|
|
1192
|
-
<div
|
|
1231
|
+
<div
|
|
1232
|
+
{...getRootProps({ onClick: (event) => event.stopPropagation() })}
|
|
1233
|
+
>
|
|
1193
1234
|
<input {...getInputProps()} />
|
|
1194
1235
|
</div>
|
|
1195
1236
|
)}
|
|
1196
1237
|
</Dropzone>
|
|
1197
|
-
)
|
|
1238
|
+
);
|
|
1198
1239
|
|
|
1199
|
-
const dropzone = container.querySelector(
|
|
1240
|
+
const dropzone = container.querySelector("div");
|
|
1200
1241
|
|
|
1201
|
-
fireEvent.click(dropzone)
|
|
1202
|
-
expect(onClickSpy).not.toHaveBeenCalled()
|
|
1203
|
-
})
|
|
1242
|
+
fireEvent.click(dropzone);
|
|
1243
|
+
expect(onClickSpy).not.toHaveBeenCalled();
|
|
1244
|
+
});
|
|
1204
1245
|
|
|
1205
|
-
it(
|
|
1206
|
-
const onClickSpy = jest.spyOn(HTMLInputElement.prototype,
|
|
1246
|
+
it("should not not proxy the click event to the input if {noClick} is true", () => {
|
|
1247
|
+
const onClickSpy = jest.spyOn(HTMLInputElement.prototype, "click");
|
|
1207
1248
|
const { container } = render(
|
|
1208
1249
|
<Dropzone noClick>
|
|
1209
1250
|
{({ getRootProps, getInputProps }) => (
|
|
@@ -1212,16 +1253,16 @@ describe('useDropzone() hook', () => {
|
|
|
1212
1253
|
</div>
|
|
1213
1254
|
)}
|
|
1214
1255
|
</Dropzone>
|
|
1215
|
-
)
|
|
1256
|
+
);
|
|
1216
1257
|
|
|
1217
|
-
const dropzone = container.querySelector(
|
|
1258
|
+
const dropzone = container.querySelector("div");
|
|
1218
1259
|
|
|
1219
|
-
fireEvent.click(dropzone)
|
|
1220
|
-
expect(onClickSpy).not.toHaveBeenCalled()
|
|
1221
|
-
})
|
|
1260
|
+
fireEvent.click(dropzone);
|
|
1261
|
+
expect(onClickSpy).not.toHaveBeenCalled();
|
|
1262
|
+
});
|
|
1222
1263
|
|
|
1223
|
-
it(
|
|
1224
|
-
const onClickSpy = jest.spyOn(HTMLInputElement.prototype,
|
|
1264
|
+
it("restores click behavior if {noClick} is set back to false", () => {
|
|
1265
|
+
const onClickSpy = jest.spyOn(HTMLInputElement.prototype, "click");
|
|
1225
1266
|
const { container, rerender } = render(
|
|
1226
1267
|
<Dropzone noClick>
|
|
1227
1268
|
{({ getRootProps, getInputProps }) => (
|
|
@@ -1230,12 +1271,12 @@ describe('useDropzone() hook', () => {
|
|
|
1230
1271
|
</div>
|
|
1231
1272
|
)}
|
|
1232
1273
|
</Dropzone>
|
|
1233
|
-
)
|
|
1274
|
+
);
|
|
1234
1275
|
|
|
1235
|
-
const dropzone = container.querySelector(
|
|
1276
|
+
const dropzone = container.querySelector("div");
|
|
1236
1277
|
|
|
1237
|
-
fireEvent.click(dropzone)
|
|
1238
|
-
expect(onClickSpy).not.toHaveBeenCalled()
|
|
1278
|
+
fireEvent.click(dropzone);
|
|
1279
|
+
expect(onClickSpy).not.toHaveBeenCalled();
|
|
1239
1280
|
|
|
1240
1281
|
rerender(
|
|
1241
1282
|
<Dropzone noClick={false}>
|
|
@@ -1245,16 +1286,16 @@ describe('useDropzone() hook', () => {
|
|
|
1245
1286
|
</div>
|
|
1246
1287
|
)}
|
|
1247
1288
|
</Dropzone>
|
|
1248
|
-
)
|
|
1289
|
+
);
|
|
1249
1290
|
|
|
1250
|
-
fireEvent.click(dropzone)
|
|
1251
|
-
expect(onClickSpy).toHaveBeenCalled()
|
|
1252
|
-
})
|
|
1291
|
+
fireEvent.click(dropzone);
|
|
1292
|
+
expect(onClickSpy).toHaveBeenCalled();
|
|
1293
|
+
});
|
|
1253
1294
|
|
|
1254
1295
|
// https://github.com/react-dropzone/react-dropzone/issues/783
|
|
1255
|
-
it(
|
|
1256
|
-
const btnClickSpy = jest.fn()
|
|
1257
|
-
const inputClickSpy = jest.spyOn(HTMLInputElement.prototype,
|
|
1296
|
+
it("should continue event propagation if {noClick} is true", () => {
|
|
1297
|
+
const btnClickSpy = jest.fn();
|
|
1298
|
+
const inputClickSpy = jest.spyOn(HTMLInputElement.prototype, "click");
|
|
1258
1299
|
const { container } = render(
|
|
1259
1300
|
<Dropzone noClick>
|
|
1260
1301
|
{({ getRootProps, getInputProps }) => (
|
|
@@ -1264,23 +1305,25 @@ describe('useDropzone() hook', () => {
|
|
|
1264
1305
|
</div>
|
|
1265
1306
|
)}
|
|
1266
1307
|
</Dropzone>
|
|
1267
|
-
)
|
|
1308
|
+
);
|
|
1268
1309
|
|
|
1269
|
-
const dropzone = container.querySelector(
|
|
1270
|
-
const btn = container.querySelector(
|
|
1310
|
+
const dropzone = container.querySelector("div");
|
|
1311
|
+
const btn = container.querySelector("button");
|
|
1271
1312
|
|
|
1272
|
-
fireEvent.click(dropzone)
|
|
1273
|
-
expect(inputClickSpy).not.toHaveBeenCalled()
|
|
1313
|
+
fireEvent.click(dropzone);
|
|
1314
|
+
expect(inputClickSpy).not.toHaveBeenCalled();
|
|
1274
1315
|
|
|
1275
|
-
fireEvent.click(btn)
|
|
1276
|
-
expect(btnClickSpy).toHaveBeenCalled()
|
|
1277
|
-
})
|
|
1316
|
+
fireEvent.click(btn);
|
|
1317
|
+
expect(btnClickSpy).toHaveBeenCalled();
|
|
1318
|
+
});
|
|
1278
1319
|
|
|
1279
|
-
it(
|
|
1280
|
-
jest.useFakeTimers()
|
|
1320
|
+
it("should schedule input click on next tick in Edge", () => {
|
|
1321
|
+
jest.useFakeTimers();
|
|
1281
1322
|
|
|
1282
|
-
const isIeOrEdgeSpy = jest
|
|
1283
|
-
|
|
1323
|
+
const isIeOrEdgeSpy = jest
|
|
1324
|
+
.spyOn(utils, "isIeOrEdge")
|
|
1325
|
+
.mockReturnValueOnce(true);
|
|
1326
|
+
const onClickSpy = jest.spyOn(HTMLInputElement.prototype, "click");
|
|
1284
1327
|
|
|
1285
1328
|
const ui = (
|
|
1286
1329
|
<Dropzone>
|
|
@@ -1290,26 +1333,282 @@ describe('useDropzone() hook', () => {
|
|
|
1290
1333
|
</div>
|
|
1291
1334
|
)}
|
|
1292
1335
|
</Dropzone>
|
|
1293
|
-
)
|
|
1336
|
+
);
|
|
1337
|
+
|
|
1338
|
+
const { container } = render(ui);
|
|
1339
|
+
|
|
1340
|
+
const dropzone = container.querySelector("div");
|
|
1341
|
+
|
|
1342
|
+
fireEvent.click(dropzone);
|
|
1343
|
+
drainTimers();
|
|
1344
|
+
|
|
1345
|
+
expect(onClickSpy).toHaveBeenCalled();
|
|
1346
|
+
jest.useRealTimers();
|
|
1347
|
+
isIeOrEdgeSpy.mockClear();
|
|
1348
|
+
});
|
|
1349
|
+
|
|
1350
|
+
it("should not use showOpenFilePicker() if supported and {useFsAccessApi} is not true", async () => {
|
|
1351
|
+
jest.useFakeTimers();
|
|
1294
1352
|
|
|
1295
|
-
const
|
|
1353
|
+
const activeRef = createRef();
|
|
1354
|
+
const active = <span ref={activeRef}>I am active</span>;
|
|
1355
|
+
const onClickSpy = jest.spyOn(HTMLInputElement.prototype, "click");
|
|
1296
1356
|
|
|
1297
|
-
const
|
|
1357
|
+
const handlers = files.map((f) => createFileSystemFileHandle(f));
|
|
1358
|
+
const showOpenFilePickerMock = jest
|
|
1359
|
+
.fn()
|
|
1360
|
+
.mockReturnValue(Promise.resolve(handlers));
|
|
1361
|
+
|
|
1362
|
+
window.showOpenFilePicker = showOpenFilePickerMock;
|
|
1363
|
+
|
|
1364
|
+
const onDropSpy = jest.fn();
|
|
1365
|
+
const onFileDialogOpenSpy = jest.fn();
|
|
1366
|
+
|
|
1367
|
+
const ui = (
|
|
1368
|
+
<Dropzone
|
|
1369
|
+
onDrop={onDropSpy}
|
|
1370
|
+
onFileDialogOpen={onFileDialogOpenSpy}
|
|
1371
|
+
accept="application/pdf"
|
|
1372
|
+
multiple
|
|
1373
|
+
useFsAccessApi={false}
|
|
1374
|
+
>
|
|
1375
|
+
{({ getRootProps, getInputProps, isFileDialogActive }) => (
|
|
1376
|
+
<div {...getRootProps()}>
|
|
1377
|
+
<input {...getInputProps()} />
|
|
1378
|
+
{isFileDialogActive && active}
|
|
1379
|
+
</div>
|
|
1380
|
+
)}
|
|
1381
|
+
</Dropzone>
|
|
1382
|
+
);
|
|
1298
1383
|
|
|
1299
|
-
|
|
1300
|
-
drainTimers()
|
|
1384
|
+
const { container, rerender } = render(ui);
|
|
1301
1385
|
|
|
1302
|
-
|
|
1303
|
-
|
|
1304
|
-
|
|
1305
|
-
|
|
1306
|
-
|
|
1386
|
+
const dropzone = container.querySelector("div");
|
|
1387
|
+
|
|
1388
|
+
fireEvent.click(dropzone);
|
|
1389
|
+
|
|
1390
|
+
await flushPromises(rerender, ui);
|
|
1391
|
+
|
|
1392
|
+
dispatchEvt(document.body, "focus");
|
|
1393
|
+
drainTimers();
|
|
1394
|
+
|
|
1395
|
+
expect(onFileDialogOpenSpy).toHaveBeenCalled();
|
|
1396
|
+
|
|
1397
|
+
expect(activeRef.current).toBeNull();
|
|
1398
|
+
expect(dropzone).not.toContainElement(activeRef.current);
|
|
1399
|
+
expect(onClickSpy).toHaveBeenCalled();
|
|
1400
|
+
expect(showOpenFilePickerMock).not.toHaveBeenCalled();
|
|
1401
|
+
expect(onDropSpy).not.toHaveBeenCalled();
|
|
1402
|
+
|
|
1403
|
+
jest.useRealTimers();
|
|
1404
|
+
});
|
|
1405
|
+
|
|
1406
|
+
it("should use showOpenFilePicker() if supported and {useFsAccessApi} is true, and not trigger click on input", async () => {
|
|
1407
|
+
const activeRef = createRef();
|
|
1408
|
+
const active = <span ref={activeRef}>I am active</span>;
|
|
1409
|
+
const onClickSpy = jest.spyOn(HTMLInputElement.prototype, "click");
|
|
1410
|
+
|
|
1411
|
+
const handlers = files.map((f) => createFileSystemFileHandle(f));
|
|
1412
|
+
const thenable = createThenable();
|
|
1413
|
+
const showOpenFilePickerMock = jest
|
|
1414
|
+
.fn()
|
|
1415
|
+
.mockReturnValue(thenable.promise);
|
|
1416
|
+
|
|
1417
|
+
window.showOpenFilePicker = showOpenFilePickerMock;
|
|
1418
|
+
|
|
1419
|
+
const onDropSpy = jest.fn();
|
|
1420
|
+
const onFileDialogOpenSpy = jest.fn();
|
|
1421
|
+
|
|
1422
|
+
const ui = (
|
|
1423
|
+
<Dropzone
|
|
1424
|
+
onDrop={onDropSpy}
|
|
1425
|
+
onFileDialogOpen={onFileDialogOpenSpy}
|
|
1426
|
+
accept="application/pdf"
|
|
1427
|
+
multiple
|
|
1428
|
+
useFsAccessApi
|
|
1429
|
+
>
|
|
1430
|
+
{({ getRootProps, getInputProps, isFileDialogActive }) => (
|
|
1431
|
+
<div {...getRootProps()}>
|
|
1432
|
+
<input {...getInputProps()} />
|
|
1433
|
+
{isFileDialogActive && active}
|
|
1434
|
+
</div>
|
|
1435
|
+
)}
|
|
1436
|
+
</Dropzone>
|
|
1437
|
+
);
|
|
1438
|
+
|
|
1439
|
+
const { container, rerender } = render(ui);
|
|
1440
|
+
|
|
1441
|
+
const dropzone = container.querySelector("div");
|
|
1442
|
+
|
|
1443
|
+
fireEvent.click(dropzone);
|
|
1444
|
+
|
|
1445
|
+
await flushPromises(rerender, ui);
|
|
1446
|
+
|
|
1447
|
+
expect(activeRef.current).not.toBeNull();
|
|
1448
|
+
expect(dropzone).toContainElement(activeRef.current);
|
|
1449
|
+
expect(onFileDialogOpenSpy).toHaveBeenCalled();
|
|
1450
|
+
|
|
1451
|
+
thenable.done(handlers);
|
|
1452
|
+
await flushPromises(rerender, ui);
|
|
1453
|
+
|
|
1454
|
+
expect(activeRef.current).toBeNull(); // We expect the dialog to be closed at this point
|
|
1455
|
+
expect(dropzone).not.toContainElement(activeRef.current);
|
|
1456
|
+
expect(onClickSpy).not.toHaveBeenCalled();
|
|
1457
|
+
expect(showOpenFilePickerMock).toHaveBeenCalledWith({
|
|
1458
|
+
multiple: true,
|
|
1459
|
+
types: [
|
|
1460
|
+
{
|
|
1461
|
+
description: "everything",
|
|
1462
|
+
accept: { "application/pdf": [] },
|
|
1463
|
+
},
|
|
1464
|
+
],
|
|
1465
|
+
});
|
|
1466
|
+
expect(onDropSpy).toHaveBeenCalledWith(files, [], null);
|
|
1467
|
+
});
|
|
1468
|
+
|
|
1469
|
+
test("if showOpenFilePicker() is supported and {useFsAccessApi} is true, it should work without the <input>", async () => {
|
|
1470
|
+
const activeRef = createRef();
|
|
1471
|
+
const active = <span ref={activeRef}>I am active</span>;
|
|
1472
|
+
|
|
1473
|
+
const handlers = files.map((f) => createFileSystemFileHandle(f));
|
|
1474
|
+
const showOpenFilePickerMock = jest
|
|
1475
|
+
.fn()
|
|
1476
|
+
.mockReturnValue(Promise.resolve(handlers));
|
|
1477
|
+
|
|
1478
|
+
window.showOpenFilePicker = showOpenFilePickerMock;
|
|
1479
|
+
|
|
1480
|
+
const onDropSpy = jest.fn();
|
|
1481
|
+
const onFileDialogOpenSpy = jest.fn();
|
|
1482
|
+
|
|
1483
|
+
const ui = (
|
|
1484
|
+
<Dropzone
|
|
1485
|
+
onDrop={onDropSpy}
|
|
1486
|
+
onFileDialogOpen={onFileDialogOpenSpy}
|
|
1487
|
+
useFsAccessApi
|
|
1488
|
+
>
|
|
1489
|
+
{({ getRootProps, isFileDialogActive }) => (
|
|
1490
|
+
<div {...getRootProps()}>{isFileDialogActive && active}</div>
|
|
1491
|
+
)}
|
|
1492
|
+
</Dropzone>
|
|
1493
|
+
);
|
|
1494
|
+
|
|
1495
|
+
const { container, rerender } = render(ui);
|
|
1496
|
+
|
|
1497
|
+
const dropzone = container.querySelector("div");
|
|
1498
|
+
|
|
1499
|
+
fireEvent.click(dropzone);
|
|
1500
|
+
await flushPromises(rerender, ui);
|
|
1501
|
+
const ref = activeRef.current;
|
|
1502
|
+
expect(ref).toBeNull(); // We expect the dialog to be closed at this point
|
|
1503
|
+
expect(dropzone).not.toContainElement(ref);
|
|
1504
|
+
expect(showOpenFilePickerMock).toHaveBeenCalled();
|
|
1505
|
+
expect(onDropSpy).toHaveBeenCalledWith(files, [], null);
|
|
1506
|
+
expect(onFileDialogOpenSpy).toHaveBeenCalled();
|
|
1507
|
+
});
|
|
1508
|
+
|
|
1509
|
+
test("if showOpenFilePicker() is supported and {useFsAccessApi} is true, and the user cancels it should call onFileDialogCancel", async () => {
|
|
1510
|
+
const activeRef = createRef();
|
|
1511
|
+
const active = <span ref={activeRef}>I am active</span>;
|
|
1512
|
+
|
|
1513
|
+
const showOpenFilePickerMock = jest
|
|
1514
|
+
.fn()
|
|
1515
|
+
.mockReturnValue(
|
|
1516
|
+
Promise.reject(new DOMException("user aborted request", "AbortError"))
|
|
1517
|
+
);
|
|
1518
|
+
|
|
1519
|
+
window.showOpenFilePicker = showOpenFilePickerMock;
|
|
1520
|
+
|
|
1521
|
+
const onDropSpy = jest.fn();
|
|
1522
|
+
const onFileDialogCancelSpy = jest.fn();
|
|
1523
|
+
|
|
1524
|
+
const ui = (
|
|
1525
|
+
<Dropzone
|
|
1526
|
+
onDrop={onDropSpy}
|
|
1527
|
+
onFileDialogCancel={onFileDialogCancelSpy}
|
|
1528
|
+
useFsAccessApi
|
|
1529
|
+
>
|
|
1530
|
+
{({ getRootProps, isFileDialogActive }) => (
|
|
1531
|
+
<div {...getRootProps()}>{isFileDialogActive && active}</div>
|
|
1532
|
+
)}
|
|
1533
|
+
</Dropzone>
|
|
1534
|
+
);
|
|
1307
1535
|
|
|
1308
|
-
|
|
1309
|
-
|
|
1310
|
-
const
|
|
1311
|
-
|
|
1312
|
-
|
|
1536
|
+
const { container, rerender } = render(ui);
|
|
1537
|
+
|
|
1538
|
+
const dropzone = container.querySelector("div");
|
|
1539
|
+
|
|
1540
|
+
fireEvent.click(dropzone);
|
|
1541
|
+
await flushPromises(rerender, ui);
|
|
1542
|
+
const ref = activeRef.current;
|
|
1543
|
+
expect(ref).toBeNull(); // We expect the dialog to be closed at this point
|
|
1544
|
+
expect(dropzone).not.toContainElement(ref);
|
|
1545
|
+
expect(showOpenFilePickerMock).toHaveBeenCalled();
|
|
1546
|
+
expect(onDropSpy).not.toHaveBeenCalled();
|
|
1547
|
+
expect(onFileDialogCancelSpy).toHaveBeenCalled();
|
|
1548
|
+
});
|
|
1549
|
+
|
|
1550
|
+
test("window focus evt is not bound if showOpenFilePicker() is supported and {useFsAccessApi} is true", async () => {
|
|
1551
|
+
jest.useFakeTimers();
|
|
1552
|
+
|
|
1553
|
+
const activeRef = createRef();
|
|
1554
|
+
const active = <span ref={activeRef}>I am active</span>;
|
|
1555
|
+
const onFileDialogCancelSpy = jest.fn();
|
|
1556
|
+
|
|
1557
|
+
const thenable = createThenable();
|
|
1558
|
+
const showOpenFilePickerMock = jest
|
|
1559
|
+
.fn()
|
|
1560
|
+
.mockReturnValue(thenable.promise);
|
|
1561
|
+
|
|
1562
|
+
window.showOpenFilePicker = showOpenFilePickerMock;
|
|
1563
|
+
|
|
1564
|
+
const ui = (
|
|
1565
|
+
<Dropzone
|
|
1566
|
+
onFileDialogCancel={onFileDialogCancelSpy}
|
|
1567
|
+
noClick
|
|
1568
|
+
useFsAccessApi
|
|
1569
|
+
>
|
|
1570
|
+
{({ getRootProps, isFileDialogActive, open }) => (
|
|
1571
|
+
<div {...getRootProps()}>
|
|
1572
|
+
{isFileDialogActive && active}
|
|
1573
|
+
<button type="button" onClick={open}>
|
|
1574
|
+
Open
|
|
1575
|
+
</button>
|
|
1576
|
+
</div>
|
|
1577
|
+
)}
|
|
1578
|
+
</Dropzone>
|
|
1579
|
+
);
|
|
1580
|
+
|
|
1581
|
+
const { container, rerender } = render(ui);
|
|
1582
|
+
|
|
1583
|
+
const dropzone = container.querySelector("div");
|
|
1584
|
+
const btn = container.querySelector("button");
|
|
1585
|
+
|
|
1586
|
+
btn.click();
|
|
1587
|
+
drainTimers();
|
|
1588
|
+
await flushPromises(rerender, ui);
|
|
1589
|
+
|
|
1590
|
+
const ref = activeRef.current;
|
|
1591
|
+
expect(ref).not.toBeNull();
|
|
1592
|
+
expect(dropzone).toContainElement(ref);
|
|
1593
|
+
|
|
1594
|
+
thenable.cancel(new DOMException("user aborted request", "AbortError"));
|
|
1595
|
+
|
|
1596
|
+
dispatchEvt(document.body, "focus");
|
|
1597
|
+
drainTimers();
|
|
1598
|
+
await flushPromises(rerender, ui);
|
|
1599
|
+
|
|
1600
|
+
expect(onFileDialogCancelSpy).toHaveBeenCalledTimes(1);
|
|
1601
|
+
expect(dropzone).not.toContainElement(ref);
|
|
1602
|
+
|
|
1603
|
+
jest.useRealTimers();
|
|
1604
|
+
});
|
|
1605
|
+
});
|
|
1606
|
+
|
|
1607
|
+
describe("onKeyDown", () => {
|
|
1608
|
+
it("triggers the click event on the input if the SPACE/ENTER keys are pressed", () => {
|
|
1609
|
+
const activeRef = createRef();
|
|
1610
|
+
const active = <span ref={activeRef}>I am active</span>;
|
|
1611
|
+
const onClickSpy = jest.spyOn(HTMLInputElement.prototype, "click");
|
|
1313
1612
|
const { container } = render(
|
|
1314
1613
|
<Dropzone>
|
|
1315
1614
|
{({ getRootProps, getInputProps, isFileDialogActive }) => (
|
|
@@ -1319,26 +1618,26 @@ describe('useDropzone() hook', () => {
|
|
|
1319
1618
|
</div>
|
|
1320
1619
|
)}
|
|
1321
1620
|
</Dropzone>
|
|
1322
|
-
)
|
|
1621
|
+
);
|
|
1323
1622
|
|
|
1324
|
-
const dropzone = container.querySelector(
|
|
1623
|
+
const dropzone = container.querySelector("div");
|
|
1325
1624
|
|
|
1326
1625
|
fireEvent.keyDown(dropzone, {
|
|
1327
|
-
keyCode: 32
|
|
1328
|
-
})
|
|
1626
|
+
keyCode: 32,
|
|
1627
|
+
});
|
|
1329
1628
|
|
|
1330
1629
|
fireEvent.keyDown(dropzone, {
|
|
1331
|
-
keyCode: 13
|
|
1332
|
-
})
|
|
1630
|
+
keyCode: 13,
|
|
1631
|
+
});
|
|
1333
1632
|
|
|
1334
|
-
const ref = activeRef.current
|
|
1335
|
-
expect(ref).not.toBeNull()
|
|
1336
|
-
expect(dropzone).toContainElement(ref)
|
|
1337
|
-
expect(onClickSpy).toHaveBeenCalledTimes(2)
|
|
1338
|
-
})
|
|
1633
|
+
const ref = activeRef.current;
|
|
1634
|
+
expect(ref).not.toBeNull();
|
|
1635
|
+
expect(dropzone).toContainElement(ref);
|
|
1636
|
+
expect(onClickSpy).toHaveBeenCalledTimes(2);
|
|
1637
|
+
});
|
|
1339
1638
|
|
|
1340
|
-
it(
|
|
1341
|
-
const onClickSpy = jest.spyOn(HTMLInputElement.prototype,
|
|
1639
|
+
it("does not trigger the click event on the input if the dropzone is not in focus", () => {
|
|
1640
|
+
const onClickSpy = jest.spyOn(HTMLInputElement.prototype, "click");
|
|
1342
1641
|
const { container } = render(
|
|
1343
1642
|
<Dropzone>
|
|
1344
1643
|
{({ getRootProps, getInputProps }) => (
|
|
@@ -1347,39 +1646,43 @@ describe('useDropzone() hook', () => {
|
|
|
1347
1646
|
</div>
|
|
1348
1647
|
)}
|
|
1349
1648
|
</Dropzone>
|
|
1350
|
-
)
|
|
1649
|
+
);
|
|
1351
1650
|
|
|
1352
|
-
const input = container.querySelector(
|
|
1651
|
+
const input = container.querySelector("input");
|
|
1353
1652
|
|
|
1354
1653
|
fireEvent.keyDown(input, {
|
|
1355
|
-
keyCode: 32
|
|
1356
|
-
})
|
|
1654
|
+
keyCode: 32,
|
|
1655
|
+
});
|
|
1357
1656
|
|
|
1358
|
-
expect(onClickSpy).not.toHaveBeenCalled()
|
|
1359
|
-
})
|
|
1657
|
+
expect(onClickSpy).not.toHaveBeenCalled();
|
|
1658
|
+
});
|
|
1360
1659
|
|
|
1361
|
-
it(
|
|
1362
|
-
const onClickSpy = jest.spyOn(HTMLInputElement.prototype,
|
|
1660
|
+
it("does not trigger the click event on the input if event propagation was stopped", () => {
|
|
1661
|
+
const onClickSpy = jest.spyOn(HTMLInputElement.prototype, "click");
|
|
1363
1662
|
const { container } = render(
|
|
1364
1663
|
<Dropzone>
|
|
1365
1664
|
{({ getRootProps, getInputProps }) => (
|
|
1366
|
-
<div
|
|
1665
|
+
<div
|
|
1666
|
+
{...getRootProps({
|
|
1667
|
+
onKeyDown: (event) => event.stopPropagation(),
|
|
1668
|
+
})}
|
|
1669
|
+
>
|
|
1367
1670
|
<input {...getInputProps()} />
|
|
1368
1671
|
</div>
|
|
1369
1672
|
)}
|
|
1370
1673
|
</Dropzone>
|
|
1371
|
-
)
|
|
1674
|
+
);
|
|
1372
1675
|
|
|
1373
|
-
const dropzone = container.querySelector(
|
|
1676
|
+
const dropzone = container.querySelector("div");
|
|
1374
1677
|
|
|
1375
1678
|
fireEvent.keyDown(dropzone, {
|
|
1376
|
-
keyCode: 32
|
|
1377
|
-
})
|
|
1378
|
-
expect(onClickSpy).not.toHaveBeenCalled()
|
|
1379
|
-
})
|
|
1679
|
+
keyCode: 32,
|
|
1680
|
+
});
|
|
1681
|
+
expect(onClickSpy).not.toHaveBeenCalled();
|
|
1682
|
+
});
|
|
1380
1683
|
|
|
1381
|
-
it(
|
|
1382
|
-
const onClickSpy = jest.spyOn(HTMLInputElement.prototype,
|
|
1684
|
+
it("does not trigger the click event on the input if {noKeyboard} is true", () => {
|
|
1685
|
+
const onClickSpy = jest.spyOn(HTMLInputElement.prototype, "click");
|
|
1383
1686
|
const { container } = render(
|
|
1384
1687
|
<Dropzone noKeyboard>
|
|
1385
1688
|
{({ getRootProps, getInputProps }) => (
|
|
@@ -1388,18 +1691,18 @@ describe('useDropzone() hook', () => {
|
|
|
1388
1691
|
</div>
|
|
1389
1692
|
)}
|
|
1390
1693
|
</Dropzone>
|
|
1391
|
-
)
|
|
1694
|
+
);
|
|
1392
1695
|
|
|
1393
|
-
const dropzone = container.querySelector(
|
|
1696
|
+
const dropzone = container.querySelector("div");
|
|
1394
1697
|
|
|
1395
1698
|
fireEvent.keyDown(dropzone, {
|
|
1396
|
-
keyCode: 32
|
|
1397
|
-
})
|
|
1398
|
-
expect(onClickSpy).not.toHaveBeenCalled()
|
|
1399
|
-
})
|
|
1699
|
+
keyCode: 32,
|
|
1700
|
+
});
|
|
1701
|
+
expect(onClickSpy).not.toHaveBeenCalled();
|
|
1702
|
+
});
|
|
1400
1703
|
|
|
1401
|
-
it(
|
|
1402
|
-
const onClickSpy = jest.spyOn(HTMLInputElement.prototype,
|
|
1704
|
+
it("restores the keydown behavior when {noKeyboard} is set back to false", () => {
|
|
1705
|
+
const onClickSpy = jest.spyOn(HTMLInputElement.prototype, "click");
|
|
1403
1706
|
const { container, rerender } = render(
|
|
1404
1707
|
<Dropzone noKeyboard>
|
|
1405
1708
|
{({ getRootProps, getInputProps }) => (
|
|
@@ -1408,14 +1711,14 @@ describe('useDropzone() hook', () => {
|
|
|
1408
1711
|
</div>
|
|
1409
1712
|
)}
|
|
1410
1713
|
</Dropzone>
|
|
1411
|
-
)
|
|
1714
|
+
);
|
|
1412
1715
|
|
|
1413
|
-
const dropzone = container.querySelector(
|
|
1716
|
+
const dropzone = container.querySelector("div");
|
|
1414
1717
|
|
|
1415
1718
|
fireEvent.keyDown(dropzone, {
|
|
1416
|
-
keyCode: 32
|
|
1417
|
-
})
|
|
1418
|
-
expect(onClickSpy).not.toHaveBeenCalled()
|
|
1719
|
+
keyCode: 32,
|
|
1720
|
+
});
|
|
1721
|
+
expect(onClickSpy).not.toHaveBeenCalled();
|
|
1419
1722
|
|
|
1420
1723
|
rerender(
|
|
1421
1724
|
<Dropzone noKeyboard={false}>
|
|
@@ -1425,16 +1728,16 @@ describe('useDropzone() hook', () => {
|
|
|
1425
1728
|
</div>
|
|
1426
1729
|
)}
|
|
1427
1730
|
</Dropzone>
|
|
1428
|
-
)
|
|
1731
|
+
);
|
|
1429
1732
|
|
|
1430
1733
|
fireEvent.keyDown(dropzone, {
|
|
1431
|
-
keyCode: 32
|
|
1432
|
-
})
|
|
1433
|
-
expect(onClickSpy).toHaveBeenCalled()
|
|
1434
|
-
})
|
|
1734
|
+
keyCode: 32,
|
|
1735
|
+
});
|
|
1736
|
+
expect(onClickSpy).toHaveBeenCalled();
|
|
1737
|
+
});
|
|
1435
1738
|
|
|
1436
|
-
it(
|
|
1437
|
-
const onClickSpy = jest.spyOn(HTMLInputElement.prototype,
|
|
1739
|
+
it("does not trigger the click event on the input for other keys", () => {
|
|
1740
|
+
const onClickSpy = jest.spyOn(HTMLInputElement.prototype, "click");
|
|
1438
1741
|
const { container } = render(
|
|
1439
1742
|
<Dropzone>
|
|
1440
1743
|
{({ getRootProps, getInputProps }) => (
|
|
@@ -1443,27 +1746,27 @@ describe('useDropzone() hook', () => {
|
|
|
1443
1746
|
</div>
|
|
1444
1747
|
)}
|
|
1445
1748
|
</Dropzone>
|
|
1446
|
-
)
|
|
1749
|
+
);
|
|
1447
1750
|
|
|
1448
|
-
const dropzone = container.querySelector(
|
|
1751
|
+
const dropzone = container.querySelector("div");
|
|
1449
1752
|
|
|
1450
1753
|
fireEvent.keyDown(dropzone, {
|
|
1451
|
-
keyCode: 97
|
|
1452
|
-
})
|
|
1453
|
-
expect(onClickSpy).not.toHaveBeenCalled()
|
|
1454
|
-
})
|
|
1455
|
-
})
|
|
1754
|
+
keyCode: 97,
|
|
1755
|
+
});
|
|
1756
|
+
expect(onClickSpy).not.toHaveBeenCalled();
|
|
1757
|
+
});
|
|
1758
|
+
});
|
|
1456
1759
|
|
|
1457
|
-
describe(
|
|
1458
|
-
it(
|
|
1459
|
-
const data = createDtWithFiles(files)
|
|
1760
|
+
describe("onDrag*", () => {
|
|
1761
|
+
it("invokes callbacks for the appropriate events", async () => {
|
|
1762
|
+
const data = createDtWithFiles(files);
|
|
1460
1763
|
|
|
1461
1764
|
const props = {
|
|
1462
1765
|
onDragEnter: jest.fn(),
|
|
1463
1766
|
onDragOver: jest.fn(),
|
|
1464
1767
|
onDragLeave: jest.fn(),
|
|
1465
|
-
onDrop: jest.fn()
|
|
1466
|
-
}
|
|
1768
|
+
onDrop: jest.fn(),
|
|
1769
|
+
};
|
|
1467
1770
|
|
|
1468
1771
|
const ui = (
|
|
1469
1772
|
<Dropzone {...props}>
|
|
@@ -1473,27 +1776,27 @@ describe('useDropzone() hook', () => {
|
|
|
1473
1776
|
</div>
|
|
1474
1777
|
)}
|
|
1475
1778
|
</Dropzone>
|
|
1476
|
-
)
|
|
1477
|
-
const { container, rerender } = render(ui)
|
|
1478
|
-
const dropzone = container.querySelector(
|
|
1779
|
+
);
|
|
1780
|
+
const { container, rerender } = render(ui);
|
|
1781
|
+
const dropzone = container.querySelector("div");
|
|
1479
1782
|
|
|
1480
|
-
fireDragEnter(dropzone, data)
|
|
1481
|
-
await flushPromises(rerender, ui)
|
|
1482
|
-
expect(props.onDragEnter).toHaveBeenCalled()
|
|
1783
|
+
fireDragEnter(dropzone, data);
|
|
1784
|
+
await flushPromises(rerender, ui);
|
|
1785
|
+
expect(props.onDragEnter).toHaveBeenCalled();
|
|
1483
1786
|
|
|
1484
|
-
fireDragOver(dropzone, data)
|
|
1485
|
-
expect(props.onDragOver).toHaveBeenCalled()
|
|
1787
|
+
fireDragOver(dropzone, data);
|
|
1788
|
+
expect(props.onDragOver).toHaveBeenCalled();
|
|
1486
1789
|
|
|
1487
|
-
fireDragLeave(dropzone, data)
|
|
1488
|
-
expect(props.onDragLeave).toHaveBeenCalled()
|
|
1790
|
+
fireDragLeave(dropzone, data);
|
|
1791
|
+
expect(props.onDragLeave).toHaveBeenCalled();
|
|
1489
1792
|
|
|
1490
|
-
fireDrop(dropzone, data)
|
|
1491
|
-
await flushPromises(rerender, ui)
|
|
1492
|
-
expect(props.onDrop).toHaveBeenCalled()
|
|
1493
|
-
})
|
|
1793
|
+
fireDrop(dropzone, data);
|
|
1794
|
+
await flushPromises(rerender, ui);
|
|
1795
|
+
expect(props.onDrop).toHaveBeenCalled();
|
|
1796
|
+
});
|
|
1494
1797
|
|
|
1495
|
-
it(
|
|
1496
|
-
const emptyData = createDtWithFiles([])
|
|
1798
|
+
it("invokes callbacks for the appropriate events even if it cannot access the data", async () => {
|
|
1799
|
+
const emptyData = createDtWithFiles([]);
|
|
1497
1800
|
|
|
1498
1801
|
const props = {
|
|
1499
1802
|
onDragEnter: jest.fn(),
|
|
@@ -1501,8 +1804,8 @@ describe('useDropzone() hook', () => {
|
|
|
1501
1804
|
onDragLeave: jest.fn(),
|
|
1502
1805
|
onDrop: jest.fn(),
|
|
1503
1806
|
onDropAccepted: jest.fn(),
|
|
1504
|
-
onDropRejected: jest.fn()
|
|
1505
|
-
}
|
|
1807
|
+
onDropRejected: jest.fn(),
|
|
1808
|
+
};
|
|
1506
1809
|
|
|
1507
1810
|
const ui = (
|
|
1508
1811
|
<Dropzone {...props}>
|
|
@@ -1512,35 +1815,38 @@ describe('useDropzone() hook', () => {
|
|
|
1512
1815
|
</div>
|
|
1513
1816
|
)}
|
|
1514
1817
|
</Dropzone>
|
|
1515
|
-
)
|
|
1516
|
-
const { container, rerender } = render(ui)
|
|
1517
|
-
const dropzone = container.querySelector(
|
|
1818
|
+
);
|
|
1819
|
+
const { container, rerender } = render(ui);
|
|
1820
|
+
const dropzone = container.querySelector("div");
|
|
1518
1821
|
|
|
1519
|
-
fireDragEnter(dropzone, emptyData)
|
|
1520
|
-
await flushPromises(rerender, ui)
|
|
1521
|
-
expect(props.onDragEnter).toHaveBeenCalled()
|
|
1822
|
+
fireDragEnter(dropzone, emptyData);
|
|
1823
|
+
await flushPromises(rerender, ui);
|
|
1824
|
+
expect(props.onDragEnter).toHaveBeenCalled();
|
|
1522
1825
|
|
|
1523
|
-
fireDragOver(dropzone, emptyData)
|
|
1524
|
-
expect(props.onDragOver).toHaveBeenCalled()
|
|
1826
|
+
fireDragOver(dropzone, emptyData);
|
|
1827
|
+
expect(props.onDragOver).toHaveBeenCalled();
|
|
1525
1828
|
|
|
1526
|
-
fireDragLeave(dropzone, emptyData)
|
|
1527
|
-
expect(props.onDragLeave).toHaveBeenCalled()
|
|
1829
|
+
fireDragLeave(dropzone, emptyData);
|
|
1830
|
+
expect(props.onDragLeave).toHaveBeenCalled();
|
|
1528
1831
|
|
|
1529
|
-
const data = createDtWithFiles(files)
|
|
1530
|
-
fireDrop(dropzone, data)
|
|
1531
|
-
await flushPromises(rerender, ui)
|
|
1532
|
-
expect(props.onDrop).toHaveBeenCalled()
|
|
1533
|
-
expect(props.onDropAccepted).toHaveBeenCalledWith(
|
|
1534
|
-
|
|
1535
|
-
|
|
1832
|
+
const data = createDtWithFiles(files);
|
|
1833
|
+
fireDrop(dropzone, data);
|
|
1834
|
+
await flushPromises(rerender, ui);
|
|
1835
|
+
expect(props.onDrop).toHaveBeenCalled();
|
|
1836
|
+
expect(props.onDropAccepted).toHaveBeenCalledWith(
|
|
1837
|
+
files,
|
|
1838
|
+
expect.any(Object)
|
|
1839
|
+
);
|
|
1840
|
+
expect(props.onDropRejected).not.toHaveBeenCalled();
|
|
1841
|
+
});
|
|
1536
1842
|
|
|
1537
|
-
it(
|
|
1843
|
+
it("does not invoke callbacks if no files are detected", async () => {
|
|
1538
1844
|
const data = {
|
|
1539
1845
|
dataTransfer: {
|
|
1540
1846
|
items: [],
|
|
1541
|
-
types: [
|
|
1542
|
-
}
|
|
1543
|
-
}
|
|
1847
|
+
types: ["text/html", "text/plain"],
|
|
1848
|
+
},
|
|
1849
|
+
};
|
|
1544
1850
|
|
|
1545
1851
|
const props = {
|
|
1546
1852
|
onDragEnter: jest.fn(),
|
|
@@ -1548,8 +1854,8 @@ describe('useDropzone() hook', () => {
|
|
|
1548
1854
|
onDragLeave: jest.fn(),
|
|
1549
1855
|
onDrop: jest.fn(),
|
|
1550
1856
|
onDropAccepted: jest.fn(),
|
|
1551
|
-
onDropRejected: jest.fn()
|
|
1552
|
-
}
|
|
1857
|
+
onDropRejected: jest.fn(),
|
|
1858
|
+
};
|
|
1553
1859
|
|
|
1554
1860
|
const ui = (
|
|
1555
1861
|
<Dropzone {...props}>
|
|
@@ -1559,29 +1865,29 @@ describe('useDropzone() hook', () => {
|
|
|
1559
1865
|
</div>
|
|
1560
1866
|
)}
|
|
1561
1867
|
</Dropzone>
|
|
1562
|
-
)
|
|
1563
|
-
const { container, rerender } = render(ui)
|
|
1564
|
-
const dropzone = container.querySelector(
|
|
1868
|
+
);
|
|
1869
|
+
const { container, rerender } = render(ui);
|
|
1870
|
+
const dropzone = container.querySelector("div");
|
|
1565
1871
|
|
|
1566
|
-
fireDragEnter(dropzone, data)
|
|
1567
|
-
await flushPromises(rerender, ui)
|
|
1568
|
-
expect(props.onDragEnter).not.toHaveBeenCalled()
|
|
1872
|
+
fireDragEnter(dropzone, data);
|
|
1873
|
+
await flushPromises(rerender, ui);
|
|
1874
|
+
expect(props.onDragEnter).not.toHaveBeenCalled();
|
|
1569
1875
|
|
|
1570
|
-
fireDragOver(dropzone, data)
|
|
1571
|
-
expect(props.onDragOver).not.toHaveBeenCalled()
|
|
1876
|
+
fireDragOver(dropzone, data);
|
|
1877
|
+
expect(props.onDragOver).not.toHaveBeenCalled();
|
|
1572
1878
|
|
|
1573
|
-
fireDragLeave(dropzone, data)
|
|
1574
|
-
expect(props.onDragLeave).not.toHaveBeenCalled()
|
|
1879
|
+
fireDragLeave(dropzone, data);
|
|
1880
|
+
expect(props.onDragLeave).not.toHaveBeenCalled();
|
|
1575
1881
|
|
|
1576
|
-
fireDrop(dropzone, data)
|
|
1577
|
-
await flushPromises(rerender, ui)
|
|
1578
|
-
expect(props.onDrop).not.toHaveBeenCalled()
|
|
1579
|
-
expect(props.onDropAccepted).not.toHaveBeenCalled()
|
|
1580
|
-
expect(props.onDropRejected).not.toHaveBeenCalled()
|
|
1581
|
-
})
|
|
1882
|
+
fireDrop(dropzone, data);
|
|
1883
|
+
await flushPromises(rerender, ui);
|
|
1884
|
+
expect(props.onDrop).not.toHaveBeenCalled();
|
|
1885
|
+
expect(props.onDropAccepted).not.toHaveBeenCalled();
|
|
1886
|
+
expect(props.onDropRejected).not.toHaveBeenCalled();
|
|
1887
|
+
});
|
|
1582
1888
|
|
|
1583
|
-
it(
|
|
1584
|
-
const data = createDtWithFiles(files)
|
|
1889
|
+
it("does not invoke callbacks if {noDrag} is true", async () => {
|
|
1890
|
+
const data = createDtWithFiles(files);
|
|
1585
1891
|
|
|
1586
1892
|
const props = {
|
|
1587
1893
|
onDragEnter: jest.fn(),
|
|
@@ -1589,8 +1895,8 @@ describe('useDropzone() hook', () => {
|
|
|
1589
1895
|
onDragLeave: jest.fn(),
|
|
1590
1896
|
onDrop: jest.fn(),
|
|
1591
1897
|
onDropAccepted: jest.fn(),
|
|
1592
|
-
onDropRejected: jest.fn()
|
|
1593
|
-
}
|
|
1898
|
+
onDropRejected: jest.fn(),
|
|
1899
|
+
};
|
|
1594
1900
|
|
|
1595
1901
|
const ui = (
|
|
1596
1902
|
<Dropzone {...props} noDrag>
|
|
@@ -1600,36 +1906,36 @@ describe('useDropzone() hook', () => {
|
|
|
1600
1906
|
</div>
|
|
1601
1907
|
)}
|
|
1602
1908
|
</Dropzone>
|
|
1603
|
-
)
|
|
1604
|
-
const { container, rerender } = render(ui)
|
|
1605
|
-
const dropzone = container.querySelector(
|
|
1909
|
+
);
|
|
1910
|
+
const { container, rerender } = render(ui);
|
|
1911
|
+
const dropzone = container.querySelector("div");
|
|
1606
1912
|
|
|
1607
|
-
fireDragEnter(dropzone, data)
|
|
1608
|
-
await flushPromises(rerender, ui)
|
|
1609
|
-
expect(props.onDragEnter).not.toHaveBeenCalled()
|
|
1913
|
+
fireDragEnter(dropzone, data);
|
|
1914
|
+
await flushPromises(rerender, ui);
|
|
1915
|
+
expect(props.onDragEnter).not.toHaveBeenCalled();
|
|
1610
1916
|
|
|
1611
|
-
fireDragOver(dropzone, data)
|
|
1612
|
-
expect(props.onDragOver).not.toHaveBeenCalled()
|
|
1917
|
+
fireDragOver(dropzone, data);
|
|
1918
|
+
expect(props.onDragOver).not.toHaveBeenCalled();
|
|
1613
1919
|
|
|
1614
|
-
fireDragLeave(dropzone, data)
|
|
1615
|
-
expect(props.onDragLeave).not.toHaveBeenCalled()
|
|
1920
|
+
fireDragLeave(dropzone, data);
|
|
1921
|
+
expect(props.onDragLeave).not.toHaveBeenCalled();
|
|
1616
1922
|
|
|
1617
|
-
fireDrop(dropzone, data)
|
|
1618
|
-
await flushPromises(rerender, ui)
|
|
1619
|
-
expect(props.onDrop).not.toHaveBeenCalled()
|
|
1620
|
-
expect(props.onDropAccepted).not.toHaveBeenCalled()
|
|
1621
|
-
expect(props.onDropRejected).not.toHaveBeenCalled()
|
|
1622
|
-
})
|
|
1923
|
+
fireDrop(dropzone, data);
|
|
1924
|
+
await flushPromises(rerender, ui);
|
|
1925
|
+
expect(props.onDrop).not.toHaveBeenCalled();
|
|
1926
|
+
expect(props.onDropAccepted).not.toHaveBeenCalled();
|
|
1927
|
+
expect(props.onDropRejected).not.toHaveBeenCalled();
|
|
1928
|
+
});
|
|
1623
1929
|
|
|
1624
|
-
it(
|
|
1625
|
-
const data = createDtWithFiles(files)
|
|
1930
|
+
it("restores drag behavior if {noDrag} is set back to false", async () => {
|
|
1931
|
+
const data = createDtWithFiles(files);
|
|
1626
1932
|
|
|
1627
1933
|
const props = {
|
|
1628
1934
|
onDragEnter: jest.fn(),
|
|
1629
1935
|
onDragOver: jest.fn(),
|
|
1630
1936
|
onDragLeave: jest.fn(),
|
|
1631
|
-
onDrop: jest.fn()
|
|
1632
|
-
}
|
|
1937
|
+
onDrop: jest.fn(),
|
|
1938
|
+
};
|
|
1633
1939
|
|
|
1634
1940
|
const noDragUi = (
|
|
1635
1941
|
<Dropzone {...props} noDrag>
|
|
@@ -1639,23 +1945,23 @@ describe('useDropzone() hook', () => {
|
|
|
1639
1945
|
</div>
|
|
1640
1946
|
)}
|
|
1641
1947
|
</Dropzone>
|
|
1642
|
-
)
|
|
1643
|
-
const { container, rerender } = render(noDragUi)
|
|
1644
|
-
const dropzone = container.querySelector(
|
|
1948
|
+
);
|
|
1949
|
+
const { container, rerender } = render(noDragUi);
|
|
1950
|
+
const dropzone = container.querySelector("div");
|
|
1645
1951
|
|
|
1646
|
-
fireDragEnter(dropzone, data)
|
|
1647
|
-
await flushPromises(rerender, noDragUi)
|
|
1648
|
-
expect(props.onDragEnter).not.toHaveBeenCalled()
|
|
1952
|
+
fireDragEnter(dropzone, data);
|
|
1953
|
+
await flushPromises(rerender, noDragUi);
|
|
1954
|
+
expect(props.onDragEnter).not.toHaveBeenCalled();
|
|
1649
1955
|
|
|
1650
|
-
fireDragOver(dropzone, data)
|
|
1651
|
-
expect(props.onDragOver).not.toHaveBeenCalled()
|
|
1956
|
+
fireDragOver(dropzone, data);
|
|
1957
|
+
expect(props.onDragOver).not.toHaveBeenCalled();
|
|
1652
1958
|
|
|
1653
|
-
fireDragLeave(dropzone, data)
|
|
1654
|
-
expect(props.onDragLeave).not.toHaveBeenCalled()
|
|
1959
|
+
fireDragLeave(dropzone, data);
|
|
1960
|
+
expect(props.onDragLeave).not.toHaveBeenCalled();
|
|
1655
1961
|
|
|
1656
|
-
fireDrop(dropzone, data)
|
|
1657
|
-
await flushPromises(rerender, noDragUi)
|
|
1658
|
-
expect(props.onDrop).not.toHaveBeenCalled()
|
|
1962
|
+
fireDrop(dropzone, data);
|
|
1963
|
+
await flushPromises(rerender, noDragUi);
|
|
1964
|
+
expect(props.onDrop).not.toHaveBeenCalled();
|
|
1659
1965
|
|
|
1660
1966
|
const ui = (
|
|
1661
1967
|
<Dropzone {...props} noDrag={false}>
|
|
@@ -1665,247 +1971,293 @@ describe('useDropzone() hook', () => {
|
|
|
1665
1971
|
</div>
|
|
1666
1972
|
)}
|
|
1667
1973
|
</Dropzone>
|
|
1668
|
-
)
|
|
1669
|
-
rerender(ui)
|
|
1974
|
+
);
|
|
1975
|
+
rerender(ui);
|
|
1670
1976
|
|
|
1671
|
-
fireDragEnter(dropzone, data)
|
|
1672
|
-
await flushPromises(rerender, ui)
|
|
1673
|
-
expect(props.onDragEnter).toHaveBeenCalled()
|
|
1977
|
+
fireDragEnter(dropzone, data);
|
|
1978
|
+
await flushPromises(rerender, ui);
|
|
1979
|
+
expect(props.onDragEnter).toHaveBeenCalled();
|
|
1674
1980
|
|
|
1675
|
-
fireDragOver(dropzone, data)
|
|
1676
|
-
expect(props.onDragOver).toHaveBeenCalled()
|
|
1981
|
+
fireDragOver(dropzone, data);
|
|
1982
|
+
expect(props.onDragOver).toHaveBeenCalled();
|
|
1677
1983
|
|
|
1678
|
-
fireDragLeave(dropzone, data)
|
|
1679
|
-
expect(props.onDragLeave).toHaveBeenCalled()
|
|
1984
|
+
fireDragLeave(dropzone, data);
|
|
1985
|
+
expect(props.onDragLeave).toHaveBeenCalled();
|
|
1680
1986
|
|
|
1681
|
-
fireDrop(dropzone, data)
|
|
1682
|
-
await flushPromises(rerender, ui)
|
|
1683
|
-
expect(props.onDrop).toHaveBeenCalled()
|
|
1684
|
-
})
|
|
1987
|
+
fireDrop(dropzone, data);
|
|
1988
|
+
await flushPromises(rerender, ui);
|
|
1989
|
+
expect(props.onDrop).toHaveBeenCalled();
|
|
1990
|
+
});
|
|
1685
1991
|
|
|
1686
|
-
it(
|
|
1992
|
+
it("sets {isDragActive} and {isDragAccept} if some files are accepted on dragenter", async () => {
|
|
1687
1993
|
const ui = (
|
|
1688
1994
|
<Dropzone>
|
|
1689
|
-
{({
|
|
1995
|
+
{({
|
|
1996
|
+
getRootProps,
|
|
1997
|
+
getInputProps,
|
|
1998
|
+
isDragActive,
|
|
1999
|
+
isDragAccept,
|
|
2000
|
+
isDragReject,
|
|
2001
|
+
}) => (
|
|
1690
2002
|
<div {...getRootProps()}>
|
|
1691
2003
|
<input {...getInputProps()} />
|
|
1692
|
-
{isDragActive &&
|
|
1693
|
-
{isDragAccept &&
|
|
1694
|
-
{isDragReject &&
|
|
2004
|
+
{isDragActive && "dragActive"}
|
|
2005
|
+
{isDragAccept && "dragAccept"}
|
|
2006
|
+
{isDragReject && "dragReject"}
|
|
1695
2007
|
</div>
|
|
1696
2008
|
)}
|
|
1697
2009
|
</Dropzone>
|
|
1698
|
-
)
|
|
1699
|
-
const { container, rerender } = render(ui)
|
|
1700
|
-
const dropzone = container.querySelector(
|
|
2010
|
+
);
|
|
2011
|
+
const { container, rerender } = render(ui);
|
|
2012
|
+
const dropzone = container.querySelector("div");
|
|
1701
2013
|
|
|
1702
|
-
const data = createDtWithFiles(files)
|
|
1703
|
-
fireDragEnter(dropzone, data)
|
|
1704
|
-
await flushPromises(rerender, ui)
|
|
2014
|
+
const data = createDtWithFiles(files);
|
|
2015
|
+
fireDragEnter(dropzone, data);
|
|
2016
|
+
await flushPromises(rerender, ui);
|
|
1705
2017
|
|
|
1706
|
-
expect(dropzone).toHaveTextContent(
|
|
1707
|
-
expect(dropzone).toHaveTextContent(
|
|
1708
|
-
expect(dropzone).not.toHaveTextContent(
|
|
1709
|
-
})
|
|
2018
|
+
expect(dropzone).toHaveTextContent("dragActive");
|
|
2019
|
+
expect(dropzone).toHaveTextContent("dragAccept");
|
|
2020
|
+
expect(dropzone).not.toHaveTextContent("dragReject");
|
|
2021
|
+
});
|
|
1710
2022
|
|
|
1711
|
-
it(
|
|
2023
|
+
it("sets {isDragActive} and {isDragReject} of some files are not accepted on dragenter", async () => {
|
|
1712
2024
|
const ui = (
|
|
1713
2025
|
<Dropzone accept="image/*">
|
|
1714
|
-
{({
|
|
2026
|
+
{({
|
|
2027
|
+
getRootProps,
|
|
2028
|
+
getInputProps,
|
|
2029
|
+
isDragActive,
|
|
2030
|
+
isDragAccept,
|
|
2031
|
+
isDragReject,
|
|
2032
|
+
}) => (
|
|
1715
2033
|
<div {...getRootProps()}>
|
|
1716
2034
|
<input {...getInputProps()} />
|
|
1717
|
-
{isDragActive &&
|
|
1718
|
-
{isDragAccept &&
|
|
1719
|
-
{isDragReject &&
|
|
2035
|
+
{isDragActive && "dragActive"}
|
|
2036
|
+
{isDragAccept && "dragAccept"}
|
|
2037
|
+
{isDragReject && "dragReject"}
|
|
1720
2038
|
</div>
|
|
1721
2039
|
)}
|
|
1722
2040
|
</Dropzone>
|
|
1723
|
-
)
|
|
1724
|
-
const { container, rerender } = render(ui)
|
|
1725
|
-
const dropzone = container.querySelector(
|
|
2041
|
+
);
|
|
2042
|
+
const { container, rerender } = render(ui);
|
|
2043
|
+
const dropzone = container.querySelector("div");
|
|
1726
2044
|
|
|
1727
|
-
const data = createDtWithFiles([...files, ...images])
|
|
1728
|
-
fireDragEnter(dropzone, data)
|
|
1729
|
-
await flushPromises(rerender, ui)
|
|
2045
|
+
const data = createDtWithFiles([...files, ...images]);
|
|
2046
|
+
fireDragEnter(dropzone, data);
|
|
2047
|
+
await flushPromises(rerender, ui);
|
|
1730
2048
|
|
|
1731
|
-
expect(dropzone).toHaveTextContent(
|
|
1732
|
-
expect(dropzone).not.toHaveTextContent(
|
|
1733
|
-
expect(dropzone).toHaveTextContent(
|
|
1734
|
-
})
|
|
2049
|
+
expect(dropzone).toHaveTextContent("dragActive");
|
|
2050
|
+
expect(dropzone).not.toHaveTextContent("dragAccept");
|
|
2051
|
+
expect(dropzone).toHaveTextContent("dragReject");
|
|
2052
|
+
});
|
|
1735
2053
|
|
|
1736
|
-
it(
|
|
2054
|
+
it("sets {isDragReject} if some files are too large", async () => {
|
|
1737
2055
|
const ui = (
|
|
1738
2056
|
<Dropzone maxSize={0}>
|
|
1739
2057
|
{({ getRootProps, getInputProps, isDragAccept, isDragReject }) => (
|
|
1740
2058
|
<div {...getRootProps()}>
|
|
1741
2059
|
<input {...getInputProps()} />
|
|
1742
|
-
{isDragAccept &&
|
|
1743
|
-
{isDragReject &&
|
|
2060
|
+
{isDragAccept && "dragAccept"}
|
|
2061
|
+
{isDragReject && "dragReject"}
|
|
1744
2062
|
</div>
|
|
1745
2063
|
)}
|
|
1746
2064
|
</Dropzone>
|
|
1747
|
-
)
|
|
1748
|
-
const { container, rerender } = render(ui)
|
|
1749
|
-
const dropzone = container.querySelector(
|
|
2065
|
+
);
|
|
2066
|
+
const { container, rerender } = render(ui);
|
|
2067
|
+
const dropzone = container.querySelector("div");
|
|
1750
2068
|
|
|
1751
|
-
const data = createDtWithFiles(files)
|
|
1752
|
-
fireDragEnter(dropzone, data)
|
|
1753
|
-
await flushPromises(rerender, ui)
|
|
2069
|
+
const data = createDtWithFiles(files);
|
|
2070
|
+
fireDragEnter(dropzone, data);
|
|
2071
|
+
await flushPromises(rerender, ui);
|
|
1754
2072
|
|
|
1755
|
-
expect(dropzone).not.toHaveTextContent(
|
|
1756
|
-
expect(dropzone).toHaveTextContent(
|
|
1757
|
-
})
|
|
2073
|
+
expect(dropzone).not.toHaveTextContent("dragAccept");
|
|
2074
|
+
expect(dropzone).toHaveTextContent("dragReject");
|
|
2075
|
+
});
|
|
1758
2076
|
|
|
1759
|
-
it(
|
|
2077
|
+
it("sets {isDragActive, isDragAccept, isDragReject} if any files are rejected and {multiple} is false on dragenter", async () => {
|
|
1760
2078
|
const ui = (
|
|
1761
2079
|
<Dropzone accept="image/*" multiple={false}>
|
|
1762
|
-
{({
|
|
2080
|
+
{({
|
|
2081
|
+
getRootProps,
|
|
2082
|
+
getInputProps,
|
|
2083
|
+
isDragActive,
|
|
2084
|
+
isDragAccept,
|
|
2085
|
+
isDragReject,
|
|
2086
|
+
}) => (
|
|
1763
2087
|
<div {...getRootProps()}>
|
|
1764
2088
|
<input {...getInputProps()} />
|
|
1765
|
-
{isDragActive &&
|
|
1766
|
-
{isDragAccept &&
|
|
1767
|
-
{isDragReject &&
|
|
2089
|
+
{isDragActive && "dragActive"}
|
|
2090
|
+
{isDragAccept && "dragAccept"}
|
|
2091
|
+
{isDragReject && "dragReject"}
|
|
1768
2092
|
</div>
|
|
1769
2093
|
)}
|
|
1770
2094
|
</Dropzone>
|
|
1771
|
-
)
|
|
1772
|
-
const { container, rerender } = render(ui)
|
|
1773
|
-
const dropzone = container.querySelector(
|
|
2095
|
+
);
|
|
2096
|
+
const { container, rerender } = render(ui);
|
|
2097
|
+
const dropzone = container.querySelector("div");
|
|
1774
2098
|
|
|
1775
|
-
const data = createDtWithFiles(images)
|
|
1776
|
-
fireDragEnter(dropzone, data)
|
|
1777
|
-
await flushPromises(rerender, ui)
|
|
2099
|
+
const data = createDtWithFiles(images);
|
|
2100
|
+
fireDragEnter(dropzone, data);
|
|
2101
|
+
await flushPromises(rerender, ui);
|
|
1778
2102
|
|
|
1779
|
-
expect(dropzone).toHaveTextContent(
|
|
1780
|
-
expect(dropzone).not.toHaveTextContent(
|
|
1781
|
-
expect(dropzone).toHaveTextContent(
|
|
1782
|
-
})
|
|
2103
|
+
expect(dropzone).toHaveTextContent("dragActive");
|
|
2104
|
+
expect(dropzone).not.toHaveTextContent("dragAccept");
|
|
2105
|
+
expect(dropzone).toHaveTextContent("dragReject");
|
|
2106
|
+
});
|
|
1783
2107
|
|
|
1784
|
-
it(
|
|
1785
|
-
const { container: overlayContainer } = render(<div />)
|
|
2108
|
+
it("keeps {isDragActive} if dragleave is triggered for some arbitrary node", async () => {
|
|
2109
|
+
const { container: overlayContainer } = render(<div />);
|
|
1786
2110
|
const ui = (
|
|
1787
2111
|
<Dropzone>
|
|
1788
|
-
{({
|
|
2112
|
+
{({
|
|
2113
|
+
getRootProps,
|
|
2114
|
+
getInputProps,
|
|
2115
|
+
isDragActive,
|
|
2116
|
+
isDragAccept,
|
|
2117
|
+
isDragReject,
|
|
2118
|
+
}) => (
|
|
1789
2119
|
<div {...getRootProps()}>
|
|
1790
2120
|
<input {...getInputProps()} />
|
|
1791
|
-
{isDragActive &&
|
|
1792
|
-
{isDragAccept &&
|
|
1793
|
-
{isDragReject &&
|
|
2121
|
+
{isDragActive && "dragActive"}
|
|
2122
|
+
{isDragAccept && "dragAccept"}
|
|
2123
|
+
{isDragReject && "dragReject"}
|
|
1794
2124
|
</div>
|
|
1795
2125
|
)}
|
|
1796
2126
|
</Dropzone>
|
|
1797
|
-
)
|
|
1798
|
-
const { container, rerender } = render(ui)
|
|
1799
|
-
const dropzone = container.querySelector(
|
|
2127
|
+
);
|
|
2128
|
+
const { container, rerender } = render(ui);
|
|
2129
|
+
const dropzone = container.querySelector("div");
|
|
1800
2130
|
|
|
1801
|
-
const data = createDtWithFiles(files)
|
|
1802
|
-
fireDragEnter(dropzone, data)
|
|
1803
|
-
await flushPromises(rerender, ui)
|
|
2131
|
+
const data = createDtWithFiles(files);
|
|
2132
|
+
fireDragEnter(dropzone, data);
|
|
2133
|
+
await flushPromises(rerender, ui);
|
|
1804
2134
|
|
|
1805
|
-
const event = new Event(
|
|
1806
|
-
Object.defineProperty(event,
|
|
1807
|
-
value: overlayContainer.querySelector(
|
|
1808
|
-
writable: false
|
|
1809
|
-
})
|
|
1810
|
-
fireEvent(dropzone, event)
|
|
2135
|
+
const event = new Event("dragleave", { bubbles: true });
|
|
2136
|
+
Object.defineProperty(event, "target", {
|
|
2137
|
+
value: overlayContainer.querySelector("div"),
|
|
2138
|
+
writable: false,
|
|
2139
|
+
});
|
|
2140
|
+
fireEvent(dropzone, event);
|
|
1811
2141
|
|
|
1812
|
-
expect(dropzone).toHaveTextContent(
|
|
1813
|
-
})
|
|
2142
|
+
expect(dropzone).toHaveTextContent("dragActive");
|
|
2143
|
+
});
|
|
1814
2144
|
|
|
1815
|
-
it(
|
|
2145
|
+
it("updates {isDragActive} if {accept} changes mid-drag", async () => {
|
|
1816
2146
|
const ui = (
|
|
1817
2147
|
<Dropzone accept="image/*">
|
|
1818
|
-
{({
|
|
2148
|
+
{({
|
|
2149
|
+
getRootProps,
|
|
2150
|
+
getInputProps,
|
|
2151
|
+
isDragActive,
|
|
2152
|
+
isDragAccept,
|
|
2153
|
+
isDragReject,
|
|
2154
|
+
}) => (
|
|
1819
2155
|
<div {...getRootProps()}>
|
|
1820
2156
|
<input {...getInputProps()} />
|
|
1821
|
-
{isDragActive &&
|
|
1822
|
-
{isDragAccept &&
|
|
1823
|
-
{isDragReject &&
|
|
2157
|
+
{isDragActive && "dragActive"}
|
|
2158
|
+
{isDragAccept && "dragAccept"}
|
|
2159
|
+
{isDragReject && "dragReject"}
|
|
1824
2160
|
</div>
|
|
1825
2161
|
)}
|
|
1826
2162
|
</Dropzone>
|
|
1827
|
-
)
|
|
1828
|
-
const { container, rerender } = render(ui)
|
|
1829
|
-
const dropzone = container.querySelector(
|
|
2163
|
+
);
|
|
2164
|
+
const { container, rerender } = render(ui);
|
|
2165
|
+
const dropzone = container.querySelector("div");
|
|
1830
2166
|
|
|
1831
|
-
const data = createDtWithFiles(images)
|
|
1832
|
-
fireDragEnter(dropzone, data)
|
|
1833
|
-
await flushPromises(rerender, ui)
|
|
2167
|
+
const data = createDtWithFiles(images);
|
|
2168
|
+
fireDragEnter(dropzone, data);
|
|
2169
|
+
await flushPromises(rerender, ui);
|
|
1834
2170
|
|
|
1835
|
-
expect(dropzone).toHaveTextContent(
|
|
1836
|
-
expect(dropzone).toHaveTextContent(
|
|
1837
|
-
expect(dropzone).not.toHaveTextContent(
|
|
2171
|
+
expect(dropzone).toHaveTextContent("dragActive");
|
|
2172
|
+
expect(dropzone).toHaveTextContent("dragAccept");
|
|
2173
|
+
expect(dropzone).not.toHaveTextContent("dragReject");
|
|
1838
2174
|
|
|
1839
2175
|
rerender(
|
|
1840
2176
|
<Dropzone accept="text/*">
|
|
1841
|
-
{({
|
|
2177
|
+
{({
|
|
2178
|
+
getRootProps,
|
|
2179
|
+
getInputProps,
|
|
2180
|
+
isDragActive,
|
|
2181
|
+
isDragAccept,
|
|
2182
|
+
isDragReject,
|
|
2183
|
+
}) => (
|
|
1842
2184
|
<div {...getRootProps()}>
|
|
1843
2185
|
<input {...getInputProps()} />
|
|
1844
|
-
{isDragActive &&
|
|
1845
|
-
{isDragAccept &&
|
|
1846
|
-
{isDragReject &&
|
|
2186
|
+
{isDragActive && "dragActive"}
|
|
2187
|
+
{isDragAccept && "dragAccept"}
|
|
2188
|
+
{isDragReject && "dragReject"}
|
|
1847
2189
|
</div>
|
|
1848
2190
|
)}
|
|
1849
2191
|
</Dropzone>
|
|
1850
|
-
)
|
|
2192
|
+
);
|
|
1851
2193
|
|
|
1852
|
-
expect(dropzone).toHaveTextContent(
|
|
1853
|
-
expect(dropzone).not.toHaveTextContent(
|
|
1854
|
-
expect(dropzone).toHaveTextContent(
|
|
1855
|
-
})
|
|
2194
|
+
expect(dropzone).toHaveTextContent("dragActive");
|
|
2195
|
+
expect(dropzone).not.toHaveTextContent("dragAccept");
|
|
2196
|
+
expect(dropzone).toHaveTextContent("dragReject");
|
|
2197
|
+
});
|
|
1856
2198
|
|
|
1857
|
-
it(
|
|
2199
|
+
it("resets {isDragActive, isDragAccept, isDragReject} on dragleave", async () => {
|
|
1858
2200
|
const ui = (
|
|
1859
2201
|
<Dropzone accept="image/*">
|
|
1860
|
-
{({
|
|
1861
|
-
|
|
1862
|
-
|
|
1863
|
-
|
|
1864
|
-
|
|
1865
|
-
|
|
2202
|
+
{({
|
|
2203
|
+
getRootProps,
|
|
2204
|
+
getInputProps,
|
|
2205
|
+
isDragActive,
|
|
2206
|
+
isDragAccept,
|
|
2207
|
+
isDragReject,
|
|
2208
|
+
}) => (
|
|
2209
|
+
<div {...getRootProps()}>
|
|
2210
|
+
<input {...getInputProps()} />
|
|
2211
|
+
{isDragActive && "dragActive"}
|
|
2212
|
+
{isDragAccept && "dragAccept"}
|
|
2213
|
+
{isDragReject && "dragReject"}
|
|
1866
2214
|
{!isDragActive && (
|
|
1867
|
-
<span
|
|
2215
|
+
<span
|
|
2216
|
+
id="child"
|
|
2217
|
+
data-accept={isDragAccept}
|
|
2218
|
+
data-reject={isDragReject}
|
|
2219
|
+
/>
|
|
1868
2220
|
)}
|
|
1869
2221
|
</div>
|
|
1870
2222
|
)}
|
|
1871
2223
|
</Dropzone>
|
|
1872
|
-
)
|
|
1873
|
-
const { container, rerender } = render(ui)
|
|
1874
|
-
const dropzone = container.querySelector(
|
|
2224
|
+
);
|
|
2225
|
+
const { container, rerender } = render(ui);
|
|
2226
|
+
const dropzone = container.querySelector("div");
|
|
1875
2227
|
|
|
1876
|
-
const data = createDtWithFiles(images)
|
|
2228
|
+
const data = createDtWithFiles(images);
|
|
1877
2229
|
|
|
1878
|
-
fireDragEnter(container.querySelector(
|
|
1879
|
-
fireDragEnter(dropzone, data)
|
|
1880
|
-
await flushPromises(rerender, ui)
|
|
1881
|
-
fireDragEnter(dropzone, data)
|
|
1882
|
-
await flushPromises(rerender, ui)
|
|
2230
|
+
fireDragEnter(container.querySelector("#child"), data);
|
|
2231
|
+
fireDragEnter(dropzone, data);
|
|
2232
|
+
await flushPromises(rerender, ui);
|
|
2233
|
+
fireDragEnter(dropzone, data);
|
|
2234
|
+
await flushPromises(rerender, ui);
|
|
1883
2235
|
|
|
1884
|
-
expect(dropzone).toHaveTextContent(
|
|
1885
|
-
expect(dropzone).toHaveTextContent(
|
|
1886
|
-
expect(dropzone).not.toHaveTextContent(
|
|
2236
|
+
expect(dropzone).toHaveTextContent("dragActive");
|
|
2237
|
+
expect(dropzone).toHaveTextContent("dragAccept");
|
|
2238
|
+
expect(dropzone).not.toHaveTextContent("dragReject");
|
|
1887
2239
|
|
|
1888
|
-
fireDragLeave(dropzone, data)
|
|
1889
|
-
await flushPromises(rerender, ui)
|
|
1890
|
-
expect(dropzone).toHaveTextContent(
|
|
1891
|
-
expect(dropzone).toHaveTextContent(
|
|
1892
|
-
expect(dropzone).not.toHaveTextContent(
|
|
2240
|
+
fireDragLeave(dropzone, data);
|
|
2241
|
+
await flushPromises(rerender, ui);
|
|
2242
|
+
expect(dropzone).toHaveTextContent("dragActive");
|
|
2243
|
+
expect(dropzone).toHaveTextContent("dragAccept");
|
|
2244
|
+
expect(dropzone).not.toHaveTextContent("dragReject");
|
|
1893
2245
|
|
|
1894
|
-
fireDragLeave(dropzone, data)
|
|
1895
|
-
await flushPromises(rerender, ui)
|
|
1896
|
-
expect(dropzone).not.toHaveTextContent(
|
|
1897
|
-
expect(dropzone).not.toHaveTextContent(
|
|
1898
|
-
expect(dropzone).not.toHaveTextContent(
|
|
2246
|
+
fireDragLeave(dropzone, data);
|
|
2247
|
+
await flushPromises(rerender, ui);
|
|
2248
|
+
expect(dropzone).not.toHaveTextContent("dragActive");
|
|
2249
|
+
expect(dropzone).not.toHaveTextContent("dragAccept");
|
|
2250
|
+
expect(dropzone).not.toHaveTextContent("dragReject");
|
|
1899
2251
|
|
|
1900
|
-
const child = container.querySelector(
|
|
1901
|
-
expect(child).toHaveAttribute(
|
|
1902
|
-
expect(child).toHaveAttribute(
|
|
1903
|
-
})
|
|
1904
|
-
})
|
|
2252
|
+
const child = container.querySelector("#child");
|
|
2253
|
+
expect(child).toHaveAttribute("data-accept", "false");
|
|
2254
|
+
expect(child).toHaveAttribute("data-reject", "false");
|
|
2255
|
+
});
|
|
2256
|
+
});
|
|
1905
2257
|
|
|
1906
|
-
describe(
|
|
1907
|
-
test(
|
|
1908
|
-
const onDropSpy = jest.fn()
|
|
2258
|
+
describe("onDrop", () => {
|
|
2259
|
+
test("callback is invoked when <input> change event occurs", async () => {
|
|
2260
|
+
const onDropSpy = jest.fn();
|
|
1909
2261
|
|
|
1910
2262
|
const ui = (
|
|
1911
2263
|
<Dropzone onDrop={onDropSpy}>
|
|
@@ -1915,28 +2267,28 @@ describe('useDropzone() hook', () => {
|
|
|
1915
2267
|
</div>
|
|
1916
2268
|
)}
|
|
1917
2269
|
</Dropzone>
|
|
1918
|
-
)
|
|
1919
|
-
const { container, rerender } = render(ui)
|
|
1920
|
-
const input = container.querySelector(
|
|
2270
|
+
);
|
|
2271
|
+
const { container, rerender } = render(ui);
|
|
2272
|
+
const input = container.querySelector("input");
|
|
1921
2273
|
|
|
1922
|
-
Object.defineProperty(input,
|
|
2274
|
+
Object.defineProperty(input, "files", { value: files });
|
|
1923
2275
|
|
|
1924
|
-
dispatchEvt(input,
|
|
1925
|
-
await flushPromises(rerender, ui)
|
|
2276
|
+
dispatchEvt(input, "change");
|
|
2277
|
+
await flushPromises(rerender, ui);
|
|
1926
2278
|
|
|
1927
|
-
expect(onDropSpy).toHaveBeenCalledWith(files, [], expect.anything())
|
|
1928
|
-
})
|
|
2279
|
+
expect(onDropSpy).toHaveBeenCalledWith(files, [], expect.anything());
|
|
2280
|
+
});
|
|
1929
2281
|
|
|
1930
|
-
it(
|
|
2282
|
+
it("sets {acceptedFiles, fileRejections}", async () => {
|
|
1931
2283
|
const FileList = ({ files = [] }) => (
|
|
1932
2284
|
<ul>
|
|
1933
|
-
{files.map(file => (
|
|
1934
|
-
<li key={file.name} data-type={
|
|
2285
|
+
{files.map((file) => (
|
|
2286
|
+
<li key={file.name} data-type={"accepted"}>
|
|
1935
2287
|
{file.name}
|
|
1936
2288
|
</li>
|
|
1937
2289
|
))}
|
|
1938
2290
|
</ul>
|
|
1939
|
-
)
|
|
2291
|
+
);
|
|
1940
2292
|
|
|
1941
2293
|
const RejectedFileList = ({ fileRejections = [] }) => (
|
|
1942
2294
|
<ul>
|
|
@@ -1944,7 +2296,7 @@ describe('useDropzone() hook', () => {
|
|
|
1944
2296
|
<li key={file.name}>
|
|
1945
2297
|
<span data-type={"rejected"}>{file.name}</span>
|
|
1946
2298
|
<ul>
|
|
1947
|
-
{errors.map(e => (
|
|
2299
|
+
{errors.map((e) => (
|
|
1948
2300
|
<li key={e.code} data-type={"error"}>
|
|
1949
2301
|
{e.code}
|
|
1950
2302
|
</li>
|
|
@@ -1953,15 +2305,20 @@ describe('useDropzone() hook', () => {
|
|
|
1953
2305
|
</li>
|
|
1954
2306
|
))}
|
|
1955
2307
|
</ul>
|
|
1956
|
-
)
|
|
1957
|
-
|
|
1958
|
-
const getAcceptedFiles = node =>
|
|
1959
|
-
|
|
1960
|
-
const
|
|
2308
|
+
);
|
|
2309
|
+
|
|
2310
|
+
const getAcceptedFiles = (node) =>
|
|
2311
|
+
node.querySelectorAll(`[data-type="accepted"]`);
|
|
2312
|
+
const getRejectedFiles = (node) =>
|
|
2313
|
+
node.querySelectorAll(`[data-type="rejected"]`);
|
|
2314
|
+
const getRejectedFilesErrors = (node) =>
|
|
2315
|
+
node.querySelectorAll(`[data-type="error"]`);
|
|
1961
2316
|
const matchToFiles = (fileList, files) =>
|
|
1962
|
-
Array.from(fileList).every(
|
|
2317
|
+
Array.from(fileList).every(
|
|
2318
|
+
(item) => !!files.find((file) => file.name === item.textContent)
|
|
2319
|
+
);
|
|
1963
2320
|
const matchToErrorCode = (errorList, code) =>
|
|
1964
|
-
Array.from(errorList).every(item => item.textContent === code)
|
|
2321
|
+
Array.from(errorList).every((item) => item.textContent === code);
|
|
1965
2322
|
|
|
1966
2323
|
const ui = (
|
|
1967
2324
|
<Dropzone accept="image/*">
|
|
@@ -1973,60 +2330,68 @@ describe('useDropzone() hook', () => {
|
|
|
1973
2330
|
</div>
|
|
1974
2331
|
)}
|
|
1975
2332
|
</Dropzone>
|
|
1976
|
-
)
|
|
1977
|
-
const { container, rerender } = render(ui)
|
|
1978
|
-
const dropzone = container.querySelector(
|
|
2333
|
+
);
|
|
2334
|
+
const { container, rerender } = render(ui);
|
|
2335
|
+
const dropzone = container.querySelector("div");
|
|
1979
2336
|
|
|
1980
|
-
fireDrop(dropzone, createDtWithFiles(images))
|
|
1981
|
-
await flushPromises(rerender, ui)
|
|
1982
|
-
const acceptedFileList = getAcceptedFiles(dropzone)
|
|
1983
|
-
expect(acceptedFileList).toHaveLength(images.length)
|
|
1984
|
-
expect(matchToFiles(acceptedFileList, images)).toBe(true)
|
|
2337
|
+
fireDrop(dropzone, createDtWithFiles(images));
|
|
2338
|
+
await flushPromises(rerender, ui);
|
|
2339
|
+
const acceptedFileList = getAcceptedFiles(dropzone);
|
|
2340
|
+
expect(acceptedFileList).toHaveLength(images.length);
|
|
2341
|
+
expect(matchToFiles(acceptedFileList, images)).toBe(true);
|
|
1985
2342
|
|
|
1986
|
-
fireDrop(dropzone, createDtWithFiles(files))
|
|
1987
|
-
await flushPromises(rerender, ui)
|
|
1988
|
-
const rejectedFileList = getRejectedFiles(dropzone)
|
|
1989
|
-
expect(rejectedFileList).toHaveLength(files.length)
|
|
1990
|
-
expect(matchToFiles(rejectedFileList, files)).toBe(true)
|
|
1991
|
-
const rejectedFileErrorList = getRejectedFilesErrors(dropzone)
|
|
1992
|
-
expect(rejectedFileErrorList).toHaveLength(files.length)
|
|
1993
|
-
expect(matchToErrorCode(rejectedFileErrorList,
|
|
1994
|
-
|
|
2343
|
+
fireDrop(dropzone, createDtWithFiles(files));
|
|
2344
|
+
await flushPromises(rerender, ui);
|
|
2345
|
+
const rejectedFileList = getRejectedFiles(dropzone);
|
|
2346
|
+
expect(rejectedFileList).toHaveLength(files.length);
|
|
2347
|
+
expect(matchToFiles(rejectedFileList, files)).toBe(true);
|
|
2348
|
+
const rejectedFileErrorList = getRejectedFilesErrors(dropzone);
|
|
2349
|
+
expect(rejectedFileErrorList).toHaveLength(files.length);
|
|
2350
|
+
expect(matchToErrorCode(rejectedFileErrorList, "file-invalid-type")).toBe(
|
|
2351
|
+
true
|
|
2352
|
+
);
|
|
2353
|
+
});
|
|
1995
2354
|
|
|
1996
|
-
it(
|
|
2355
|
+
it("resets {isDragActive, isDragAccept, isDragReject}", async () => {
|
|
1997
2356
|
const ui = (
|
|
1998
2357
|
<Dropzone>
|
|
1999
|
-
{({
|
|
2358
|
+
{({
|
|
2359
|
+
getRootProps,
|
|
2360
|
+
getInputProps,
|
|
2361
|
+
isDragActive,
|
|
2362
|
+
isDragAccept,
|
|
2363
|
+
isDragReject,
|
|
2364
|
+
}) => (
|
|
2000
2365
|
<div {...getRootProps()}>
|
|
2001
2366
|
<input {...getInputProps()} />
|
|
2002
|
-
{isDragActive &&
|
|
2003
|
-
{isDragAccept &&
|
|
2004
|
-
{isDragReject &&
|
|
2367
|
+
{isDragActive && "dragActive"}
|
|
2368
|
+
{isDragAccept && "dragAccept"}
|
|
2369
|
+
{isDragReject && "dragReject"}
|
|
2005
2370
|
</div>
|
|
2006
2371
|
)}
|
|
2007
2372
|
</Dropzone>
|
|
2008
|
-
)
|
|
2009
|
-
const { container, rerender } = render(ui)
|
|
2010
|
-
const dropzone = container.querySelector(
|
|
2373
|
+
);
|
|
2374
|
+
const { container, rerender } = render(ui);
|
|
2375
|
+
const dropzone = container.querySelector("div");
|
|
2011
2376
|
|
|
2012
|
-
const data = createDtWithFiles(files)
|
|
2377
|
+
const data = createDtWithFiles(files);
|
|
2013
2378
|
|
|
2014
|
-
fireDragEnter(dropzone, data)
|
|
2015
|
-
await flushPromises(rerender, ui)
|
|
2379
|
+
fireDragEnter(dropzone, data);
|
|
2380
|
+
await flushPromises(rerender, ui);
|
|
2016
2381
|
|
|
2017
|
-
expect(dropzone).toHaveTextContent(
|
|
2018
|
-
expect(dropzone).toHaveTextContent(
|
|
2019
|
-
expect(dropzone).not.toHaveTextContent(
|
|
2382
|
+
expect(dropzone).toHaveTextContent("dragActive");
|
|
2383
|
+
expect(dropzone).toHaveTextContent("dragAccept");
|
|
2384
|
+
expect(dropzone).not.toHaveTextContent("dragReject");
|
|
2020
2385
|
|
|
2021
|
-
fireDrop(dropzone, data)
|
|
2022
|
-
await flushPromises(rerender, ui)
|
|
2023
|
-
expect(dropzone).not.toHaveTextContent(
|
|
2024
|
-
expect(dropzone).not.toHaveTextContent(
|
|
2025
|
-
expect(dropzone).not.toHaveTextContent(
|
|
2026
|
-
})
|
|
2386
|
+
fireDrop(dropzone, data);
|
|
2387
|
+
await flushPromises(rerender, ui);
|
|
2388
|
+
expect(dropzone).not.toHaveTextContent("dragActive");
|
|
2389
|
+
expect(dropzone).not.toHaveTextContent("dragAccept");
|
|
2390
|
+
expect(dropzone).not.toHaveTextContent("dragReject");
|
|
2391
|
+
});
|
|
2027
2392
|
|
|
2028
|
-
it(
|
|
2029
|
-
const onDropSpy = jest.fn()
|
|
2393
|
+
it("rejects all files if {multiple} is false and {accept} criteria is not met", async () => {
|
|
2394
|
+
const onDropSpy = jest.fn();
|
|
2030
2395
|
const ui = (
|
|
2031
2396
|
<Dropzone accept="image/*" onDrop={onDropSpy} multiple={false}>
|
|
2032
2397
|
{({ getRootProps, getInputProps }) => (
|
|
@@ -2035,27 +2400,31 @@ describe('useDropzone() hook', () => {
|
|
|
2035
2400
|
</div>
|
|
2036
2401
|
)}
|
|
2037
2402
|
</Dropzone>
|
|
2038
|
-
)
|
|
2039
|
-
const { container, rerender } = render(ui)
|
|
2040
|
-
const dropzone = container.querySelector(
|
|
2403
|
+
);
|
|
2404
|
+
const { container, rerender } = render(ui);
|
|
2405
|
+
const dropzone = container.querySelector("div");
|
|
2041
2406
|
|
|
2042
|
-
fireDrop(dropzone, createDtWithFiles(files))
|
|
2043
|
-
await flushPromises(rerender, ui)
|
|
2044
|
-
expect(onDropSpy).toHaveBeenCalledWith(
|
|
2045
|
-
|
|
2046
|
-
|
|
2047
|
-
|
|
2048
|
-
|
|
2049
|
-
|
|
2050
|
-
|
|
2051
|
-
|
|
2052
|
-
|
|
2053
|
-
|
|
2054
|
-
|
|
2055
|
-
|
|
2407
|
+
fireDrop(dropzone, createDtWithFiles(files));
|
|
2408
|
+
await flushPromises(rerender, ui);
|
|
2409
|
+
expect(onDropSpy).toHaveBeenCalledWith(
|
|
2410
|
+
[],
|
|
2411
|
+
[
|
|
2412
|
+
{
|
|
2413
|
+
file: files[0],
|
|
2414
|
+
errors: [
|
|
2415
|
+
{
|
|
2416
|
+
code: "file-invalid-type",
|
|
2417
|
+
message: "File type must be image/*",
|
|
2418
|
+
},
|
|
2419
|
+
],
|
|
2420
|
+
},
|
|
2421
|
+
],
|
|
2422
|
+
expect.anything()
|
|
2423
|
+
);
|
|
2424
|
+
});
|
|
2056
2425
|
|
|
2057
|
-
it(
|
|
2058
|
-
const onDropSpy = jest.fn()
|
|
2426
|
+
it("rejects all files if {multiple} is false and {accept} criteria is met", async () => {
|
|
2427
|
+
const onDropSpy = jest.fn();
|
|
2059
2428
|
const ui = (
|
|
2060
2429
|
<Dropzone accept="image/*" onDrop={onDropSpy} multiple={false}>
|
|
2061
2430
|
{({ getRootProps, getInputProps }) => (
|
|
@@ -2064,132 +2433,162 @@ describe('useDropzone() hook', () => {
|
|
|
2064
2433
|
</div>
|
|
2065
2434
|
)}
|
|
2066
2435
|
</Dropzone>
|
|
2067
|
-
)
|
|
2068
|
-
const { container, rerender } = render(ui)
|
|
2069
|
-
const dropzone = container.querySelector(
|
|
2070
|
-
|
|
2071
|
-
fireDrop(dropzone, createDtWithFiles(images))
|
|
2072
|
-
await flushPromises(rerender, ui)
|
|
2073
|
-
expect(onDropSpy).toHaveBeenCalledWith(
|
|
2074
|
-
|
|
2075
|
-
|
|
2076
|
-
|
|
2077
|
-
|
|
2078
|
-
|
|
2079
|
-
|
|
2080
|
-
|
|
2081
|
-
|
|
2082
|
-
|
|
2083
|
-
|
|
2084
|
-
|
|
2085
|
-
|
|
2086
|
-
|
|
2087
|
-
|
|
2088
|
-
|
|
2089
|
-
|
|
2090
|
-
|
|
2091
|
-
|
|
2092
|
-
|
|
2093
|
-
|
|
2436
|
+
);
|
|
2437
|
+
const { container, rerender } = render(ui);
|
|
2438
|
+
const dropzone = container.querySelector("div");
|
|
2439
|
+
|
|
2440
|
+
fireDrop(dropzone, createDtWithFiles(images));
|
|
2441
|
+
await flushPromises(rerender, ui);
|
|
2442
|
+
expect(onDropSpy).toHaveBeenCalledWith(
|
|
2443
|
+
[],
|
|
2444
|
+
[
|
|
2445
|
+
{
|
|
2446
|
+
file: images[0],
|
|
2447
|
+
errors: [
|
|
2448
|
+
{
|
|
2449
|
+
code: "too-many-files",
|
|
2450
|
+
message: "Too many files",
|
|
2451
|
+
},
|
|
2452
|
+
],
|
|
2453
|
+
},
|
|
2454
|
+
{
|
|
2455
|
+
file: images[1],
|
|
2456
|
+
errors: [
|
|
2457
|
+
{
|
|
2458
|
+
code: "too-many-files",
|
|
2459
|
+
message: "Too many files",
|
|
2460
|
+
},
|
|
2461
|
+
],
|
|
2462
|
+
},
|
|
2463
|
+
],
|
|
2464
|
+
expect.anything()
|
|
2465
|
+
);
|
|
2466
|
+
});
|
|
2094
2467
|
|
|
2095
|
-
it(
|
|
2096
|
-
const onDropSpy = jest.fn()
|
|
2097
|
-
const onDropRejectedSpy = jest.fn()
|
|
2468
|
+
it("rejects all files if {multiple} is true and maxFiles is less than files and {accept} criteria is met", async () => {
|
|
2469
|
+
const onDropSpy = jest.fn();
|
|
2470
|
+
const onDropRejectedSpy = jest.fn();
|
|
2098
2471
|
const ui = (
|
|
2099
|
-
<Dropzone
|
|
2472
|
+
<Dropzone
|
|
2473
|
+
accept="image/*"
|
|
2474
|
+
onDrop={onDropSpy}
|
|
2475
|
+
onDropRejected={onDropRejectedSpy}
|
|
2476
|
+
multiple={true}
|
|
2477
|
+
maxFiles={1}
|
|
2478
|
+
>
|
|
2100
2479
|
{({ getRootProps, getInputProps, isDragReject, isDragAccept }) => (
|
|
2101
2480
|
<div {...getRootProps()}>
|
|
2102
2481
|
<input {...getInputProps()} />
|
|
2103
|
-
|
|
2104
|
-
|
|
2105
|
-
</div>
|
|
2106
|
-
)}
|
|
2107
|
-
</Dropzone>
|
|
2108
|
-
)
|
|
2109
|
-
const { container, rerender } = render(ui)
|
|
2110
|
-
const dropzone = container.querySelector(
|
|
2111
|
-
fireDrop(dropzone, createDtWithFiles(images))
|
|
2112
|
-
await flushPromises(rerender, ui)
|
|
2113
|
-
expect(onDropRejectedSpy).toHaveBeenCalled()
|
|
2114
|
-
fireDragEnter(dropzone, createDtWithFiles(images))
|
|
2115
|
-
await flushPromises(rerender, ui)
|
|
2116
|
-
expect(dropzone).toHaveTextContent(
|
|
2117
|
-
expect(dropzone).not.toHaveTextContent(
|
|
2118
|
-
expect(onDropSpy).toHaveBeenCalledWith(
|
|
2119
|
-
|
|
2120
|
-
|
|
2121
|
-
|
|
2122
|
-
|
|
2123
|
-
|
|
2124
|
-
|
|
2125
|
-
|
|
2126
|
-
|
|
2127
|
-
|
|
2128
|
-
|
|
2129
|
-
|
|
2130
|
-
|
|
2131
|
-
|
|
2132
|
-
|
|
2133
|
-
|
|
2134
|
-
|
|
2135
|
-
|
|
2136
|
-
|
|
2137
|
-
|
|
2138
|
-
|
|
2482
|
+
{isDragReject && "dragReject"}
|
|
2483
|
+
{isDragAccept && "dragAccept"}
|
|
2484
|
+
</div>
|
|
2485
|
+
)}
|
|
2486
|
+
</Dropzone>
|
|
2487
|
+
);
|
|
2488
|
+
const { container, rerender } = render(ui);
|
|
2489
|
+
const dropzone = container.querySelector("div");
|
|
2490
|
+
fireDrop(dropzone, createDtWithFiles(images));
|
|
2491
|
+
await flushPromises(rerender, ui);
|
|
2492
|
+
expect(onDropRejectedSpy).toHaveBeenCalled();
|
|
2493
|
+
fireDragEnter(dropzone, createDtWithFiles(images));
|
|
2494
|
+
await flushPromises(rerender, ui);
|
|
2495
|
+
expect(dropzone).toHaveTextContent("dragReject");
|
|
2496
|
+
expect(dropzone).not.toHaveTextContent("dragAccept");
|
|
2497
|
+
expect(onDropSpy).toHaveBeenCalledWith(
|
|
2498
|
+
[],
|
|
2499
|
+
[
|
|
2500
|
+
{
|
|
2501
|
+
file: images[0],
|
|
2502
|
+
errors: [
|
|
2503
|
+
{
|
|
2504
|
+
code: "too-many-files",
|
|
2505
|
+
message: "Too many files",
|
|
2506
|
+
},
|
|
2507
|
+
],
|
|
2508
|
+
},
|
|
2509
|
+
{
|
|
2510
|
+
file: images[1],
|
|
2511
|
+
errors: [
|
|
2512
|
+
{
|
|
2513
|
+
code: "too-many-files",
|
|
2514
|
+
message: "Too many files",
|
|
2515
|
+
},
|
|
2516
|
+
],
|
|
2517
|
+
},
|
|
2518
|
+
],
|
|
2519
|
+
expect.anything()
|
|
2520
|
+
);
|
|
2521
|
+
});
|
|
2139
2522
|
|
|
2140
|
-
it(
|
|
2141
|
-
const onDropSpy = jest.fn()
|
|
2142
|
-
const onDropRejectedSpy = jest.fn()
|
|
2523
|
+
it("rejects all files if {multiple} is true and maxFiles has been updated so that it is less than files", async () => {
|
|
2524
|
+
const onDropSpy = jest.fn();
|
|
2525
|
+
const onDropRejectedSpy = jest.fn();
|
|
2143
2526
|
const ui = (maxFiles) => (
|
|
2144
|
-
<Dropzone
|
|
2527
|
+
<Dropzone
|
|
2528
|
+
accept="image/*"
|
|
2529
|
+
onDrop={onDropSpy}
|
|
2530
|
+
multiple={true}
|
|
2531
|
+
maxFiles={maxFiles}
|
|
2532
|
+
onDropRejected={onDropRejectedSpy}
|
|
2533
|
+
>
|
|
2145
2534
|
{({ getRootProps, getInputProps }) => (
|
|
2146
2535
|
<div {...getRootProps()}>
|
|
2147
2536
|
<input {...getInputProps()} />
|
|
2148
2537
|
</div>
|
|
2149
2538
|
)}
|
|
2150
2539
|
</Dropzone>
|
|
2151
|
-
)
|
|
2152
|
-
const { container, rerender } = render(ui(3))
|
|
2153
|
-
const dropzone = container.querySelector(
|
|
2540
|
+
);
|
|
2541
|
+
const { container, rerender } = render(ui(3));
|
|
2542
|
+
const dropzone = container.querySelector("div");
|
|
2154
2543
|
|
|
2155
|
-
fireDrop(dropzone, createDtWithFiles(images))
|
|
2156
|
-
await flushPromises(rerender, ui(3))
|
|
2157
|
-
expect(onDropRejectedSpy).not.toHaveBeenCalled()
|
|
2158
|
-
expect(onDropSpy).toHaveBeenCalledWith(images, [], expect.anything())
|
|
2544
|
+
fireDrop(dropzone, createDtWithFiles(images));
|
|
2545
|
+
await flushPromises(rerender, ui(3));
|
|
2546
|
+
expect(onDropRejectedSpy).not.toHaveBeenCalled();
|
|
2547
|
+
expect(onDropSpy).toHaveBeenCalledWith(images, [], expect.anything());
|
|
2159
2548
|
|
|
2160
2549
|
rerender(ui(1));
|
|
2161
2550
|
|
|
2162
|
-
fireDrop(dropzone, createDtWithFiles(images))
|
|
2163
|
-
await flushPromises(rerender, ui(1))
|
|
2551
|
+
fireDrop(dropzone, createDtWithFiles(images));
|
|
2552
|
+
await flushPromises(rerender, ui(1));
|
|
2164
2553
|
expect(onDropRejectedSpy).toHaveBeenCalledWith(
|
|
2165
|
-
expect.arrayContaining(
|
|
2554
|
+
expect.arrayContaining(
|
|
2555
|
+
images.map((image) =>
|
|
2556
|
+
expect.objectContaining({ errors: expect.any(Array), file: image })
|
|
2557
|
+
)
|
|
2558
|
+
),
|
|
2166
2559
|
expect.anything()
|
|
2167
|
-
)
|
|
2168
|
-
})
|
|
2560
|
+
);
|
|
2561
|
+
});
|
|
2169
2562
|
|
|
2170
|
-
it(
|
|
2171
|
-
const onDropSpy = jest.fn()
|
|
2172
|
-
const onDropRejectedSpy = jest.fn()
|
|
2563
|
+
it("accepts multiple files if {multiple} is true and {accept} criteria is met", async () => {
|
|
2564
|
+
const onDropSpy = jest.fn();
|
|
2565
|
+
const onDropRejectedSpy = jest.fn();
|
|
2173
2566
|
const ui = (
|
|
2174
|
-
<Dropzone
|
|
2567
|
+
<Dropzone
|
|
2568
|
+
accept="image/*"
|
|
2569
|
+
onDrop={onDropSpy}
|
|
2570
|
+
multiple={true}
|
|
2571
|
+
maxFiles={3}
|
|
2572
|
+
onDropRejected={onDropRejectedSpy}
|
|
2573
|
+
>
|
|
2175
2574
|
{({ getRootProps, getInputProps }) => (
|
|
2176
2575
|
<div {...getRootProps()}>
|
|
2177
2576
|
<input {...getInputProps()} />
|
|
2178
2577
|
</div>
|
|
2179
2578
|
)}
|
|
2180
2579
|
</Dropzone>
|
|
2181
|
-
)
|
|
2182
|
-
const { container, rerender } = render(ui)
|
|
2183
|
-
const dropzone = container.querySelector(
|
|
2580
|
+
);
|
|
2581
|
+
const { container, rerender } = render(ui);
|
|
2582
|
+
const dropzone = container.querySelector("div");
|
|
2184
2583
|
|
|
2185
|
-
fireDrop(dropzone, createDtWithFiles(images))
|
|
2186
|
-
await flushPromises(rerender, ui)
|
|
2187
|
-
expect(onDropRejectedSpy).not.toHaveBeenCalled()
|
|
2188
|
-
expect(onDropSpy).toHaveBeenCalledWith(images, [], expect.anything())
|
|
2189
|
-
})
|
|
2584
|
+
fireDrop(dropzone, createDtWithFiles(images));
|
|
2585
|
+
await flushPromises(rerender, ui);
|
|
2586
|
+
expect(onDropRejectedSpy).not.toHaveBeenCalled();
|
|
2587
|
+
expect(onDropSpy).toHaveBeenCalledWith(images, [], expect.anything());
|
|
2588
|
+
});
|
|
2190
2589
|
|
|
2191
|
-
it(
|
|
2192
|
-
const onDropSpy = jest.fn()
|
|
2590
|
+
it("accepts a single files if {multiple} is false and {accept} criteria is met", async () => {
|
|
2591
|
+
const onDropSpy = jest.fn();
|
|
2193
2592
|
const ui = (
|
|
2194
2593
|
<Dropzone accept="image/*" onDrop={onDropSpy} multiple={false}>
|
|
2195
2594
|
{({ getRootProps, getInputProps }) => (
|
|
@@ -2198,18 +2597,18 @@ describe('useDropzone() hook', () => {
|
|
|
2198
2597
|
</div>
|
|
2199
2598
|
)}
|
|
2200
2599
|
</Dropzone>
|
|
2201
|
-
)
|
|
2202
|
-
const { container, rerender } = render(ui)
|
|
2203
|
-
const dropzone = container.querySelector(
|
|
2600
|
+
);
|
|
2601
|
+
const { container, rerender } = render(ui);
|
|
2602
|
+
const dropzone = container.querySelector("div");
|
|
2204
2603
|
|
|
2205
|
-
const [image] = images
|
|
2206
|
-
fireDrop(dropzone, createDtWithFiles([image]))
|
|
2207
|
-
await flushPromises(rerender, ui)
|
|
2208
|
-
expect(onDropSpy).toHaveBeenCalledWith([image], [], expect.anything())
|
|
2209
|
-
})
|
|
2604
|
+
const [image] = images;
|
|
2605
|
+
fireDrop(dropzone, createDtWithFiles([image]));
|
|
2606
|
+
await flushPromises(rerender, ui);
|
|
2607
|
+
expect(onDropSpy).toHaveBeenCalledWith([image], [], expect.anything());
|
|
2608
|
+
});
|
|
2210
2609
|
|
|
2211
|
-
it(
|
|
2212
|
-
const onDropSpy = jest.fn()
|
|
2610
|
+
it("accepts all files if {multiple} is true", async () => {
|
|
2611
|
+
const onDropSpy = jest.fn();
|
|
2213
2612
|
const ui = (
|
|
2214
2613
|
<Dropzone onDrop={onDropSpy}>
|
|
2215
2614
|
{({ getRootProps, getInputProps }) => (
|
|
@@ -2218,19 +2617,19 @@ describe('useDropzone() hook', () => {
|
|
|
2218
2617
|
</div>
|
|
2219
2618
|
)}
|
|
2220
2619
|
</Dropzone>
|
|
2221
|
-
)
|
|
2222
|
-
const { container, rerender } = render(ui)
|
|
2223
|
-
const dropzone = container.querySelector(
|
|
2620
|
+
);
|
|
2621
|
+
const { container, rerender } = render(ui);
|
|
2622
|
+
const dropzone = container.querySelector("div");
|
|
2224
2623
|
|
|
2225
|
-
fireDrop(dropzone, createDtWithFiles(files))
|
|
2226
|
-
await flushPromises(rerender, ui)
|
|
2227
|
-
expect(onDropSpy).toHaveBeenCalledWith(files, [], expect.anything())
|
|
2228
|
-
})
|
|
2624
|
+
fireDrop(dropzone, createDtWithFiles(files));
|
|
2625
|
+
await flushPromises(rerender, ui);
|
|
2626
|
+
expect(onDropSpy).toHaveBeenCalledWith(files, [], expect.anything());
|
|
2627
|
+
});
|
|
2229
2628
|
|
|
2230
|
-
it(
|
|
2231
|
-
const onDropSpy = jest.fn()
|
|
2232
|
-
const activeRef = createRef()
|
|
2233
|
-
const active = <span ref={activeRef}>I am active</span
|
|
2629
|
+
it("resets {isFileDialogActive} state", async () => {
|
|
2630
|
+
const onDropSpy = jest.fn();
|
|
2631
|
+
const activeRef = createRef();
|
|
2632
|
+
const active = <span ref={activeRef}>I am active</span>;
|
|
2234
2633
|
|
|
2235
2634
|
const ui = (
|
|
2236
2635
|
<Dropzone onDrop={onDropSpy}>
|
|
@@ -2244,24 +2643,24 @@ describe('useDropzone() hook', () => {
|
|
|
2244
2643
|
</div>
|
|
2245
2644
|
)}
|
|
2246
2645
|
</Dropzone>
|
|
2247
|
-
)
|
|
2248
|
-
const { container, rerender } = render(ui)
|
|
2249
|
-
const dropzone = container.querySelector(
|
|
2250
|
-
const btn = container.querySelector(
|
|
2646
|
+
);
|
|
2647
|
+
const { container, rerender } = render(ui);
|
|
2648
|
+
const dropzone = container.querySelector("div");
|
|
2649
|
+
const btn = container.querySelector("button");
|
|
2251
2650
|
|
|
2252
|
-
btn.click()
|
|
2651
|
+
btn.click();
|
|
2253
2652
|
|
|
2254
|
-
const ref = activeRef.current
|
|
2255
|
-
expect(dropzone).toContainElement(ref)
|
|
2653
|
+
const ref = activeRef.current;
|
|
2654
|
+
expect(dropzone).toContainElement(ref);
|
|
2256
2655
|
|
|
2257
|
-
fireDrop(dropzone, createDtWithFiles(files))
|
|
2258
|
-
await flushPromises(rerender, ui)
|
|
2656
|
+
fireDrop(dropzone, createDtWithFiles(files));
|
|
2657
|
+
await flushPromises(rerender, ui);
|
|
2259
2658
|
|
|
2260
|
-
expect(dropzone).not.toContainElement(ref)
|
|
2261
|
-
})
|
|
2659
|
+
expect(dropzone).not.toContainElement(ref);
|
|
2660
|
+
});
|
|
2262
2661
|
|
|
2263
|
-
it(
|
|
2264
|
-
const onDropSpy = jest.fn()
|
|
2662
|
+
it("gets invoked with both accepted/rejected files", async () => {
|
|
2663
|
+
const onDropSpy = jest.fn();
|
|
2265
2664
|
const ui = (
|
|
2266
2665
|
<Dropzone accept="image/*" onDrop={onDropSpy}>
|
|
2267
2666
|
{({ getRootProps, getInputProps }) => (
|
|
@@ -2270,47 +2669,55 @@ describe('useDropzone() hook', () => {
|
|
|
2270
2669
|
</div>
|
|
2271
2670
|
)}
|
|
2272
2671
|
</Dropzone>
|
|
2273
|
-
)
|
|
2274
|
-
const { container, rerender } = render(ui)
|
|
2275
|
-
const dropzone = container.querySelector(
|
|
2672
|
+
);
|
|
2673
|
+
const { container, rerender } = render(ui);
|
|
2674
|
+
const dropzone = container.querySelector("div");
|
|
2276
2675
|
|
|
2277
|
-
fireDrop(dropzone, createDtWithFiles(files))
|
|
2278
|
-
await flushPromises(rerender, ui)
|
|
2279
|
-
expect(onDropSpy).toHaveBeenCalledWith(
|
|
2280
|
-
|
|
2281
|
-
|
|
2282
|
-
|
|
2283
|
-
|
|
2284
|
-
|
|
2285
|
-
|
|
2286
|
-
|
|
2287
|
-
|
|
2288
|
-
|
|
2289
|
-
|
|
2290
|
-
|
|
2291
|
-
|
|
2292
|
-
|
|
2293
|
-
|
|
2294
|
-
|
|
2295
|
-
|
|
2296
|
-
|
|
2297
|
-
|
|
2298
|
-
|
|
2299
|
-
|
|
2300
|
-
|
|
2301
|
-
|
|
2302
|
-
|
|
2303
|
-
|
|
2304
|
-
|
|
2305
|
-
|
|
2306
|
-
|
|
2307
|
-
|
|
2308
|
-
|
|
2309
|
-
|
|
2310
|
-
|
|
2676
|
+
fireDrop(dropzone, createDtWithFiles(files));
|
|
2677
|
+
await flushPromises(rerender, ui);
|
|
2678
|
+
expect(onDropSpy).toHaveBeenCalledWith(
|
|
2679
|
+
[],
|
|
2680
|
+
[
|
|
2681
|
+
{
|
|
2682
|
+
file: files[0],
|
|
2683
|
+
errors: [
|
|
2684
|
+
{
|
|
2685
|
+
code: "file-invalid-type",
|
|
2686
|
+
message: "File type must be image/*",
|
|
2687
|
+
},
|
|
2688
|
+
],
|
|
2689
|
+
},
|
|
2690
|
+
],
|
|
2691
|
+
expect.anything()
|
|
2692
|
+
);
|
|
2693
|
+
onDropSpy.mockClear();
|
|
2694
|
+
|
|
2695
|
+
fireDrop(dropzone, createDtWithFiles(images));
|
|
2696
|
+
await flushPromises(rerender, ui);
|
|
2697
|
+
expect(onDropSpy).toHaveBeenCalledWith(images, [], expect.anything());
|
|
2698
|
+
onDropSpy.mockClear();
|
|
2699
|
+
|
|
2700
|
+
fireDrop(dropzone, createDtWithFiles([...files, ...images]));
|
|
2701
|
+
await flushPromises(rerender, ui);
|
|
2702
|
+
expect(onDropSpy).toHaveBeenCalledWith(
|
|
2703
|
+
images,
|
|
2704
|
+
[
|
|
2705
|
+
{
|
|
2706
|
+
file: files[0],
|
|
2707
|
+
errors: [
|
|
2708
|
+
{
|
|
2709
|
+
code: "file-invalid-type",
|
|
2710
|
+
message: "File type must be image/*",
|
|
2711
|
+
},
|
|
2712
|
+
],
|
|
2713
|
+
},
|
|
2714
|
+
],
|
|
2715
|
+
expect.anything()
|
|
2716
|
+
);
|
|
2717
|
+
});
|
|
2311
2718
|
|
|
2312
|
-
test(
|
|
2313
|
-
const onDropAcceptedSpy = jest.fn()
|
|
2719
|
+
test("onDropAccepted callback is invoked if some files are accepted", async () => {
|
|
2720
|
+
const onDropAcceptedSpy = jest.fn();
|
|
2314
2721
|
const ui = (
|
|
2315
2722
|
<Dropzone accept="image/*" onDropAccepted={onDropAcceptedSpy}>
|
|
2316
2723
|
{({ getRootProps, getInputProps }) => (
|
|
@@ -2319,27 +2726,27 @@ describe('useDropzone() hook', () => {
|
|
|
2319
2726
|
</div>
|
|
2320
2727
|
)}
|
|
2321
2728
|
</Dropzone>
|
|
2322
|
-
)
|
|
2323
|
-
const { container, rerender } = render(ui)
|
|
2324
|
-
const dropzone = container.querySelector(
|
|
2729
|
+
);
|
|
2730
|
+
const { container, rerender } = render(ui);
|
|
2731
|
+
const dropzone = container.querySelector("div");
|
|
2325
2732
|
|
|
2326
|
-
fireDrop(dropzone, createDtWithFiles(files))
|
|
2327
|
-
await flushPromises(rerender, ui)
|
|
2328
|
-
expect(onDropAcceptedSpy).not.toHaveBeenCalled()
|
|
2329
|
-
onDropAcceptedSpy.mockClear()
|
|
2733
|
+
fireDrop(dropzone, createDtWithFiles(files));
|
|
2734
|
+
await flushPromises(rerender, ui);
|
|
2735
|
+
expect(onDropAcceptedSpy).not.toHaveBeenCalled();
|
|
2736
|
+
onDropAcceptedSpy.mockClear();
|
|
2330
2737
|
|
|
2331
|
-
fireDrop(dropzone, createDtWithFiles(images))
|
|
2332
|
-
await flushPromises(rerender, ui)
|
|
2333
|
-
expect(onDropAcceptedSpy).toHaveBeenCalledWith(images, expect.anything())
|
|
2334
|
-
onDropAcceptedSpy.mockClear()
|
|
2738
|
+
fireDrop(dropzone, createDtWithFiles(images));
|
|
2739
|
+
await flushPromises(rerender, ui);
|
|
2740
|
+
expect(onDropAcceptedSpy).toHaveBeenCalledWith(images, expect.anything());
|
|
2741
|
+
onDropAcceptedSpy.mockClear();
|
|
2335
2742
|
|
|
2336
|
-
fireDrop(dropzone, createDtWithFiles([...files, ...images]))
|
|
2337
|
-
await flushPromises(rerender, ui)
|
|
2338
|
-
expect(onDropAcceptedSpy).toHaveBeenCalledWith(images, expect.anything())
|
|
2339
|
-
})
|
|
2743
|
+
fireDrop(dropzone, createDtWithFiles([...files, ...images]));
|
|
2744
|
+
await flushPromises(rerender, ui);
|
|
2745
|
+
expect(onDropAcceptedSpy).toHaveBeenCalledWith(images, expect.anything());
|
|
2746
|
+
});
|
|
2340
2747
|
|
|
2341
|
-
test(
|
|
2342
|
-
const onDropRejectedSpy = jest.fn()
|
|
2748
|
+
test("onDropRejected callback is invoked if some files are rejected", async () => {
|
|
2749
|
+
const onDropRejectedSpy = jest.fn();
|
|
2343
2750
|
const ui = (
|
|
2344
2751
|
<Dropzone accept="image/*" onDropRejected={onDropRejectedSpy}>
|
|
2345
2752
|
{({ getRootProps, getInputProps }) => (
|
|
@@ -2348,47 +2755,53 @@ describe('useDropzone() hook', () => {
|
|
|
2348
2755
|
</div>
|
|
2349
2756
|
)}
|
|
2350
2757
|
</Dropzone>
|
|
2351
|
-
)
|
|
2352
|
-
const { container, rerender } = render(ui)
|
|
2353
|
-
const dropzone = container.querySelector(
|
|
2758
|
+
);
|
|
2759
|
+
const { container, rerender } = render(ui);
|
|
2760
|
+
const dropzone = container.querySelector("div");
|
|
2354
2761
|
|
|
2355
|
-
fireDrop(dropzone, createDtWithFiles(files))
|
|
2356
|
-
await flushPromises(rerender, ui)
|
|
2357
|
-
expect(onDropRejectedSpy).toHaveBeenCalledWith(
|
|
2358
|
-
|
|
2359
|
-
|
|
2360
|
-
|
|
2361
|
-
|
|
2362
|
-
|
|
2363
|
-
|
|
2364
|
-
|
|
2365
|
-
|
|
2366
|
-
|
|
2367
|
-
|
|
2368
|
-
|
|
2369
|
-
|
|
2370
|
-
|
|
2371
|
-
|
|
2372
|
-
expect(onDropRejectedSpy).not.toHaveBeenCalled()
|
|
2373
|
-
onDropRejectedSpy.mockClear()
|
|
2374
|
-
|
|
2375
|
-
fireDrop(dropzone, createDtWithFiles([...files, ...images]))
|
|
2376
|
-
await flushPromises(rerender, ui)
|
|
2377
|
-
expect(onDropRejectedSpy).toHaveBeenCalledWith([
|
|
2378
|
-
{
|
|
2379
|
-
file: files[0],
|
|
2380
|
-
errors: [
|
|
2381
|
-
{
|
|
2382
|
-
code: 'file-invalid-type',
|
|
2383
|
-
message: 'File type must be image/*',
|
|
2384
|
-
}
|
|
2385
|
-
]
|
|
2386
|
-
}
|
|
2387
|
-
], expect.anything())
|
|
2388
|
-
})
|
|
2762
|
+
fireDrop(dropzone, createDtWithFiles(files));
|
|
2763
|
+
await flushPromises(rerender, ui);
|
|
2764
|
+
expect(onDropRejectedSpy).toHaveBeenCalledWith(
|
|
2765
|
+
[
|
|
2766
|
+
{
|
|
2767
|
+
file: files[0],
|
|
2768
|
+
errors: [
|
|
2769
|
+
{
|
|
2770
|
+
code: "file-invalid-type",
|
|
2771
|
+
message: "File type must be image/*",
|
|
2772
|
+
},
|
|
2773
|
+
],
|
|
2774
|
+
},
|
|
2775
|
+
],
|
|
2776
|
+
expect.anything()
|
|
2777
|
+
);
|
|
2778
|
+
onDropRejectedSpy.mockClear();
|
|
2389
2779
|
|
|
2390
|
-
|
|
2391
|
-
|
|
2780
|
+
fireDrop(dropzone, createDtWithFiles(images));
|
|
2781
|
+
await flushPromises(rerender, ui);
|
|
2782
|
+
expect(onDropRejectedSpy).not.toHaveBeenCalled();
|
|
2783
|
+
onDropRejectedSpy.mockClear();
|
|
2784
|
+
|
|
2785
|
+
fireDrop(dropzone, createDtWithFiles([...files, ...images]));
|
|
2786
|
+
await flushPromises(rerender, ui);
|
|
2787
|
+
expect(onDropRejectedSpy).toHaveBeenCalledWith(
|
|
2788
|
+
[
|
|
2789
|
+
{
|
|
2790
|
+
file: files[0],
|
|
2791
|
+
errors: [
|
|
2792
|
+
{
|
|
2793
|
+
code: "file-invalid-type",
|
|
2794
|
+
message: "File type must be image/*",
|
|
2795
|
+
},
|
|
2796
|
+
],
|
|
2797
|
+
},
|
|
2798
|
+
],
|
|
2799
|
+
expect.anything()
|
|
2800
|
+
);
|
|
2801
|
+
});
|
|
2802
|
+
|
|
2803
|
+
it("accepts a dropped image when Firefox provides a bogus file type", async () => {
|
|
2804
|
+
const onDropSpy = jest.fn();
|
|
2392
2805
|
const ui = (
|
|
2393
2806
|
<Dropzone accept="image/*" onDrop={onDropSpy}>
|
|
2394
2807
|
{({ getRootProps, getInputProps }) => (
|
|
@@ -2397,19 +2810,19 @@ describe('useDropzone() hook', () => {
|
|
|
2397
2810
|
</div>
|
|
2398
2811
|
)}
|
|
2399
2812
|
</Dropzone>
|
|
2400
|
-
)
|
|
2401
|
-
const { container, rerender } = render(ui)
|
|
2402
|
-
const dropzone = container.querySelector(
|
|
2813
|
+
);
|
|
2814
|
+
const { container, rerender } = render(ui);
|
|
2815
|
+
const dropzone = container.querySelector("div");
|
|
2403
2816
|
|
|
2404
|
-
const images = [createFile(
|
|
2405
|
-
fireDrop(dropzone, createDtWithFiles(images))
|
|
2406
|
-
await flushPromises(rerender, ui)
|
|
2817
|
+
const images = [createFile("bogus.gif", 1234, "application/x-moz-file")];
|
|
2818
|
+
fireDrop(dropzone, createDtWithFiles(images));
|
|
2819
|
+
await flushPromises(rerender, ui);
|
|
2407
2820
|
|
|
2408
|
-
expect(onDropSpy).toHaveBeenCalledWith(images, [], expect.anything())
|
|
2409
|
-
})
|
|
2821
|
+
expect(onDropSpy).toHaveBeenCalledWith(images, [], expect.anything());
|
|
2822
|
+
});
|
|
2410
2823
|
|
|
2411
|
-
it(
|
|
2412
|
-
const onDropSpy = jest.fn()
|
|
2824
|
+
it("filters files according to {maxSize}", async () => {
|
|
2825
|
+
const onDropSpy = jest.fn();
|
|
2413
2826
|
const ui = (
|
|
2414
2827
|
<Dropzone onDrop={onDropSpy} maxSize={1111}>
|
|
2415
2828
|
{({ getRootProps, getInputProps }) => (
|
|
@@ -2418,37 +2831,41 @@ describe('useDropzone() hook', () => {
|
|
|
2418
2831
|
</div>
|
|
2419
2832
|
)}
|
|
2420
2833
|
</Dropzone>
|
|
2421
|
-
)
|
|
2422
|
-
const { container, rerender } = render(ui)
|
|
2423
|
-
const dropzone = container.querySelector(
|
|
2834
|
+
);
|
|
2835
|
+
const { container, rerender } = render(ui);
|
|
2836
|
+
const dropzone = container.querySelector("div");
|
|
2424
2837
|
|
|
2425
|
-
fireDrop(dropzone, createDtWithFiles(images))
|
|
2426
|
-
await flushPromises(rerender, ui)
|
|
2838
|
+
fireDrop(dropzone, createDtWithFiles(images));
|
|
2839
|
+
await flushPromises(rerender, ui);
|
|
2427
2840
|
|
|
2428
|
-
expect(onDropSpy).toHaveBeenCalledWith(
|
|
2429
|
-
|
|
2430
|
-
|
|
2431
|
-
|
|
2432
|
-
|
|
2433
|
-
|
|
2434
|
-
|
|
2435
|
-
|
|
2436
|
-
|
|
2437
|
-
|
|
2438
|
-
|
|
2439
|
-
|
|
2440
|
-
|
|
2441
|
-
|
|
2442
|
-
|
|
2443
|
-
|
|
2444
|
-
|
|
2445
|
-
|
|
2446
|
-
|
|
2447
|
-
|
|
2448
|
-
|
|
2841
|
+
expect(onDropSpy).toHaveBeenCalledWith(
|
|
2842
|
+
[],
|
|
2843
|
+
[
|
|
2844
|
+
{
|
|
2845
|
+
file: images[0],
|
|
2846
|
+
errors: [
|
|
2847
|
+
{
|
|
2848
|
+
code: "file-too-large",
|
|
2849
|
+
message: "File is larger than 1111 bytes",
|
|
2850
|
+
},
|
|
2851
|
+
],
|
|
2852
|
+
},
|
|
2853
|
+
{
|
|
2854
|
+
file: images[1],
|
|
2855
|
+
errors: [
|
|
2856
|
+
{
|
|
2857
|
+
code: "file-too-large",
|
|
2858
|
+
message: "File is larger than 1111 bytes",
|
|
2859
|
+
},
|
|
2860
|
+
],
|
|
2861
|
+
},
|
|
2862
|
+
],
|
|
2863
|
+
expect.anything()
|
|
2864
|
+
);
|
|
2865
|
+
});
|
|
2449
2866
|
|
|
2450
|
-
it(
|
|
2451
|
-
const onDropSpy = jest.fn()
|
|
2867
|
+
it("filters files according to {minSize}", async () => {
|
|
2868
|
+
const onDropSpy = jest.fn();
|
|
2452
2869
|
const ui = (
|
|
2453
2870
|
<Dropzone onDrop={onDropSpy} minSize={1112}>
|
|
2454
2871
|
{({ getRootProps, getInputProps }) => (
|
|
@@ -2457,38 +2874,42 @@ describe('useDropzone() hook', () => {
|
|
|
2457
2874
|
</div>
|
|
2458
2875
|
)}
|
|
2459
2876
|
</Dropzone>
|
|
2460
|
-
)
|
|
2461
|
-
const { container, rerender } = render(ui)
|
|
2462
|
-
const dropzone = container.querySelector(
|
|
2877
|
+
);
|
|
2878
|
+
const { container, rerender } = render(ui);
|
|
2879
|
+
const dropzone = container.querySelector("div");
|
|
2463
2880
|
|
|
2464
|
-
fireDrop(dropzone, createDtWithFiles(files))
|
|
2465
|
-
await flushPromises(rerender, ui)
|
|
2881
|
+
fireDrop(dropzone, createDtWithFiles(files));
|
|
2882
|
+
await flushPromises(rerender, ui);
|
|
2466
2883
|
|
|
2467
|
-
expect(onDropSpy).toHaveBeenCalledWith(
|
|
2468
|
-
|
|
2469
|
-
|
|
2470
|
-
|
|
2471
|
-
|
|
2472
|
-
|
|
2473
|
-
|
|
2474
|
-
|
|
2475
|
-
|
|
2476
|
-
|
|
2477
|
-
|
|
2478
|
-
|
|
2479
|
-
|
|
2884
|
+
expect(onDropSpy).toHaveBeenCalledWith(
|
|
2885
|
+
[],
|
|
2886
|
+
[
|
|
2887
|
+
{
|
|
2888
|
+
file: files[0],
|
|
2889
|
+
errors: [
|
|
2890
|
+
{
|
|
2891
|
+
code: "file-too-small",
|
|
2892
|
+
message: "File is smaller than 1112 bytes",
|
|
2893
|
+
},
|
|
2894
|
+
],
|
|
2895
|
+
},
|
|
2896
|
+
],
|
|
2897
|
+
expect.anything()
|
|
2898
|
+
);
|
|
2899
|
+
});
|
|
2900
|
+
});
|
|
2480
2901
|
|
|
2481
|
-
describe(
|
|
2902
|
+
describe("onFileDialogCancel", () => {
|
|
2482
2903
|
beforeEach(() => {
|
|
2483
|
-
jest.useFakeTimers()
|
|
2484
|
-
})
|
|
2904
|
+
jest.useFakeTimers();
|
|
2905
|
+
});
|
|
2485
2906
|
|
|
2486
2907
|
afterEach(() => {
|
|
2487
|
-
jest.useRealTimers()
|
|
2488
|
-
})
|
|
2908
|
+
jest.useRealTimers();
|
|
2909
|
+
});
|
|
2489
2910
|
|
|
2490
|
-
it(
|
|
2491
|
-
const onFileDialogCancelSpy = jest.fn()
|
|
2911
|
+
it("is not invoked every time window receives focus", () => {
|
|
2912
|
+
const onFileDialogCancelSpy = jest.fn();
|
|
2492
2913
|
|
|
2493
2914
|
render(
|
|
2494
2915
|
<Dropzone onFileDialogCancel={onFileDialogCancelSpy}>
|
|
@@ -2498,18 +2919,18 @@ describe('useDropzone() hook', () => {
|
|
|
2498
2919
|
</div>
|
|
2499
2920
|
)}
|
|
2500
2921
|
</Dropzone>
|
|
2501
|
-
)
|
|
2922
|
+
);
|
|
2502
2923
|
|
|
2503
|
-
dispatchEvt(document.body,
|
|
2504
|
-
drainTimers()
|
|
2924
|
+
dispatchEvt(document.body, "focus");
|
|
2925
|
+
drainTimers();
|
|
2505
2926
|
|
|
2506
|
-
expect(onFileDialogCancelSpy).not.toHaveBeenCalled()
|
|
2507
|
-
})
|
|
2927
|
+
expect(onFileDialogCancelSpy).not.toHaveBeenCalled();
|
|
2928
|
+
});
|
|
2508
2929
|
|
|
2509
|
-
it(
|
|
2510
|
-
const activeRef = createRef()
|
|
2511
|
-
const active = <span ref={activeRef}>I am active</span
|
|
2512
|
-
const onFileDialogCancelSpy = jest.fn()
|
|
2930
|
+
it("resets {isFileDialogActive}", () => {
|
|
2931
|
+
const activeRef = createRef();
|
|
2932
|
+
const active = <span ref={activeRef}>I am active</span>;
|
|
2933
|
+
const onFileDialogCancelSpy = jest.fn();
|
|
2513
2934
|
|
|
2514
2935
|
const { container } = render(
|
|
2515
2936
|
<Dropzone onFileDialogCancel={onFileDialogCancelSpy}>
|
|
@@ -2523,26 +2944,26 @@ describe('useDropzone() hook', () => {
|
|
|
2523
2944
|
</div>
|
|
2524
2945
|
)}
|
|
2525
2946
|
</Dropzone>
|
|
2526
|
-
)
|
|
2947
|
+
);
|
|
2527
2948
|
|
|
2528
|
-
const dropzone = container.querySelector(
|
|
2529
|
-
const btn = container.querySelector(
|
|
2949
|
+
const dropzone = container.querySelector("div");
|
|
2950
|
+
const btn = container.querySelector("button");
|
|
2530
2951
|
|
|
2531
|
-
btn.click()
|
|
2532
|
-
drainTimers()
|
|
2533
|
-
const ref = activeRef.current
|
|
2534
|
-
expect(ref).not.toBeNull()
|
|
2535
|
-
expect(dropzone).toContainElement(ref)
|
|
2952
|
+
btn.click();
|
|
2953
|
+
drainTimers();
|
|
2954
|
+
const ref = activeRef.current;
|
|
2955
|
+
expect(ref).not.toBeNull();
|
|
2956
|
+
expect(dropzone).toContainElement(ref);
|
|
2536
2957
|
|
|
2537
|
-
dispatchEvt(document.body,
|
|
2538
|
-
drainTimers()
|
|
2958
|
+
dispatchEvt(document.body, "focus");
|
|
2959
|
+
drainTimers();
|
|
2539
2960
|
|
|
2540
|
-
expect(onFileDialogCancelSpy).toHaveBeenCalled()
|
|
2541
|
-
expect(dropzone).not.toContainElement(ref)
|
|
2542
|
-
})
|
|
2961
|
+
expect(onFileDialogCancelSpy).toHaveBeenCalled();
|
|
2962
|
+
expect(dropzone).not.toContainElement(ref);
|
|
2963
|
+
});
|
|
2543
2964
|
|
|
2544
|
-
it(
|
|
2545
|
-
const onFileDialogCancelSpy = jest.fn()
|
|
2965
|
+
it("is not invoked if <input> is not rendered", () => {
|
|
2966
|
+
const onFileDialogCancelSpy = jest.fn();
|
|
2546
2967
|
const { container, rerender } = render(
|
|
2547
2968
|
<Dropzone onFileDialogCancel={onFileDialogCancelSpy}>
|
|
2548
2969
|
{({ getRootProps, getInputProps, open }) => (
|
|
@@ -2554,27 +2975,27 @@ describe('useDropzone() hook', () => {
|
|
|
2554
2975
|
</div>
|
|
2555
2976
|
)}
|
|
2556
2977
|
</Dropzone>
|
|
2557
|
-
)
|
|
2978
|
+
);
|
|
2558
2979
|
|
|
2559
|
-
const btn = container.querySelector(
|
|
2560
|
-
btn.click()
|
|
2561
|
-
drainTimers()
|
|
2980
|
+
const btn = container.querySelector("button");
|
|
2981
|
+
btn.click();
|
|
2982
|
+
drainTimers();
|
|
2562
2983
|
|
|
2563
2984
|
rerender(
|
|
2564
2985
|
<Dropzone onFileDialogCancel={onFileDialogCancelSpy}>
|
|
2565
2986
|
{({ getRootProps }) => <div {...getRootProps()} />}
|
|
2566
2987
|
</Dropzone>
|
|
2567
|
-
)
|
|
2568
|
-
drainTimers()
|
|
2988
|
+
);
|
|
2989
|
+
drainTimers();
|
|
2569
2990
|
|
|
2570
|
-
dispatchEvt(document.body,
|
|
2571
|
-
drainTimers()
|
|
2991
|
+
dispatchEvt(document.body, "focus");
|
|
2992
|
+
drainTimers();
|
|
2572
2993
|
|
|
2573
|
-
expect(onFileDialogCancelSpy).not.toHaveBeenCalled()
|
|
2574
|
-
})
|
|
2994
|
+
expect(onFileDialogCancelSpy).not.toHaveBeenCalled();
|
|
2995
|
+
});
|
|
2575
2996
|
|
|
2576
|
-
it(
|
|
2577
|
-
const onFileDialogCancelSpy = jest.fn()
|
|
2997
|
+
it("is not invoked if files were selected", () => {
|
|
2998
|
+
const onFileDialogCancelSpy = jest.fn();
|
|
2578
2999
|
|
|
2579
3000
|
const { container } = render(
|
|
2580
3001
|
<Dropzone onFileDialogCancel={onFileDialogCancelSpy}>
|
|
@@ -2587,22 +3008,22 @@ describe('useDropzone() hook', () => {
|
|
|
2587
3008
|
</div>
|
|
2588
3009
|
)}
|
|
2589
3010
|
</Dropzone>
|
|
2590
|
-
)
|
|
3011
|
+
);
|
|
2591
3012
|
|
|
2592
|
-
const input = container.querySelector(
|
|
2593
|
-
Object.defineProperty(input,
|
|
3013
|
+
const input = container.querySelector("input");
|
|
3014
|
+
Object.defineProperty(input, "files", { value: files });
|
|
2594
3015
|
|
|
2595
|
-
const btn = container.querySelector(
|
|
2596
|
-
btn.click()
|
|
2597
|
-
drainTimers()
|
|
3016
|
+
const btn = container.querySelector("button");
|
|
3017
|
+
btn.click();
|
|
3018
|
+
drainTimers();
|
|
2598
3019
|
|
|
2599
|
-
dispatchEvt(document.body,
|
|
2600
|
-
drainTimers()
|
|
3020
|
+
dispatchEvt(document.body, "focus");
|
|
3021
|
+
drainTimers();
|
|
2601
3022
|
|
|
2602
|
-
expect(onFileDialogCancelSpy).not.toHaveBeenCalled()
|
|
2603
|
-
})
|
|
3023
|
+
expect(onFileDialogCancelSpy).not.toHaveBeenCalled();
|
|
3024
|
+
});
|
|
2604
3025
|
|
|
2605
|
-
it(
|
|
3026
|
+
it("does not throw if callback is not provided", () => {
|
|
2606
3027
|
const { container } = render(
|
|
2607
3028
|
<Dropzone onFileDialogCancel={null}>
|
|
2608
3029
|
{({ getRootProps, getInputProps, open }) => (
|
|
@@ -2614,45 +3035,43 @@ describe('useDropzone() hook', () => {
|
|
|
2614
3035
|
</div>
|
|
2615
3036
|
)}
|
|
2616
3037
|
</Dropzone>
|
|
2617
|
-
)
|
|
3038
|
+
);
|
|
2618
3039
|
|
|
2619
|
-
const btn = container.querySelector(
|
|
2620
|
-
btn.click()
|
|
2621
|
-
drainTimers()
|
|
3040
|
+
const btn = container.querySelector("button");
|
|
3041
|
+
btn.click();
|
|
3042
|
+
drainTimers();
|
|
2622
3043
|
|
|
2623
3044
|
const fn = () => {
|
|
2624
|
-
dispatchEvt(document.body,
|
|
2625
|
-
drainTimers()
|
|
2626
|
-
}
|
|
2627
|
-
expect(fn).not.toThrow()
|
|
2628
|
-
})
|
|
2629
|
-
})
|
|
2630
|
-
|
|
2631
|
-
describe(
|
|
2632
|
-
it(
|
|
2633
|
-
const onFileDialogOpenSpy = jest.fn()
|
|
3045
|
+
dispatchEvt(document.body, "focus");
|
|
3046
|
+
drainTimers();
|
|
3047
|
+
};
|
|
3048
|
+
expect(fn).not.toThrow();
|
|
3049
|
+
});
|
|
3050
|
+
});
|
|
3051
|
+
|
|
3052
|
+
describe("onFileDialogOpen", () => {
|
|
3053
|
+
it("is invoked when opening the file dialog", () => {
|
|
3054
|
+
const onFileDialogOpenSpy = jest.fn();
|
|
2634
3055
|
const { container } = render(
|
|
2635
|
-
<Dropzone
|
|
2636
|
-
onFileDialogOpen={onFileDialogOpenSpy}>
|
|
3056
|
+
<Dropzone onFileDialogOpen={onFileDialogOpenSpy}>
|
|
2637
3057
|
{({ getRootProps, getInputProps }) => (
|
|
2638
3058
|
<div {...getRootProps()}>
|
|
2639
3059
|
<input {...getInputProps()} />
|
|
2640
3060
|
</div>
|
|
2641
3061
|
)}
|
|
2642
3062
|
</Dropzone>
|
|
2643
|
-
)
|
|
3063
|
+
);
|
|
2644
3064
|
|
|
2645
|
-
const dropzone = container.querySelector(
|
|
2646
|
-
fireEvent.click(dropzone)
|
|
3065
|
+
const dropzone = container.querySelector("div");
|
|
3066
|
+
fireEvent.click(dropzone);
|
|
2647
3067
|
|
|
2648
|
-
expect(onFileDialogOpenSpy).toHaveBeenCalled()
|
|
2649
|
-
})
|
|
3068
|
+
expect(onFileDialogOpenSpy).toHaveBeenCalled();
|
|
3069
|
+
});
|
|
2650
3070
|
|
|
2651
|
-
it(
|
|
2652
|
-
const onFileDialogOpenSpy = jest.fn()
|
|
3071
|
+
it("is invoked when opening the file dialog programmatically", () => {
|
|
3072
|
+
const onFileDialogOpenSpy = jest.fn();
|
|
2653
3073
|
const { container } = render(
|
|
2654
|
-
<Dropzone
|
|
2655
|
-
onFileDialogOpen={onFileDialogOpenSpy}>
|
|
3074
|
+
<Dropzone onFileDialogOpen={onFileDialogOpenSpy}>
|
|
2656
3075
|
{({ getRootProps, getInputProps, open }) => (
|
|
2657
3076
|
<div {...getRootProps()}>
|
|
2658
3077
|
<input {...getInputProps()} />
|
|
@@ -2662,18 +3081,18 @@ describe('useDropzone() hook', () => {
|
|
|
2662
3081
|
</div>
|
|
2663
3082
|
)}
|
|
2664
3083
|
</Dropzone>
|
|
2665
|
-
)
|
|
3084
|
+
);
|
|
2666
3085
|
|
|
2667
|
-
const btn = container.querySelector(
|
|
2668
|
-
btn.click()
|
|
3086
|
+
const btn = container.querySelector("button");
|
|
3087
|
+
btn.click();
|
|
2669
3088
|
|
|
2670
|
-
expect(onFileDialogOpenSpy).toHaveBeenCalled()
|
|
2671
|
-
})
|
|
2672
|
-
})
|
|
3089
|
+
expect(onFileDialogOpenSpy).toHaveBeenCalled();
|
|
3090
|
+
});
|
|
3091
|
+
});
|
|
2673
3092
|
|
|
2674
|
-
describe(
|
|
2675
|
-
it(
|
|
2676
|
-
const onClickSpy = jest.spyOn(HTMLInputElement.prototype,
|
|
3093
|
+
describe("{open}", () => {
|
|
3094
|
+
it("can open file dialog programmatically", () => {
|
|
3095
|
+
const onClickSpy = jest.spyOn(HTMLInputElement.prototype, "click");
|
|
2677
3096
|
const { container } = render(
|
|
2678
3097
|
<Dropzone>
|
|
2679
3098
|
{({ getRootProps, getInputProps, open }) => (
|
|
@@ -2685,18 +3104,18 @@ describe('useDropzone() hook', () => {
|
|
|
2685
3104
|
</div>
|
|
2686
3105
|
)}
|
|
2687
3106
|
</Dropzone>
|
|
2688
|
-
)
|
|
3107
|
+
);
|
|
2689
3108
|
|
|
2690
|
-
const btn = container.querySelector(
|
|
3109
|
+
const btn = container.querySelector("button");
|
|
2691
3110
|
|
|
2692
|
-
btn.click()
|
|
3111
|
+
btn.click();
|
|
2693
3112
|
|
|
2694
|
-
expect(onClickSpy).toHaveBeenCalled()
|
|
2695
|
-
})
|
|
3113
|
+
expect(onClickSpy).toHaveBeenCalled();
|
|
3114
|
+
});
|
|
2696
3115
|
|
|
2697
|
-
it(
|
|
2698
|
-
const activeRef = createRef()
|
|
2699
|
-
const active = <span ref={activeRef}>I am active</span
|
|
3116
|
+
it("sets {isFileDialogActive} state", () => {
|
|
3117
|
+
const activeRef = createRef();
|
|
3118
|
+
const active = <span ref={activeRef}>I am active</span>;
|
|
2700
3119
|
const { container } = render(
|
|
2701
3120
|
<Dropzone>
|
|
2702
3121
|
{({ getRootProps, getInputProps, isFileDialogActive, open }) => (
|
|
@@ -2709,20 +3128,20 @@ describe('useDropzone() hook', () => {
|
|
|
2709
3128
|
</div>
|
|
2710
3129
|
)}
|
|
2711
3130
|
</Dropzone>
|
|
2712
|
-
)
|
|
3131
|
+
);
|
|
2713
3132
|
|
|
2714
|
-
const dropzone = container.querySelector(
|
|
2715
|
-
const btn = container.querySelector(
|
|
3133
|
+
const dropzone = container.querySelector("div");
|
|
3134
|
+
const btn = container.querySelector("button");
|
|
2716
3135
|
|
|
2717
|
-
btn.click()
|
|
3136
|
+
btn.click();
|
|
2718
3137
|
|
|
2719
|
-
const ref = activeRef.current
|
|
2720
|
-
expect(ref).not.toBeNull()
|
|
2721
|
-
expect(dropzone).toContainElement(ref)
|
|
2722
|
-
})
|
|
3138
|
+
const ref = activeRef.current;
|
|
3139
|
+
expect(ref).not.toBeNull();
|
|
3140
|
+
expect(dropzone).toContainElement(ref);
|
|
3141
|
+
});
|
|
2723
3142
|
|
|
2724
|
-
it(
|
|
2725
|
-
const onClickSpy = jest.spyOn(HTMLInputElement.prototype,
|
|
3143
|
+
it("does nothing if {disabled} is true", () => {
|
|
3144
|
+
const onClickSpy = jest.spyOn(HTMLInputElement.prototype, "click");
|
|
2726
3145
|
const { container } = render(
|
|
2727
3146
|
<Dropzone disabled>
|
|
2728
3147
|
{({ getRootProps, getInputProps, open }) => (
|
|
@@ -2734,16 +3153,16 @@ describe('useDropzone() hook', () => {
|
|
|
2734
3153
|
</div>
|
|
2735
3154
|
)}
|
|
2736
3155
|
</Dropzone>
|
|
2737
|
-
)
|
|
3156
|
+
);
|
|
2738
3157
|
|
|
2739
|
-
const btn = container.querySelector(
|
|
3158
|
+
const btn = container.querySelector("button");
|
|
2740
3159
|
|
|
2741
|
-
btn.click()
|
|
3160
|
+
btn.click();
|
|
2742
3161
|
|
|
2743
|
-
expect(onClickSpy).not.toHaveBeenCalled()
|
|
2744
|
-
})
|
|
3162
|
+
expect(onClickSpy).not.toHaveBeenCalled();
|
|
3163
|
+
});
|
|
2745
3164
|
|
|
2746
|
-
it(
|
|
3165
|
+
it("does not throw if <input> is missing", () => {
|
|
2747
3166
|
const { container } = render(
|
|
2748
3167
|
<Dropzone>
|
|
2749
3168
|
{({ getRootProps, open }) => (
|
|
@@ -2754,25 +3173,25 @@ describe('useDropzone() hook', () => {
|
|
|
2754
3173
|
</div>
|
|
2755
3174
|
)}
|
|
2756
3175
|
</Dropzone>
|
|
2757
|
-
)
|
|
3176
|
+
);
|
|
2758
3177
|
|
|
2759
|
-
const btn = container.querySelector(
|
|
3178
|
+
const btn = container.querySelector("button");
|
|
2760
3179
|
|
|
2761
|
-
const fn = () => btn.click()
|
|
2762
|
-
expect(fn).not.toThrow()
|
|
2763
|
-
})
|
|
2764
|
-
})
|
|
3180
|
+
const fn = () => btn.click();
|
|
3181
|
+
expect(fn).not.toThrow();
|
|
3182
|
+
});
|
|
3183
|
+
});
|
|
2765
3184
|
|
|
2766
|
-
describe(
|
|
2767
|
-
it(
|
|
2768
|
-
const validator = file => {
|
|
3185
|
+
describe("validator", () => {
|
|
3186
|
+
it("rejects with custom error", async () => {
|
|
3187
|
+
const validator = (file) => {
|
|
2769
3188
|
if (/dogs/i.test(file.name))
|
|
2770
|
-
return { code:
|
|
3189
|
+
return { code: "dogs-not-allowed", message: "Dogs not allowed" };
|
|
2771
3190
|
|
|
2772
3191
|
return null;
|
|
2773
|
-
}
|
|
3192
|
+
};
|
|
2774
3193
|
|
|
2775
|
-
const onDropSpy = jest.fn()
|
|
3194
|
+
const onDropSpy = jest.fn();
|
|
2776
3195
|
|
|
2777
3196
|
const ui = (
|
|
2778
3197
|
<Dropzone validator={validator} onDrop={onDropSpy} multiple={true}>
|
|
@@ -2782,84 +3201,133 @@ describe('useDropzone() hook', () => {
|
|
|
2782
3201
|
</div>
|
|
2783
3202
|
)}
|
|
2784
3203
|
</Dropzone>
|
|
2785
|
-
)
|
|
3204
|
+
);
|
|
2786
3205
|
|
|
2787
|
-
const { container, rerender } = render(ui)
|
|
2788
|
-
const dropzone = container.querySelector(
|
|
3206
|
+
const { container, rerender } = render(ui);
|
|
3207
|
+
const dropzone = container.querySelector("div");
|
|
2789
3208
|
|
|
2790
|
-
fireDrop(dropzone, createDtWithFiles(images))
|
|
2791
|
-
await flushPromises(rerender, ui)
|
|
3209
|
+
fireDrop(dropzone, createDtWithFiles(images));
|
|
3210
|
+
await flushPromises(rerender, ui);
|
|
2792
3211
|
|
|
2793
|
-
expect(onDropSpy).toHaveBeenCalledWith(
|
|
2794
|
-
|
|
2795
|
-
|
|
2796
|
-
|
|
2797
|
-
|
|
2798
|
-
|
|
2799
|
-
|
|
2800
|
-
|
|
2801
|
-
|
|
2802
|
-
|
|
2803
|
-
|
|
2804
|
-
|
|
2805
|
-
|
|
2806
|
-
|
|
3212
|
+
expect(onDropSpy).toHaveBeenCalledWith(
|
|
3213
|
+
[images[0]],
|
|
3214
|
+
[
|
|
3215
|
+
{
|
|
3216
|
+
file: images[1],
|
|
3217
|
+
errors: [
|
|
3218
|
+
{
|
|
3219
|
+
code: "dogs-not-allowed",
|
|
3220
|
+
message: "Dogs not allowed",
|
|
3221
|
+
},
|
|
3222
|
+
],
|
|
3223
|
+
},
|
|
3224
|
+
],
|
|
3225
|
+
expect.anything()
|
|
3226
|
+
);
|
|
3227
|
+
});
|
|
3228
|
+
});
|
|
3229
|
+
|
|
3230
|
+
describe("accessibility", () => {
|
|
3231
|
+
it("sets the role attribute to button by default on the root", () => {
|
|
3232
|
+
const { container } = render(
|
|
3233
|
+
<Dropzone>
|
|
3234
|
+
{({ getRootProps }) => <div id="root" {...getRootProps()} />}
|
|
3235
|
+
</Dropzone>
|
|
3236
|
+
);
|
|
3237
|
+
const root = container.querySelector("#root");
|
|
3238
|
+
|
|
3239
|
+
expect(root).toHaveAttribute("role", "button");
|
|
3240
|
+
});
|
|
3241
|
+
|
|
3242
|
+
test("users can override the default role attribute on the root", () => {
|
|
3243
|
+
const { container } = render(
|
|
3244
|
+
<Dropzone>
|
|
3245
|
+
{({ getRootProps }) => (
|
|
3246
|
+
<div id="root" {...getRootProps({ role: "generic" })} />
|
|
3247
|
+
)}
|
|
3248
|
+
</Dropzone>
|
|
3249
|
+
);
|
|
3250
|
+
const root = container.querySelector("#root");
|
|
3251
|
+
|
|
3252
|
+
expect(root).toHaveAttribute("role", "generic");
|
|
3253
|
+
});
|
|
3254
|
+
});
|
|
3255
|
+
});
|
|
2807
3256
|
|
|
2808
3257
|
async function flushPromises(rerender, ui) {
|
|
2809
|
-
await act(() => waitFor(() => rerender(ui)))
|
|
3258
|
+
await act(() => waitFor(() => rerender(ui)));
|
|
2810
3259
|
}
|
|
2811
3260
|
|
|
2812
3261
|
function drainTimers() {
|
|
2813
|
-
act(() => jest.runAllTimers())
|
|
3262
|
+
act(() => jest.runAllTimers());
|
|
2814
3263
|
}
|
|
2815
3264
|
|
|
2816
3265
|
function createDtWithFiles(files = []) {
|
|
2817
3266
|
return {
|
|
2818
3267
|
dataTransfer: {
|
|
2819
3268
|
files,
|
|
2820
|
-
items: files.map(file => ({
|
|
2821
|
-
kind:
|
|
3269
|
+
items: files.map((file) => ({
|
|
3270
|
+
kind: "file",
|
|
2822
3271
|
size: file.size,
|
|
2823
3272
|
type: file.type,
|
|
2824
|
-
getAsFile: () => file
|
|
3273
|
+
getAsFile: () => file,
|
|
2825
3274
|
})),
|
|
2826
|
-
types: [
|
|
2827
|
-
}
|
|
2828
|
-
}
|
|
3275
|
+
types: ["Files"],
|
|
3276
|
+
},
|
|
3277
|
+
};
|
|
2829
3278
|
}
|
|
2830
3279
|
|
|
2831
3280
|
function fireDragEnter(node, data) {
|
|
2832
|
-
dispatchEvt(node,
|
|
3281
|
+
dispatchEvt(node, "dragenter", data);
|
|
2833
3282
|
}
|
|
2834
3283
|
|
|
2835
3284
|
function fireDragOver(node, data) {
|
|
2836
|
-
dispatchEvt(node,
|
|
3285
|
+
dispatchEvt(node, "dragover", data);
|
|
2837
3286
|
}
|
|
2838
3287
|
|
|
2839
3288
|
function fireDragLeave(node, data) {
|
|
2840
|
-
dispatchEvt(node,
|
|
3289
|
+
dispatchEvt(node, "dragleave", data);
|
|
2841
3290
|
}
|
|
2842
3291
|
|
|
2843
3292
|
function fireDrop(node, data) {
|
|
2844
|
-
dispatchEvt(node,
|
|
3293
|
+
dispatchEvt(node, "drop", data);
|
|
2845
3294
|
}
|
|
2846
3295
|
|
|
2847
3296
|
// Using fireEvent.* doesn't work for our use case,
|
|
2848
3297
|
// we cannot set the event props
|
|
2849
3298
|
function dispatchEvt(node, type, data) {
|
|
2850
|
-
const event = new Event(type, { bubbles: true })
|
|
3299
|
+
const event = new Event(type, { bubbles: true });
|
|
2851
3300
|
if (data) {
|
|
2852
|
-
Object.assign(event, data)
|
|
3301
|
+
Object.assign(event, data);
|
|
2853
3302
|
}
|
|
2854
|
-
fireEvent(node, event)
|
|
3303
|
+
fireEvent(node, event);
|
|
3304
|
+
}
|
|
3305
|
+
|
|
3306
|
+
function createFileSystemFileHandle(file) {
|
|
3307
|
+
return { getFile: () => Promise.resolve(file) };
|
|
2855
3308
|
}
|
|
2856
3309
|
|
|
2857
3310
|
function createFile(name, size, type) {
|
|
2858
|
-
const file = new File([], name, { type })
|
|
2859
|
-
Object.defineProperty(file,
|
|
3311
|
+
const file = new File([], name, { type });
|
|
3312
|
+
Object.defineProperty(file, "size", {
|
|
2860
3313
|
get() {
|
|
2861
|
-
return size
|
|
2862
|
-
}
|
|
2863
|
-
})
|
|
2864
|
-
return file
|
|
3314
|
+
return size;
|
|
3315
|
+
},
|
|
3316
|
+
});
|
|
3317
|
+
return file;
|
|
3318
|
+
}
|
|
3319
|
+
|
|
3320
|
+
function createThenable() {
|
|
3321
|
+
let done, cancel;
|
|
3322
|
+
|
|
3323
|
+
const promise = new Promise((resolve, reject) => {
|
|
3324
|
+
done = resolve;
|
|
3325
|
+
cancel = reject;
|
|
3326
|
+
});
|
|
3327
|
+
|
|
3328
|
+
return {
|
|
3329
|
+
promise,
|
|
3330
|
+
done,
|
|
3331
|
+
cancel,
|
|
3332
|
+
};
|
|
2865
3333
|
}
|