Skip to content

Commit

Permalink
fix(content-uploader): fix multiple items droppable issue (box#3565)
Browse files Browse the repository at this point in the history
* fix(content-uploader): fix multiple items droppable issue

* fix(content-uploader): add tests

* fix(content-uploader): fix flow issue
  • Loading branch information
tjiang-box authored and mhagmajer committed Jul 4, 2024
1 parent 3103983 commit 36d02ac
Show file tree
Hide file tree
Showing 2 changed files with 95 additions and 26 deletions.
68 changes: 42 additions & 26 deletions src/elements/content-uploader/ContentUploader.js
Original file line number Diff line number Diff line change
Expand Up @@ -378,9 +378,7 @@ class ContentUploader extends Component<Props, State> {
if (droppedItems.items) {
this.addDataTransferItemsToUploadQueue(droppedItems.items, itemUpdateCallback);
} else {
Array.from(droppedItems.files).forEach(file => {
this.addFilesToUploadQueue([file], itemUpdateCallback);
});
this.addFilesToUploadQueue(Array.from(droppedItems.files), itemUpdateCallback);
}
};

Expand Down Expand Up @@ -426,20 +424,20 @@ class ContentUploader extends Component<Props, State> {
* @private
* @param {Array<DataTransferItem | UploadDataTransferItemWithAPIOptions>} dataTransferItems
* @param {Function} itemUpdateCallback
* @returns {void}
* @returns {Promise<any>}
*/
addFileDataTransferItemsToUploadQueue = (
addFileDataTransferItemsToUploadQueue = async (
dataTransferItems: Array<DataTransferItem | UploadDataTransferItemWithAPIOptions>,
itemUpdateCallback: Function,
): void => {
dataTransferItems.forEach(async item => {
const file = await getFileFromDataTransferItem(item);
if (!file) {
return;
): Promise<any> => {
const files = await Promise.all(dataTransferItems.map(async item => getFileFromDataTransferItem(item)));
const filesArray = [];
files.forEach(file => {
if (file) {
filesArray.push(file);
}

this.addFilesToUploadQueue([file], itemUpdateCallback);
});
this.addFilesToUploadQueue(filesArray, itemUpdateCallback);
};

/**
Expand All @@ -448,21 +446,22 @@ class ContentUploader extends Component<Props, State> {
* @private
* @param {Array<DataTransferItem | UploadDataTransferItemWithAPIOptions>} dataTransferItems
* @param {Function} itemUpdateCallback
* @returns {void}
* @returns {Promise<any>}
*/
addPackageDataTransferItemsToUploadQueue = (
addPackageDataTransferItemsToUploadQueue = async (
dataTransferItems: Array<DataTransferItem | UploadDataTransferItemWithAPIOptions>,
itemUpdateCallback: Function,
): void => {
dataTransferItems.forEach(item => {
const file = getPackageFileFromDataTransferItem(item);

if (!file) {
return;
): Promise<any> => {
const packageFiles = await Promise.all(
dataTransferItems.map(async item => getPackageFileFromDataTransferItem(item)),
);
const packageFilesArray = [];
packageFiles.forEach(packageFile => {
if (packageFile) {
packageFilesArray.push(packageFile);
}

this.addFilesToUploadQueue([file], itemUpdateCallback);
});
this.addFilesToUploadQueue(packageFilesArray, itemUpdateCallback);
};

/**
Expand Down Expand Up @@ -494,11 +493,28 @@ class ContentUploader extends Component<Props, State> {

const fileAPIOptions: Object = getDataTransferItemAPIOptions(newItems[0]);
const { folderId = rootFolderId } = fileAPIOptions;
newItems.forEach(async item => {
const folderUpload = this.getFolderUploadAPI(folderId);
await folderUpload.buildFolderTreeFromDataTransferItem(item);
this.addFolderToUploadQueue(folderUpload, itemUpdateCallback, fileAPIOptions);
const folderUploads = await Promise.all(
newItems.map(async item => {
const folderUpload = this.getFolderUploadAPI(folderId);
await folderUpload.buildFolderTreeFromDataTransferItem(item);
return folderUpload;
}),
);
const folderUploadsArray = [];
folderUploads.forEach(folderUpload => {
// $FlowFixMe no file property
folderUploadsArray.push({
api: folderUpload,
extension: '',
isFolder: true,
name: folderUpload.folder.name,
options: fileAPIOptions,
progress: 0,
size: 1,
status: STATUS_PENDING,
});
});
this.addToQueue(folderUploadsArray, itemUpdateCallback);
};

/**
Expand Down
53 changes: 53 additions & 0 deletions src/elements/content-uploader/__tests__/ContentUploader.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -649,4 +649,57 @@ describe('elements/content-uploader/ContentUploader', () => {
expect(instance.addFilesToUploadQueue).not.toHaveBeenCalled();
});
});

describe('addFileDataTransferItemsToUploadQueue()', () => {
test('should pass multiple files to the upload queue', async () => {
jest.spyOn(UploaderUtils, 'getFileFromDataTransferItem').mockResolvedValue(() => 'file');

const itemsLength = 3;
const wrapper = getWrapper();
const instance = wrapper.instance();
instance.addFilesToUploadQueue = jest.fn();

const files = createMockFiles(itemsLength);
await instance.addFileDataTransferItemsToUploadQueue(files, jest.fn());
expect(instance.addFilesToUploadQueue).toBeCalledTimes(1);
expect(instance.addFilesToUploadQueue.mock.calls[0][0].length).toBe(itemsLength);
});
});

describe('addPackageDataTransferItemsToUploadQueue()', () => {
test('should pass multiple packages to the upload queue', async () => {
jest.spyOn(UploaderUtils, 'getPackageFileFromDataTransferItem').mockResolvedValue(() => 'package');

const itemsLength = 3;
const wrapper = getWrapper();
const instance = wrapper.instance();
instance.addFilesToUploadQueue = jest.fn();

const files = createMockFiles(itemsLength);
await instance.addPackageDataTransferItemsToUploadQueue(files, jest.fn());
expect(instance.addFilesToUploadQueue).toBeCalledTimes(1);
expect(instance.addFilesToUploadQueue.mock.calls[0][0].length).toBe(itemsLength);
});
});

describe('addFolderDataTransferItemsToUploadQueue()', () => {
test('should pass multiple folders to the upload queue', async () => {
jest.spyOn(UploaderUtils, 'getDataTransferItemId').mockResolvedValue(() => 'folder123');
jest.spyOn(UploaderUtils, 'getDataTransferItemAPIOptions').mockResolvedValue(() => {});

const wrapper = getWrapper();
const instance = wrapper.instance();
const mockFoldersList = ['folder1', 'folder2'];
const mockFolderUpload = { folder: { name: 'mockFolder' } };
mockFolderUpload.buildFolderTreeFromDataTransferItem = jest.fn();

instance.addToQueue = jest.fn();
instance.getFolderUploadAPI = jest.fn().mockReturnValue(mockFolderUpload);
instance.getNewDataTransferItems = jest.fn().mockReturnValue(mockFoldersList);

await instance.addFolderDataTransferItemsToUploadQueue(mockFoldersList, jest.fn());
expect(instance.addToQueue).toBeCalledTimes(1);
expect(instance.addToQueue.mock.calls[0][0].length).toBe(mockFoldersList.length);
});
});
});

0 comments on commit 36d02ac

Please sign in to comment.