Skip to content
Open
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
4 changes: 3 additions & 1 deletion apps/files/src/services/DropService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,9 @@ export async function dataTransferToFileTree(items: DataTransferItem[]): Promise

// Warn the user that the browser does not support the Filesystem API
// we therefore cannot upload directories recursively.
if (file.type === 'httpd/unix-directory' || !file.type) {
// Note: files with an unknown type are kept on purpose, the server
// detects their mime type on upload (content sniffing + extension map).
if (file.type === 'httpd/unix-directory') {
if (!warned) {
logger.warn('Browser does not support Filesystem API. Directories will not be uploaded')
showWarning(t('files', 'Your browser does not support the Filesystem API. Directories will not be uploaded'))
Expand Down
42 changes: 37 additions & 5 deletions apps/files/src/services/DropServiceUtils.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -196,7 +196,7 @@ describe('DropService dataTransferToFileTree', () => {
expect(logger.warn).not.toBeCalled()
})

it('Should return a RootDirectory with legacy File API ignoring recursive directories', async () => {
it('Should return a RootDirectory with legacy File API keeping unknown types', async () => {
vi.spyOn(logger, 'error').mockImplementation(() => vi.fn())
vi.spyOn(logger, 'warn').mockImplementation(() => vi.fn())

Expand All @@ -206,7 +206,9 @@ describe('DropService dataTransferToFileTree', () => {

expect(fileTree.name).toBe('root')
expect(fileTree).toBeInstanceOf(Directory)
expect(fileTree.contents).toHaveLength(1)
// file0.txt plus the two directories as empty files: unknown types are
// kept on purpose, the server detects their mime type on upload
expect(fileTree.contents).toHaveLength(3)

// The file tree should be recursive when using the Filesystem API
expect(fileTree.contents[0]).not.toBeInstanceOf(Directory)
Expand All @@ -215,8 +217,38 @@ describe('DropService dataTransferToFileTree', () => {
expect(logger.error).not.toBeCalled()
expect(logger.warn).toHaveBeenNthCalledWith(1, 'Could not get FilesystemEntry of item, falling back to file')
expect(logger.warn).toHaveBeenNthCalledWith(2, 'Could not get FilesystemEntry of item, falling back to file')
expect(logger.warn).toHaveBeenNthCalledWith(3, 'Browser does not support Filesystem API. Directories will not be uploaded')
expect(logger.warn).toHaveBeenNthCalledWith(4, 'Could not get FilesystemEntry of item, falling back to file')
expect(logger.warn).toHaveBeenCalledTimes(4)
expect(logger.warn).toHaveBeenNthCalledWith(3, 'Could not get FilesystemEntry of item, falling back to file')
expect(logger.warn).toHaveBeenCalledTimes(3)
})

it('Should keep files with an unknown mime type for server-side detection', async () => {
const { showWarning } = await import('@nextcloud/dialogs')
const file = new File(['data'], 'notes.unknown-ext', { type: '' })
const item = Object.create(DataTransferItemMock.prototype)
Object.defineProperties(item, {
kind: { value: 'file' },
getAsFile: { value: () => file },
})

const fileTree = await dataTransferToFileTree([item as unknown as DataTransferItem])

expect(fileTree.contents).toHaveLength(1)
expect(fileTree.contents[0].name).toBe('notes.unknown-ext')
expect(showWarning).not.toHaveBeenCalled()
})

it('Should still skip unix directories with a warning', async () => {
const { showWarning } = await import('@nextcloud/dialogs')
const file = new File([], 'mydir', { type: 'httpd/unix-directory' })
const item = Object.create(DataTransferItemMock.prototype)
Object.defineProperties(item, {
kind: { value: 'file' },
getAsFile: { value: () => file },
})

const fileTree = await dataTransferToFileTree([item as unknown as DataTransferItem])

expect(fileTree.contents).toHaveLength(0)
expect(showWarning).toHaveBeenCalledTimes(1)
})
})
Loading