/**
* Tests for the EditArchiveModal component.
*/
import { describe, it, expect, vi, beforeEach } from 'vitest';
import { screen, waitFor } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import { render } from '../utils';
import { EditArchiveModal } from '../../components/EditArchiveModal';
import { http, HttpResponse } from 'msw';
import { server } from '../mocks/server';
const mockArchive = {
id: 1,
filename: 'benchy.gcode.3mf',
print_name: 'Benchy',
printer_id: 1,
printer_name: 'X1 Carbon',
notes: 'Test notes',
rating: 4,
project_id: null,
tags: 'test,calibration',
};
const mockProjects = [
{ id: 1, name: 'Functional Parts', color: '#00ae42' },
{ id: 2, name: 'Art', color: '#ff5500' },
];
describe('EditArchiveModal', () => {
const mockOnClose = vi.fn();
const mockOnSave = vi.fn();
beforeEach(() => {
vi.clearAllMocks();
server.use(
http.get('/api/v1/projects/', () => {
return HttpResponse.json(mockProjects);
}),
http.get('/api/v1/archives/tags', () => {
return HttpResponse.json([
{ name: 'test', count: 2 },
{ name: 'calibration', count: 1 },
{ name: 'functional', count: 3 },
]);
}),
http.patch('/api/v1/archives/:id', async ({ request }) => {
const body = await request.json();
return HttpResponse.json({ ...mockArchive, ...body });
})
);
});
describe('rendering', () => {
it('renders the modal title', () => {
render(
);
expect(screen.getByText(/edit/i)).toBeInTheDocument();
});
it('shows print name field', async () => {
render(
);
await waitFor(() => {
// Name field should be present
const nameInput = screen.getByDisplayValue('Benchy');
expect(nameInput).toBeInTheDocument();
});
});
it('shows notes field', async () => {
render(
);
await waitFor(() => {
const notesField = screen.getByDisplayValue('Test notes');
expect(notesField).toBeInTheDocument();
});
});
it('shows rating selector', async () => {
render(
);
await waitFor(() => {
// Rating may be shown as stars or dropdown
expect(screen.getByText(/edit/i)).toBeInTheDocument();
});
});
it('shows project selector', async () => {
render(
);
await waitFor(() => {
// Project section should be present
expect(screen.getByText(/edit/i)).toBeInTheDocument();
});
});
it('shows tags input', () => {
render(
);
expect(screen.getByText(/tags/i)).toBeInTheDocument();
});
});
describe('existing values', () => {
it('shows existing tags', () => {
render(
);
expect(screen.getByText('test')).toBeInTheDocument();
expect(screen.getByText('calibration')).toBeInTheDocument();
});
});
describe('actions', () => {
it('has save button', () => {
render(
);
expect(screen.getByRole('button', { name: /save/i })).toBeInTheDocument();
});
it('has cancel button', () => {
render(
);
expect(screen.getByRole('button', { name: /cancel/i })).toBeInTheDocument();
});
it('calls onClose when cancel is clicked', async () => {
const user = userEvent.setup();
render(
);
await user.click(screen.getByRole('button', { name: /cancel/i }));
expect(mockOnClose).toHaveBeenCalled();
});
it('can edit print name', async () => {
const user = userEvent.setup();
render(
);
const nameInput = screen.getByDisplayValue('Benchy');
await user.clear(nameInput);
await user.type(nameInput, 'New Name');
expect(nameInput).toHaveValue('New Name');
});
});
});