react-dropzone 11.7.1 → 12.0.3
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/.eslintrc +1 -3
- package/README.md +6 -1
- package/commitlint.config.js +1 -1
- package/dist/es/index.js +66 -54
- package/dist/es/utils/index.js +44 -22
- package/dist/index.js +2 -2
- package/examples/accept/README.md +10 -3
- package/package.json +7 -6
- package/rollup.config.js +20 -20
- package/src/.eslintrc +1 -2
- package/src/index.js +333 -281
- package/src/index.spec.js +1851 -1523
- package/src/utils/index.js +128 -73
- package/src/utils/index.spec.js +440 -289
- package/styleguide.config.js +55 -52
- package/testSetup.js +7 -1
- package/typings/.eslintrc +1 -1
- package/typings/react-dropzone.d.ts +25 -14
- package/typings/tests/accept.tsx +10 -9
- package/typings/tests/all.tsx +7 -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/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,32 +1176,32 @@ describe('useDropzone() hook', () => {
|
|
|
1151
1176
|
</div>
|
|
1152
1177
|
)}
|
|
1153
1178
|
</Dropzone>
|
|
1154
|
-
)
|
|
1179
|
+
);
|
|
1155
1180
|
|
|
1156
|
-
fireEvent.blur(dropzone)
|
|
1157
|
-
expect(dropzone.querySelector(
|
|
1158
|
-
})
|
|
1159
|
-
})
|
|
1181
|
+
fireEvent.blur(dropzone);
|
|
1182
|
+
expect(dropzone.querySelector("#focus")).toBeNull();
|
|
1183
|
+
});
|
|
1184
|
+
});
|
|
1160
1185
|
|
|
1161
|
-
describe(
|
|
1186
|
+
describe("onClick", () => {
|
|
1162
1187
|
let currentShowOpenFilePicker;
|
|
1163
1188
|
|
|
1164
1189
|
beforeEach(() => {
|
|
1165
|
-
currentShowOpenFilePicker = window.showOpenFilePicker
|
|
1166
|
-
})
|
|
1190
|
+
currentShowOpenFilePicker = window.showOpenFilePicker;
|
|
1191
|
+
});
|
|
1167
1192
|
|
|
1168
1193
|
afterEach(() => {
|
|
1169
1194
|
if (currentShowOpenFilePicker) {
|
|
1170
|
-
window.showOpenFilePicker = currentShowOpenFilePicker
|
|
1195
|
+
window.showOpenFilePicker = currentShowOpenFilePicker;
|
|
1171
1196
|
} else {
|
|
1172
|
-
delete window.showOpenFilePicker
|
|
1197
|
+
delete window.showOpenFilePicker;
|
|
1173
1198
|
}
|
|
1174
|
-
})
|
|
1199
|
+
});
|
|
1175
1200
|
|
|
1176
|
-
it(
|
|
1177
|
-
const activeRef = createRef()
|
|
1178
|
-
const active = <span ref={activeRef}>I am active</span
|
|
1179
|
-
const onClickSpy = jest.spyOn(HTMLInputElement.prototype,
|
|
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");
|
|
1180
1205
|
|
|
1181
1206
|
const { container } = render(
|
|
1182
1207
|
<Dropzone>
|
|
@@ -1187,37 +1212,39 @@ describe('useDropzone() hook', () => {
|
|
|
1187
1212
|
</div>
|
|
1188
1213
|
)}
|
|
1189
1214
|
</Dropzone>
|
|
1190
|
-
)
|
|
1215
|
+
);
|
|
1191
1216
|
|
|
1192
|
-
const dropzone = container.querySelector(
|
|
1217
|
+
const dropzone = container.querySelector("div");
|
|
1193
1218
|
|
|
1194
|
-
fireEvent.click(dropzone)
|
|
1195
|
-
const ref = activeRef.current
|
|
1196
|
-
expect(ref).not.toBeNull()
|
|
1197
|
-
expect(dropzone).toContainElement(ref)
|
|
1198
|
-
expect(onClickSpy).toHaveBeenCalled()
|
|
1199
|
-
})
|
|
1219
|
+
fireEvent.click(dropzone);
|
|
1220
|
+
const ref = activeRef.current;
|
|
1221
|
+
expect(ref).not.toBeNull();
|
|
1222
|
+
expect(dropzone).toContainElement(ref);
|
|
1223
|
+
expect(onClickSpy).toHaveBeenCalled();
|
|
1224
|
+
});
|
|
1200
1225
|
|
|
1201
|
-
it(
|
|
1202
|
-
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");
|
|
1203
1228
|
const { container } = render(
|
|
1204
1229
|
<Dropzone>
|
|
1205
1230
|
{({ getRootProps, getInputProps }) => (
|
|
1206
|
-
<div
|
|
1231
|
+
<div
|
|
1232
|
+
{...getRootProps({ onClick: (event) => event.stopPropagation() })}
|
|
1233
|
+
>
|
|
1207
1234
|
<input {...getInputProps()} />
|
|
1208
1235
|
</div>
|
|
1209
1236
|
)}
|
|
1210
1237
|
</Dropzone>
|
|
1211
|
-
)
|
|
1238
|
+
);
|
|
1212
1239
|
|
|
1213
|
-
const dropzone = container.querySelector(
|
|
1240
|
+
const dropzone = container.querySelector("div");
|
|
1214
1241
|
|
|
1215
|
-
fireEvent.click(dropzone)
|
|
1216
|
-
expect(onClickSpy).not.toHaveBeenCalled()
|
|
1217
|
-
})
|
|
1242
|
+
fireEvent.click(dropzone);
|
|
1243
|
+
expect(onClickSpy).not.toHaveBeenCalled();
|
|
1244
|
+
});
|
|
1218
1245
|
|
|
1219
|
-
it(
|
|
1220
|
-
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");
|
|
1221
1248
|
const { container } = render(
|
|
1222
1249
|
<Dropzone noClick>
|
|
1223
1250
|
{({ getRootProps, getInputProps }) => (
|
|
@@ -1226,16 +1253,16 @@ describe('useDropzone() hook', () => {
|
|
|
1226
1253
|
</div>
|
|
1227
1254
|
)}
|
|
1228
1255
|
</Dropzone>
|
|
1229
|
-
)
|
|
1256
|
+
);
|
|
1230
1257
|
|
|
1231
|
-
const dropzone = container.querySelector(
|
|
1258
|
+
const dropzone = container.querySelector("div");
|
|
1232
1259
|
|
|
1233
|
-
fireEvent.click(dropzone)
|
|
1234
|
-
expect(onClickSpy).not.toHaveBeenCalled()
|
|
1235
|
-
})
|
|
1260
|
+
fireEvent.click(dropzone);
|
|
1261
|
+
expect(onClickSpy).not.toHaveBeenCalled();
|
|
1262
|
+
});
|
|
1236
1263
|
|
|
1237
|
-
it(
|
|
1238
|
-
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");
|
|
1239
1266
|
const { container, rerender } = render(
|
|
1240
1267
|
<Dropzone noClick>
|
|
1241
1268
|
{({ getRootProps, getInputProps }) => (
|
|
@@ -1244,12 +1271,12 @@ describe('useDropzone() hook', () => {
|
|
|
1244
1271
|
</div>
|
|
1245
1272
|
)}
|
|
1246
1273
|
</Dropzone>
|
|
1247
|
-
)
|
|
1274
|
+
);
|
|
1248
1275
|
|
|
1249
|
-
const dropzone = container.querySelector(
|
|
1276
|
+
const dropzone = container.querySelector("div");
|
|
1250
1277
|
|
|
1251
|
-
fireEvent.click(dropzone)
|
|
1252
|
-
expect(onClickSpy).not.toHaveBeenCalled()
|
|
1278
|
+
fireEvent.click(dropzone);
|
|
1279
|
+
expect(onClickSpy).not.toHaveBeenCalled();
|
|
1253
1280
|
|
|
1254
1281
|
rerender(
|
|
1255
1282
|
<Dropzone noClick={false}>
|
|
@@ -1259,16 +1286,16 @@ describe('useDropzone() hook', () => {
|
|
|
1259
1286
|
</div>
|
|
1260
1287
|
)}
|
|
1261
1288
|
</Dropzone>
|
|
1262
|
-
)
|
|
1289
|
+
);
|
|
1263
1290
|
|
|
1264
|
-
fireEvent.click(dropzone)
|
|
1265
|
-
expect(onClickSpy).toHaveBeenCalled()
|
|
1266
|
-
})
|
|
1291
|
+
fireEvent.click(dropzone);
|
|
1292
|
+
expect(onClickSpy).toHaveBeenCalled();
|
|
1293
|
+
});
|
|
1267
1294
|
|
|
1268
1295
|
// https://github.com/react-dropzone/react-dropzone/issues/783
|
|
1269
|
-
it(
|
|
1270
|
-
const btnClickSpy = jest.fn()
|
|
1271
|
-
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");
|
|
1272
1299
|
const { container } = render(
|
|
1273
1300
|
<Dropzone noClick>
|
|
1274
1301
|
{({ getRootProps, getInputProps }) => (
|
|
@@ -1278,23 +1305,25 @@ describe('useDropzone() hook', () => {
|
|
|
1278
1305
|
</div>
|
|
1279
1306
|
)}
|
|
1280
1307
|
</Dropzone>
|
|
1281
|
-
)
|
|
1308
|
+
);
|
|
1282
1309
|
|
|
1283
|
-
const dropzone = container.querySelector(
|
|
1284
|
-
const btn = container.querySelector(
|
|
1310
|
+
const dropzone = container.querySelector("div");
|
|
1311
|
+
const btn = container.querySelector("button");
|
|
1285
1312
|
|
|
1286
|
-
fireEvent.click(dropzone)
|
|
1287
|
-
expect(inputClickSpy).not.toHaveBeenCalled()
|
|
1313
|
+
fireEvent.click(dropzone);
|
|
1314
|
+
expect(inputClickSpy).not.toHaveBeenCalled();
|
|
1288
1315
|
|
|
1289
|
-
fireEvent.click(btn)
|
|
1290
|
-
expect(btnClickSpy).toHaveBeenCalled()
|
|
1291
|
-
})
|
|
1316
|
+
fireEvent.click(btn);
|
|
1317
|
+
expect(btnClickSpy).toHaveBeenCalled();
|
|
1318
|
+
});
|
|
1292
1319
|
|
|
1293
|
-
it(
|
|
1294
|
-
jest.useFakeTimers()
|
|
1320
|
+
it("should schedule input click on next tick in Edge", () => {
|
|
1321
|
+
jest.useFakeTimers();
|
|
1295
1322
|
|
|
1296
|
-
const isIeOrEdgeSpy = jest
|
|
1297
|
-
|
|
1323
|
+
const isIeOrEdgeSpy = jest
|
|
1324
|
+
.spyOn(utils, "isIeOrEdge")
|
|
1325
|
+
.mockReturnValueOnce(true);
|
|
1326
|
+
const onClickSpy = jest.spyOn(HTMLInputElement.prototype, "click");
|
|
1298
1327
|
|
|
1299
1328
|
const ui = (
|
|
1300
1329
|
<Dropzone>
|
|
@@ -1304,34 +1333,36 @@ describe('useDropzone() hook', () => {
|
|
|
1304
1333
|
</div>
|
|
1305
1334
|
)}
|
|
1306
1335
|
</Dropzone>
|
|
1307
|
-
)
|
|
1336
|
+
);
|
|
1308
1337
|
|
|
1309
|
-
const { container } = render(ui)
|
|
1338
|
+
const { container } = render(ui);
|
|
1310
1339
|
|
|
1311
|
-
const dropzone = container.querySelector(
|
|
1340
|
+
const dropzone = container.querySelector("div");
|
|
1312
1341
|
|
|
1313
|
-
fireEvent.click(dropzone)
|
|
1314
|
-
drainTimers()
|
|
1342
|
+
fireEvent.click(dropzone);
|
|
1343
|
+
drainTimers();
|
|
1315
1344
|
|
|
1316
|
-
expect(onClickSpy).toHaveBeenCalled()
|
|
1317
|
-
jest.useRealTimers()
|
|
1318
|
-
isIeOrEdgeSpy.mockClear()
|
|
1319
|
-
})
|
|
1345
|
+
expect(onClickSpy).toHaveBeenCalled();
|
|
1346
|
+
jest.useRealTimers();
|
|
1347
|
+
isIeOrEdgeSpy.mockClear();
|
|
1348
|
+
});
|
|
1320
1349
|
|
|
1321
|
-
it(
|
|
1322
|
-
jest.useFakeTimers()
|
|
1350
|
+
it("should not use showOpenFilePicker() if supported and {useFsAccessApi} is not true", async () => {
|
|
1351
|
+
jest.useFakeTimers();
|
|
1323
1352
|
|
|
1324
|
-
const activeRef = createRef()
|
|
1325
|
-
const active = <span ref={activeRef}>I am active</span
|
|
1326
|
-
const onClickSpy = jest.spyOn(HTMLInputElement.prototype,
|
|
1353
|
+
const activeRef = createRef();
|
|
1354
|
+
const active = <span ref={activeRef}>I am active</span>;
|
|
1355
|
+
const onClickSpy = jest.spyOn(HTMLInputElement.prototype, "click");
|
|
1327
1356
|
|
|
1328
|
-
const handlers = files.map(f => createFileSystemFileHandle(f))
|
|
1329
|
-
const showOpenFilePickerMock = jest
|
|
1357
|
+
const handlers = files.map((f) => createFileSystemFileHandle(f));
|
|
1358
|
+
const showOpenFilePickerMock = jest
|
|
1359
|
+
.fn()
|
|
1360
|
+
.mockReturnValue(Promise.resolve(handlers));
|
|
1330
1361
|
|
|
1331
|
-
window.showOpenFilePicker = showOpenFilePickerMock
|
|
1362
|
+
window.showOpenFilePicker = showOpenFilePickerMock;
|
|
1332
1363
|
|
|
1333
|
-
const onDropSpy = jest.fn()
|
|
1334
|
-
const onFileDialogOpenSpy = jest.fn()
|
|
1364
|
+
const onDropSpy = jest.fn();
|
|
1365
|
+
const onFileDialogOpenSpy = jest.fn();
|
|
1335
1366
|
|
|
1336
1367
|
const ui = (
|
|
1337
1368
|
<Dropzone
|
|
@@ -1339,6 +1370,7 @@ describe('useDropzone() hook', () => {
|
|
|
1339
1370
|
onFileDialogOpen={onFileDialogOpenSpy}
|
|
1340
1371
|
accept="application/pdf"
|
|
1341
1372
|
multiple
|
|
1373
|
+
useFsAccessApi={false}
|
|
1342
1374
|
>
|
|
1343
1375
|
{({ getRootProps, getInputProps, isFileDialogActive }) => (
|
|
1344
1376
|
<div {...getRootProps()}>
|
|
@@ -1347,43 +1379,47 @@ describe('useDropzone() hook', () => {
|
|
|
1347
1379
|
</div>
|
|
1348
1380
|
)}
|
|
1349
1381
|
</Dropzone>
|
|
1350
|
-
)
|
|
1382
|
+
);
|
|
1383
|
+
|
|
1384
|
+
const { container, rerender } = render(ui);
|
|
1351
1385
|
|
|
1352
|
-
const
|
|
1386
|
+
const dropzone = container.querySelector("div");
|
|
1353
1387
|
|
|
1354
|
-
|
|
1388
|
+
fireEvent.click(dropzone);
|
|
1355
1389
|
|
|
1356
|
-
|
|
1390
|
+
await flushPromises(rerender, ui);
|
|
1357
1391
|
|
|
1358
|
-
|
|
1392
|
+
dispatchEvt(document.body, "focus");
|
|
1393
|
+
drainTimers();
|
|
1359
1394
|
|
|
1360
|
-
|
|
1361
|
-
drainTimers()
|
|
1395
|
+
expect(onFileDialogOpenSpy).toHaveBeenCalled();
|
|
1362
1396
|
|
|
1363
|
-
expect(
|
|
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();
|
|
1364
1402
|
|
|
1365
|
-
|
|
1366
|
-
|
|
1367
|
-
expect(onClickSpy).toHaveBeenCalled()
|
|
1368
|
-
expect(showOpenFilePickerMock).not.toHaveBeenCalled()
|
|
1369
|
-
expect(onDropSpy).not.toHaveBeenCalled()
|
|
1403
|
+
jest.useRealTimers();
|
|
1404
|
+
});
|
|
1370
1405
|
|
|
1371
|
-
|
|
1372
|
-
|
|
1406
|
+
it("should not use showOpenFilePicker() if supported and {isSecureContext} is not true", async () => {
|
|
1407
|
+
jest.useFakeTimers();
|
|
1373
1408
|
|
|
1374
|
-
|
|
1375
|
-
const
|
|
1376
|
-
const
|
|
1377
|
-
const onClickSpy = jest.spyOn(HTMLInputElement.prototype, 'click')
|
|
1409
|
+
const activeRef = createRef();
|
|
1410
|
+
const active = <span ref={activeRef}>I am active</span>;
|
|
1411
|
+
const onClickSpy = jest.spyOn(HTMLInputElement.prototype, "click");
|
|
1378
1412
|
|
|
1379
|
-
const handlers = files.map(f => createFileSystemFileHandle(f))
|
|
1380
|
-
const
|
|
1381
|
-
|
|
1413
|
+
const handlers = files.map((f) => createFileSystemFileHandle(f));
|
|
1414
|
+
const showOpenFilePickerMock = jest
|
|
1415
|
+
.fn()
|
|
1416
|
+
.mockReturnValue(Promise.resolve(handlers));
|
|
1382
1417
|
|
|
1383
|
-
window.showOpenFilePicker = showOpenFilePickerMock
|
|
1418
|
+
window.showOpenFilePicker = showOpenFilePickerMock;
|
|
1419
|
+
window.isSecureContext = false;
|
|
1384
1420
|
|
|
1385
|
-
const onDropSpy = jest.fn()
|
|
1386
|
-
const onFileDialogOpenSpy = jest.fn()
|
|
1421
|
+
const onDropSpy = jest.fn();
|
|
1422
|
+
const onFileDialogOpenSpy = jest.fn();
|
|
1387
1423
|
|
|
1388
1424
|
const ui = (
|
|
1389
1425
|
<Dropzone
|
|
@@ -1391,7 +1427,6 @@ describe('useDropzone() hook', () => {
|
|
|
1391
1427
|
onFileDialogOpen={onFileDialogOpenSpy}
|
|
1392
1428
|
accept="application/pdf"
|
|
1393
1429
|
multiple
|
|
1394
|
-
useFsAccessApi
|
|
1395
1430
|
>
|
|
1396
1431
|
{({ getRootProps, getInputProps, isFileDialogActive }) => (
|
|
1397
1432
|
<div {...getRootProps()}>
|
|
@@ -1400,86 +1435,149 @@ describe('useDropzone() hook', () => {
|
|
|
1400
1435
|
</div>
|
|
1401
1436
|
)}
|
|
1402
1437
|
</Dropzone>
|
|
1403
|
-
)
|
|
1438
|
+
);
|
|
1404
1439
|
|
|
1405
|
-
const { container, rerender } = render(ui)
|
|
1440
|
+
const { container, rerender } = render(ui);
|
|
1406
1441
|
|
|
1407
|
-
const dropzone = container.querySelector(
|
|
1442
|
+
const dropzone = container.querySelector("div");
|
|
1408
1443
|
|
|
1409
|
-
fireEvent.click(dropzone)
|
|
1444
|
+
fireEvent.click(dropzone);
|
|
1410
1445
|
|
|
1411
|
-
await flushPromises(rerender, ui)
|
|
1446
|
+
await flushPromises(rerender, ui);
|
|
1412
1447
|
|
|
1413
|
-
|
|
1414
|
-
|
|
1415
|
-
expect(onFileDialogOpenSpy).toHaveBeenCalled()
|
|
1448
|
+
dispatchEvt(document.body, "focus");
|
|
1449
|
+
drainTimers();
|
|
1416
1450
|
|
|
1417
|
-
|
|
1418
|
-
await flushPromises(rerender, ui)
|
|
1451
|
+
expect(onFileDialogOpenSpy).toHaveBeenCalled();
|
|
1419
1452
|
|
|
1420
|
-
expect(activeRef.current).toBeNull()
|
|
1421
|
-
expect(dropzone).not.toContainElement(activeRef.current)
|
|
1422
|
-
expect(onClickSpy).
|
|
1423
|
-
expect(showOpenFilePickerMock).
|
|
1424
|
-
|
|
1425
|
-
|
|
1426
|
-
|
|
1427
|
-
accept: {'application/pdf': []}
|
|
1428
|
-
}]
|
|
1429
|
-
})
|
|
1430
|
-
expect(onDropSpy).toHaveBeenCalledWith(files, [], null)
|
|
1431
|
-
})
|
|
1453
|
+
expect(activeRef.current).toBeNull();
|
|
1454
|
+
expect(dropzone).not.toContainElement(activeRef.current);
|
|
1455
|
+
expect(onClickSpy).toHaveBeenCalled();
|
|
1456
|
+
expect(showOpenFilePickerMock).not.toHaveBeenCalled();
|
|
1457
|
+
expect(onDropSpy).not.toHaveBeenCalled();
|
|
1458
|
+
|
|
1459
|
+
jest.useRealTimers();
|
|
1432
1460
|
|
|
1433
|
-
|
|
1434
|
-
|
|
1435
|
-
const active = <span ref={activeRef}>I am active</span>
|
|
1461
|
+
window.isSecureContext = true;
|
|
1462
|
+
});
|
|
1436
1463
|
|
|
1437
|
-
|
|
1438
|
-
const
|
|
1464
|
+
it("should use showOpenFilePicker() if supported and {useFsAccessApi} is true, and not trigger click on input", async () => {
|
|
1465
|
+
const activeRef = createRef();
|
|
1466
|
+
const active = <span ref={activeRef}>I am active</span>;
|
|
1467
|
+
const onClickSpy = jest.spyOn(HTMLInputElement.prototype, "click");
|
|
1439
1468
|
|
|
1440
|
-
|
|
1469
|
+
const handlers = files.map((f) => createFileSystemFileHandle(f));
|
|
1470
|
+
const thenable = createThenable();
|
|
1471
|
+
const showOpenFilePickerMock = jest
|
|
1472
|
+
.fn()
|
|
1473
|
+
.mockReturnValue(thenable.promise);
|
|
1441
1474
|
|
|
1442
|
-
|
|
1443
|
-
|
|
1475
|
+
window.showOpenFilePicker = showOpenFilePickerMock;
|
|
1476
|
+
|
|
1477
|
+
const onDropSpy = jest.fn();
|
|
1478
|
+
const onFileDialogOpenSpy = jest.fn();
|
|
1444
1479
|
|
|
1445
1480
|
const ui = (
|
|
1446
1481
|
<Dropzone
|
|
1447
1482
|
onDrop={onDropSpy}
|
|
1448
1483
|
onFileDialogOpen={onFileDialogOpenSpy}
|
|
1484
|
+
accept="application/pdf"
|
|
1485
|
+
multiple
|
|
1449
1486
|
useFsAccessApi
|
|
1450
1487
|
>
|
|
1451
|
-
{({ getRootProps, isFileDialogActive }) => (
|
|
1488
|
+
{({ getRootProps, getInputProps, isFileDialogActive }) => (
|
|
1452
1489
|
<div {...getRootProps()}>
|
|
1490
|
+
<input {...getInputProps()} />
|
|
1453
1491
|
{isFileDialogActive && active}
|
|
1454
1492
|
</div>
|
|
1455
1493
|
)}
|
|
1456
1494
|
</Dropzone>
|
|
1457
|
-
)
|
|
1495
|
+
);
|
|
1458
1496
|
|
|
1459
|
-
const { container, rerender } = render(ui)
|
|
1497
|
+
const { container, rerender } = render(ui);
|
|
1460
1498
|
|
|
1461
|
-
const dropzone = container.querySelector(
|
|
1499
|
+
const dropzone = container.querySelector("div");
|
|
1462
1500
|
|
|
1463
|
-
fireEvent.click(dropzone)
|
|
1464
|
-
await flushPromises(rerender, ui)
|
|
1465
|
-
const ref = activeRef.current
|
|
1466
|
-
expect(ref).toBeNull() // We expect the dialog to be closed at this point
|
|
1467
|
-
expect(dropzone).not.toContainElement(ref)
|
|
1468
|
-
expect(showOpenFilePickerMock).toHaveBeenCalled()
|
|
1469
|
-
expect(onDropSpy).toHaveBeenCalledWith(files, [], null)
|
|
1470
|
-
expect(onFileDialogOpenSpy).toHaveBeenCalled()
|
|
1471
|
-
})
|
|
1501
|
+
fireEvent.click(dropzone);
|
|
1472
1502
|
|
|
1473
|
-
|
|
1474
|
-
const activeRef = createRef()
|
|
1475
|
-
const active = <span ref={activeRef}>I am active</span>
|
|
1503
|
+
await flushPromises(rerender, ui);
|
|
1476
1504
|
|
|
1477
|
-
|
|
1505
|
+
expect(activeRef.current).not.toBeNull();
|
|
1506
|
+
expect(dropzone).toContainElement(activeRef.current);
|
|
1507
|
+
expect(onFileDialogOpenSpy).toHaveBeenCalled();
|
|
1478
1508
|
|
|
1479
|
-
|
|
1509
|
+
thenable.done(handlers);
|
|
1510
|
+
await flushPromises(rerender, ui);
|
|
1480
1511
|
|
|
1481
|
-
|
|
1482
|
-
|
|
1512
|
+
expect(activeRef.current).toBeNull(); // We expect the dialog to be closed at this point
|
|
1513
|
+
expect(dropzone).not.toContainElement(activeRef.current);
|
|
1514
|
+
expect(onClickSpy).not.toHaveBeenCalled();
|
|
1515
|
+
expect(showOpenFilePickerMock).toHaveBeenCalledWith({
|
|
1516
|
+
multiple: true,
|
|
1517
|
+
types: [
|
|
1518
|
+
{
|
|
1519
|
+
description: "everything",
|
|
1520
|
+
accept: { "application/pdf": [] },
|
|
1521
|
+
},
|
|
1522
|
+
],
|
|
1523
|
+
});
|
|
1524
|
+
expect(onDropSpy).toHaveBeenCalledWith(files, [], null);
|
|
1525
|
+
});
|
|
1526
|
+
|
|
1527
|
+
test("if showOpenFilePicker() is supported and {useFsAccessApi} is true, it should work without the <input>", async () => {
|
|
1528
|
+
const activeRef = createRef();
|
|
1529
|
+
const active = <span ref={activeRef}>I am active</span>;
|
|
1530
|
+
|
|
1531
|
+
const handlers = files.map((f) => createFileSystemFileHandle(f));
|
|
1532
|
+
const showOpenFilePickerMock = jest
|
|
1533
|
+
.fn()
|
|
1534
|
+
.mockReturnValue(Promise.resolve(handlers));
|
|
1535
|
+
|
|
1536
|
+
window.showOpenFilePicker = showOpenFilePickerMock;
|
|
1537
|
+
|
|
1538
|
+
const onDropSpy = jest.fn();
|
|
1539
|
+
const onFileDialogOpenSpy = jest.fn();
|
|
1540
|
+
|
|
1541
|
+
const ui = (
|
|
1542
|
+
<Dropzone
|
|
1543
|
+
onDrop={onDropSpy}
|
|
1544
|
+
onFileDialogOpen={onFileDialogOpenSpy}
|
|
1545
|
+
useFsAccessApi
|
|
1546
|
+
>
|
|
1547
|
+
{({ getRootProps, isFileDialogActive }) => (
|
|
1548
|
+
<div {...getRootProps()}>{isFileDialogActive && active}</div>
|
|
1549
|
+
)}
|
|
1550
|
+
</Dropzone>
|
|
1551
|
+
);
|
|
1552
|
+
|
|
1553
|
+
const { container, rerender } = render(ui);
|
|
1554
|
+
|
|
1555
|
+
const dropzone = container.querySelector("div");
|
|
1556
|
+
|
|
1557
|
+
fireEvent.click(dropzone);
|
|
1558
|
+
await flushPromises(rerender, ui);
|
|
1559
|
+
const ref = activeRef.current;
|
|
1560
|
+
expect(ref).toBeNull(); // We expect the dialog to be closed at this point
|
|
1561
|
+
expect(dropzone).not.toContainElement(ref);
|
|
1562
|
+
expect(showOpenFilePickerMock).toHaveBeenCalled();
|
|
1563
|
+
expect(onDropSpy).toHaveBeenCalledWith(files, [], null);
|
|
1564
|
+
expect(onFileDialogOpenSpy).toHaveBeenCalled();
|
|
1565
|
+
});
|
|
1566
|
+
|
|
1567
|
+
test("if showOpenFilePicker() is supported and {useFsAccessApi} is true, and the user cancels it should call onFileDialogCancel", async () => {
|
|
1568
|
+
const activeRef = createRef();
|
|
1569
|
+
const active = <span ref={activeRef}>I am active</span>;
|
|
1570
|
+
|
|
1571
|
+
const showOpenFilePickerMock = jest
|
|
1572
|
+
.fn()
|
|
1573
|
+
.mockReturnValue(
|
|
1574
|
+
Promise.reject(new DOMException("user aborted request", "AbortError"))
|
|
1575
|
+
);
|
|
1576
|
+
|
|
1577
|
+
window.showOpenFilePicker = showOpenFilePickerMock;
|
|
1578
|
+
|
|
1579
|
+
const onDropSpy = jest.fn();
|
|
1580
|
+
const onFileDialogCancelSpy = jest.fn();
|
|
1483
1581
|
|
|
1484
1582
|
const ui = (
|
|
1485
1583
|
<Dropzone
|
|
@@ -1488,38 +1586,38 @@ describe('useDropzone() hook', () => {
|
|
|
1488
1586
|
useFsAccessApi
|
|
1489
1587
|
>
|
|
1490
1588
|
{({ getRootProps, isFileDialogActive }) => (
|
|
1491
|
-
<div {...getRootProps()}>
|
|
1492
|
-
{isFileDialogActive && active}
|
|
1493
|
-
</div>
|
|
1589
|
+
<div {...getRootProps()}>{isFileDialogActive && active}</div>
|
|
1494
1590
|
)}
|
|
1495
1591
|
</Dropzone>
|
|
1496
|
-
)
|
|
1592
|
+
);
|
|
1497
1593
|
|
|
1498
|
-
const { container, rerender } = render(ui)
|
|
1594
|
+
const { container, rerender } = render(ui);
|
|
1499
1595
|
|
|
1500
|
-
const dropzone = container.querySelector(
|
|
1596
|
+
const dropzone = container.querySelector("div");
|
|
1501
1597
|
|
|
1502
|
-
fireEvent.click(dropzone)
|
|
1503
|
-
await flushPromises(rerender, ui)
|
|
1504
|
-
const ref = activeRef.current
|
|
1505
|
-
expect(ref).toBeNull() // We expect the dialog to be closed at this point
|
|
1506
|
-
expect(dropzone).not.toContainElement(ref)
|
|
1507
|
-
expect(showOpenFilePickerMock).toHaveBeenCalled()
|
|
1508
|
-
expect(onDropSpy).not.toHaveBeenCalled()
|
|
1509
|
-
expect(onFileDialogCancelSpy).toHaveBeenCalled()
|
|
1510
|
-
})
|
|
1598
|
+
fireEvent.click(dropzone);
|
|
1599
|
+
await flushPromises(rerender, ui);
|
|
1600
|
+
const ref = activeRef.current;
|
|
1601
|
+
expect(ref).toBeNull(); // We expect the dialog to be closed at this point
|
|
1602
|
+
expect(dropzone).not.toContainElement(ref);
|
|
1603
|
+
expect(showOpenFilePickerMock).toHaveBeenCalled();
|
|
1604
|
+
expect(onDropSpy).not.toHaveBeenCalled();
|
|
1605
|
+
expect(onFileDialogCancelSpy).toHaveBeenCalled();
|
|
1606
|
+
});
|
|
1511
1607
|
|
|
1512
|
-
test(
|
|
1513
|
-
jest.useFakeTimers()
|
|
1608
|
+
test("window focus evt is not bound if showOpenFilePicker() is supported and {useFsAccessApi} is true", async () => {
|
|
1609
|
+
jest.useFakeTimers();
|
|
1514
1610
|
|
|
1515
|
-
const activeRef = createRef()
|
|
1516
|
-
const active = <span ref={activeRef}>I am active</span
|
|
1517
|
-
const onFileDialogCancelSpy = jest.fn()
|
|
1611
|
+
const activeRef = createRef();
|
|
1612
|
+
const active = <span ref={activeRef}>I am active</span>;
|
|
1613
|
+
const onFileDialogCancelSpy = jest.fn();
|
|
1518
1614
|
|
|
1519
|
-
const thenable = createThenable()
|
|
1520
|
-
const showOpenFilePickerMock = jest
|
|
1615
|
+
const thenable = createThenable();
|
|
1616
|
+
const showOpenFilePickerMock = jest
|
|
1617
|
+
.fn()
|
|
1618
|
+
.mockReturnValue(thenable.promise);
|
|
1521
1619
|
|
|
1522
|
-
window.showOpenFilePicker = showOpenFilePickerMock
|
|
1620
|
+
window.showOpenFilePicker = showOpenFilePickerMock;
|
|
1523
1621
|
|
|
1524
1622
|
const ui = (
|
|
1525
1623
|
<Dropzone
|
|
@@ -1536,39 +1634,147 @@ describe('useDropzone() hook', () => {
|
|
|
1536
1634
|
</div>
|
|
1537
1635
|
)}
|
|
1538
1636
|
</Dropzone>
|
|
1539
|
-
)
|
|
1637
|
+
);
|
|
1638
|
+
|
|
1639
|
+
const { container, rerender } = render(ui);
|
|
1640
|
+
|
|
1641
|
+
const dropzone = container.querySelector("div");
|
|
1642
|
+
const btn = container.querySelector("button");
|
|
1643
|
+
|
|
1644
|
+
btn.click();
|
|
1645
|
+
drainTimers();
|
|
1646
|
+
await flushPromises(rerender, ui);
|
|
1647
|
+
|
|
1648
|
+
const ref = activeRef.current;
|
|
1649
|
+
expect(ref).not.toBeNull();
|
|
1650
|
+
expect(dropzone).toContainElement(ref);
|
|
1651
|
+
|
|
1652
|
+
thenable.cancel(new DOMException("user aborted request", "AbortError"));
|
|
1653
|
+
|
|
1654
|
+
dispatchEvt(document.body, "focus");
|
|
1655
|
+
drainTimers();
|
|
1656
|
+
await flushPromises(rerender, ui);
|
|
1657
|
+
|
|
1658
|
+
expect(onFileDialogCancelSpy).toHaveBeenCalledTimes(1);
|
|
1659
|
+
expect(dropzone).not.toContainElement(ref);
|
|
1660
|
+
|
|
1661
|
+
jest.useRealTimers();
|
|
1662
|
+
});
|
|
1663
|
+
|
|
1664
|
+
it("should try to use showOpenFilePicker() and fallback to input in case of a security error", async () => {
|
|
1665
|
+
const activeRef = createRef();
|
|
1666
|
+
const active = <span ref={activeRef}>I am active</span>;
|
|
1667
|
+
const onClickSpy = jest.spyOn(HTMLInputElement.prototype, "click");
|
|
1668
|
+
|
|
1669
|
+
const thenable = createThenable();
|
|
1670
|
+
const showOpenFilePickerMock = jest
|
|
1671
|
+
.fn()
|
|
1672
|
+
.mockReturnValue(thenable.promise);
|
|
1673
|
+
|
|
1674
|
+
window.showOpenFilePicker = showOpenFilePickerMock;
|
|
1675
|
+
|
|
1676
|
+
const onDropSpy = jest.fn();
|
|
1677
|
+
const onFileDialogOpenSpy = jest.fn();
|
|
1678
|
+
|
|
1679
|
+
const ui = (
|
|
1680
|
+
<Dropzone
|
|
1681
|
+
onDrop={onDropSpy}
|
|
1682
|
+
onFileDialogOpen={onFileDialogOpenSpy}
|
|
1683
|
+
accept="application/pdf"
|
|
1684
|
+
multiple
|
|
1685
|
+
useFsAccessApi
|
|
1686
|
+
>
|
|
1687
|
+
{({ getRootProps, getInputProps, isFileDialogActive }) => (
|
|
1688
|
+
<div {...getRootProps()}>
|
|
1689
|
+
<input {...getInputProps()} />
|
|
1690
|
+
{isFileDialogActive && active}
|
|
1691
|
+
</div>
|
|
1692
|
+
)}
|
|
1693
|
+
</Dropzone>
|
|
1694
|
+
);
|
|
1695
|
+
|
|
1696
|
+
const { container, rerender } = render(ui);
|
|
1697
|
+
|
|
1698
|
+
const dropzone = container.querySelector("div");
|
|
1699
|
+
|
|
1700
|
+
fireEvent.click(dropzone);
|
|
1701
|
+
|
|
1702
|
+
await flushPromises(rerender, ui);
|
|
1703
|
+
|
|
1704
|
+
expect(activeRef.current).not.toBeNull();
|
|
1705
|
+
expect(dropzone).toContainElement(activeRef.current);
|
|
1706
|
+
expect(onFileDialogOpenSpy).toHaveBeenCalled();
|
|
1707
|
+
|
|
1708
|
+
thenable.cancel(
|
|
1709
|
+
new DOMException("Cannot use this API cross-origin", "SecurityError")
|
|
1710
|
+
);
|
|
1711
|
+
await flushPromises(rerender, ui);
|
|
1712
|
+
|
|
1713
|
+
expect(activeRef.current).not.toBeNull();
|
|
1714
|
+
expect(dropzone).toContainElement(activeRef.current);
|
|
1715
|
+
expect(onClickSpy).toHaveBeenCalled();
|
|
1716
|
+
});
|
|
1717
|
+
|
|
1718
|
+
test("window focus evt is bound if showOpenFilePicker() is supported but errors due to a security error", async () => {
|
|
1719
|
+
jest.useFakeTimers();
|
|
1720
|
+
|
|
1721
|
+
const activeRef = createRef();
|
|
1722
|
+
const active = <span ref={activeRef}>I am active</span>;
|
|
1723
|
+
const onFileDialogCancelSpy = jest.fn();
|
|
1540
1724
|
|
|
1541
|
-
const
|
|
1725
|
+
const thenable = createThenable();
|
|
1726
|
+
const showOpenFilePickerMock = jest
|
|
1727
|
+
.fn()
|
|
1728
|
+
.mockReturnValue(thenable.promise);
|
|
1729
|
+
|
|
1730
|
+
window.showOpenFilePicker = showOpenFilePickerMock;
|
|
1731
|
+
|
|
1732
|
+
const ui = (
|
|
1733
|
+
<Dropzone onFileDialogCancel={onFileDialogCancelSpy}>
|
|
1734
|
+
{({ getRootProps, getInputProps, isFileDialogActive }) => (
|
|
1735
|
+
<div {...getRootProps()}>
|
|
1736
|
+
<input {...getInputProps()} />
|
|
1737
|
+
{isFileDialogActive && active}
|
|
1738
|
+
</div>
|
|
1739
|
+
)}
|
|
1740
|
+
</Dropzone>
|
|
1741
|
+
);
|
|
1542
1742
|
|
|
1543
|
-
const
|
|
1544
|
-
const btn = container.querySelector('button')
|
|
1743
|
+
const { container, rerender } = render(ui);
|
|
1545
1744
|
|
|
1546
|
-
|
|
1547
|
-
drainTimers()
|
|
1548
|
-
await flushPromises(rerender, ui)
|
|
1745
|
+
const dropzone = container.querySelector("div");
|
|
1549
1746
|
|
|
1550
|
-
|
|
1551
|
-
expect(ref).not.toBeNull()
|
|
1552
|
-
expect(dropzone).toContainElement(ref)
|
|
1747
|
+
fireEvent.click(dropzone);
|
|
1553
1748
|
|
|
1554
|
-
|
|
1749
|
+
drainTimers();
|
|
1750
|
+
await flushPromises(rerender, ui);
|
|
1555
1751
|
|
|
1556
|
-
|
|
1557
|
-
|
|
1558
|
-
|
|
1752
|
+
const ref = activeRef.current;
|
|
1753
|
+
expect(ref).not.toBeNull();
|
|
1754
|
+
expect(dropzone).toContainElement(ref);
|
|
1559
1755
|
|
|
1560
|
-
|
|
1561
|
-
|
|
1756
|
+
thenable.cancel(
|
|
1757
|
+
new DOMException("Cannot use this API cross-origin", "SecurityError")
|
|
1758
|
+
);
|
|
1562
1759
|
|
|
1563
|
-
|
|
1564
|
-
})
|
|
1565
|
-
})
|
|
1760
|
+
await flushPromises(rerender, ui);
|
|
1566
1761
|
|
|
1567
|
-
|
|
1568
|
-
|
|
1569
|
-
|
|
1570
|
-
|
|
1571
|
-
|
|
1762
|
+
dispatchEvt(document.body, "focus");
|
|
1763
|
+
drainTimers();
|
|
1764
|
+
await flushPromises(rerender, ui);
|
|
1765
|
+
|
|
1766
|
+
expect(onFileDialogCancelSpy).toHaveBeenCalled();
|
|
1767
|
+
expect(dropzone).not.toContainElement(ref);
|
|
1768
|
+
|
|
1769
|
+
jest.useRealTimers();
|
|
1770
|
+
});
|
|
1771
|
+
});
|
|
1772
|
+
|
|
1773
|
+
describe("onKeyDown", () => {
|
|
1774
|
+
it("triggers the click event on the input if the SPACE/ENTER keys are pressed", () => {
|
|
1775
|
+
const activeRef = createRef();
|
|
1776
|
+
const active = <span ref={activeRef}>I am active</span>;
|
|
1777
|
+
const onClickSpy = jest.spyOn(HTMLInputElement.prototype, "click");
|
|
1572
1778
|
const { container } = render(
|
|
1573
1779
|
<Dropzone>
|
|
1574
1780
|
{({ getRootProps, getInputProps, isFileDialogActive }) => (
|
|
@@ -1578,26 +1784,26 @@ describe('useDropzone() hook', () => {
|
|
|
1578
1784
|
</div>
|
|
1579
1785
|
)}
|
|
1580
1786
|
</Dropzone>
|
|
1581
|
-
)
|
|
1787
|
+
);
|
|
1582
1788
|
|
|
1583
|
-
const dropzone = container.querySelector(
|
|
1789
|
+
const dropzone = container.querySelector("div");
|
|
1584
1790
|
|
|
1585
1791
|
fireEvent.keyDown(dropzone, {
|
|
1586
|
-
keyCode: 32
|
|
1587
|
-
})
|
|
1792
|
+
keyCode: 32,
|
|
1793
|
+
});
|
|
1588
1794
|
|
|
1589
1795
|
fireEvent.keyDown(dropzone, {
|
|
1590
|
-
keyCode: 13
|
|
1591
|
-
})
|
|
1796
|
+
keyCode: 13,
|
|
1797
|
+
});
|
|
1592
1798
|
|
|
1593
|
-
const ref = activeRef.current
|
|
1594
|
-
expect(ref).not.toBeNull()
|
|
1595
|
-
expect(dropzone).toContainElement(ref)
|
|
1596
|
-
expect(onClickSpy).toHaveBeenCalledTimes(2)
|
|
1597
|
-
})
|
|
1799
|
+
const ref = activeRef.current;
|
|
1800
|
+
expect(ref).not.toBeNull();
|
|
1801
|
+
expect(dropzone).toContainElement(ref);
|
|
1802
|
+
expect(onClickSpy).toHaveBeenCalledTimes(2);
|
|
1803
|
+
});
|
|
1598
1804
|
|
|
1599
|
-
it(
|
|
1600
|
-
const onClickSpy = jest.spyOn(HTMLInputElement.prototype,
|
|
1805
|
+
it("does not trigger the click event on the input if the dropzone is not in focus", () => {
|
|
1806
|
+
const onClickSpy = jest.spyOn(HTMLInputElement.prototype, "click");
|
|
1601
1807
|
const { container } = render(
|
|
1602
1808
|
<Dropzone>
|
|
1603
1809
|
{({ getRootProps, getInputProps }) => (
|
|
@@ -1606,39 +1812,43 @@ describe('useDropzone() hook', () => {
|
|
|
1606
1812
|
</div>
|
|
1607
1813
|
)}
|
|
1608
1814
|
</Dropzone>
|
|
1609
|
-
)
|
|
1815
|
+
);
|
|
1610
1816
|
|
|
1611
|
-
const input = container.querySelector(
|
|
1817
|
+
const input = container.querySelector("input");
|
|
1612
1818
|
|
|
1613
1819
|
fireEvent.keyDown(input, {
|
|
1614
|
-
keyCode: 32
|
|
1615
|
-
})
|
|
1820
|
+
keyCode: 32,
|
|
1821
|
+
});
|
|
1616
1822
|
|
|
1617
|
-
expect(onClickSpy).not.toHaveBeenCalled()
|
|
1618
|
-
})
|
|
1823
|
+
expect(onClickSpy).not.toHaveBeenCalled();
|
|
1824
|
+
});
|
|
1619
1825
|
|
|
1620
|
-
it(
|
|
1621
|
-
const onClickSpy = jest.spyOn(HTMLInputElement.prototype,
|
|
1826
|
+
it("does not trigger the click event on the input if event propagation was stopped", () => {
|
|
1827
|
+
const onClickSpy = jest.spyOn(HTMLInputElement.prototype, "click");
|
|
1622
1828
|
const { container } = render(
|
|
1623
1829
|
<Dropzone>
|
|
1624
1830
|
{({ getRootProps, getInputProps }) => (
|
|
1625
|
-
<div
|
|
1831
|
+
<div
|
|
1832
|
+
{...getRootProps({
|
|
1833
|
+
onKeyDown: (event) => event.stopPropagation(),
|
|
1834
|
+
})}
|
|
1835
|
+
>
|
|
1626
1836
|
<input {...getInputProps()} />
|
|
1627
1837
|
</div>
|
|
1628
1838
|
)}
|
|
1629
1839
|
</Dropzone>
|
|
1630
|
-
)
|
|
1840
|
+
);
|
|
1631
1841
|
|
|
1632
|
-
const dropzone = container.querySelector(
|
|
1842
|
+
const dropzone = container.querySelector("div");
|
|
1633
1843
|
|
|
1634
1844
|
fireEvent.keyDown(dropzone, {
|
|
1635
|
-
keyCode: 32
|
|
1636
|
-
})
|
|
1637
|
-
expect(onClickSpy).not.toHaveBeenCalled()
|
|
1638
|
-
})
|
|
1845
|
+
keyCode: 32,
|
|
1846
|
+
});
|
|
1847
|
+
expect(onClickSpy).not.toHaveBeenCalled();
|
|
1848
|
+
});
|
|
1639
1849
|
|
|
1640
|
-
it(
|
|
1641
|
-
const onClickSpy = jest.spyOn(HTMLInputElement.prototype,
|
|
1850
|
+
it("does not trigger the click event on the input if {noKeyboard} is true", () => {
|
|
1851
|
+
const onClickSpy = jest.spyOn(HTMLInputElement.prototype, "click");
|
|
1642
1852
|
const { container } = render(
|
|
1643
1853
|
<Dropzone noKeyboard>
|
|
1644
1854
|
{({ getRootProps, getInputProps }) => (
|
|
@@ -1647,18 +1857,18 @@ describe('useDropzone() hook', () => {
|
|
|
1647
1857
|
</div>
|
|
1648
1858
|
)}
|
|
1649
1859
|
</Dropzone>
|
|
1650
|
-
)
|
|
1860
|
+
);
|
|
1651
1861
|
|
|
1652
|
-
const dropzone = container.querySelector(
|
|
1862
|
+
const dropzone = container.querySelector("div");
|
|
1653
1863
|
|
|
1654
1864
|
fireEvent.keyDown(dropzone, {
|
|
1655
|
-
keyCode: 32
|
|
1656
|
-
})
|
|
1657
|
-
expect(onClickSpy).not.toHaveBeenCalled()
|
|
1658
|
-
})
|
|
1865
|
+
keyCode: 32,
|
|
1866
|
+
});
|
|
1867
|
+
expect(onClickSpy).not.toHaveBeenCalled();
|
|
1868
|
+
});
|
|
1659
1869
|
|
|
1660
|
-
it(
|
|
1661
|
-
const onClickSpy = jest.spyOn(HTMLInputElement.prototype,
|
|
1870
|
+
it("restores the keydown behavior when {noKeyboard} is set back to false", () => {
|
|
1871
|
+
const onClickSpy = jest.spyOn(HTMLInputElement.prototype, "click");
|
|
1662
1872
|
const { container, rerender } = render(
|
|
1663
1873
|
<Dropzone noKeyboard>
|
|
1664
1874
|
{({ getRootProps, getInputProps }) => (
|
|
@@ -1667,14 +1877,14 @@ describe('useDropzone() hook', () => {
|
|
|
1667
1877
|
</div>
|
|
1668
1878
|
)}
|
|
1669
1879
|
</Dropzone>
|
|
1670
|
-
)
|
|
1880
|
+
);
|
|
1671
1881
|
|
|
1672
|
-
const dropzone = container.querySelector(
|
|
1882
|
+
const dropzone = container.querySelector("div");
|
|
1673
1883
|
|
|
1674
1884
|
fireEvent.keyDown(dropzone, {
|
|
1675
|
-
keyCode: 32
|
|
1676
|
-
})
|
|
1677
|
-
expect(onClickSpy).not.toHaveBeenCalled()
|
|
1885
|
+
keyCode: 32,
|
|
1886
|
+
});
|
|
1887
|
+
expect(onClickSpy).not.toHaveBeenCalled();
|
|
1678
1888
|
|
|
1679
1889
|
rerender(
|
|
1680
1890
|
<Dropzone noKeyboard={false}>
|
|
@@ -1684,16 +1894,16 @@ describe('useDropzone() hook', () => {
|
|
|
1684
1894
|
</div>
|
|
1685
1895
|
)}
|
|
1686
1896
|
</Dropzone>
|
|
1687
|
-
)
|
|
1897
|
+
);
|
|
1688
1898
|
|
|
1689
1899
|
fireEvent.keyDown(dropzone, {
|
|
1690
|
-
keyCode: 32
|
|
1691
|
-
})
|
|
1692
|
-
expect(onClickSpy).toHaveBeenCalled()
|
|
1693
|
-
})
|
|
1900
|
+
keyCode: 32,
|
|
1901
|
+
});
|
|
1902
|
+
expect(onClickSpy).toHaveBeenCalled();
|
|
1903
|
+
});
|
|
1694
1904
|
|
|
1695
|
-
it(
|
|
1696
|
-
const onClickSpy = jest.spyOn(HTMLInputElement.prototype,
|
|
1905
|
+
it("does not trigger the click event on the input for other keys", () => {
|
|
1906
|
+
const onClickSpy = jest.spyOn(HTMLInputElement.prototype, "click");
|
|
1697
1907
|
const { container } = render(
|
|
1698
1908
|
<Dropzone>
|
|
1699
1909
|
{({ getRootProps, getInputProps }) => (
|
|
@@ -1702,27 +1912,27 @@ describe('useDropzone() hook', () => {
|
|
|
1702
1912
|
</div>
|
|
1703
1913
|
)}
|
|
1704
1914
|
</Dropzone>
|
|
1705
|
-
)
|
|
1915
|
+
);
|
|
1706
1916
|
|
|
1707
|
-
const dropzone = container.querySelector(
|
|
1917
|
+
const dropzone = container.querySelector("div");
|
|
1708
1918
|
|
|
1709
1919
|
fireEvent.keyDown(dropzone, {
|
|
1710
|
-
keyCode: 97
|
|
1711
|
-
})
|
|
1712
|
-
expect(onClickSpy).not.toHaveBeenCalled()
|
|
1713
|
-
})
|
|
1714
|
-
})
|
|
1920
|
+
keyCode: 97,
|
|
1921
|
+
});
|
|
1922
|
+
expect(onClickSpy).not.toHaveBeenCalled();
|
|
1923
|
+
});
|
|
1924
|
+
});
|
|
1715
1925
|
|
|
1716
|
-
describe(
|
|
1717
|
-
it(
|
|
1718
|
-
const data = createDtWithFiles(files)
|
|
1926
|
+
describe("onDrag*", () => {
|
|
1927
|
+
it("invokes callbacks for the appropriate events", async () => {
|
|
1928
|
+
const data = createDtWithFiles(files);
|
|
1719
1929
|
|
|
1720
1930
|
const props = {
|
|
1721
1931
|
onDragEnter: jest.fn(),
|
|
1722
1932
|
onDragOver: jest.fn(),
|
|
1723
1933
|
onDragLeave: jest.fn(),
|
|
1724
|
-
onDrop: jest.fn()
|
|
1725
|
-
}
|
|
1934
|
+
onDrop: jest.fn(),
|
|
1935
|
+
};
|
|
1726
1936
|
|
|
1727
1937
|
const ui = (
|
|
1728
1938
|
<Dropzone {...props}>
|
|
@@ -1732,27 +1942,27 @@ describe('useDropzone() hook', () => {
|
|
|
1732
1942
|
</div>
|
|
1733
1943
|
)}
|
|
1734
1944
|
</Dropzone>
|
|
1735
|
-
)
|
|
1736
|
-
const { container, rerender } = render(ui)
|
|
1737
|
-
const dropzone = container.querySelector(
|
|
1945
|
+
);
|
|
1946
|
+
const { container, rerender } = render(ui);
|
|
1947
|
+
const dropzone = container.querySelector("div");
|
|
1738
1948
|
|
|
1739
|
-
fireDragEnter(dropzone, data)
|
|
1740
|
-
await flushPromises(rerender, ui)
|
|
1741
|
-
expect(props.onDragEnter).toHaveBeenCalled()
|
|
1949
|
+
fireDragEnter(dropzone, data);
|
|
1950
|
+
await flushPromises(rerender, ui);
|
|
1951
|
+
expect(props.onDragEnter).toHaveBeenCalled();
|
|
1742
1952
|
|
|
1743
|
-
fireDragOver(dropzone, data)
|
|
1744
|
-
expect(props.onDragOver).toHaveBeenCalled()
|
|
1953
|
+
fireDragOver(dropzone, data);
|
|
1954
|
+
expect(props.onDragOver).toHaveBeenCalled();
|
|
1745
1955
|
|
|
1746
|
-
fireDragLeave(dropzone, data)
|
|
1747
|
-
expect(props.onDragLeave).toHaveBeenCalled()
|
|
1956
|
+
fireDragLeave(dropzone, data);
|
|
1957
|
+
expect(props.onDragLeave).toHaveBeenCalled();
|
|
1748
1958
|
|
|
1749
|
-
fireDrop(dropzone, data)
|
|
1750
|
-
await flushPromises(rerender, ui)
|
|
1751
|
-
expect(props.onDrop).toHaveBeenCalled()
|
|
1752
|
-
})
|
|
1959
|
+
fireDrop(dropzone, data);
|
|
1960
|
+
await flushPromises(rerender, ui);
|
|
1961
|
+
expect(props.onDrop).toHaveBeenCalled();
|
|
1962
|
+
});
|
|
1753
1963
|
|
|
1754
|
-
it(
|
|
1755
|
-
const emptyData = createDtWithFiles([])
|
|
1964
|
+
it("invokes callbacks for the appropriate events even if it cannot access the data", async () => {
|
|
1965
|
+
const emptyData = createDtWithFiles([]);
|
|
1756
1966
|
|
|
1757
1967
|
const props = {
|
|
1758
1968
|
onDragEnter: jest.fn(),
|
|
@@ -1760,8 +1970,8 @@ describe('useDropzone() hook', () => {
|
|
|
1760
1970
|
onDragLeave: jest.fn(),
|
|
1761
1971
|
onDrop: jest.fn(),
|
|
1762
1972
|
onDropAccepted: jest.fn(),
|
|
1763
|
-
onDropRejected: jest.fn()
|
|
1764
|
-
}
|
|
1973
|
+
onDropRejected: jest.fn(),
|
|
1974
|
+
};
|
|
1765
1975
|
|
|
1766
1976
|
const ui = (
|
|
1767
1977
|
<Dropzone {...props}>
|
|
@@ -1771,35 +1981,38 @@ describe('useDropzone() hook', () => {
|
|
|
1771
1981
|
</div>
|
|
1772
1982
|
)}
|
|
1773
1983
|
</Dropzone>
|
|
1774
|
-
)
|
|
1775
|
-
const { container, rerender } = render(ui)
|
|
1776
|
-
const dropzone = container.querySelector(
|
|
1984
|
+
);
|
|
1985
|
+
const { container, rerender } = render(ui);
|
|
1986
|
+
const dropzone = container.querySelector("div");
|
|
1777
1987
|
|
|
1778
|
-
fireDragEnter(dropzone, emptyData)
|
|
1779
|
-
await flushPromises(rerender, ui)
|
|
1780
|
-
expect(props.onDragEnter).toHaveBeenCalled()
|
|
1988
|
+
fireDragEnter(dropzone, emptyData);
|
|
1989
|
+
await flushPromises(rerender, ui);
|
|
1990
|
+
expect(props.onDragEnter).toHaveBeenCalled();
|
|
1781
1991
|
|
|
1782
|
-
fireDragOver(dropzone, emptyData)
|
|
1783
|
-
expect(props.onDragOver).toHaveBeenCalled()
|
|
1992
|
+
fireDragOver(dropzone, emptyData);
|
|
1993
|
+
expect(props.onDragOver).toHaveBeenCalled();
|
|
1784
1994
|
|
|
1785
|
-
fireDragLeave(dropzone, emptyData)
|
|
1786
|
-
expect(props.onDragLeave).toHaveBeenCalled()
|
|
1995
|
+
fireDragLeave(dropzone, emptyData);
|
|
1996
|
+
expect(props.onDragLeave).toHaveBeenCalled();
|
|
1787
1997
|
|
|
1788
|
-
const data = createDtWithFiles(files)
|
|
1789
|
-
fireDrop(dropzone, data)
|
|
1790
|
-
await flushPromises(rerender, ui)
|
|
1791
|
-
expect(props.onDrop).toHaveBeenCalled()
|
|
1792
|
-
expect(props.onDropAccepted).toHaveBeenCalledWith(
|
|
1793
|
-
|
|
1794
|
-
|
|
1998
|
+
const data = createDtWithFiles(files);
|
|
1999
|
+
fireDrop(dropzone, data);
|
|
2000
|
+
await flushPromises(rerender, ui);
|
|
2001
|
+
expect(props.onDrop).toHaveBeenCalled();
|
|
2002
|
+
expect(props.onDropAccepted).toHaveBeenCalledWith(
|
|
2003
|
+
files,
|
|
2004
|
+
expect.any(Object)
|
|
2005
|
+
);
|
|
2006
|
+
expect(props.onDropRejected).not.toHaveBeenCalled();
|
|
2007
|
+
});
|
|
1795
2008
|
|
|
1796
|
-
it(
|
|
2009
|
+
it("does not invoke callbacks if no files are detected", async () => {
|
|
1797
2010
|
const data = {
|
|
1798
2011
|
dataTransfer: {
|
|
1799
2012
|
items: [],
|
|
1800
|
-
types: [
|
|
1801
|
-
}
|
|
1802
|
-
}
|
|
2013
|
+
types: ["text/html", "text/plain"],
|
|
2014
|
+
},
|
|
2015
|
+
};
|
|
1803
2016
|
|
|
1804
2017
|
const props = {
|
|
1805
2018
|
onDragEnter: jest.fn(),
|
|
@@ -1807,8 +2020,8 @@ describe('useDropzone() hook', () => {
|
|
|
1807
2020
|
onDragLeave: jest.fn(),
|
|
1808
2021
|
onDrop: jest.fn(),
|
|
1809
2022
|
onDropAccepted: jest.fn(),
|
|
1810
|
-
onDropRejected: jest.fn()
|
|
1811
|
-
}
|
|
2023
|
+
onDropRejected: jest.fn(),
|
|
2024
|
+
};
|
|
1812
2025
|
|
|
1813
2026
|
const ui = (
|
|
1814
2027
|
<Dropzone {...props}>
|
|
@@ -1818,29 +2031,29 @@ describe('useDropzone() hook', () => {
|
|
|
1818
2031
|
</div>
|
|
1819
2032
|
)}
|
|
1820
2033
|
</Dropzone>
|
|
1821
|
-
)
|
|
1822
|
-
const { container, rerender } = render(ui)
|
|
1823
|
-
const dropzone = container.querySelector(
|
|
2034
|
+
);
|
|
2035
|
+
const { container, rerender } = render(ui);
|
|
2036
|
+
const dropzone = container.querySelector("div");
|
|
1824
2037
|
|
|
1825
|
-
fireDragEnter(dropzone, data)
|
|
1826
|
-
await flushPromises(rerender, ui)
|
|
1827
|
-
expect(props.onDragEnter).not.toHaveBeenCalled()
|
|
2038
|
+
fireDragEnter(dropzone, data);
|
|
2039
|
+
await flushPromises(rerender, ui);
|
|
2040
|
+
expect(props.onDragEnter).not.toHaveBeenCalled();
|
|
1828
2041
|
|
|
1829
|
-
fireDragOver(dropzone, data)
|
|
1830
|
-
expect(props.onDragOver).not.toHaveBeenCalled()
|
|
2042
|
+
fireDragOver(dropzone, data);
|
|
2043
|
+
expect(props.onDragOver).not.toHaveBeenCalled();
|
|
1831
2044
|
|
|
1832
|
-
fireDragLeave(dropzone, data)
|
|
1833
|
-
expect(props.onDragLeave).not.toHaveBeenCalled()
|
|
2045
|
+
fireDragLeave(dropzone, data);
|
|
2046
|
+
expect(props.onDragLeave).not.toHaveBeenCalled();
|
|
1834
2047
|
|
|
1835
|
-
fireDrop(dropzone, data)
|
|
1836
|
-
await flushPromises(rerender, ui)
|
|
1837
|
-
expect(props.onDrop).not.toHaveBeenCalled()
|
|
1838
|
-
expect(props.onDropAccepted).not.toHaveBeenCalled()
|
|
1839
|
-
expect(props.onDropRejected).not.toHaveBeenCalled()
|
|
1840
|
-
})
|
|
2048
|
+
fireDrop(dropzone, data);
|
|
2049
|
+
await flushPromises(rerender, ui);
|
|
2050
|
+
expect(props.onDrop).not.toHaveBeenCalled();
|
|
2051
|
+
expect(props.onDropAccepted).not.toHaveBeenCalled();
|
|
2052
|
+
expect(props.onDropRejected).not.toHaveBeenCalled();
|
|
2053
|
+
});
|
|
1841
2054
|
|
|
1842
|
-
it(
|
|
1843
|
-
const data = createDtWithFiles(files)
|
|
2055
|
+
it("does not invoke callbacks if {noDrag} is true", async () => {
|
|
2056
|
+
const data = createDtWithFiles(files);
|
|
1844
2057
|
|
|
1845
2058
|
const props = {
|
|
1846
2059
|
onDragEnter: jest.fn(),
|
|
@@ -1848,8 +2061,8 @@ describe('useDropzone() hook', () => {
|
|
|
1848
2061
|
onDragLeave: jest.fn(),
|
|
1849
2062
|
onDrop: jest.fn(),
|
|
1850
2063
|
onDropAccepted: jest.fn(),
|
|
1851
|
-
onDropRejected: jest.fn()
|
|
1852
|
-
}
|
|
2064
|
+
onDropRejected: jest.fn(),
|
|
2065
|
+
};
|
|
1853
2066
|
|
|
1854
2067
|
const ui = (
|
|
1855
2068
|
<Dropzone {...props} noDrag>
|
|
@@ -1859,36 +2072,36 @@ describe('useDropzone() hook', () => {
|
|
|
1859
2072
|
</div>
|
|
1860
2073
|
)}
|
|
1861
2074
|
</Dropzone>
|
|
1862
|
-
)
|
|
1863
|
-
const { container, rerender } = render(ui)
|
|
1864
|
-
const dropzone = container.querySelector(
|
|
2075
|
+
);
|
|
2076
|
+
const { container, rerender } = render(ui);
|
|
2077
|
+
const dropzone = container.querySelector("div");
|
|
1865
2078
|
|
|
1866
|
-
fireDragEnter(dropzone, data)
|
|
1867
|
-
await flushPromises(rerender, ui)
|
|
1868
|
-
expect(props.onDragEnter).not.toHaveBeenCalled()
|
|
2079
|
+
fireDragEnter(dropzone, data);
|
|
2080
|
+
await flushPromises(rerender, ui);
|
|
2081
|
+
expect(props.onDragEnter).not.toHaveBeenCalled();
|
|
1869
2082
|
|
|
1870
|
-
fireDragOver(dropzone, data)
|
|
1871
|
-
expect(props.onDragOver).not.toHaveBeenCalled()
|
|
2083
|
+
fireDragOver(dropzone, data);
|
|
2084
|
+
expect(props.onDragOver).not.toHaveBeenCalled();
|
|
1872
2085
|
|
|
1873
|
-
fireDragLeave(dropzone, data)
|
|
1874
|
-
expect(props.onDragLeave).not.toHaveBeenCalled()
|
|
2086
|
+
fireDragLeave(dropzone, data);
|
|
2087
|
+
expect(props.onDragLeave).not.toHaveBeenCalled();
|
|
1875
2088
|
|
|
1876
|
-
fireDrop(dropzone, data)
|
|
1877
|
-
await flushPromises(rerender, ui)
|
|
1878
|
-
expect(props.onDrop).not.toHaveBeenCalled()
|
|
1879
|
-
expect(props.onDropAccepted).not.toHaveBeenCalled()
|
|
1880
|
-
expect(props.onDropRejected).not.toHaveBeenCalled()
|
|
1881
|
-
})
|
|
2089
|
+
fireDrop(dropzone, data);
|
|
2090
|
+
await flushPromises(rerender, ui);
|
|
2091
|
+
expect(props.onDrop).not.toHaveBeenCalled();
|
|
2092
|
+
expect(props.onDropAccepted).not.toHaveBeenCalled();
|
|
2093
|
+
expect(props.onDropRejected).not.toHaveBeenCalled();
|
|
2094
|
+
});
|
|
1882
2095
|
|
|
1883
|
-
it(
|
|
1884
|
-
const data = createDtWithFiles(files)
|
|
2096
|
+
it("restores drag behavior if {noDrag} is set back to false", async () => {
|
|
2097
|
+
const data = createDtWithFiles(files);
|
|
1885
2098
|
|
|
1886
2099
|
const props = {
|
|
1887
2100
|
onDragEnter: jest.fn(),
|
|
1888
2101
|
onDragOver: jest.fn(),
|
|
1889
2102
|
onDragLeave: jest.fn(),
|
|
1890
|
-
onDrop: jest.fn()
|
|
1891
|
-
}
|
|
2103
|
+
onDrop: jest.fn(),
|
|
2104
|
+
};
|
|
1892
2105
|
|
|
1893
2106
|
const noDragUi = (
|
|
1894
2107
|
<Dropzone {...props} noDrag>
|
|
@@ -1898,23 +2111,23 @@ describe('useDropzone() hook', () => {
|
|
|
1898
2111
|
</div>
|
|
1899
2112
|
)}
|
|
1900
2113
|
</Dropzone>
|
|
1901
|
-
)
|
|
1902
|
-
const { container, rerender } = render(noDragUi)
|
|
1903
|
-
const dropzone = container.querySelector(
|
|
2114
|
+
);
|
|
2115
|
+
const { container, rerender } = render(noDragUi);
|
|
2116
|
+
const dropzone = container.querySelector("div");
|
|
1904
2117
|
|
|
1905
|
-
fireDragEnter(dropzone, data)
|
|
1906
|
-
await flushPromises(rerender, noDragUi)
|
|
1907
|
-
expect(props.onDragEnter).not.toHaveBeenCalled()
|
|
2118
|
+
fireDragEnter(dropzone, data);
|
|
2119
|
+
await flushPromises(rerender, noDragUi);
|
|
2120
|
+
expect(props.onDragEnter).not.toHaveBeenCalled();
|
|
1908
2121
|
|
|
1909
|
-
fireDragOver(dropzone, data)
|
|
1910
|
-
expect(props.onDragOver).not.toHaveBeenCalled()
|
|
2122
|
+
fireDragOver(dropzone, data);
|
|
2123
|
+
expect(props.onDragOver).not.toHaveBeenCalled();
|
|
1911
2124
|
|
|
1912
|
-
fireDragLeave(dropzone, data)
|
|
1913
|
-
expect(props.onDragLeave).not.toHaveBeenCalled()
|
|
2125
|
+
fireDragLeave(dropzone, data);
|
|
2126
|
+
expect(props.onDragLeave).not.toHaveBeenCalled();
|
|
1914
2127
|
|
|
1915
|
-
fireDrop(dropzone, data)
|
|
1916
|
-
await flushPromises(rerender, noDragUi)
|
|
1917
|
-
expect(props.onDrop).not.toHaveBeenCalled()
|
|
2128
|
+
fireDrop(dropzone, data);
|
|
2129
|
+
await flushPromises(rerender, noDragUi);
|
|
2130
|
+
expect(props.onDrop).not.toHaveBeenCalled();
|
|
1918
2131
|
|
|
1919
2132
|
const ui = (
|
|
1920
2133
|
<Dropzone {...props} noDrag={false}>
|
|
@@ -1924,247 +2137,293 @@ describe('useDropzone() hook', () => {
|
|
|
1924
2137
|
</div>
|
|
1925
2138
|
)}
|
|
1926
2139
|
</Dropzone>
|
|
1927
|
-
)
|
|
1928
|
-
rerender(ui)
|
|
2140
|
+
);
|
|
2141
|
+
rerender(ui);
|
|
1929
2142
|
|
|
1930
|
-
fireDragEnter(dropzone, data)
|
|
1931
|
-
await flushPromises(rerender, ui)
|
|
1932
|
-
expect(props.onDragEnter).toHaveBeenCalled()
|
|
2143
|
+
fireDragEnter(dropzone, data);
|
|
2144
|
+
await flushPromises(rerender, ui);
|
|
2145
|
+
expect(props.onDragEnter).toHaveBeenCalled();
|
|
1933
2146
|
|
|
1934
|
-
fireDragOver(dropzone, data)
|
|
1935
|
-
expect(props.onDragOver).toHaveBeenCalled()
|
|
2147
|
+
fireDragOver(dropzone, data);
|
|
2148
|
+
expect(props.onDragOver).toHaveBeenCalled();
|
|
1936
2149
|
|
|
1937
|
-
fireDragLeave(dropzone, data)
|
|
1938
|
-
expect(props.onDragLeave).toHaveBeenCalled()
|
|
2150
|
+
fireDragLeave(dropzone, data);
|
|
2151
|
+
expect(props.onDragLeave).toHaveBeenCalled();
|
|
1939
2152
|
|
|
1940
|
-
fireDrop(dropzone, data)
|
|
1941
|
-
await flushPromises(rerender, ui)
|
|
1942
|
-
expect(props.onDrop).toHaveBeenCalled()
|
|
1943
|
-
})
|
|
2153
|
+
fireDrop(dropzone, data);
|
|
2154
|
+
await flushPromises(rerender, ui);
|
|
2155
|
+
expect(props.onDrop).toHaveBeenCalled();
|
|
2156
|
+
});
|
|
1944
2157
|
|
|
1945
|
-
it(
|
|
2158
|
+
it("sets {isDragActive} and {isDragAccept} if some files are accepted on dragenter", async () => {
|
|
1946
2159
|
const ui = (
|
|
1947
2160
|
<Dropzone>
|
|
1948
|
-
{({
|
|
2161
|
+
{({
|
|
2162
|
+
getRootProps,
|
|
2163
|
+
getInputProps,
|
|
2164
|
+
isDragActive,
|
|
2165
|
+
isDragAccept,
|
|
2166
|
+
isDragReject,
|
|
2167
|
+
}) => (
|
|
1949
2168
|
<div {...getRootProps()}>
|
|
1950
2169
|
<input {...getInputProps()} />
|
|
1951
|
-
{isDragActive &&
|
|
1952
|
-
{isDragAccept &&
|
|
1953
|
-
{isDragReject &&
|
|
2170
|
+
{isDragActive && "dragActive"}
|
|
2171
|
+
{isDragAccept && "dragAccept"}
|
|
2172
|
+
{isDragReject && "dragReject"}
|
|
1954
2173
|
</div>
|
|
1955
2174
|
)}
|
|
1956
2175
|
</Dropzone>
|
|
1957
|
-
)
|
|
1958
|
-
const { container, rerender } = render(ui)
|
|
1959
|
-
const dropzone = container.querySelector(
|
|
2176
|
+
);
|
|
2177
|
+
const { container, rerender } = render(ui);
|
|
2178
|
+
const dropzone = container.querySelector("div");
|
|
1960
2179
|
|
|
1961
|
-
const data = createDtWithFiles(files)
|
|
1962
|
-
fireDragEnter(dropzone, data)
|
|
1963
|
-
await flushPromises(rerender, ui)
|
|
2180
|
+
const data = createDtWithFiles(files);
|
|
2181
|
+
fireDragEnter(dropzone, data);
|
|
2182
|
+
await flushPromises(rerender, ui);
|
|
1964
2183
|
|
|
1965
|
-
expect(dropzone).toHaveTextContent(
|
|
1966
|
-
expect(dropzone).toHaveTextContent(
|
|
1967
|
-
expect(dropzone).not.toHaveTextContent(
|
|
1968
|
-
})
|
|
2184
|
+
expect(dropzone).toHaveTextContent("dragActive");
|
|
2185
|
+
expect(dropzone).toHaveTextContent("dragAccept");
|
|
2186
|
+
expect(dropzone).not.toHaveTextContent("dragReject");
|
|
2187
|
+
});
|
|
1969
2188
|
|
|
1970
|
-
it(
|
|
2189
|
+
it("sets {isDragActive} and {isDragReject} of some files are not accepted on dragenter", async () => {
|
|
1971
2190
|
const ui = (
|
|
1972
2191
|
<Dropzone accept="image/*">
|
|
1973
|
-
{({
|
|
2192
|
+
{({
|
|
2193
|
+
getRootProps,
|
|
2194
|
+
getInputProps,
|
|
2195
|
+
isDragActive,
|
|
2196
|
+
isDragAccept,
|
|
2197
|
+
isDragReject,
|
|
2198
|
+
}) => (
|
|
1974
2199
|
<div {...getRootProps()}>
|
|
1975
2200
|
<input {...getInputProps()} />
|
|
1976
|
-
{isDragActive &&
|
|
1977
|
-
{isDragAccept &&
|
|
1978
|
-
{isDragReject &&
|
|
2201
|
+
{isDragActive && "dragActive"}
|
|
2202
|
+
{isDragAccept && "dragAccept"}
|
|
2203
|
+
{isDragReject && "dragReject"}
|
|
1979
2204
|
</div>
|
|
1980
2205
|
)}
|
|
1981
2206
|
</Dropzone>
|
|
1982
|
-
)
|
|
1983
|
-
const { container, rerender } = render(ui)
|
|
1984
|
-
const dropzone = container.querySelector(
|
|
2207
|
+
);
|
|
2208
|
+
const { container, rerender } = render(ui);
|
|
2209
|
+
const dropzone = container.querySelector("div");
|
|
1985
2210
|
|
|
1986
|
-
const data = createDtWithFiles([...files, ...images])
|
|
1987
|
-
fireDragEnter(dropzone, data)
|
|
1988
|
-
await flushPromises(rerender, ui)
|
|
2211
|
+
const data = createDtWithFiles([...files, ...images]);
|
|
2212
|
+
fireDragEnter(dropzone, data);
|
|
2213
|
+
await flushPromises(rerender, ui);
|
|
1989
2214
|
|
|
1990
|
-
expect(dropzone).toHaveTextContent(
|
|
1991
|
-
expect(dropzone).not.toHaveTextContent(
|
|
1992
|
-
expect(dropzone).toHaveTextContent(
|
|
1993
|
-
})
|
|
2215
|
+
expect(dropzone).toHaveTextContent("dragActive");
|
|
2216
|
+
expect(dropzone).not.toHaveTextContent("dragAccept");
|
|
2217
|
+
expect(dropzone).toHaveTextContent("dragReject");
|
|
2218
|
+
});
|
|
1994
2219
|
|
|
1995
|
-
it(
|
|
2220
|
+
it("sets {isDragReject} if some files are too large", async () => {
|
|
1996
2221
|
const ui = (
|
|
1997
2222
|
<Dropzone maxSize={0}>
|
|
1998
2223
|
{({ getRootProps, getInputProps, isDragAccept, isDragReject }) => (
|
|
1999
2224
|
<div {...getRootProps()}>
|
|
2000
2225
|
<input {...getInputProps()} />
|
|
2001
|
-
{isDragAccept &&
|
|
2002
|
-
{isDragReject &&
|
|
2226
|
+
{isDragAccept && "dragAccept"}
|
|
2227
|
+
{isDragReject && "dragReject"}
|
|
2003
2228
|
</div>
|
|
2004
2229
|
)}
|
|
2005
2230
|
</Dropzone>
|
|
2006
|
-
)
|
|
2007
|
-
const { container, rerender } = render(ui)
|
|
2008
|
-
const dropzone = container.querySelector(
|
|
2231
|
+
);
|
|
2232
|
+
const { container, rerender } = render(ui);
|
|
2233
|
+
const dropzone = container.querySelector("div");
|
|
2009
2234
|
|
|
2010
|
-
const data = createDtWithFiles(files)
|
|
2011
|
-
fireDragEnter(dropzone, data)
|
|
2012
|
-
await flushPromises(rerender, ui)
|
|
2235
|
+
const data = createDtWithFiles(files);
|
|
2236
|
+
fireDragEnter(dropzone, data);
|
|
2237
|
+
await flushPromises(rerender, ui);
|
|
2013
2238
|
|
|
2014
|
-
expect(dropzone).not.toHaveTextContent(
|
|
2015
|
-
expect(dropzone).toHaveTextContent(
|
|
2016
|
-
})
|
|
2239
|
+
expect(dropzone).not.toHaveTextContent("dragAccept");
|
|
2240
|
+
expect(dropzone).toHaveTextContent("dragReject");
|
|
2241
|
+
});
|
|
2017
2242
|
|
|
2018
|
-
it(
|
|
2243
|
+
it("sets {isDragActive, isDragAccept, isDragReject} if any files are rejected and {multiple} is false on dragenter", async () => {
|
|
2019
2244
|
const ui = (
|
|
2020
2245
|
<Dropzone accept="image/*" multiple={false}>
|
|
2021
|
-
{({
|
|
2246
|
+
{({
|
|
2247
|
+
getRootProps,
|
|
2248
|
+
getInputProps,
|
|
2249
|
+
isDragActive,
|
|
2250
|
+
isDragAccept,
|
|
2251
|
+
isDragReject,
|
|
2252
|
+
}) => (
|
|
2022
2253
|
<div {...getRootProps()}>
|
|
2023
2254
|
<input {...getInputProps()} />
|
|
2024
|
-
{isDragActive &&
|
|
2025
|
-
{isDragAccept &&
|
|
2026
|
-
{isDragReject &&
|
|
2255
|
+
{isDragActive && "dragActive"}
|
|
2256
|
+
{isDragAccept && "dragAccept"}
|
|
2257
|
+
{isDragReject && "dragReject"}
|
|
2027
2258
|
</div>
|
|
2028
2259
|
)}
|
|
2029
2260
|
</Dropzone>
|
|
2030
|
-
)
|
|
2031
|
-
const { container, rerender } = render(ui)
|
|
2032
|
-
const dropzone = container.querySelector(
|
|
2261
|
+
);
|
|
2262
|
+
const { container, rerender } = render(ui);
|
|
2263
|
+
const dropzone = container.querySelector("div");
|
|
2033
2264
|
|
|
2034
|
-
const data = createDtWithFiles(images)
|
|
2035
|
-
fireDragEnter(dropzone, data)
|
|
2036
|
-
await flushPromises(rerender, ui)
|
|
2265
|
+
const data = createDtWithFiles(images);
|
|
2266
|
+
fireDragEnter(dropzone, data);
|
|
2267
|
+
await flushPromises(rerender, ui);
|
|
2037
2268
|
|
|
2038
|
-
expect(dropzone).toHaveTextContent(
|
|
2039
|
-
expect(dropzone).not.toHaveTextContent(
|
|
2040
|
-
expect(dropzone).toHaveTextContent(
|
|
2041
|
-
})
|
|
2269
|
+
expect(dropzone).toHaveTextContent("dragActive");
|
|
2270
|
+
expect(dropzone).not.toHaveTextContent("dragAccept");
|
|
2271
|
+
expect(dropzone).toHaveTextContent("dragReject");
|
|
2272
|
+
});
|
|
2042
2273
|
|
|
2043
|
-
it(
|
|
2044
|
-
const { container: overlayContainer } = render(<div />)
|
|
2274
|
+
it("keeps {isDragActive} if dragleave is triggered for some arbitrary node", async () => {
|
|
2275
|
+
const { container: overlayContainer } = render(<div />);
|
|
2045
2276
|
const ui = (
|
|
2046
2277
|
<Dropzone>
|
|
2047
|
-
{({
|
|
2278
|
+
{({
|
|
2279
|
+
getRootProps,
|
|
2280
|
+
getInputProps,
|
|
2281
|
+
isDragActive,
|
|
2282
|
+
isDragAccept,
|
|
2283
|
+
isDragReject,
|
|
2284
|
+
}) => (
|
|
2048
2285
|
<div {...getRootProps()}>
|
|
2049
2286
|
<input {...getInputProps()} />
|
|
2050
|
-
{isDragActive &&
|
|
2051
|
-
{isDragAccept &&
|
|
2052
|
-
{isDragReject &&
|
|
2287
|
+
{isDragActive && "dragActive"}
|
|
2288
|
+
{isDragAccept && "dragAccept"}
|
|
2289
|
+
{isDragReject && "dragReject"}
|
|
2053
2290
|
</div>
|
|
2054
2291
|
)}
|
|
2055
2292
|
</Dropzone>
|
|
2056
|
-
)
|
|
2057
|
-
const { container, rerender } = render(ui)
|
|
2058
|
-
const dropzone = container.querySelector(
|
|
2293
|
+
);
|
|
2294
|
+
const { container, rerender } = render(ui);
|
|
2295
|
+
const dropzone = container.querySelector("div");
|
|
2059
2296
|
|
|
2060
|
-
const data = createDtWithFiles(files)
|
|
2061
|
-
fireDragEnter(dropzone, data)
|
|
2062
|
-
await flushPromises(rerender, ui)
|
|
2297
|
+
const data = createDtWithFiles(files);
|
|
2298
|
+
fireDragEnter(dropzone, data);
|
|
2299
|
+
await flushPromises(rerender, ui);
|
|
2063
2300
|
|
|
2064
|
-
const event = new Event(
|
|
2065
|
-
Object.defineProperty(event,
|
|
2066
|
-
value: overlayContainer.querySelector(
|
|
2067
|
-
writable: false
|
|
2068
|
-
})
|
|
2069
|
-
fireEvent(dropzone, event)
|
|
2301
|
+
const event = new Event("dragleave", { bubbles: true });
|
|
2302
|
+
Object.defineProperty(event, "target", {
|
|
2303
|
+
value: overlayContainer.querySelector("div"),
|
|
2304
|
+
writable: false,
|
|
2305
|
+
});
|
|
2306
|
+
fireEvent(dropzone, event);
|
|
2070
2307
|
|
|
2071
|
-
expect(dropzone).toHaveTextContent(
|
|
2072
|
-
})
|
|
2308
|
+
expect(dropzone).toHaveTextContent("dragActive");
|
|
2309
|
+
});
|
|
2073
2310
|
|
|
2074
|
-
it(
|
|
2311
|
+
it("updates {isDragActive} if {accept} changes mid-drag", async () => {
|
|
2075
2312
|
const ui = (
|
|
2076
2313
|
<Dropzone accept="image/*">
|
|
2077
|
-
{({
|
|
2314
|
+
{({
|
|
2315
|
+
getRootProps,
|
|
2316
|
+
getInputProps,
|
|
2317
|
+
isDragActive,
|
|
2318
|
+
isDragAccept,
|
|
2319
|
+
isDragReject,
|
|
2320
|
+
}) => (
|
|
2078
2321
|
<div {...getRootProps()}>
|
|
2079
2322
|
<input {...getInputProps()} />
|
|
2080
|
-
{isDragActive &&
|
|
2081
|
-
{isDragAccept &&
|
|
2082
|
-
{isDragReject &&
|
|
2323
|
+
{isDragActive && "dragActive"}
|
|
2324
|
+
{isDragAccept && "dragAccept"}
|
|
2325
|
+
{isDragReject && "dragReject"}
|
|
2083
2326
|
</div>
|
|
2084
2327
|
)}
|
|
2085
2328
|
</Dropzone>
|
|
2086
|
-
)
|
|
2087
|
-
const { container, rerender } = render(ui)
|
|
2088
|
-
const dropzone = container.querySelector(
|
|
2329
|
+
);
|
|
2330
|
+
const { container, rerender } = render(ui);
|
|
2331
|
+
const dropzone = container.querySelector("div");
|
|
2089
2332
|
|
|
2090
|
-
const data = createDtWithFiles(images)
|
|
2091
|
-
fireDragEnter(dropzone, data)
|
|
2092
|
-
await flushPromises(rerender, ui)
|
|
2333
|
+
const data = createDtWithFiles(images);
|
|
2334
|
+
fireDragEnter(dropzone, data);
|
|
2335
|
+
await flushPromises(rerender, ui);
|
|
2093
2336
|
|
|
2094
|
-
expect(dropzone).toHaveTextContent(
|
|
2095
|
-
expect(dropzone).toHaveTextContent(
|
|
2096
|
-
expect(dropzone).not.toHaveTextContent(
|
|
2337
|
+
expect(dropzone).toHaveTextContent("dragActive");
|
|
2338
|
+
expect(dropzone).toHaveTextContent("dragAccept");
|
|
2339
|
+
expect(dropzone).not.toHaveTextContent("dragReject");
|
|
2097
2340
|
|
|
2098
2341
|
rerender(
|
|
2099
2342
|
<Dropzone accept="text/*">
|
|
2100
|
-
{({
|
|
2343
|
+
{({
|
|
2344
|
+
getRootProps,
|
|
2345
|
+
getInputProps,
|
|
2346
|
+
isDragActive,
|
|
2347
|
+
isDragAccept,
|
|
2348
|
+
isDragReject,
|
|
2349
|
+
}) => (
|
|
2101
2350
|
<div {...getRootProps()}>
|
|
2102
2351
|
<input {...getInputProps()} />
|
|
2103
|
-
{isDragActive &&
|
|
2104
|
-
{isDragAccept &&
|
|
2105
|
-
{isDragReject &&
|
|
2352
|
+
{isDragActive && "dragActive"}
|
|
2353
|
+
{isDragAccept && "dragAccept"}
|
|
2354
|
+
{isDragReject && "dragReject"}
|
|
2106
2355
|
</div>
|
|
2107
2356
|
)}
|
|
2108
2357
|
</Dropzone>
|
|
2109
|
-
)
|
|
2358
|
+
);
|
|
2110
2359
|
|
|
2111
|
-
expect(dropzone).toHaveTextContent(
|
|
2112
|
-
expect(dropzone).not.toHaveTextContent(
|
|
2113
|
-
expect(dropzone).toHaveTextContent(
|
|
2114
|
-
})
|
|
2360
|
+
expect(dropzone).toHaveTextContent("dragActive");
|
|
2361
|
+
expect(dropzone).not.toHaveTextContent("dragAccept");
|
|
2362
|
+
expect(dropzone).toHaveTextContent("dragReject");
|
|
2363
|
+
});
|
|
2115
2364
|
|
|
2116
|
-
it(
|
|
2365
|
+
it("resets {isDragActive, isDragAccept, isDragReject} on dragleave", async () => {
|
|
2117
2366
|
const ui = (
|
|
2118
2367
|
<Dropzone accept="image/*">
|
|
2119
|
-
{({
|
|
2120
|
-
|
|
2121
|
-
|
|
2122
|
-
|
|
2123
|
-
|
|
2124
|
-
|
|
2368
|
+
{({
|
|
2369
|
+
getRootProps,
|
|
2370
|
+
getInputProps,
|
|
2371
|
+
isDragActive,
|
|
2372
|
+
isDragAccept,
|
|
2373
|
+
isDragReject,
|
|
2374
|
+
}) => (
|
|
2375
|
+
<div {...getRootProps()}>
|
|
2376
|
+
<input {...getInputProps()} />
|
|
2377
|
+
{isDragActive && "dragActive"}
|
|
2378
|
+
{isDragAccept && "dragAccept"}
|
|
2379
|
+
{isDragReject && "dragReject"}
|
|
2125
2380
|
{!isDragActive && (
|
|
2126
|
-
<span
|
|
2381
|
+
<span
|
|
2382
|
+
id="child"
|
|
2383
|
+
data-accept={isDragAccept}
|
|
2384
|
+
data-reject={isDragReject}
|
|
2385
|
+
/>
|
|
2127
2386
|
)}
|
|
2128
2387
|
</div>
|
|
2129
2388
|
)}
|
|
2130
2389
|
</Dropzone>
|
|
2131
|
-
)
|
|
2132
|
-
const { container, rerender } = render(ui)
|
|
2133
|
-
const dropzone = container.querySelector(
|
|
2390
|
+
);
|
|
2391
|
+
const { container, rerender } = render(ui);
|
|
2392
|
+
const dropzone = container.querySelector("div");
|
|
2134
2393
|
|
|
2135
|
-
const data = createDtWithFiles(images)
|
|
2394
|
+
const data = createDtWithFiles(images);
|
|
2136
2395
|
|
|
2137
|
-
fireDragEnter(container.querySelector(
|
|
2138
|
-
fireDragEnter(dropzone, data)
|
|
2139
|
-
await flushPromises(rerender, ui)
|
|
2140
|
-
fireDragEnter(dropzone, data)
|
|
2141
|
-
await flushPromises(rerender, ui)
|
|
2396
|
+
fireDragEnter(container.querySelector("#child"), data);
|
|
2397
|
+
fireDragEnter(dropzone, data);
|
|
2398
|
+
await flushPromises(rerender, ui);
|
|
2399
|
+
fireDragEnter(dropzone, data);
|
|
2400
|
+
await flushPromises(rerender, ui);
|
|
2142
2401
|
|
|
2143
|
-
expect(dropzone).toHaveTextContent(
|
|
2144
|
-
expect(dropzone).toHaveTextContent(
|
|
2145
|
-
expect(dropzone).not.toHaveTextContent(
|
|
2402
|
+
expect(dropzone).toHaveTextContent("dragActive");
|
|
2403
|
+
expect(dropzone).toHaveTextContent("dragAccept");
|
|
2404
|
+
expect(dropzone).not.toHaveTextContent("dragReject");
|
|
2146
2405
|
|
|
2147
|
-
fireDragLeave(dropzone, data)
|
|
2148
|
-
await flushPromises(rerender, ui)
|
|
2149
|
-
expect(dropzone).toHaveTextContent(
|
|
2150
|
-
expect(dropzone).toHaveTextContent(
|
|
2151
|
-
expect(dropzone).not.toHaveTextContent(
|
|
2406
|
+
fireDragLeave(dropzone, data);
|
|
2407
|
+
await flushPromises(rerender, ui);
|
|
2408
|
+
expect(dropzone).toHaveTextContent("dragActive");
|
|
2409
|
+
expect(dropzone).toHaveTextContent("dragAccept");
|
|
2410
|
+
expect(dropzone).not.toHaveTextContent("dragReject");
|
|
2152
2411
|
|
|
2153
|
-
fireDragLeave(dropzone, data)
|
|
2154
|
-
await flushPromises(rerender, ui)
|
|
2155
|
-
expect(dropzone).not.toHaveTextContent(
|
|
2156
|
-
expect(dropzone).not.toHaveTextContent(
|
|
2157
|
-
expect(dropzone).not.toHaveTextContent(
|
|
2412
|
+
fireDragLeave(dropzone, data);
|
|
2413
|
+
await flushPromises(rerender, ui);
|
|
2414
|
+
expect(dropzone).not.toHaveTextContent("dragActive");
|
|
2415
|
+
expect(dropzone).not.toHaveTextContent("dragAccept");
|
|
2416
|
+
expect(dropzone).not.toHaveTextContent("dragReject");
|
|
2158
2417
|
|
|
2159
|
-
const child = container.querySelector(
|
|
2160
|
-
expect(child).toHaveAttribute(
|
|
2161
|
-
expect(child).toHaveAttribute(
|
|
2162
|
-
})
|
|
2163
|
-
})
|
|
2418
|
+
const child = container.querySelector("#child");
|
|
2419
|
+
expect(child).toHaveAttribute("data-accept", "false");
|
|
2420
|
+
expect(child).toHaveAttribute("data-reject", "false");
|
|
2421
|
+
});
|
|
2422
|
+
});
|
|
2164
2423
|
|
|
2165
|
-
describe(
|
|
2166
|
-
test(
|
|
2167
|
-
const onDropSpy = jest.fn()
|
|
2424
|
+
describe("onDrop", () => {
|
|
2425
|
+
test("callback is invoked when <input> change event occurs", async () => {
|
|
2426
|
+
const onDropSpy = jest.fn();
|
|
2168
2427
|
|
|
2169
2428
|
const ui = (
|
|
2170
2429
|
<Dropzone onDrop={onDropSpy}>
|
|
@@ -2174,28 +2433,28 @@ describe('useDropzone() hook', () => {
|
|
|
2174
2433
|
</div>
|
|
2175
2434
|
)}
|
|
2176
2435
|
</Dropzone>
|
|
2177
|
-
)
|
|
2178
|
-
const { container, rerender } = render(ui)
|
|
2179
|
-
const input = container.querySelector(
|
|
2436
|
+
);
|
|
2437
|
+
const { container, rerender } = render(ui);
|
|
2438
|
+
const input = container.querySelector("input");
|
|
2180
2439
|
|
|
2181
|
-
Object.defineProperty(input,
|
|
2440
|
+
Object.defineProperty(input, "files", { value: files });
|
|
2182
2441
|
|
|
2183
|
-
dispatchEvt(input,
|
|
2184
|
-
await flushPromises(rerender, ui)
|
|
2442
|
+
dispatchEvt(input, "change");
|
|
2443
|
+
await flushPromises(rerender, ui);
|
|
2185
2444
|
|
|
2186
|
-
expect(onDropSpy).toHaveBeenCalledWith(files, [], expect.anything())
|
|
2187
|
-
})
|
|
2445
|
+
expect(onDropSpy).toHaveBeenCalledWith(files, [], expect.anything());
|
|
2446
|
+
});
|
|
2188
2447
|
|
|
2189
|
-
it(
|
|
2448
|
+
it("sets {acceptedFiles, fileRejections}", async () => {
|
|
2190
2449
|
const FileList = ({ files = [] }) => (
|
|
2191
2450
|
<ul>
|
|
2192
|
-
{files.map(file => (
|
|
2193
|
-
<li key={file.name} data-type={
|
|
2451
|
+
{files.map((file) => (
|
|
2452
|
+
<li key={file.name} data-type={"accepted"}>
|
|
2194
2453
|
{file.name}
|
|
2195
2454
|
</li>
|
|
2196
2455
|
))}
|
|
2197
2456
|
</ul>
|
|
2198
|
-
)
|
|
2457
|
+
);
|
|
2199
2458
|
|
|
2200
2459
|
const RejectedFileList = ({ fileRejections = [] }) => (
|
|
2201
2460
|
<ul>
|
|
@@ -2203,7 +2462,7 @@ describe('useDropzone() hook', () => {
|
|
|
2203
2462
|
<li key={file.name}>
|
|
2204
2463
|
<span data-type={"rejected"}>{file.name}</span>
|
|
2205
2464
|
<ul>
|
|
2206
|
-
{errors.map(e => (
|
|
2465
|
+
{errors.map((e) => (
|
|
2207
2466
|
<li key={e.code} data-type={"error"}>
|
|
2208
2467
|
{e.code}
|
|
2209
2468
|
</li>
|
|
@@ -2212,15 +2471,20 @@ describe('useDropzone() hook', () => {
|
|
|
2212
2471
|
</li>
|
|
2213
2472
|
))}
|
|
2214
2473
|
</ul>
|
|
2215
|
-
)
|
|
2216
|
-
|
|
2217
|
-
const getAcceptedFiles = node =>
|
|
2218
|
-
|
|
2219
|
-
const
|
|
2474
|
+
);
|
|
2475
|
+
|
|
2476
|
+
const getAcceptedFiles = (node) =>
|
|
2477
|
+
node.querySelectorAll(`[data-type="accepted"]`);
|
|
2478
|
+
const getRejectedFiles = (node) =>
|
|
2479
|
+
node.querySelectorAll(`[data-type="rejected"]`);
|
|
2480
|
+
const getRejectedFilesErrors = (node) =>
|
|
2481
|
+
node.querySelectorAll(`[data-type="error"]`);
|
|
2220
2482
|
const matchToFiles = (fileList, files) =>
|
|
2221
|
-
Array.from(fileList).every(
|
|
2483
|
+
Array.from(fileList).every(
|
|
2484
|
+
(item) => !!files.find((file) => file.name === item.textContent)
|
|
2485
|
+
);
|
|
2222
2486
|
const matchToErrorCode = (errorList, code) =>
|
|
2223
|
-
Array.from(errorList).every(item => item.textContent === code)
|
|
2487
|
+
Array.from(errorList).every((item) => item.textContent === code);
|
|
2224
2488
|
|
|
2225
2489
|
const ui = (
|
|
2226
2490
|
<Dropzone accept="image/*">
|
|
@@ -2232,60 +2496,68 @@ describe('useDropzone() hook', () => {
|
|
|
2232
2496
|
</div>
|
|
2233
2497
|
)}
|
|
2234
2498
|
</Dropzone>
|
|
2235
|
-
)
|
|
2236
|
-
const { container, rerender } = render(ui)
|
|
2237
|
-
const dropzone = container.querySelector(
|
|
2499
|
+
);
|
|
2500
|
+
const { container, rerender } = render(ui);
|
|
2501
|
+
const dropzone = container.querySelector("div");
|
|
2238
2502
|
|
|
2239
|
-
fireDrop(dropzone, createDtWithFiles(images))
|
|
2240
|
-
await flushPromises(rerender, ui)
|
|
2241
|
-
const acceptedFileList = getAcceptedFiles(dropzone)
|
|
2242
|
-
expect(acceptedFileList).toHaveLength(images.length)
|
|
2243
|
-
expect(matchToFiles(acceptedFileList, images)).toBe(true)
|
|
2503
|
+
fireDrop(dropzone, createDtWithFiles(images));
|
|
2504
|
+
await flushPromises(rerender, ui);
|
|
2505
|
+
const acceptedFileList = getAcceptedFiles(dropzone);
|
|
2506
|
+
expect(acceptedFileList).toHaveLength(images.length);
|
|
2507
|
+
expect(matchToFiles(acceptedFileList, images)).toBe(true);
|
|
2244
2508
|
|
|
2245
|
-
fireDrop(dropzone, createDtWithFiles(files))
|
|
2246
|
-
await flushPromises(rerender, ui)
|
|
2247
|
-
const rejectedFileList = getRejectedFiles(dropzone)
|
|
2248
|
-
expect(rejectedFileList).toHaveLength(files.length)
|
|
2249
|
-
expect(matchToFiles(rejectedFileList, files)).toBe(true)
|
|
2250
|
-
const rejectedFileErrorList = getRejectedFilesErrors(dropzone)
|
|
2251
|
-
expect(rejectedFileErrorList).toHaveLength(files.length)
|
|
2252
|
-
expect(matchToErrorCode(rejectedFileErrorList,
|
|
2253
|
-
|
|
2509
|
+
fireDrop(dropzone, createDtWithFiles(files));
|
|
2510
|
+
await flushPromises(rerender, ui);
|
|
2511
|
+
const rejectedFileList = getRejectedFiles(dropzone);
|
|
2512
|
+
expect(rejectedFileList).toHaveLength(files.length);
|
|
2513
|
+
expect(matchToFiles(rejectedFileList, files)).toBe(true);
|
|
2514
|
+
const rejectedFileErrorList = getRejectedFilesErrors(dropzone);
|
|
2515
|
+
expect(rejectedFileErrorList).toHaveLength(files.length);
|
|
2516
|
+
expect(matchToErrorCode(rejectedFileErrorList, "file-invalid-type")).toBe(
|
|
2517
|
+
true
|
|
2518
|
+
);
|
|
2519
|
+
});
|
|
2254
2520
|
|
|
2255
|
-
it(
|
|
2521
|
+
it("resets {isDragActive, isDragAccept, isDragReject}", async () => {
|
|
2256
2522
|
const ui = (
|
|
2257
2523
|
<Dropzone>
|
|
2258
|
-
{({
|
|
2524
|
+
{({
|
|
2525
|
+
getRootProps,
|
|
2526
|
+
getInputProps,
|
|
2527
|
+
isDragActive,
|
|
2528
|
+
isDragAccept,
|
|
2529
|
+
isDragReject,
|
|
2530
|
+
}) => (
|
|
2259
2531
|
<div {...getRootProps()}>
|
|
2260
2532
|
<input {...getInputProps()} />
|
|
2261
|
-
{isDragActive &&
|
|
2262
|
-
{isDragAccept &&
|
|
2263
|
-
{isDragReject &&
|
|
2533
|
+
{isDragActive && "dragActive"}
|
|
2534
|
+
{isDragAccept && "dragAccept"}
|
|
2535
|
+
{isDragReject && "dragReject"}
|
|
2264
2536
|
</div>
|
|
2265
2537
|
)}
|
|
2266
2538
|
</Dropzone>
|
|
2267
|
-
)
|
|
2268
|
-
const { container, rerender } = render(ui)
|
|
2269
|
-
const dropzone = container.querySelector(
|
|
2539
|
+
);
|
|
2540
|
+
const { container, rerender } = render(ui);
|
|
2541
|
+
const dropzone = container.querySelector("div");
|
|
2270
2542
|
|
|
2271
|
-
const data = createDtWithFiles(files)
|
|
2543
|
+
const data = createDtWithFiles(files);
|
|
2272
2544
|
|
|
2273
|
-
fireDragEnter(dropzone, data)
|
|
2274
|
-
await flushPromises(rerender, ui)
|
|
2545
|
+
fireDragEnter(dropzone, data);
|
|
2546
|
+
await flushPromises(rerender, ui);
|
|
2275
2547
|
|
|
2276
|
-
expect(dropzone).toHaveTextContent(
|
|
2277
|
-
expect(dropzone).toHaveTextContent(
|
|
2278
|
-
expect(dropzone).not.toHaveTextContent(
|
|
2548
|
+
expect(dropzone).toHaveTextContent("dragActive");
|
|
2549
|
+
expect(dropzone).toHaveTextContent("dragAccept");
|
|
2550
|
+
expect(dropzone).not.toHaveTextContent("dragReject");
|
|
2279
2551
|
|
|
2280
|
-
fireDrop(dropzone, data)
|
|
2281
|
-
await flushPromises(rerender, ui)
|
|
2282
|
-
expect(dropzone).not.toHaveTextContent(
|
|
2283
|
-
expect(dropzone).not.toHaveTextContent(
|
|
2284
|
-
expect(dropzone).not.toHaveTextContent(
|
|
2285
|
-
})
|
|
2552
|
+
fireDrop(dropzone, data);
|
|
2553
|
+
await flushPromises(rerender, ui);
|
|
2554
|
+
expect(dropzone).not.toHaveTextContent("dragActive");
|
|
2555
|
+
expect(dropzone).not.toHaveTextContent("dragAccept");
|
|
2556
|
+
expect(dropzone).not.toHaveTextContent("dragReject");
|
|
2557
|
+
});
|
|
2286
2558
|
|
|
2287
|
-
it(
|
|
2288
|
-
const onDropSpy = jest.fn()
|
|
2559
|
+
it("rejects all files if {multiple} is false and {accept} criteria is not met", async () => {
|
|
2560
|
+
const onDropSpy = jest.fn();
|
|
2289
2561
|
const ui = (
|
|
2290
2562
|
<Dropzone accept="image/*" onDrop={onDropSpy} multiple={false}>
|
|
2291
2563
|
{({ getRootProps, getInputProps }) => (
|
|
@@ -2294,27 +2566,31 @@ describe('useDropzone() hook', () => {
|
|
|
2294
2566
|
</div>
|
|
2295
2567
|
)}
|
|
2296
2568
|
</Dropzone>
|
|
2297
|
-
)
|
|
2298
|
-
const { container, rerender } = render(ui)
|
|
2299
|
-
const dropzone = container.querySelector(
|
|
2569
|
+
);
|
|
2570
|
+
const { container, rerender } = render(ui);
|
|
2571
|
+
const dropzone = container.querySelector("div");
|
|
2300
2572
|
|
|
2301
|
-
fireDrop(dropzone, createDtWithFiles(files))
|
|
2302
|
-
await flushPromises(rerender, ui)
|
|
2303
|
-
expect(onDropSpy).toHaveBeenCalledWith(
|
|
2304
|
-
|
|
2305
|
-
|
|
2306
|
-
|
|
2307
|
-
|
|
2308
|
-
|
|
2309
|
-
|
|
2310
|
-
|
|
2311
|
-
|
|
2312
|
-
|
|
2313
|
-
|
|
2314
|
-
|
|
2573
|
+
fireDrop(dropzone, createDtWithFiles(files));
|
|
2574
|
+
await flushPromises(rerender, ui);
|
|
2575
|
+
expect(onDropSpy).toHaveBeenCalledWith(
|
|
2576
|
+
[],
|
|
2577
|
+
[
|
|
2578
|
+
{
|
|
2579
|
+
file: files[0],
|
|
2580
|
+
errors: [
|
|
2581
|
+
{
|
|
2582
|
+
code: "file-invalid-type",
|
|
2583
|
+
message: "File type must be image/*",
|
|
2584
|
+
},
|
|
2585
|
+
],
|
|
2586
|
+
},
|
|
2587
|
+
],
|
|
2588
|
+
expect.anything()
|
|
2589
|
+
);
|
|
2590
|
+
});
|
|
2315
2591
|
|
|
2316
|
-
it(
|
|
2317
|
-
const onDropSpy = jest.fn()
|
|
2592
|
+
it("rejects all files if {multiple} is false and {accept} criteria is met", async () => {
|
|
2593
|
+
const onDropSpy = jest.fn();
|
|
2318
2594
|
const ui = (
|
|
2319
2595
|
<Dropzone accept="image/*" onDrop={onDropSpy} multiple={false}>
|
|
2320
2596
|
{({ getRootProps, getInputProps }) => (
|
|
@@ -2323,132 +2599,162 @@ describe('useDropzone() hook', () => {
|
|
|
2323
2599
|
</div>
|
|
2324
2600
|
)}
|
|
2325
2601
|
</Dropzone>
|
|
2326
|
-
)
|
|
2327
|
-
const { container, rerender } = render(ui)
|
|
2328
|
-
const dropzone = container.querySelector(
|
|
2329
|
-
|
|
2330
|
-
fireDrop(dropzone, createDtWithFiles(images))
|
|
2331
|
-
await flushPromises(rerender, ui)
|
|
2332
|
-
expect(onDropSpy).toHaveBeenCalledWith(
|
|
2333
|
-
|
|
2334
|
-
|
|
2335
|
-
|
|
2336
|
-
|
|
2337
|
-
|
|
2338
|
-
|
|
2339
|
-
|
|
2340
|
-
|
|
2341
|
-
|
|
2342
|
-
|
|
2343
|
-
|
|
2344
|
-
|
|
2345
|
-
|
|
2346
|
-
|
|
2347
|
-
|
|
2348
|
-
|
|
2349
|
-
|
|
2350
|
-
|
|
2351
|
-
|
|
2352
|
-
|
|
2602
|
+
);
|
|
2603
|
+
const { container, rerender } = render(ui);
|
|
2604
|
+
const dropzone = container.querySelector("div");
|
|
2605
|
+
|
|
2606
|
+
fireDrop(dropzone, createDtWithFiles(images));
|
|
2607
|
+
await flushPromises(rerender, ui);
|
|
2608
|
+
expect(onDropSpy).toHaveBeenCalledWith(
|
|
2609
|
+
[],
|
|
2610
|
+
[
|
|
2611
|
+
{
|
|
2612
|
+
file: images[0],
|
|
2613
|
+
errors: [
|
|
2614
|
+
{
|
|
2615
|
+
code: "too-many-files",
|
|
2616
|
+
message: "Too many files",
|
|
2617
|
+
},
|
|
2618
|
+
],
|
|
2619
|
+
},
|
|
2620
|
+
{
|
|
2621
|
+
file: images[1],
|
|
2622
|
+
errors: [
|
|
2623
|
+
{
|
|
2624
|
+
code: "too-many-files",
|
|
2625
|
+
message: "Too many files",
|
|
2626
|
+
},
|
|
2627
|
+
],
|
|
2628
|
+
},
|
|
2629
|
+
],
|
|
2630
|
+
expect.anything()
|
|
2631
|
+
);
|
|
2632
|
+
});
|
|
2353
2633
|
|
|
2354
|
-
it(
|
|
2355
|
-
const onDropSpy = jest.fn()
|
|
2356
|
-
const onDropRejectedSpy = jest.fn()
|
|
2634
|
+
it("rejects all files if {multiple} is true and maxFiles is less than files and {accept} criteria is met", async () => {
|
|
2635
|
+
const onDropSpy = jest.fn();
|
|
2636
|
+
const onDropRejectedSpy = jest.fn();
|
|
2357
2637
|
const ui = (
|
|
2358
|
-
<Dropzone
|
|
2638
|
+
<Dropzone
|
|
2639
|
+
accept="image/*"
|
|
2640
|
+
onDrop={onDropSpy}
|
|
2641
|
+
onDropRejected={onDropRejectedSpy}
|
|
2642
|
+
multiple={true}
|
|
2643
|
+
maxFiles={1}
|
|
2644
|
+
>
|
|
2359
2645
|
{({ getRootProps, getInputProps, isDragReject, isDragAccept }) => (
|
|
2360
2646
|
<div {...getRootProps()}>
|
|
2361
2647
|
<input {...getInputProps()} />
|
|
2362
|
-
|
|
2363
|
-
|
|
2364
|
-
</div>
|
|
2365
|
-
)}
|
|
2366
|
-
</Dropzone>
|
|
2367
|
-
)
|
|
2368
|
-
const { container, rerender } = render(ui)
|
|
2369
|
-
const dropzone = container.querySelector(
|
|
2370
|
-
fireDrop(dropzone, createDtWithFiles(images))
|
|
2371
|
-
await flushPromises(rerender, ui)
|
|
2372
|
-
expect(onDropRejectedSpy).toHaveBeenCalled()
|
|
2373
|
-
fireDragEnter(dropzone, createDtWithFiles(images))
|
|
2374
|
-
await flushPromises(rerender, ui)
|
|
2375
|
-
expect(dropzone).toHaveTextContent(
|
|
2376
|
-
expect(dropzone).not.toHaveTextContent(
|
|
2377
|
-
expect(onDropSpy).toHaveBeenCalledWith(
|
|
2378
|
-
|
|
2379
|
-
|
|
2380
|
-
|
|
2381
|
-
|
|
2382
|
-
|
|
2383
|
-
|
|
2384
|
-
|
|
2385
|
-
|
|
2386
|
-
|
|
2387
|
-
|
|
2388
|
-
|
|
2389
|
-
|
|
2390
|
-
|
|
2391
|
-
|
|
2392
|
-
|
|
2393
|
-
|
|
2394
|
-
|
|
2395
|
-
|
|
2396
|
-
|
|
2397
|
-
|
|
2648
|
+
{isDragReject && "dragReject"}
|
|
2649
|
+
{isDragAccept && "dragAccept"}
|
|
2650
|
+
</div>
|
|
2651
|
+
)}
|
|
2652
|
+
</Dropzone>
|
|
2653
|
+
);
|
|
2654
|
+
const { container, rerender } = render(ui);
|
|
2655
|
+
const dropzone = container.querySelector("div");
|
|
2656
|
+
fireDrop(dropzone, createDtWithFiles(images));
|
|
2657
|
+
await flushPromises(rerender, ui);
|
|
2658
|
+
expect(onDropRejectedSpy).toHaveBeenCalled();
|
|
2659
|
+
fireDragEnter(dropzone, createDtWithFiles(images));
|
|
2660
|
+
await flushPromises(rerender, ui);
|
|
2661
|
+
expect(dropzone).toHaveTextContent("dragReject");
|
|
2662
|
+
expect(dropzone).not.toHaveTextContent("dragAccept");
|
|
2663
|
+
expect(onDropSpy).toHaveBeenCalledWith(
|
|
2664
|
+
[],
|
|
2665
|
+
[
|
|
2666
|
+
{
|
|
2667
|
+
file: images[0],
|
|
2668
|
+
errors: [
|
|
2669
|
+
{
|
|
2670
|
+
code: "too-many-files",
|
|
2671
|
+
message: "Too many files",
|
|
2672
|
+
},
|
|
2673
|
+
],
|
|
2674
|
+
},
|
|
2675
|
+
{
|
|
2676
|
+
file: images[1],
|
|
2677
|
+
errors: [
|
|
2678
|
+
{
|
|
2679
|
+
code: "too-many-files",
|
|
2680
|
+
message: "Too many files",
|
|
2681
|
+
},
|
|
2682
|
+
],
|
|
2683
|
+
},
|
|
2684
|
+
],
|
|
2685
|
+
expect.anything()
|
|
2686
|
+
);
|
|
2687
|
+
});
|
|
2398
2688
|
|
|
2399
|
-
it(
|
|
2400
|
-
const onDropSpy = jest.fn()
|
|
2401
|
-
const onDropRejectedSpy = jest.fn()
|
|
2689
|
+
it("rejects all files if {multiple} is true and maxFiles has been updated so that it is less than files", async () => {
|
|
2690
|
+
const onDropSpy = jest.fn();
|
|
2691
|
+
const onDropRejectedSpy = jest.fn();
|
|
2402
2692
|
const ui = (maxFiles) => (
|
|
2403
|
-
<Dropzone
|
|
2693
|
+
<Dropzone
|
|
2694
|
+
accept="image/*"
|
|
2695
|
+
onDrop={onDropSpy}
|
|
2696
|
+
multiple={true}
|
|
2697
|
+
maxFiles={maxFiles}
|
|
2698
|
+
onDropRejected={onDropRejectedSpy}
|
|
2699
|
+
>
|
|
2404
2700
|
{({ getRootProps, getInputProps }) => (
|
|
2405
2701
|
<div {...getRootProps()}>
|
|
2406
2702
|
<input {...getInputProps()} />
|
|
2407
2703
|
</div>
|
|
2408
2704
|
)}
|
|
2409
2705
|
</Dropzone>
|
|
2410
|
-
)
|
|
2411
|
-
const { container, rerender } = render(ui(3))
|
|
2412
|
-
const dropzone = container.querySelector(
|
|
2706
|
+
);
|
|
2707
|
+
const { container, rerender } = render(ui(3));
|
|
2708
|
+
const dropzone = container.querySelector("div");
|
|
2413
2709
|
|
|
2414
|
-
fireDrop(dropzone, createDtWithFiles(images))
|
|
2415
|
-
await flushPromises(rerender, ui(3))
|
|
2416
|
-
expect(onDropRejectedSpy).not.toHaveBeenCalled()
|
|
2417
|
-
expect(onDropSpy).toHaveBeenCalledWith(images, [], expect.anything())
|
|
2710
|
+
fireDrop(dropzone, createDtWithFiles(images));
|
|
2711
|
+
await flushPromises(rerender, ui(3));
|
|
2712
|
+
expect(onDropRejectedSpy).not.toHaveBeenCalled();
|
|
2713
|
+
expect(onDropSpy).toHaveBeenCalledWith(images, [], expect.anything());
|
|
2418
2714
|
|
|
2419
2715
|
rerender(ui(1));
|
|
2420
2716
|
|
|
2421
|
-
fireDrop(dropzone, createDtWithFiles(images))
|
|
2422
|
-
await flushPromises(rerender, ui(1))
|
|
2717
|
+
fireDrop(dropzone, createDtWithFiles(images));
|
|
2718
|
+
await flushPromises(rerender, ui(1));
|
|
2423
2719
|
expect(onDropRejectedSpy).toHaveBeenCalledWith(
|
|
2424
|
-
expect.arrayContaining(
|
|
2720
|
+
expect.arrayContaining(
|
|
2721
|
+
images.map((image) =>
|
|
2722
|
+
expect.objectContaining({ errors: expect.any(Array), file: image })
|
|
2723
|
+
)
|
|
2724
|
+
),
|
|
2425
2725
|
expect.anything()
|
|
2426
|
-
)
|
|
2427
|
-
})
|
|
2726
|
+
);
|
|
2727
|
+
});
|
|
2428
2728
|
|
|
2429
|
-
it(
|
|
2430
|
-
const onDropSpy = jest.fn()
|
|
2431
|
-
const onDropRejectedSpy = jest.fn()
|
|
2729
|
+
it("accepts multiple files if {multiple} is true and {accept} criteria is met", async () => {
|
|
2730
|
+
const onDropSpy = jest.fn();
|
|
2731
|
+
const onDropRejectedSpy = jest.fn();
|
|
2432
2732
|
const ui = (
|
|
2433
|
-
<Dropzone
|
|
2733
|
+
<Dropzone
|
|
2734
|
+
accept="image/*"
|
|
2735
|
+
onDrop={onDropSpy}
|
|
2736
|
+
multiple={true}
|
|
2737
|
+
maxFiles={3}
|
|
2738
|
+
onDropRejected={onDropRejectedSpy}
|
|
2739
|
+
>
|
|
2434
2740
|
{({ getRootProps, getInputProps }) => (
|
|
2435
2741
|
<div {...getRootProps()}>
|
|
2436
2742
|
<input {...getInputProps()} />
|
|
2437
2743
|
</div>
|
|
2438
2744
|
)}
|
|
2439
2745
|
</Dropzone>
|
|
2440
|
-
)
|
|
2441
|
-
const { container, rerender } = render(ui)
|
|
2442
|
-
const dropzone = container.querySelector(
|
|
2746
|
+
);
|
|
2747
|
+
const { container, rerender } = render(ui);
|
|
2748
|
+
const dropzone = container.querySelector("div");
|
|
2443
2749
|
|
|
2444
|
-
fireDrop(dropzone, createDtWithFiles(images))
|
|
2445
|
-
await flushPromises(rerender, ui)
|
|
2446
|
-
expect(onDropRejectedSpy).not.toHaveBeenCalled()
|
|
2447
|
-
expect(onDropSpy).toHaveBeenCalledWith(images, [], expect.anything())
|
|
2448
|
-
})
|
|
2750
|
+
fireDrop(dropzone, createDtWithFiles(images));
|
|
2751
|
+
await flushPromises(rerender, ui);
|
|
2752
|
+
expect(onDropRejectedSpy).not.toHaveBeenCalled();
|
|
2753
|
+
expect(onDropSpy).toHaveBeenCalledWith(images, [], expect.anything());
|
|
2754
|
+
});
|
|
2449
2755
|
|
|
2450
|
-
it(
|
|
2451
|
-
const onDropSpy = jest.fn()
|
|
2756
|
+
it("accepts a single files if {multiple} is false and {accept} criteria is met", async () => {
|
|
2757
|
+
const onDropSpy = jest.fn();
|
|
2452
2758
|
const ui = (
|
|
2453
2759
|
<Dropzone accept="image/*" onDrop={onDropSpy} multiple={false}>
|
|
2454
2760
|
{({ getRootProps, getInputProps }) => (
|
|
@@ -2457,18 +2763,18 @@ describe('useDropzone() hook', () => {
|
|
|
2457
2763
|
</div>
|
|
2458
2764
|
)}
|
|
2459
2765
|
</Dropzone>
|
|
2460
|
-
)
|
|
2461
|
-
const { container, rerender } = render(ui)
|
|
2462
|
-
const dropzone = container.querySelector(
|
|
2766
|
+
);
|
|
2767
|
+
const { container, rerender } = render(ui);
|
|
2768
|
+
const dropzone = container.querySelector("div");
|
|
2463
2769
|
|
|
2464
|
-
const [image] = images
|
|
2465
|
-
fireDrop(dropzone, createDtWithFiles([image]))
|
|
2466
|
-
await flushPromises(rerender, ui)
|
|
2467
|
-
expect(onDropSpy).toHaveBeenCalledWith([image], [], expect.anything())
|
|
2468
|
-
})
|
|
2770
|
+
const [image] = images;
|
|
2771
|
+
fireDrop(dropzone, createDtWithFiles([image]));
|
|
2772
|
+
await flushPromises(rerender, ui);
|
|
2773
|
+
expect(onDropSpy).toHaveBeenCalledWith([image], [], expect.anything());
|
|
2774
|
+
});
|
|
2469
2775
|
|
|
2470
|
-
it(
|
|
2471
|
-
const onDropSpy = jest.fn()
|
|
2776
|
+
it("accepts all files if {multiple} is true", async () => {
|
|
2777
|
+
const onDropSpy = jest.fn();
|
|
2472
2778
|
const ui = (
|
|
2473
2779
|
<Dropzone onDrop={onDropSpy}>
|
|
2474
2780
|
{({ getRootProps, getInputProps }) => (
|
|
@@ -2477,19 +2783,19 @@ describe('useDropzone() hook', () => {
|
|
|
2477
2783
|
</div>
|
|
2478
2784
|
)}
|
|
2479
2785
|
</Dropzone>
|
|
2480
|
-
)
|
|
2481
|
-
const { container, rerender } = render(ui)
|
|
2482
|
-
const dropzone = container.querySelector(
|
|
2786
|
+
);
|
|
2787
|
+
const { container, rerender } = render(ui);
|
|
2788
|
+
const dropzone = container.querySelector("div");
|
|
2483
2789
|
|
|
2484
|
-
fireDrop(dropzone, createDtWithFiles(files))
|
|
2485
|
-
await flushPromises(rerender, ui)
|
|
2486
|
-
expect(onDropSpy).toHaveBeenCalledWith(files, [], expect.anything())
|
|
2487
|
-
})
|
|
2790
|
+
fireDrop(dropzone, createDtWithFiles(files));
|
|
2791
|
+
await flushPromises(rerender, ui);
|
|
2792
|
+
expect(onDropSpy).toHaveBeenCalledWith(files, [], expect.anything());
|
|
2793
|
+
});
|
|
2488
2794
|
|
|
2489
|
-
it(
|
|
2490
|
-
const onDropSpy = jest.fn()
|
|
2491
|
-
const activeRef = createRef()
|
|
2492
|
-
const active = <span ref={activeRef}>I am active</span
|
|
2795
|
+
it("resets {isFileDialogActive} state", async () => {
|
|
2796
|
+
const onDropSpy = jest.fn();
|
|
2797
|
+
const activeRef = createRef();
|
|
2798
|
+
const active = <span ref={activeRef}>I am active</span>;
|
|
2493
2799
|
|
|
2494
2800
|
const ui = (
|
|
2495
2801
|
<Dropzone onDrop={onDropSpy}>
|
|
@@ -2503,24 +2809,24 @@ describe('useDropzone() hook', () => {
|
|
|
2503
2809
|
</div>
|
|
2504
2810
|
)}
|
|
2505
2811
|
</Dropzone>
|
|
2506
|
-
)
|
|
2507
|
-
const { container, rerender } = render(ui)
|
|
2508
|
-
const dropzone = container.querySelector(
|
|
2509
|
-
const btn = container.querySelector(
|
|
2812
|
+
);
|
|
2813
|
+
const { container, rerender } = render(ui);
|
|
2814
|
+
const dropzone = container.querySelector("div");
|
|
2815
|
+
const btn = container.querySelector("button");
|
|
2510
2816
|
|
|
2511
|
-
btn.click()
|
|
2817
|
+
btn.click();
|
|
2512
2818
|
|
|
2513
|
-
const ref = activeRef.current
|
|
2514
|
-
expect(dropzone).toContainElement(ref)
|
|
2819
|
+
const ref = activeRef.current;
|
|
2820
|
+
expect(dropzone).toContainElement(ref);
|
|
2515
2821
|
|
|
2516
|
-
fireDrop(dropzone, createDtWithFiles(files))
|
|
2517
|
-
await flushPromises(rerender, ui)
|
|
2822
|
+
fireDrop(dropzone, createDtWithFiles(files));
|
|
2823
|
+
await flushPromises(rerender, ui);
|
|
2518
2824
|
|
|
2519
|
-
expect(dropzone).not.toContainElement(ref)
|
|
2520
|
-
})
|
|
2825
|
+
expect(dropzone).not.toContainElement(ref);
|
|
2826
|
+
});
|
|
2521
2827
|
|
|
2522
|
-
it(
|
|
2523
|
-
const onDropSpy = jest.fn()
|
|
2828
|
+
it("gets invoked with both accepted/rejected files", async () => {
|
|
2829
|
+
const onDropSpy = jest.fn();
|
|
2524
2830
|
const ui = (
|
|
2525
2831
|
<Dropzone accept="image/*" onDrop={onDropSpy}>
|
|
2526
2832
|
{({ getRootProps, getInputProps }) => (
|
|
@@ -2529,47 +2835,55 @@ describe('useDropzone() hook', () => {
|
|
|
2529
2835
|
</div>
|
|
2530
2836
|
)}
|
|
2531
2837
|
</Dropzone>
|
|
2532
|
-
)
|
|
2533
|
-
const { container, rerender } = render(ui)
|
|
2534
|
-
const dropzone = container.querySelector(
|
|
2838
|
+
);
|
|
2839
|
+
const { container, rerender } = render(ui);
|
|
2840
|
+
const dropzone = container.querySelector("div");
|
|
2535
2841
|
|
|
2536
|
-
fireDrop(dropzone, createDtWithFiles(files))
|
|
2537
|
-
await flushPromises(rerender, ui)
|
|
2538
|
-
expect(onDropSpy).toHaveBeenCalledWith(
|
|
2539
|
-
|
|
2540
|
-
|
|
2541
|
-
|
|
2542
|
-
|
|
2543
|
-
|
|
2544
|
-
|
|
2545
|
-
|
|
2546
|
-
|
|
2547
|
-
|
|
2548
|
-
|
|
2549
|
-
|
|
2550
|
-
|
|
2551
|
-
|
|
2552
|
-
|
|
2553
|
-
|
|
2554
|
-
|
|
2555
|
-
|
|
2556
|
-
|
|
2557
|
-
|
|
2558
|
-
|
|
2559
|
-
|
|
2560
|
-
|
|
2561
|
-
|
|
2562
|
-
|
|
2563
|
-
|
|
2564
|
-
|
|
2565
|
-
|
|
2566
|
-
|
|
2567
|
-
|
|
2568
|
-
|
|
2569
|
-
|
|
2842
|
+
fireDrop(dropzone, createDtWithFiles(files));
|
|
2843
|
+
await flushPromises(rerender, ui);
|
|
2844
|
+
expect(onDropSpy).toHaveBeenCalledWith(
|
|
2845
|
+
[],
|
|
2846
|
+
[
|
|
2847
|
+
{
|
|
2848
|
+
file: files[0],
|
|
2849
|
+
errors: [
|
|
2850
|
+
{
|
|
2851
|
+
code: "file-invalid-type",
|
|
2852
|
+
message: "File type must be image/*",
|
|
2853
|
+
},
|
|
2854
|
+
],
|
|
2855
|
+
},
|
|
2856
|
+
],
|
|
2857
|
+
expect.anything()
|
|
2858
|
+
);
|
|
2859
|
+
onDropSpy.mockClear();
|
|
2860
|
+
|
|
2861
|
+
fireDrop(dropzone, createDtWithFiles(images));
|
|
2862
|
+
await flushPromises(rerender, ui);
|
|
2863
|
+
expect(onDropSpy).toHaveBeenCalledWith(images, [], expect.anything());
|
|
2864
|
+
onDropSpy.mockClear();
|
|
2865
|
+
|
|
2866
|
+
fireDrop(dropzone, createDtWithFiles([...files, ...images]));
|
|
2867
|
+
await flushPromises(rerender, ui);
|
|
2868
|
+
expect(onDropSpy).toHaveBeenCalledWith(
|
|
2869
|
+
images,
|
|
2870
|
+
[
|
|
2871
|
+
{
|
|
2872
|
+
file: files[0],
|
|
2873
|
+
errors: [
|
|
2874
|
+
{
|
|
2875
|
+
code: "file-invalid-type",
|
|
2876
|
+
message: "File type must be image/*",
|
|
2877
|
+
},
|
|
2878
|
+
],
|
|
2879
|
+
},
|
|
2880
|
+
],
|
|
2881
|
+
expect.anything()
|
|
2882
|
+
);
|
|
2883
|
+
});
|
|
2570
2884
|
|
|
2571
|
-
test(
|
|
2572
|
-
const onDropAcceptedSpy = jest.fn()
|
|
2885
|
+
test("onDropAccepted callback is invoked if some files are accepted", async () => {
|
|
2886
|
+
const onDropAcceptedSpy = jest.fn();
|
|
2573
2887
|
const ui = (
|
|
2574
2888
|
<Dropzone accept="image/*" onDropAccepted={onDropAcceptedSpy}>
|
|
2575
2889
|
{({ getRootProps, getInputProps }) => (
|
|
@@ -2578,27 +2892,27 @@ describe('useDropzone() hook', () => {
|
|
|
2578
2892
|
</div>
|
|
2579
2893
|
)}
|
|
2580
2894
|
</Dropzone>
|
|
2581
|
-
)
|
|
2582
|
-
const { container, rerender } = render(ui)
|
|
2583
|
-
const dropzone = container.querySelector(
|
|
2895
|
+
);
|
|
2896
|
+
const { container, rerender } = render(ui);
|
|
2897
|
+
const dropzone = container.querySelector("div");
|
|
2584
2898
|
|
|
2585
|
-
fireDrop(dropzone, createDtWithFiles(files))
|
|
2586
|
-
await flushPromises(rerender, ui)
|
|
2587
|
-
expect(onDropAcceptedSpy).not.toHaveBeenCalled()
|
|
2588
|
-
onDropAcceptedSpy.mockClear()
|
|
2899
|
+
fireDrop(dropzone, createDtWithFiles(files));
|
|
2900
|
+
await flushPromises(rerender, ui);
|
|
2901
|
+
expect(onDropAcceptedSpy).not.toHaveBeenCalled();
|
|
2902
|
+
onDropAcceptedSpy.mockClear();
|
|
2589
2903
|
|
|
2590
|
-
fireDrop(dropzone, createDtWithFiles(images))
|
|
2591
|
-
await flushPromises(rerender, ui)
|
|
2592
|
-
expect(onDropAcceptedSpy).toHaveBeenCalledWith(images, expect.anything())
|
|
2593
|
-
onDropAcceptedSpy.mockClear()
|
|
2904
|
+
fireDrop(dropzone, createDtWithFiles(images));
|
|
2905
|
+
await flushPromises(rerender, ui);
|
|
2906
|
+
expect(onDropAcceptedSpy).toHaveBeenCalledWith(images, expect.anything());
|
|
2907
|
+
onDropAcceptedSpy.mockClear();
|
|
2594
2908
|
|
|
2595
|
-
fireDrop(dropzone, createDtWithFiles([...files, ...images]))
|
|
2596
|
-
await flushPromises(rerender, ui)
|
|
2597
|
-
expect(onDropAcceptedSpy).toHaveBeenCalledWith(images, expect.anything())
|
|
2598
|
-
})
|
|
2909
|
+
fireDrop(dropzone, createDtWithFiles([...files, ...images]));
|
|
2910
|
+
await flushPromises(rerender, ui);
|
|
2911
|
+
expect(onDropAcceptedSpy).toHaveBeenCalledWith(images, expect.anything());
|
|
2912
|
+
});
|
|
2599
2913
|
|
|
2600
|
-
test(
|
|
2601
|
-
const onDropRejectedSpy = jest.fn()
|
|
2914
|
+
test("onDropRejected callback is invoked if some files are rejected", async () => {
|
|
2915
|
+
const onDropRejectedSpy = jest.fn();
|
|
2602
2916
|
const ui = (
|
|
2603
2917
|
<Dropzone accept="image/*" onDropRejected={onDropRejectedSpy}>
|
|
2604
2918
|
{({ getRootProps, getInputProps }) => (
|
|
@@ -2607,47 +2921,53 @@ describe('useDropzone() hook', () => {
|
|
|
2607
2921
|
</div>
|
|
2608
2922
|
)}
|
|
2609
2923
|
</Dropzone>
|
|
2610
|
-
)
|
|
2611
|
-
const { container, rerender } = render(ui)
|
|
2612
|
-
const dropzone = container.querySelector(
|
|
2924
|
+
);
|
|
2925
|
+
const { container, rerender } = render(ui);
|
|
2926
|
+
const dropzone = container.querySelector("div");
|
|
2613
2927
|
|
|
2614
|
-
fireDrop(dropzone, createDtWithFiles(files))
|
|
2615
|
-
await flushPromises(rerender, ui)
|
|
2616
|
-
expect(onDropRejectedSpy).toHaveBeenCalledWith(
|
|
2617
|
-
|
|
2618
|
-
|
|
2619
|
-
|
|
2620
|
-
|
|
2621
|
-
|
|
2622
|
-
|
|
2623
|
-
|
|
2624
|
-
|
|
2625
|
-
|
|
2626
|
-
|
|
2627
|
-
|
|
2628
|
-
|
|
2629
|
-
|
|
2630
|
-
|
|
2631
|
-
|
|
2632
|
-
|
|
2633
|
-
|
|
2634
|
-
|
|
2635
|
-
|
|
2636
|
-
|
|
2637
|
-
|
|
2638
|
-
|
|
2639
|
-
|
|
2640
|
-
|
|
2641
|
-
|
|
2642
|
-
|
|
2643
|
-
|
|
2644
|
-
|
|
2645
|
-
|
|
2646
|
-
|
|
2647
|
-
|
|
2928
|
+
fireDrop(dropzone, createDtWithFiles(files));
|
|
2929
|
+
await flushPromises(rerender, ui);
|
|
2930
|
+
expect(onDropRejectedSpy).toHaveBeenCalledWith(
|
|
2931
|
+
[
|
|
2932
|
+
{
|
|
2933
|
+
file: files[0],
|
|
2934
|
+
errors: [
|
|
2935
|
+
{
|
|
2936
|
+
code: "file-invalid-type",
|
|
2937
|
+
message: "File type must be image/*",
|
|
2938
|
+
},
|
|
2939
|
+
],
|
|
2940
|
+
},
|
|
2941
|
+
],
|
|
2942
|
+
expect.anything()
|
|
2943
|
+
);
|
|
2944
|
+
onDropRejectedSpy.mockClear();
|
|
2945
|
+
|
|
2946
|
+
fireDrop(dropzone, createDtWithFiles(images));
|
|
2947
|
+
await flushPromises(rerender, ui);
|
|
2948
|
+
expect(onDropRejectedSpy).not.toHaveBeenCalled();
|
|
2949
|
+
onDropRejectedSpy.mockClear();
|
|
2950
|
+
|
|
2951
|
+
fireDrop(dropzone, createDtWithFiles([...files, ...images]));
|
|
2952
|
+
await flushPromises(rerender, ui);
|
|
2953
|
+
expect(onDropRejectedSpy).toHaveBeenCalledWith(
|
|
2954
|
+
[
|
|
2955
|
+
{
|
|
2956
|
+
file: files[0],
|
|
2957
|
+
errors: [
|
|
2958
|
+
{
|
|
2959
|
+
code: "file-invalid-type",
|
|
2960
|
+
message: "File type must be image/*",
|
|
2961
|
+
},
|
|
2962
|
+
],
|
|
2963
|
+
},
|
|
2964
|
+
],
|
|
2965
|
+
expect.anything()
|
|
2966
|
+
);
|
|
2967
|
+
});
|
|
2648
2968
|
|
|
2649
|
-
it(
|
|
2650
|
-
const onDropSpy = jest.fn()
|
|
2969
|
+
it("accepts a dropped image when Firefox provides a bogus file type", async () => {
|
|
2970
|
+
const onDropSpy = jest.fn();
|
|
2651
2971
|
const ui = (
|
|
2652
2972
|
<Dropzone accept="image/*" onDrop={onDropSpy}>
|
|
2653
2973
|
{({ getRootProps, getInputProps }) => (
|
|
@@ -2656,19 +2976,19 @@ describe('useDropzone() hook', () => {
|
|
|
2656
2976
|
</div>
|
|
2657
2977
|
)}
|
|
2658
2978
|
</Dropzone>
|
|
2659
|
-
)
|
|
2660
|
-
const { container, rerender } = render(ui)
|
|
2661
|
-
const dropzone = container.querySelector(
|
|
2979
|
+
);
|
|
2980
|
+
const { container, rerender } = render(ui);
|
|
2981
|
+
const dropzone = container.querySelector("div");
|
|
2662
2982
|
|
|
2663
|
-
const images = [createFile(
|
|
2664
|
-
fireDrop(dropzone, createDtWithFiles(images))
|
|
2665
|
-
await flushPromises(rerender, ui)
|
|
2983
|
+
const images = [createFile("bogus.gif", 1234, "application/x-moz-file")];
|
|
2984
|
+
fireDrop(dropzone, createDtWithFiles(images));
|
|
2985
|
+
await flushPromises(rerender, ui);
|
|
2666
2986
|
|
|
2667
|
-
expect(onDropSpy).toHaveBeenCalledWith(images, [], expect.anything())
|
|
2668
|
-
})
|
|
2987
|
+
expect(onDropSpy).toHaveBeenCalledWith(images, [], expect.anything());
|
|
2988
|
+
});
|
|
2669
2989
|
|
|
2670
|
-
it(
|
|
2671
|
-
const onDropSpy = jest.fn()
|
|
2990
|
+
it("filters files according to {maxSize}", async () => {
|
|
2991
|
+
const onDropSpy = jest.fn();
|
|
2672
2992
|
const ui = (
|
|
2673
2993
|
<Dropzone onDrop={onDropSpy} maxSize={1111}>
|
|
2674
2994
|
{({ getRootProps, getInputProps }) => (
|
|
@@ -2677,37 +2997,41 @@ describe('useDropzone() hook', () => {
|
|
|
2677
2997
|
</div>
|
|
2678
2998
|
)}
|
|
2679
2999
|
</Dropzone>
|
|
2680
|
-
)
|
|
2681
|
-
const { container, rerender } = render(ui)
|
|
2682
|
-
const dropzone = container.querySelector(
|
|
3000
|
+
);
|
|
3001
|
+
const { container, rerender } = render(ui);
|
|
3002
|
+
const dropzone = container.querySelector("div");
|
|
2683
3003
|
|
|
2684
|
-
fireDrop(dropzone, createDtWithFiles(images))
|
|
2685
|
-
await flushPromises(rerender, ui)
|
|
3004
|
+
fireDrop(dropzone, createDtWithFiles(images));
|
|
3005
|
+
await flushPromises(rerender, ui);
|
|
2686
3006
|
|
|
2687
|
-
expect(onDropSpy).toHaveBeenCalledWith(
|
|
2688
|
-
|
|
2689
|
-
|
|
2690
|
-
|
|
2691
|
-
|
|
2692
|
-
|
|
2693
|
-
|
|
2694
|
-
|
|
2695
|
-
|
|
2696
|
-
|
|
2697
|
-
|
|
2698
|
-
|
|
2699
|
-
|
|
2700
|
-
|
|
2701
|
-
|
|
2702
|
-
|
|
2703
|
-
|
|
2704
|
-
|
|
2705
|
-
|
|
2706
|
-
|
|
2707
|
-
|
|
3007
|
+
expect(onDropSpy).toHaveBeenCalledWith(
|
|
3008
|
+
[],
|
|
3009
|
+
[
|
|
3010
|
+
{
|
|
3011
|
+
file: images[0],
|
|
3012
|
+
errors: [
|
|
3013
|
+
{
|
|
3014
|
+
code: "file-too-large",
|
|
3015
|
+
message: "File is larger than 1111 bytes",
|
|
3016
|
+
},
|
|
3017
|
+
],
|
|
3018
|
+
},
|
|
3019
|
+
{
|
|
3020
|
+
file: images[1],
|
|
3021
|
+
errors: [
|
|
3022
|
+
{
|
|
3023
|
+
code: "file-too-large",
|
|
3024
|
+
message: "File is larger than 1111 bytes",
|
|
3025
|
+
},
|
|
3026
|
+
],
|
|
3027
|
+
},
|
|
3028
|
+
],
|
|
3029
|
+
expect.anything()
|
|
3030
|
+
);
|
|
3031
|
+
});
|
|
2708
3032
|
|
|
2709
|
-
it(
|
|
2710
|
-
const onDropSpy = jest.fn()
|
|
3033
|
+
it("filters files according to {minSize}", async () => {
|
|
3034
|
+
const onDropSpy = jest.fn();
|
|
2711
3035
|
const ui = (
|
|
2712
3036
|
<Dropzone onDrop={onDropSpy} minSize={1112}>
|
|
2713
3037
|
{({ getRootProps, getInputProps }) => (
|
|
@@ -2716,38 +3040,42 @@ describe('useDropzone() hook', () => {
|
|
|
2716
3040
|
</div>
|
|
2717
3041
|
)}
|
|
2718
3042
|
</Dropzone>
|
|
2719
|
-
)
|
|
2720
|
-
const { container, rerender } = render(ui)
|
|
2721
|
-
const dropzone = container.querySelector(
|
|
3043
|
+
);
|
|
3044
|
+
const { container, rerender } = render(ui);
|
|
3045
|
+
const dropzone = container.querySelector("div");
|
|
2722
3046
|
|
|
2723
|
-
fireDrop(dropzone, createDtWithFiles(files))
|
|
2724
|
-
await flushPromises(rerender, ui)
|
|
3047
|
+
fireDrop(dropzone, createDtWithFiles(files));
|
|
3048
|
+
await flushPromises(rerender, ui);
|
|
2725
3049
|
|
|
2726
|
-
expect(onDropSpy).toHaveBeenCalledWith(
|
|
2727
|
-
|
|
2728
|
-
|
|
2729
|
-
|
|
2730
|
-
|
|
2731
|
-
|
|
2732
|
-
|
|
2733
|
-
|
|
2734
|
-
|
|
2735
|
-
|
|
2736
|
-
|
|
2737
|
-
|
|
2738
|
-
|
|
3050
|
+
expect(onDropSpy).toHaveBeenCalledWith(
|
|
3051
|
+
[],
|
|
3052
|
+
[
|
|
3053
|
+
{
|
|
3054
|
+
file: files[0],
|
|
3055
|
+
errors: [
|
|
3056
|
+
{
|
|
3057
|
+
code: "file-too-small",
|
|
3058
|
+
message: "File is smaller than 1112 bytes",
|
|
3059
|
+
},
|
|
3060
|
+
],
|
|
3061
|
+
},
|
|
3062
|
+
],
|
|
3063
|
+
expect.anything()
|
|
3064
|
+
);
|
|
3065
|
+
});
|
|
3066
|
+
});
|
|
2739
3067
|
|
|
2740
|
-
describe(
|
|
3068
|
+
describe("onFileDialogCancel", () => {
|
|
2741
3069
|
beforeEach(() => {
|
|
2742
|
-
jest.useFakeTimers()
|
|
2743
|
-
})
|
|
3070
|
+
jest.useFakeTimers();
|
|
3071
|
+
});
|
|
2744
3072
|
|
|
2745
3073
|
afterEach(() => {
|
|
2746
|
-
jest.useRealTimers()
|
|
2747
|
-
})
|
|
3074
|
+
jest.useRealTimers();
|
|
3075
|
+
});
|
|
2748
3076
|
|
|
2749
|
-
it(
|
|
2750
|
-
const onFileDialogCancelSpy = jest.fn()
|
|
3077
|
+
it("is not invoked every time window receives focus", () => {
|
|
3078
|
+
const onFileDialogCancelSpy = jest.fn();
|
|
2751
3079
|
|
|
2752
3080
|
render(
|
|
2753
3081
|
<Dropzone onFileDialogCancel={onFileDialogCancelSpy}>
|
|
@@ -2757,18 +3085,18 @@ describe('useDropzone() hook', () => {
|
|
|
2757
3085
|
</div>
|
|
2758
3086
|
)}
|
|
2759
3087
|
</Dropzone>
|
|
2760
|
-
)
|
|
3088
|
+
);
|
|
2761
3089
|
|
|
2762
|
-
dispatchEvt(document.body,
|
|
2763
|
-
drainTimers()
|
|
3090
|
+
dispatchEvt(document.body, "focus");
|
|
3091
|
+
drainTimers();
|
|
2764
3092
|
|
|
2765
|
-
expect(onFileDialogCancelSpy).not.toHaveBeenCalled()
|
|
2766
|
-
})
|
|
3093
|
+
expect(onFileDialogCancelSpy).not.toHaveBeenCalled();
|
|
3094
|
+
});
|
|
2767
3095
|
|
|
2768
|
-
it(
|
|
2769
|
-
const activeRef = createRef()
|
|
2770
|
-
const active = <span ref={activeRef}>I am active</span
|
|
2771
|
-
const onFileDialogCancelSpy = jest.fn()
|
|
3096
|
+
it("resets {isFileDialogActive}", () => {
|
|
3097
|
+
const activeRef = createRef();
|
|
3098
|
+
const active = <span ref={activeRef}>I am active</span>;
|
|
3099
|
+
const onFileDialogCancelSpy = jest.fn();
|
|
2772
3100
|
|
|
2773
3101
|
const { container } = render(
|
|
2774
3102
|
<Dropzone onFileDialogCancel={onFileDialogCancelSpy}>
|
|
@@ -2782,26 +3110,26 @@ describe('useDropzone() hook', () => {
|
|
|
2782
3110
|
</div>
|
|
2783
3111
|
)}
|
|
2784
3112
|
</Dropzone>
|
|
2785
|
-
)
|
|
3113
|
+
);
|
|
2786
3114
|
|
|
2787
|
-
const dropzone = container.querySelector(
|
|
2788
|
-
const btn = container.querySelector(
|
|
3115
|
+
const dropzone = container.querySelector("div");
|
|
3116
|
+
const btn = container.querySelector("button");
|
|
2789
3117
|
|
|
2790
|
-
btn.click()
|
|
2791
|
-
drainTimers()
|
|
2792
|
-
const ref = activeRef.current
|
|
2793
|
-
expect(ref).not.toBeNull()
|
|
2794
|
-
expect(dropzone).toContainElement(ref)
|
|
3118
|
+
btn.click();
|
|
3119
|
+
drainTimers();
|
|
3120
|
+
const ref = activeRef.current;
|
|
3121
|
+
expect(ref).not.toBeNull();
|
|
3122
|
+
expect(dropzone).toContainElement(ref);
|
|
2795
3123
|
|
|
2796
|
-
dispatchEvt(document.body,
|
|
2797
|
-
drainTimers()
|
|
3124
|
+
dispatchEvt(document.body, "focus");
|
|
3125
|
+
drainTimers();
|
|
2798
3126
|
|
|
2799
|
-
expect(onFileDialogCancelSpy).toHaveBeenCalled()
|
|
2800
|
-
expect(dropzone).not.toContainElement(ref)
|
|
2801
|
-
})
|
|
3127
|
+
expect(onFileDialogCancelSpy).toHaveBeenCalled();
|
|
3128
|
+
expect(dropzone).not.toContainElement(ref);
|
|
3129
|
+
});
|
|
2802
3130
|
|
|
2803
|
-
it(
|
|
2804
|
-
const onFileDialogCancelSpy = jest.fn()
|
|
3131
|
+
it("is not invoked if <input> is not rendered", () => {
|
|
3132
|
+
const onFileDialogCancelSpy = jest.fn();
|
|
2805
3133
|
const { container, rerender } = render(
|
|
2806
3134
|
<Dropzone onFileDialogCancel={onFileDialogCancelSpy}>
|
|
2807
3135
|
{({ getRootProps, getInputProps, open }) => (
|
|
@@ -2813,27 +3141,27 @@ describe('useDropzone() hook', () => {
|
|
|
2813
3141
|
</div>
|
|
2814
3142
|
)}
|
|
2815
3143
|
</Dropzone>
|
|
2816
|
-
)
|
|
3144
|
+
);
|
|
2817
3145
|
|
|
2818
|
-
const btn = container.querySelector(
|
|
2819
|
-
btn.click()
|
|
2820
|
-
drainTimers()
|
|
3146
|
+
const btn = container.querySelector("button");
|
|
3147
|
+
btn.click();
|
|
3148
|
+
drainTimers();
|
|
2821
3149
|
|
|
2822
3150
|
rerender(
|
|
2823
3151
|
<Dropzone onFileDialogCancel={onFileDialogCancelSpy}>
|
|
2824
3152
|
{({ getRootProps }) => <div {...getRootProps()} />}
|
|
2825
3153
|
</Dropzone>
|
|
2826
|
-
)
|
|
2827
|
-
drainTimers()
|
|
3154
|
+
);
|
|
3155
|
+
drainTimers();
|
|
2828
3156
|
|
|
2829
|
-
dispatchEvt(document.body,
|
|
2830
|
-
drainTimers()
|
|
3157
|
+
dispatchEvt(document.body, "focus");
|
|
3158
|
+
drainTimers();
|
|
2831
3159
|
|
|
2832
|
-
expect(onFileDialogCancelSpy).not.toHaveBeenCalled()
|
|
2833
|
-
})
|
|
3160
|
+
expect(onFileDialogCancelSpy).not.toHaveBeenCalled();
|
|
3161
|
+
});
|
|
2834
3162
|
|
|
2835
|
-
it(
|
|
2836
|
-
const onFileDialogCancelSpy = jest.fn()
|
|
3163
|
+
it("is not invoked if files were selected", () => {
|
|
3164
|
+
const onFileDialogCancelSpy = jest.fn();
|
|
2837
3165
|
|
|
2838
3166
|
const { container } = render(
|
|
2839
3167
|
<Dropzone onFileDialogCancel={onFileDialogCancelSpy}>
|
|
@@ -2846,22 +3174,22 @@ describe('useDropzone() hook', () => {
|
|
|
2846
3174
|
</div>
|
|
2847
3175
|
)}
|
|
2848
3176
|
</Dropzone>
|
|
2849
|
-
)
|
|
3177
|
+
);
|
|
2850
3178
|
|
|
2851
|
-
const input = container.querySelector(
|
|
2852
|
-
Object.defineProperty(input,
|
|
3179
|
+
const input = container.querySelector("input");
|
|
3180
|
+
Object.defineProperty(input, "files", { value: files });
|
|
2853
3181
|
|
|
2854
|
-
const btn = container.querySelector(
|
|
2855
|
-
btn.click()
|
|
2856
|
-
drainTimers()
|
|
3182
|
+
const btn = container.querySelector("button");
|
|
3183
|
+
btn.click();
|
|
3184
|
+
drainTimers();
|
|
2857
3185
|
|
|
2858
|
-
dispatchEvt(document.body,
|
|
2859
|
-
drainTimers()
|
|
3186
|
+
dispatchEvt(document.body, "focus");
|
|
3187
|
+
drainTimers();
|
|
2860
3188
|
|
|
2861
|
-
expect(onFileDialogCancelSpy).not.toHaveBeenCalled()
|
|
2862
|
-
})
|
|
3189
|
+
expect(onFileDialogCancelSpy).not.toHaveBeenCalled();
|
|
3190
|
+
});
|
|
2863
3191
|
|
|
2864
|
-
it(
|
|
3192
|
+
it("does not throw if callback is not provided", () => {
|
|
2865
3193
|
const { container } = render(
|
|
2866
3194
|
<Dropzone onFileDialogCancel={null}>
|
|
2867
3195
|
{({ getRootProps, getInputProps, open }) => (
|
|
@@ -2873,45 +3201,43 @@ describe('useDropzone() hook', () => {
|
|
|
2873
3201
|
</div>
|
|
2874
3202
|
)}
|
|
2875
3203
|
</Dropzone>
|
|
2876
|
-
)
|
|
3204
|
+
);
|
|
2877
3205
|
|
|
2878
|
-
const btn = container.querySelector(
|
|
2879
|
-
btn.click()
|
|
2880
|
-
drainTimers()
|
|
3206
|
+
const btn = container.querySelector("button");
|
|
3207
|
+
btn.click();
|
|
3208
|
+
drainTimers();
|
|
2881
3209
|
|
|
2882
3210
|
const fn = () => {
|
|
2883
|
-
dispatchEvt(document.body,
|
|
2884
|
-
drainTimers()
|
|
2885
|
-
}
|
|
2886
|
-
expect(fn).not.toThrow()
|
|
2887
|
-
})
|
|
2888
|
-
})
|
|
2889
|
-
|
|
2890
|
-
describe(
|
|
2891
|
-
it(
|
|
2892
|
-
const onFileDialogOpenSpy = jest.fn()
|
|
3211
|
+
dispatchEvt(document.body, "focus");
|
|
3212
|
+
drainTimers();
|
|
3213
|
+
};
|
|
3214
|
+
expect(fn).not.toThrow();
|
|
3215
|
+
});
|
|
3216
|
+
});
|
|
3217
|
+
|
|
3218
|
+
describe("onFileDialogOpen", () => {
|
|
3219
|
+
it("is invoked when opening the file dialog", () => {
|
|
3220
|
+
const onFileDialogOpenSpy = jest.fn();
|
|
2893
3221
|
const { container } = render(
|
|
2894
|
-
<Dropzone
|
|
2895
|
-
onFileDialogOpen={onFileDialogOpenSpy}>
|
|
3222
|
+
<Dropzone onFileDialogOpen={onFileDialogOpenSpy}>
|
|
2896
3223
|
{({ getRootProps, getInputProps }) => (
|
|
2897
3224
|
<div {...getRootProps()}>
|
|
2898
3225
|
<input {...getInputProps()} />
|
|
2899
3226
|
</div>
|
|
2900
3227
|
)}
|
|
2901
3228
|
</Dropzone>
|
|
2902
|
-
)
|
|
3229
|
+
);
|
|
2903
3230
|
|
|
2904
|
-
const dropzone = container.querySelector(
|
|
2905
|
-
fireEvent.click(dropzone)
|
|
3231
|
+
const dropzone = container.querySelector("div");
|
|
3232
|
+
fireEvent.click(dropzone);
|
|
2906
3233
|
|
|
2907
|
-
expect(onFileDialogOpenSpy).toHaveBeenCalled()
|
|
2908
|
-
})
|
|
3234
|
+
expect(onFileDialogOpenSpy).toHaveBeenCalled();
|
|
3235
|
+
});
|
|
2909
3236
|
|
|
2910
|
-
it(
|
|
2911
|
-
const onFileDialogOpenSpy = jest.fn()
|
|
3237
|
+
it("is invoked when opening the file dialog programmatically", () => {
|
|
3238
|
+
const onFileDialogOpenSpy = jest.fn();
|
|
2912
3239
|
const { container } = render(
|
|
2913
|
-
<Dropzone
|
|
2914
|
-
onFileDialogOpen={onFileDialogOpenSpy}>
|
|
3240
|
+
<Dropzone onFileDialogOpen={onFileDialogOpenSpy}>
|
|
2915
3241
|
{({ getRootProps, getInputProps, open }) => (
|
|
2916
3242
|
<div {...getRootProps()}>
|
|
2917
3243
|
<input {...getInputProps()} />
|
|
@@ -2921,18 +3247,18 @@ describe('useDropzone() hook', () => {
|
|
|
2921
3247
|
</div>
|
|
2922
3248
|
)}
|
|
2923
3249
|
</Dropzone>
|
|
2924
|
-
)
|
|
3250
|
+
);
|
|
2925
3251
|
|
|
2926
|
-
const btn = container.querySelector(
|
|
2927
|
-
btn.click()
|
|
3252
|
+
const btn = container.querySelector("button");
|
|
3253
|
+
btn.click();
|
|
2928
3254
|
|
|
2929
|
-
expect(onFileDialogOpenSpy).toHaveBeenCalled()
|
|
2930
|
-
})
|
|
2931
|
-
})
|
|
3255
|
+
expect(onFileDialogOpenSpy).toHaveBeenCalled();
|
|
3256
|
+
});
|
|
3257
|
+
});
|
|
2932
3258
|
|
|
2933
|
-
describe(
|
|
2934
|
-
it(
|
|
2935
|
-
const onClickSpy = jest.spyOn(HTMLInputElement.prototype,
|
|
3259
|
+
describe("{open}", () => {
|
|
3260
|
+
it("can open file dialog programmatically", () => {
|
|
3261
|
+
const onClickSpy = jest.spyOn(HTMLInputElement.prototype, "click");
|
|
2936
3262
|
const { container } = render(
|
|
2937
3263
|
<Dropzone>
|
|
2938
3264
|
{({ getRootProps, getInputProps, open }) => (
|
|
@@ -2944,18 +3270,18 @@ describe('useDropzone() hook', () => {
|
|
|
2944
3270
|
</div>
|
|
2945
3271
|
)}
|
|
2946
3272
|
</Dropzone>
|
|
2947
|
-
)
|
|
3273
|
+
);
|
|
2948
3274
|
|
|
2949
|
-
const btn = container.querySelector(
|
|
3275
|
+
const btn = container.querySelector("button");
|
|
2950
3276
|
|
|
2951
|
-
btn.click()
|
|
3277
|
+
btn.click();
|
|
2952
3278
|
|
|
2953
|
-
expect(onClickSpy).toHaveBeenCalled()
|
|
2954
|
-
})
|
|
3279
|
+
expect(onClickSpy).toHaveBeenCalled();
|
|
3280
|
+
});
|
|
2955
3281
|
|
|
2956
|
-
it(
|
|
2957
|
-
const activeRef = createRef()
|
|
2958
|
-
const active = <span ref={activeRef}>I am active</span
|
|
3282
|
+
it("sets {isFileDialogActive} state", () => {
|
|
3283
|
+
const activeRef = createRef();
|
|
3284
|
+
const active = <span ref={activeRef}>I am active</span>;
|
|
2959
3285
|
const { container } = render(
|
|
2960
3286
|
<Dropzone>
|
|
2961
3287
|
{({ getRootProps, getInputProps, isFileDialogActive, open }) => (
|
|
@@ -2968,20 +3294,20 @@ describe('useDropzone() hook', () => {
|
|
|
2968
3294
|
</div>
|
|
2969
3295
|
)}
|
|
2970
3296
|
</Dropzone>
|
|
2971
|
-
)
|
|
3297
|
+
);
|
|
2972
3298
|
|
|
2973
|
-
const dropzone = container.querySelector(
|
|
2974
|
-
const btn = container.querySelector(
|
|
3299
|
+
const dropzone = container.querySelector("div");
|
|
3300
|
+
const btn = container.querySelector("button");
|
|
2975
3301
|
|
|
2976
|
-
btn.click()
|
|
3302
|
+
btn.click();
|
|
2977
3303
|
|
|
2978
|
-
const ref = activeRef.current
|
|
2979
|
-
expect(ref).not.toBeNull()
|
|
2980
|
-
expect(dropzone).toContainElement(ref)
|
|
2981
|
-
})
|
|
3304
|
+
const ref = activeRef.current;
|
|
3305
|
+
expect(ref).not.toBeNull();
|
|
3306
|
+
expect(dropzone).toContainElement(ref);
|
|
3307
|
+
});
|
|
2982
3308
|
|
|
2983
|
-
it(
|
|
2984
|
-
const onClickSpy = jest.spyOn(HTMLInputElement.prototype,
|
|
3309
|
+
it("does nothing if {disabled} is true", () => {
|
|
3310
|
+
const onClickSpy = jest.spyOn(HTMLInputElement.prototype, "click");
|
|
2985
3311
|
const { container } = render(
|
|
2986
3312
|
<Dropzone disabled>
|
|
2987
3313
|
{({ getRootProps, getInputProps, open }) => (
|
|
@@ -2993,16 +3319,16 @@ describe('useDropzone() hook', () => {
|
|
|
2993
3319
|
</div>
|
|
2994
3320
|
)}
|
|
2995
3321
|
</Dropzone>
|
|
2996
|
-
)
|
|
3322
|
+
);
|
|
2997
3323
|
|
|
2998
|
-
const btn = container.querySelector(
|
|
3324
|
+
const btn = container.querySelector("button");
|
|
2999
3325
|
|
|
3000
|
-
btn.click()
|
|
3326
|
+
btn.click();
|
|
3001
3327
|
|
|
3002
|
-
expect(onClickSpy).not.toHaveBeenCalled()
|
|
3003
|
-
})
|
|
3328
|
+
expect(onClickSpy).not.toHaveBeenCalled();
|
|
3329
|
+
});
|
|
3004
3330
|
|
|
3005
|
-
it(
|
|
3331
|
+
it("does not throw if <input> is missing", () => {
|
|
3006
3332
|
const { container } = render(
|
|
3007
3333
|
<Dropzone>
|
|
3008
3334
|
{({ getRootProps, open }) => (
|
|
@@ -3013,25 +3339,25 @@ describe('useDropzone() hook', () => {
|
|
|
3013
3339
|
</div>
|
|
3014
3340
|
)}
|
|
3015
3341
|
</Dropzone>
|
|
3016
|
-
)
|
|
3342
|
+
);
|
|
3017
3343
|
|
|
3018
|
-
const btn = container.querySelector(
|
|
3344
|
+
const btn = container.querySelector("button");
|
|
3019
3345
|
|
|
3020
|
-
const fn = () => btn.click()
|
|
3021
|
-
expect(fn).not.toThrow()
|
|
3022
|
-
})
|
|
3023
|
-
})
|
|
3346
|
+
const fn = () => btn.click();
|
|
3347
|
+
expect(fn).not.toThrow();
|
|
3348
|
+
});
|
|
3349
|
+
});
|
|
3024
3350
|
|
|
3025
|
-
describe(
|
|
3026
|
-
it(
|
|
3027
|
-
const validator = file => {
|
|
3351
|
+
describe("validator", () => {
|
|
3352
|
+
it("rejects with custom error", async () => {
|
|
3353
|
+
const validator = (file) => {
|
|
3028
3354
|
if (/dogs/i.test(file.name))
|
|
3029
|
-
return { code:
|
|
3355
|
+
return { code: "dogs-not-allowed", message: "Dogs not allowed" };
|
|
3030
3356
|
|
|
3031
3357
|
return null;
|
|
3032
|
-
}
|
|
3358
|
+
};
|
|
3033
3359
|
|
|
3034
|
-
const onDropSpy = jest.fn()
|
|
3360
|
+
const onDropSpy = jest.fn();
|
|
3035
3361
|
|
|
3036
3362
|
const ui = (
|
|
3037
3363
|
<Dropzone validator={validator} onDrop={onDropSpy} multiple={true}>
|
|
@@ -3041,131 +3367,133 @@ describe('useDropzone() hook', () => {
|
|
|
3041
3367
|
</div>
|
|
3042
3368
|
)}
|
|
3043
3369
|
</Dropzone>
|
|
3044
|
-
)
|
|
3370
|
+
);
|
|
3045
3371
|
|
|
3046
|
-
const { container, rerender } = render(ui)
|
|
3047
|
-
const dropzone = container.querySelector(
|
|
3372
|
+
const { container, rerender } = render(ui);
|
|
3373
|
+
const dropzone = container.querySelector("div");
|
|
3048
3374
|
|
|
3049
|
-
fireDrop(dropzone, createDtWithFiles(images))
|
|
3050
|
-
await flushPromises(rerender, ui)
|
|
3375
|
+
fireDrop(dropzone, createDtWithFiles(images));
|
|
3376
|
+
await flushPromises(rerender, ui);
|
|
3051
3377
|
|
|
3052
|
-
expect(onDropSpy).toHaveBeenCalledWith(
|
|
3053
|
-
|
|
3054
|
-
|
|
3055
|
-
|
|
3056
|
-
|
|
3057
|
-
|
|
3058
|
-
|
|
3059
|
-
|
|
3060
|
-
|
|
3061
|
-
|
|
3062
|
-
|
|
3063
|
-
|
|
3064
|
-
|
|
3378
|
+
expect(onDropSpy).toHaveBeenCalledWith(
|
|
3379
|
+
[images[0]],
|
|
3380
|
+
[
|
|
3381
|
+
{
|
|
3382
|
+
file: images[1],
|
|
3383
|
+
errors: [
|
|
3384
|
+
{
|
|
3385
|
+
code: "dogs-not-allowed",
|
|
3386
|
+
message: "Dogs not allowed",
|
|
3387
|
+
},
|
|
3388
|
+
],
|
|
3389
|
+
},
|
|
3390
|
+
],
|
|
3391
|
+
expect.anything()
|
|
3392
|
+
);
|
|
3393
|
+
});
|
|
3394
|
+
});
|
|
3065
3395
|
|
|
3066
|
-
describe(
|
|
3067
|
-
it(
|
|
3396
|
+
describe("accessibility", () => {
|
|
3397
|
+
it("sets the role attribute to button by default on the root", () => {
|
|
3068
3398
|
const { container } = render(
|
|
3069
3399
|
<Dropzone>
|
|
3070
|
-
{({ getRootProps }) => (
|
|
3071
|
-
<div id="root" {...getRootProps()} />
|
|
3072
|
-
)}
|
|
3400
|
+
{({ getRootProps }) => <div id="root" {...getRootProps()} />}
|
|
3073
3401
|
</Dropzone>
|
|
3074
|
-
)
|
|
3075
|
-
const root = container.querySelector(
|
|
3402
|
+
);
|
|
3403
|
+
const root = container.querySelector("#root");
|
|
3076
3404
|
|
|
3077
|
-
expect(root).toHaveAttribute(
|
|
3078
|
-
})
|
|
3405
|
+
expect(root).toHaveAttribute("role", "button");
|
|
3406
|
+
});
|
|
3079
3407
|
|
|
3080
|
-
test(
|
|
3408
|
+
test("users can override the default role attribute on the root", () => {
|
|
3081
3409
|
const { container } = render(
|
|
3082
3410
|
<Dropzone>
|
|
3083
3411
|
{({ getRootProps }) => (
|
|
3084
|
-
<div id="root" {...getRootProps({role:
|
|
3412
|
+
<div id="root" {...getRootProps({ role: "generic" })} />
|
|
3085
3413
|
)}
|
|
3086
3414
|
</Dropzone>
|
|
3087
|
-
)
|
|
3088
|
-
const root = container.querySelector(
|
|
3415
|
+
);
|
|
3416
|
+
const root = container.querySelector("#root");
|
|
3089
3417
|
|
|
3090
|
-
expect(root).toHaveAttribute(
|
|
3091
|
-
})
|
|
3092
|
-
})
|
|
3093
|
-
})
|
|
3418
|
+
expect(root).toHaveAttribute("role", "generic");
|
|
3419
|
+
});
|
|
3420
|
+
});
|
|
3421
|
+
});
|
|
3094
3422
|
|
|
3095
3423
|
async function flushPromises(rerender, ui) {
|
|
3096
|
-
await act(() => waitFor(() => rerender(ui)))
|
|
3424
|
+
await act(() => waitFor(() => rerender(ui)));
|
|
3097
3425
|
}
|
|
3098
3426
|
|
|
3099
3427
|
function drainTimers() {
|
|
3100
|
-
act(() => jest.runAllTimers())
|
|
3428
|
+
act(() => jest.runAllTimers());
|
|
3101
3429
|
}
|
|
3102
3430
|
|
|
3103
3431
|
function createDtWithFiles(files = []) {
|
|
3104
3432
|
return {
|
|
3105
3433
|
dataTransfer: {
|
|
3106
3434
|
files,
|
|
3107
|
-
items: files.map(file => ({
|
|
3108
|
-
kind:
|
|
3435
|
+
items: files.map((file) => ({
|
|
3436
|
+
kind: "file",
|
|
3109
3437
|
size: file.size,
|
|
3110
3438
|
type: file.type,
|
|
3111
|
-
getAsFile: () => file
|
|
3439
|
+
getAsFile: () => file,
|
|
3112
3440
|
})),
|
|
3113
|
-
types: [
|
|
3114
|
-
}
|
|
3115
|
-
}
|
|
3441
|
+
types: ["Files"],
|
|
3442
|
+
},
|
|
3443
|
+
};
|
|
3116
3444
|
}
|
|
3117
3445
|
|
|
3118
3446
|
function fireDragEnter(node, data) {
|
|
3119
|
-
dispatchEvt(node,
|
|
3447
|
+
dispatchEvt(node, "dragenter", data);
|
|
3120
3448
|
}
|
|
3121
3449
|
|
|
3122
3450
|
function fireDragOver(node, data) {
|
|
3123
|
-
dispatchEvt(node,
|
|
3451
|
+
dispatchEvt(node, "dragover", data);
|
|
3124
3452
|
}
|
|
3125
3453
|
|
|
3126
3454
|
function fireDragLeave(node, data) {
|
|
3127
|
-
dispatchEvt(node,
|
|
3455
|
+
dispatchEvt(node, "dragleave", data);
|
|
3128
3456
|
}
|
|
3129
3457
|
|
|
3130
3458
|
function fireDrop(node, data) {
|
|
3131
|
-
dispatchEvt(node,
|
|
3459
|
+
dispatchEvt(node, "drop", data);
|
|
3132
3460
|
}
|
|
3133
3461
|
|
|
3134
3462
|
// Using fireEvent.* doesn't work for our use case,
|
|
3135
3463
|
// we cannot set the event props
|
|
3136
3464
|
function dispatchEvt(node, type, data) {
|
|
3137
|
-
const event = new Event(type, { bubbles: true })
|
|
3465
|
+
const event = new Event(type, { bubbles: true });
|
|
3138
3466
|
if (data) {
|
|
3139
|
-
Object.assign(event, data)
|
|
3467
|
+
Object.assign(event, data);
|
|
3140
3468
|
}
|
|
3141
|
-
fireEvent(node, event)
|
|
3469
|
+
fireEvent(node, event);
|
|
3142
3470
|
}
|
|
3143
3471
|
|
|
3144
3472
|
function createFileSystemFileHandle(file) {
|
|
3145
|
-
return {getFile: () => Promise.resolve(file)}
|
|
3473
|
+
return { getFile: () => Promise.resolve(file) };
|
|
3146
3474
|
}
|
|
3147
3475
|
|
|
3148
3476
|
function createFile(name, size, type) {
|
|
3149
|
-
const file = new File([], name, { type })
|
|
3150
|
-
Object.defineProperty(file,
|
|
3477
|
+
const file = new File([], name, { type });
|
|
3478
|
+
Object.defineProperty(file, "size", {
|
|
3151
3479
|
get() {
|
|
3152
|
-
return size
|
|
3153
|
-
}
|
|
3154
|
-
})
|
|
3155
|
-
return file
|
|
3480
|
+
return size;
|
|
3481
|
+
},
|
|
3482
|
+
});
|
|
3483
|
+
return file;
|
|
3156
3484
|
}
|
|
3157
3485
|
|
|
3158
3486
|
function createThenable() {
|
|
3159
3487
|
let done, cancel;
|
|
3160
3488
|
|
|
3161
3489
|
const promise = new Promise((resolve, reject) => {
|
|
3162
|
-
done = resolve
|
|
3163
|
-
cancel = reject
|
|
3164
|
-
})
|
|
3490
|
+
done = resolve;
|
|
3491
|
+
cancel = reject;
|
|
3492
|
+
});
|
|
3165
3493
|
|
|
3166
3494
|
return {
|
|
3167
3495
|
promise,
|
|
3168
3496
|
done,
|
|
3169
|
-
cancel
|
|
3170
|
-
}
|
|
3497
|
+
cancel,
|
|
3498
|
+
};
|
|
3171
3499
|
}
|