Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -956,6 +956,39 @@ describe('DotContentDriveShellComponent', () => {
});
});

it('should consume the file before resetting the input (live FileList)', () => {
// Regression: `input.files` is a LIVE FileList, so clearing `input.value` empties it.
// The component must consume the files BEFORE resetting the input; resetting first
// drops the selection and the upload silently no-ops (the real Chrome bug).
// jsdom doesn't model this, so we mock it faithfully: `.files` is one stable object
// that is emptied when `.value` is cleared.
uploadService.uploadFileByBaseType.mockReturnValue(of({} as DotCMSContentlet));
const file = createFile();
const fileInput = spectator.query('input[type="file"]') as HTMLInputElement;

const liveFiles: File[] = [file];
Object.defineProperty(fileInput, 'files', {
get: () => liveFiles as unknown as FileList,
configurable: true
});
Object.defineProperty(fileInput, 'value', {
get: () => (liveFiles.length ? 'C:\\fakepath\\test.png' : ''),
set: () => {
liveFiles.length = 0; // clearing the input empties the live FileList
},
configurable: true
});

selectUploadType({ targetFolder: TARGET_FOLDER_DATA, baseType: 'FILEASSET' });
spectator.triggerEventHandler('input[type="file"]', 'change', { target: fileInput });

expect(uploadService.uploadFileByBaseType).toHaveBeenCalledWith(file, 'FILEASSET', {
hostFolder: TARGET_FOLDER_DATA.id,
indexPolicy: 'WAIT_FOR'
});
expect(fileInput.value).toBe(''); // still reset afterwards
});

it('should not upload when the file picker is dismissed without files', () => {
const fileInput = spectator.query('input[type="file"]') as HTMLInputElement;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -430,15 +430,16 @@ export class DotContentDriveShellComponent implements OnInit {
const files = input.files;
const selection = this.$activeSelection();

// Always reset so a cancelled/re-opened picker can't reuse a stale selection.
this.$activeSelection.set(undefined);
input.value = '';

if (!files || files.length === 0 || !selection) {
return;
// Consume the files BEFORE resetting the input: `input.files` is a live FileList, so
// `input.value = ''` empties it. Resetting first would drop the selection and the upload
// would never fire (the file is captured synchronously into FormData by resolveFilesUpload).
if (files && files.length > 0 && selection) {
this.resolveFilesUpload({ ...selection, files });
}

this.resolveFilesUpload({ ...selection, files });
// Reset so a cancelled/re-opened picker can't reuse a stale selection.
this.$activeSelection.set(undefined);
input.value = '';
}

/**
Expand Down
Loading