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