@@ -178,4 +178,128 @@ describe("useFilesUploading", () => {
178178
179179 expect ( result . current . allFilesDone ) . toBe ( false ) ;
180180 } ) ;
181+
182+ describe ( "paste" , ( ) => {
183+ const createPasteEvent = ( files : File [ ] ) => {
184+ const dataTransfer = {
185+ files : files as unknown as FileList ,
186+ } ;
187+ return {
188+ clipboardData : dataTransfer ,
189+ preventDefault : jest . fn ( ) ,
190+ stopPropagation : jest . fn ( ) ,
191+ } as unknown as React . ClipboardEvent < HTMLTextAreaElement > ;
192+ } ;
193+
194+ it ( "should do nothing when not enabled" , async ( ) => {
195+ const { result } = renderHook ( ( ) =>
196+ useFilesUploading ( { enabled : false } )
197+ ) ;
198+
199+ const pasteEvent = createPasteEvent ( [ new File ( [ "test" ] , "test.txt" ) ] ) ;
200+
201+ act ( ( ) => {
202+ result . current . paste ( pasteEvent ) ;
203+ } ) ;
204+
205+ expect ( pasteEvent . preventDefault ) . not . toHaveBeenCalled ( ) ;
206+ expect ( result . current . files ) . toBeUndefined ( ) ;
207+ } ) ;
208+
209+ it ( "should do nothing when no files in clipboard" , async ( ) => {
210+ const { result } = renderHook ( ( ) => useFilesUploading ( { enabled : true } ) ) ;
211+
212+ const pasteEvent = createPasteEvent ( [ ] ) ;
213+
214+ act ( ( ) => {
215+ result . current . paste ( pasteEvent ) ;
216+ } ) ;
217+
218+ expect ( pasteEvent . preventDefault ) . not . toHaveBeenCalled ( ) ;
219+ expect ( result . current . files ) . toBeUndefined ( ) ;
220+ } ) ;
221+
222+ it ( "should handle pasted files" , async ( ) => {
223+ const { result } = renderHook ( ( ) => useFilesUploading ( { enabled : true } ) ) ;
224+
225+ const pasteEvent = createPasteEvent ( [ new File ( [ "test" ] , "test.txt" ) ] ) ;
226+
227+ act ( ( ) => {
228+ result . current . paste ( pasteEvent ) ;
229+ } ) ;
230+
231+ expect ( pasteEvent . preventDefault ) . toHaveBeenCalled ( ) ;
232+ expect ( pasteEvent . stopPropagation ) . toHaveBeenCalled ( ) ;
233+ expect ( result . current . files ?. length ) . toBe ( 1 ) ;
234+ expect ( result . current . files ?. [ 0 ] . file . name ) . toBe ( "test.txt" ) ;
235+
236+ await act ( async ( ) => {
237+ await ( global as any ) . flushPromises ( ) ;
238+ } ) ;
239+ } ) ;
240+
241+ it ( "should rename pasted image.png to unique name" , async ( ) => {
242+ const { result } = renderHook ( ( ) => useFilesUploading ( { enabled : true } ) ) ;
243+
244+ const pasteEvent = createPasteEvent ( [
245+ new File ( [ "image data" ] , "image.png" , { type : "image/png" } ) ,
246+ ] ) ;
247+
248+ act ( ( ) => {
249+ result . current . paste ( pasteEvent ) ;
250+ } ) ;
251+
252+ expect ( result . current . files ?. length ) . toBe ( 1 ) ;
253+ expect ( result . current . files ?. [ 0 ] . file . name ) . toMatch (
254+ / ^ p a s t e d - i m a g e - \d + - \d + \. p n g $ /
255+ ) ;
256+ expect ( result . current . files ?. [ 0 ] . file . type ) . toBe ( "image/png" ) ;
257+
258+ await act ( async ( ) => {
259+ await ( global as any ) . flushPromises ( ) ;
260+ } ) ;
261+ } ) ;
262+
263+ it ( "should not rename non-image.png files" , async ( ) => {
264+ const { result } = renderHook ( ( ) => useFilesUploading ( { enabled : true } ) ) ;
265+
266+ const pasteEvent = createPasteEvent ( [
267+ new File ( [ "image data" ] , "screenshot.png" , { type : "image/png" } ) ,
268+ ] ) ;
269+
270+ act ( ( ) => {
271+ result . current . paste ( pasteEvent ) ;
272+ } ) ;
273+
274+ expect ( result . current . files ?. length ) . toBe ( 1 ) ;
275+ expect ( result . current . files ?. [ 0 ] . file . name ) . toBe ( "screenshot.png" ) ;
276+
277+ await act ( async ( ) => {
278+ await ( global as any ) . flushPromises ( ) ;
279+ } ) ;
280+ } ) ;
281+
282+ it ( "should handle multiple pasted files" , async ( ) => {
283+ const { result } = renderHook ( ( ) => useFilesUploading ( { enabled : true } ) ) ;
284+
285+ const pasteEvent = createPasteEvent ( [
286+ new File ( [ "test1" ] , "file1.txt" ) ,
287+ new File ( [ "image data" ] , "image.png" , { type : "image/png" } ) ,
288+ ] ) ;
289+
290+ act ( ( ) => {
291+ result . current . paste ( pasteEvent ) ;
292+ } ) ;
293+
294+ expect ( result . current . files ?. length ) . toBe ( 2 ) ;
295+ expect ( result . current . files ?. [ 0 ] . file . name ) . toBe ( "file1.txt" ) ;
296+ expect ( result . current . files ?. [ 1 ] . file . name ) . toMatch (
297+ / ^ p a s t e d - i m a g e - \d + - \d + \. p n g $ /
298+ ) ;
299+
300+ await act ( async ( ) => {
301+ await ( global as any ) . flushPromises ( ) ;
302+ } ) ;
303+ } ) ;
304+ } ) ;
181305} ) ;
0 commit comments