Merge branch 'feat/rbf-wording' into 'main'
[ProtonMail-WebClient.git] / packages / drive-store / store / _uploads / UploadProvider / useUploadQueue.add.test.ts
blob692c39beacd95b340aefede18afce15f4c52bb81
1 import { act, renderHook } from '@testing-library/react-hooks';
3 import { TransferState } from '../../../components/TransferManager/transfer';
4 import { mockGlobalFile, testFile } from '../../../utils/test/file';
5 import type { UploadFileList } from '../interface';
6 import type { FileUpload, FolderUpload, UploadQueue } from './interface';
7 import useUploadQueue, { addItemToQueue } from './useUploadQueue';
9 function createEmptyQueue(): UploadQueue {
10     return {
11         shareId: 'shareId',
12         linkId: 'parentId',
13         files: [],
14         folders: [],
15     };
18 describe('useUploadQueue::add', () => {
19     const mockLogCallback = jest.fn();
21     let hook: {
22         current: {
23             fileUploads: FileUpload[];
24             folderUploads: FolderUpload[];
25             add: (shareId: string, parentId: string, fileList: UploadFileList) => void;
26         };
27     };
29     beforeEach(() => {
30         mockGlobalFile();
31         const { result } = renderHook(() => useUploadQueue(mockLogCallback));
32         hook = result;
33     });
35     it('creates new upload queue', () => {
36         act(() => {
37             hook.current.add('shareId', 'parentId', [{ path: [], folder: 'folder' }]);
38             hook.current.add('shareId2', 'parentId2', [{ path: [], folder: 'folder' }]);
39         });
40         expect(hook.current.folderUploads).toMatchObject([
41             {
42                 name: 'folder',
43                 shareId: 'shareId',
44                 parentId: 'parentId',
45             },
46             {
47                 name: 'folder',
48                 shareId: 'shareId2',
49                 parentId: 'parentId2',
50             },
51         ]);
52     });
54     it('merges upload queue', () => {
55         act(() => {
56             hook.current.add('shareId', 'parentId', [{ path: [], folder: 'folder' }]);
57             hook.current.add('shareId', 'parentId', [{ path: [], folder: 'folder2' }]);
58         });
59         expect(hook.current.folderUploads).toMatchObject([
60             {
61                 name: 'folder',
62                 shareId: 'shareId',
63                 parentId: 'parentId',
64             },
65             {
66                 name: 'folder2',
67                 shareId: 'shareId',
68                 parentId: 'parentId',
69             },
70         ]);
71     });
73     it('throws error when adding file with empty name', () => {
74         expect(() => {
75             addItemToQueue(mockLogCallback, 'shareId', createEmptyQueue(), { path: [], file: testFile('') });
76         }).toThrow('File or folder is missing a name');
77     });
79     it('throws error when adding folder with empty name', () => {
80         expect(() => {
81             addItemToQueue(mockLogCallback, 'shareId', createEmptyQueue(), { path: [], folder: '' });
82         }).toThrow('File or folder is missing a name');
83     });
85     it('throws error when adding file to non-existing folder', () => {
86         expect(() => {
87             addItemToQueue(mockLogCallback, 'shareId', createEmptyQueue(), {
88                 path: ['folder'],
89                 file: testFile('a.txt'),
90             });
91         }).toThrow('Wrong file or folder structure');
92     });
94     it('throws error when adding the same file again', () => {
95         const queue = createEmptyQueue();
96         addItemToQueue(mockLogCallback, 'shareId', queue, { path: [], file: testFile('a.txt') });
97         expect(() => {
98             addItemToQueue(mockLogCallback, 'shareId', queue, { path: [], file: testFile('a.txt') });
99         }).toThrow('File or folder "a.txt" is already uploading');
100         addItemToQueue(mockLogCallback, 'shareId', queue, { path: [], folder: 'folder' });
101         addItemToQueue(mockLogCallback, 'shareId', queue, { path: ['folder'], file: testFile('a.txt') });
102         expect(() => {
103             addItemToQueue(mockLogCallback, 'shareId', queue, { path: ['folder'], file: testFile('a.txt') });
104         }).toThrow('File or folder "a.txt" is already uploading');
105     });
107     it('throws error when adding the same folder again', () => {
108         const queue = createEmptyQueue();
109         addItemToQueue(mockLogCallback, 'shareId', queue, { path: [], folder: 'folder' });
110         expect(() => {
111             addItemToQueue(mockLogCallback, 'shareId', queue, { path: [], folder: 'folder' });
112         }).toThrow('File or folder "folder" is already uploading');
113         addItemToQueue(mockLogCallback, 'shareId', queue, { path: ['folder'], folder: 'subfolder' });
114         expect(() => {
115             addItemToQueue(mockLogCallback, 'shareId', queue, { path: ['folder'], folder: 'subfolder' });
116         }).toThrow('File or folder "subfolder" is already uploading');
117     });
119     it('throws error when adding the same folder again with unfinished childs', () => {
120         const queue = createEmptyQueue();
121         addItemToQueue(mockLogCallback, 'shareId', queue, { path: [], folder: 'folder' });
122         addItemToQueue(mockLogCallback, 'shareId', queue, { path: ['folder'], file: testFile('a.txt') });
124         queue.folders[0].state = TransferState.Done;
125         expect(() => {
126             addItemToQueue(mockLogCallback, 'shareId', queue, { path: [], folder: 'folder' });
127         }).toThrow('File or folder "folder" is already uploading');
129         queue.folders[0].files[0].state = TransferState.Done;
130         addItemToQueue(mockLogCallback, 'shareId', queue, { path: [], folder: 'folder' });
131     });
133     it('adds files to the latest folder', () => {
134         const queue = createEmptyQueue();
135         addItemToQueue(mockLogCallback, 'shareId', queue, { path: [], folder: 'folder' });
136         queue.folders[0].state = TransferState.Done;
138         addItemToQueue(mockLogCallback, 'shareId', queue, { path: [], folder: 'folder' });
139         addItemToQueue(mockLogCallback, 'shareId', queue, { path: ['folder'], file: testFile('b.txt') });
140         expect(queue.folders[0].files.length).toBe(0);
141         expect(queue.folders[1].files.length).toBe(1);
142         expect(queue.folders[1].files[0].meta.filename).toBe('b.txt');
143     });
145     it('adds files to already prepared filter with pending state', () => {
146         const queue = createEmptyQueue();
147         addItemToQueue(mockLogCallback, 'shareId', queue, { path: [], folder: 'folder' });
149         // The first file, before folder is done, is set to init state.
150         addItemToQueue(mockLogCallback, 'shareId', queue, { path: ['folder'], file: testFile('a.txt') });
151         expect(queue.folders[0].files[0]).toMatchObject({
152             meta: { filename: 'a.txt' },
153             state: TransferState.Initializing,
154         });
156         // The second file, after folder is done, is set to pending state.
157         queue.folders[0].state = TransferState.Done;
158         queue.folders[0].linkId = 'folderId';
159         addItemToQueue(mockLogCallback, 'shareId', queue, { path: ['folder'], file: testFile('b.txt') });
160         expect(queue.folders[0].files[1]).toMatchObject({
161             meta: { filename: 'b.txt' },
162             state: TransferState.Pending,
163         });
164     });