diff --git a/apps/files/src/services/DropService.spec.ts b/apps/files/src/services/DropService.spec.ts new file mode 100644 index 0000000000000..3bf1d30003157 --- /dev/null +++ b/apps/files/src/services/DropService.spec.ts @@ -0,0 +1,85 @@ +/*! + * SPDX-FileCopyrightText: 2026 Nextcloud GmbH and Nextcloud contributors + * SPDX-License-Identifier: AGPL-3.0-or-later + */ + +import type { IFolder } from '@nextcloud/files' + +import { beforeEach, describe, expect, it, vi } from 'vitest' +import { onDropExternalFiles } from './DropService.ts' +import { createDirectoryIfNotExists, Directory } from './DropServiceUtils.ts' + +const { getUploaderMock, hasConflictMock } = vi.hoisted(() => { + return { + getUploaderMock: vi.fn(), + hasConflictMock: vi.fn(), + } +}) + +vi.mock('@nextcloud/dialogs', () => ({ + showError: vi.fn(), + showInfo: vi.fn(), + showSuccess: vi.fn(), + showWarning: vi.fn(), +})) + +vi.mock('@nextcloud/upload', () => ({ + getUploader: getUploaderMock, + hasConflict: hasConflictMock, +})) + +vi.mock('../logger.ts', () => ({ + default: { + debug: vi.fn(), + info: vi.fn(), + warn: vi.fn(), + error: vi.fn(), + }, +})) + +vi.mock('./DropServiceUtils.ts', async () => { + const actual = await vi.importActual('./DropServiceUtils.ts') + return { + ...actual, + createDirectoryIfNotExists: vi.fn(), + resolveConflict: vi.fn(async (files) => files), + } +}) + +describe('DropService onDropExternalFiles', () => { + const uploaderMock = { + pause: vi.fn(), + start: vi.fn(), + upload: vi.fn(async () => ({})), + } + + beforeEach(() => { + vi.clearAllMocks() + getUploaderMock.mockReturnValue(uploaderMock) + hasConflictMock.mockResolvedValue(false) + }) + + it('creates dropped directories under the destination path', async () => { + const root = new Directory('root') as Directory & { name: 'root' } + root.contents = [ + new Directory('py-vetlog-buddy-main', [ + new Directory('.venv', [ + new Directory('lib', [ + new File(['content'], 'hello.txt', { type: 'text/plain' }), + ]), + ]), + ]), + ] + + const destination = { + path: '/archive', + source: '/remote.php/dav/files/devadmin/archive', + } as unknown as IFolder + + await onDropExternalFiles(root, destination, []) + + expect(createDirectoryIfNotExists).toHaveBeenCalledWith('/archive/py-vetlog-buddy-main') + expect(createDirectoryIfNotExists).toHaveBeenCalledWith('/archive/py-vetlog-buddy-main/.venv') + expect(createDirectoryIfNotExists).toHaveBeenCalledWith('/archive/py-vetlog-buddy-main/.venv/lib') + }) +}) diff --git a/apps/files/src/services/DropService.ts b/apps/files/src/services/DropService.ts index 096ae48ca1fbd..7d2aa1c03a985 100644 --- a/apps/files/src/services/DropService.ts +++ b/apps/files/src/services/DropService.ts @@ -124,7 +124,7 @@ export async function onDropExternalFiles(root: RootDirectory, destination: IFol if (file instanceof Directory) { try { logger.debug('Processing directory', { relativePath }) - await createDirectoryIfNotExists(relativePath) + await createDirectoryIfNotExists(join(destination.path, relativePath)) await uploadDirectoryContents(file, relativePath) } catch (error) { showError(t('files', 'Unable to create the directory {directory}', { directory: file.name }))