RestoreModal.test.tsx 2.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889
  1. /**
  2. * Tests for the RestoreModal component.
  3. */
  4. import { describe, it, expect, vi, beforeEach } from 'vitest';
  5. import { screen, waitFor } from '@testing-library/react';
  6. import userEvent from '@testing-library/user-event';
  7. import { render } from '../utils';
  8. import { RestoreModal } from '../../components/RestoreModal';
  9. import { http, HttpResponse } from 'msw';
  10. import { server } from '../mocks/server';
  11. describe('RestoreModal', () => {
  12. const mockOnClose = vi.fn();
  13. const mockOnRestore = vi.fn();
  14. const mockOnSuccess = vi.fn();
  15. beforeEach(() => {
  16. vi.clearAllMocks();
  17. server.use(
  18. http.post('/api/v1/settings/restore', () => {
  19. return HttpResponse.json({ success: true });
  20. })
  21. );
  22. });
  23. describe('rendering', () => {
  24. it('renders the modal title', () => {
  25. render(<RestoreModal onClose={mockOnClose} onRestore={mockOnRestore} onSuccess={mockOnSuccess} />);
  26. // Title is "Restore Backup"
  27. expect(screen.getByText('Restore Backup')).toBeInTheDocument();
  28. });
  29. it('shows file upload area', () => {
  30. render(<RestoreModal onClose={mockOnClose} onRestore={mockOnRestore} onSuccess={mockOnSuccess} />);
  31. expect(screen.getByText(/select.*file/i)).toBeInTheDocument();
  32. });
  33. it('shows cancel button', () => {
  34. render(<RestoreModal onClose={mockOnClose} onRestore={mockOnRestore} onSuccess={mockOnSuccess} />);
  35. expect(screen.getByRole('button', { name: /cancel/i })).toBeInTheDocument();
  36. });
  37. });
  38. describe('file input', () => {
  39. it('accepts backup files', () => {
  40. render(<RestoreModal onClose={mockOnClose} onRestore={mockOnRestore} onSuccess={mockOnSuccess} />);
  41. const fileInput = document.querySelector('input[type="file"]');
  42. expect(fileInput).toBeInTheDocument();
  43. });
  44. });
  45. describe('actions', () => {
  46. it('calls onClose when cancel is clicked', async () => {
  47. const user = userEvent.setup();
  48. render(<RestoreModal onClose={mockOnClose} onRestore={mockOnRestore} onSuccess={mockOnSuccess} />);
  49. await user.click(screen.getByRole('button', { name: /cancel/i }));
  50. expect(mockOnClose).toHaveBeenCalled();
  51. });
  52. });
  53. describe('overwrite option', () => {
  54. it('has overwrite toggle', () => {
  55. render(<RestoreModal onClose={mockOnClose} onRestore={mockOnRestore} onSuccess={mockOnSuccess} />);
  56. // The modal has toggle for replacing existing data
  57. expect(screen.getByText('Keep existing data')).toBeInTheDocument();
  58. });
  59. it('shows warning when overwrite is enabled', async () => {
  60. const user = userEvent.setup();
  61. render(<RestoreModal onClose={mockOnClose} onRestore={mockOnRestore} onSuccess={mockOnSuccess} />);
  62. // Find and click the toggle (uses role="switch")
  63. const toggle = screen.getByRole('switch');
  64. await user.click(toggle);
  65. await waitFor(() => {
  66. expect(screen.getByText(/Caution/)).toBeInTheDocument();
  67. });
  68. });
  69. });
  70. });