486819f80b
- der Merkzettel wird geleert, wenn neu abgelegt wird und nichts mehr laeuft, nach jedem Loeschen, Verschieben und Umbenennen in der Ansicht und wenn ein Hochladen mit pathConflict/notFound scheitert (dann legt "Erneut versuchen" den Ordner wieder an) - innerhalb einer Ablage wird jeder Ordner weiter nur einmal angelegt - Hook-Tests fuer alle drei Wege Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
90 lines
3.7 KiB
TypeScript
90 lines
3.7 KiB
TypeScript
import { act, renderHook, waitFor } from '@testing-library/react';
|
|
import { beforeEach, describe, expect, it, vi } from 'vitest';
|
|
import { NextcloudFilesRequestError } from '@/lib/nextcloud-files-api';
|
|
import { useTransfers } from './use-transfers';
|
|
|
|
const mockCreate = vi.fn();
|
|
const mockUpload = vi.fn();
|
|
|
|
vi.mock('@/lib/nextcloud-files-api', async (importOriginal) => {
|
|
const actual = await importOriginal<typeof import('@/lib/nextcloud-files-api')>();
|
|
return {
|
|
...actual,
|
|
createFolder: (...a: unknown[]) => mockCreate(...a),
|
|
listFolder: vi.fn(),
|
|
};
|
|
});
|
|
vi.mock('@/lib/nextcloud-files-upload', () => ({
|
|
uploadFile: (...a: unknown[]) => mockUpload(...a),
|
|
}));
|
|
|
|
const file = (name: string) => new File(['x'], name);
|
|
|
|
beforeEach(() => {
|
|
mockCreate.mockReset().mockResolvedValue({ path: '/A' });
|
|
mockUpload.mockReset().mockResolvedValue({ path: '/A/a.txt', size: 1 });
|
|
});
|
|
|
|
describe('useTransfers — Ordner-Merkzettel (WR-07)', () => {
|
|
it('eine neue Ablage nach dem Ende der vorigen legt den Ordner erneut an (er kann inzwischen geloescht sein)', async () => {
|
|
const { result } = renderHook(() => useTransfers({ quotaAvailable: null }));
|
|
act(() => result.current.enqueue([{ file: file('a.txt'), relativeDir: 'A' }], '/'));
|
|
await waitFor(() => expect(result.current.transfers[0]?.status).toBe('done'));
|
|
expect(mockCreate).toHaveBeenCalledTimes(1);
|
|
expect(mockCreate).toHaveBeenLastCalledWith('/A');
|
|
|
|
act(() => result.current.enqueue([{ file: file('b.txt'), relativeDir: 'A' }], '/'));
|
|
await waitFor(() => expect(result.current.transfers[1]?.status).toBe('done'));
|
|
expect(mockCreate).toHaveBeenCalledTimes(2);
|
|
});
|
|
|
|
it('innerhalb einer Ablage wird jeder Ordner nur einmal angelegt', async () => {
|
|
const { result } = renderHook(() => useTransfers({ quotaAvailable: null }));
|
|
act(() =>
|
|
result.current.enqueue(
|
|
[
|
|
{ file: file('a.txt'), relativeDir: 'A' },
|
|
{ file: file('b.txt'), relativeDir: 'A' },
|
|
{ file: file('c.txt'), relativeDir: 'A' },
|
|
],
|
|
'/',
|
|
),
|
|
);
|
|
await waitFor(() =>
|
|
expect(result.current.transfers.every((t) => t.status === 'done')).toBe(true),
|
|
);
|
|
expect(mockCreate).toHaveBeenCalledTimes(1);
|
|
});
|
|
|
|
it('forgetFolders und ein Hochladen mit pathConflict leeren den Merkzettel', async () => {
|
|
let release!: () => void;
|
|
const hold = new Promise<void>((r) => {
|
|
release = r;
|
|
});
|
|
mockUpload
|
|
.mockImplementationOnce(async () => {
|
|
await hold;
|
|
return { path: '/A/a.txt', size: 1 };
|
|
})
|
|
.mockRejectedValueOnce(new NextcloudFilesRequestError(409, 'pathConflict', 'fehlt'))
|
|
.mockResolvedValue({ path: '/A/c.txt', size: 1 });
|
|
const { result } = renderHook(() => useTransfers({ quotaAvailable: null }));
|
|
// Die erste Datei laeuft noch: die zweite Ablage nutzt den Merkzettel.
|
|
act(() => result.current.enqueue([{ file: file('a.txt'), relativeDir: 'A' }], '/'));
|
|
await waitFor(() => expect(mockUpload).toHaveBeenCalledTimes(1));
|
|
act(() => result.current.enqueue([{ file: file('b.txt'), relativeDir: 'A' }], '/'));
|
|
await waitFor(() => expect(result.current.transfers[1]?.status).toBe('error'));
|
|
expect(mockCreate).toHaveBeenCalledTimes(1);
|
|
// pathConflict: "Erneut versuchen" legt den Ordner wieder an.
|
|
act(() => result.current.retry(result.current.transfers[1].id));
|
|
await waitFor(() => expect(result.current.transfers[1]?.status).toBe('done'));
|
|
expect(mockCreate).toHaveBeenCalledTimes(2);
|
|
|
|
act(() => result.current.forgetFolders());
|
|
act(() => result.current.enqueue([{ file: file('c.txt'), relativeDir: 'A' }], '/'));
|
|
await waitFor(() => expect(result.current.transfers[2]?.status).toBe('done'));
|
|
expect(mockCreate).toHaveBeenCalledTimes(3);
|
|
release();
|
|
});
|
|
});
|