All files / lib files.js

82.35% Statements 14/17
73.33% Branches 11/15
100% Functions 3/3
100% Lines 12/12

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58                2x 2x 2x 2x   2x 2x 2x 2x 2x 2x 2x   2x                                                                        
/**
 *
 * @param {object} [param0 ]
 * @param {string | string[]} [param0.accept] - accepted file types, e.g. "image/*,.pdf"
 * @param {boolean} [param0.multiple] - allow multiple file selection
 * @returns {Promise<File[]>} - selected files
 */
export async function promptForFiles({ accept = '', multiple = false } = {}) {
	const input = document.createElement('input');
	input.type = 'file';
	Eif (accept) input.accept = typeof accept === 'string' ? accept : accept.join(',');
	if (multiple) input.multiple = true;
 
	return new Promise((resolve) => {
		input.addEventListener('change', (event) => {
			Iif (!(event.currentTarget instanceof HTMLInputElement)) return;
			Iif (!event.currentTarget.files) return;
			const files = Array.from(event.currentTarget.files);
			Iif (files.length === 0) return;
			resolve(files);
		});
		input.click();
	});
}
 
if (import.meta.vitest) {
	const { it, expect, vi } = import.meta.vitest;
	it('promptForFiles', async () => {
		const mockFiles = [new File(['content'], 'test.txt', { type: 'text/plain' })];
 
		// Mock the input.click() to trigger change event with mock files
		const origClick = HTMLInputElement.prototype.click;
		HTMLInputElement.prototype.click = function () {
			if (this.type === 'file') {
				// Use Object.defineProperty to set files on the input
				Object.defineProperty(this, 'files', {
					value: mockFiles,
					writable: false,
				});
				// Dispatch change event
				const event = new Event('change', { bubbles: true });
				Object.defineProperty(event, 'currentTarget', { value: this, writable: false });
				this.dispatchEvent(event);
			}
		};
 
		const result = await promptForFiles({ accept: 'text/*', multiple: false });
 
		expect(result).toEqual(mockFiles);
 
		// Test with array of accept types
		const result2 = await promptForFiles({ accept: ['.jpg', '.png'], multiple: true });
		expect(result2).toEqual(mockFiles);
 
		HTMLInputElement.prototype.click = origClick;
	});
}