| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302 |
- /**
- * Tests for External Folder functionality in FileManagerPage.
- */
- import { describe, it, expect, beforeEach } from 'vitest';
- import { screen, waitFor } from '@testing-library/react';
- import userEvent from '@testing-library/user-event';
- import { render } from '../utils';
- import { FileManagerPage } from '../../pages/FileManagerPage';
- import { http, HttpResponse } from 'msw';
- import { server } from '../mocks/server';
- // Mock data with external folder
- const mockFoldersWithExternal = [
- {
- id: 1,
- name: 'Regular Folder',
- parent_id: null,
- file_count: 3,
- project_id: null,
- archive_id: null,
- project_name: null,
- archive_name: null,
- is_external: false,
- external_path: null,
- external_readonly: false,
- children: [],
- },
- {
- id: 2,
- name: 'NAS Prints',
- parent_id: null,
- file_count: 5,
- project_id: null,
- archive_id: null,
- project_name: null,
- archive_name: null,
- is_external: true,
- external_path: '/mnt/nas/prints',
- external_readonly: true,
- children: [],
- },
- {
- id: 3,
- name: 'USB Drive',
- parent_id: null,
- file_count: 2,
- project_id: null,
- archive_id: null,
- project_name: null,
- archive_name: null,
- is_external: true,
- external_path: '/mnt/usb',
- external_readonly: false,
- children: [],
- },
- ];
- const mockFiles = [
- {
- id: 1,
- filename: 'benchy.3mf',
- file_path: '/mnt/nas/prints/benchy.3mf',
- file_size: 1048576,
- file_type: '3mf',
- folder_id: 2,
- is_external: true,
- thumbnail_path: null,
- print_name: 'Benchy',
- print_time_seconds: 3600,
- print_count: 0,
- duplicate_count: 0,
- created_at: '2024-01-01T00:00:00Z',
- },
- ];
- const mockStats = {
- total_files: 10,
- total_folders: 3,
- total_size_bytes: 104857600,
- disk_free_bytes: 10737418240,
- disk_total_bytes: 107374182400,
- };
- describe('FileManagerPage - External Folders', () => {
- beforeEach(() => {
- localStorage.clear();
- server.use(
- http.get('/api/v1/library/folders', () => {
- return HttpResponse.json(mockFoldersWithExternal);
- }),
- http.get('/api/v1/library/files', () => {
- return HttpResponse.json(mockFiles);
- }),
- http.get('/api/v1/library/stats', () => {
- return HttpResponse.json(mockStats);
- }),
- http.get('/api/v1/settings/', () => {
- return HttpResponse.json({
- check_updates: false,
- check_printer_firmware: false,
- library_disk_warning_gb: 5,
- });
- }),
- http.post('/api/v1/library/folders/external', async ({ request }) => {
- const body = await request.json() as { name: string; external_path: string };
- return HttpResponse.json({
- id: 10,
- name: body.name,
- parent_id: null,
- is_external: true,
- external_path: body.external_path,
- external_readonly: true,
- external_show_hidden: false,
- file_count: 0,
- created_at: '2024-01-01T00:00:00Z',
- updated_at: '2024-01-01T00:00:00Z',
- });
- }),
- http.post('/api/v1/library/folders/:id/scan', () => {
- return HttpResponse.json({ status: 'success', added: 3, removed: 0 });
- }),
- http.get('/api/v1/projects/', () => {
- return HttpResponse.json([]);
- }),
- http.get('/api/v1/archives/', () => {
- return HttpResponse.json([]);
- }),
- http.delete('/api/v1/library/folders/:id', () => {
- return HttpResponse.json({ success: true });
- }),
- http.delete('/api/v1/library/files/:id', () => {
- return HttpResponse.json({ success: true });
- }),
- http.post('/api/v1/library/files/move', () => {
- return HttpResponse.json({ success: true });
- }),
- );
- });
- describe('rendering', () => {
- it('shows Link External button', async () => {
- render(<FileManagerPage />);
- await waitFor(() => {
- expect(screen.getByText('Link External')).toBeInTheDocument();
- });
- });
- it('shows external folder in sidebar', async () => {
- render(<FileManagerPage />);
- await waitFor(() => {
- expect(screen.getByText('NAS Prints')).toBeInTheDocument();
- expect(screen.getByText('USB Drive')).toBeInTheDocument();
- });
- });
- it('shows regular folder alongside external', async () => {
- render(<FileManagerPage />);
- await waitFor(() => {
- expect(screen.getByText('Regular Folder')).toBeInTheDocument();
- expect(screen.getByText('NAS Prints')).toBeInTheDocument();
- });
- });
- it('shows read-only indicator for readonly external folders', async () => {
- render(<FileManagerPage />);
- await waitFor(() => {
- // NAS Prints is readonly, should have a lock icon title
- const lockIcons = document.querySelectorAll('[title="Read Only"]');
- expect(lockIcons.length).toBeGreaterThan(0);
- });
- });
- });
- describe('external folder modal', () => {
- it('opens modal when Link External clicked', async () => {
- const user = userEvent.setup();
- render(<FileManagerPage />);
- await waitFor(() => {
- expect(screen.getByText('Link External')).toBeInTheDocument();
- });
- await user.click(screen.getByText('Link External'));
- await waitFor(() => {
- expect(screen.getByText('Link External Folder')).toBeInTheDocument();
- });
- });
- it('modal has name and path fields', async () => {
- const user = userEvent.setup();
- render(<FileManagerPage />);
- await waitFor(() => {
- expect(screen.getByText('Link External')).toBeInTheDocument();
- });
- await user.click(screen.getByText('Link External'));
- await waitFor(() => {
- expect(screen.getByPlaceholderText('e.g., NAS Prints')).toBeInTheDocument();
- expect(screen.getByPlaceholderText('/mnt/nas/3d-prints')).toBeInTheDocument();
- });
- });
- it('modal has readonly checkbox checked by default', async () => {
- const user = userEvent.setup();
- render(<FileManagerPage />);
- await waitFor(() => {
- expect(screen.getByText('Link External')).toBeInTheDocument();
- });
- await user.click(screen.getByText('Link External'));
- await waitFor(() => {
- const readonlyCheckbox = screen.getByText('Read Only').previousElementSibling as HTMLInputElement;
- expect(readonlyCheckbox).toBeChecked();
- });
- });
- it('modal can be closed', async () => {
- const user = userEvent.setup();
- render(<FileManagerPage />);
- await waitFor(() => {
- expect(screen.getByText('Link External')).toBeInTheDocument();
- });
- await user.click(screen.getByText('Link External'));
- await waitFor(() => {
- expect(screen.getByText('Link External Folder')).toBeInTheDocument();
- });
- await user.click(screen.getByText('Cancel'));
- await waitFor(() => {
- expect(screen.queryByText('Link External Folder')).not.toBeInTheDocument();
- });
- });
- });
- describe('external folder info bar', () => {
- it('shows info bar when external folder selected', async () => {
- const user = userEvent.setup();
- render(<FileManagerPage />);
- await waitFor(() => {
- expect(screen.getByText('NAS Prints')).toBeInTheDocument();
- });
- // Click on NAS Prints folder - there are multiple elements, get the one in the sidebar
- const folderElements = screen.getAllByText('NAS Prints');
- await user.click(folderElements[0]);
- await waitFor(() => {
- expect(screen.getByText('External Folder')).toBeInTheDocument();
- expect(screen.getByText('/mnt/nas/prints')).toBeInTheDocument();
- });
- });
- it('shows scan button for external folders', async () => {
- const user = userEvent.setup();
- render(<FileManagerPage />);
- await waitFor(() => {
- expect(screen.getByText('NAS Prints')).toBeInTheDocument();
- });
- const folderElements = screen.getAllByText('NAS Prints');
- await user.click(folderElements[0]);
- await waitFor(() => {
- expect(screen.getByText('Scan')).toBeInTheDocument();
- });
- });
- it('does not show info bar for regular folders', async () => {
- const user = userEvent.setup();
- render(<FileManagerPage />);
- await waitFor(() => {
- expect(screen.getByText('Regular Folder')).toBeInTheDocument();
- });
- const folderElements = screen.getAllByText('Regular Folder');
- await user.click(folderElements[0]);
- // External Folder label should NOT appear
- await waitFor(() => {
- expect(screen.queryByText('External Folder')).not.toBeInTheDocument();
- });
- });
- });
- });
|