import { render, screen, fireEvent } from '@testing-library/react'; import { describe, it, expect, vi } from 'vitest'; import { ImageViewerModal } from './ImageViewerModal'; describe('ImageViewerModal Component', () => { const mockOnClose = vi.fn(); const mockOnNext = vi.fn(); const mockOnPrev = vi.fn(); beforeEach(() => { vi.clearAllMocks(); }); it('renders image', () => { render( , ); const image = screen.getByAltText('Test image'); expect(image).toBeInTheDocument(); expect(image).toHaveAttribute('src', 'test.jpg'); }); it('calls onClose when close button is clicked', () => { render( , ); const closeButton = screen.getByTitle('Close'); fireEvent.click(closeButton); expect(mockOnClose).toHaveBeenCalled(); }); it('calls onClose when Escape key is pressed', () => { render( , ); fireEvent.keyDown(document, { key: 'Escape' }); expect(mockOnClose).toHaveBeenCalled(); }); it('calls onNext when ArrowRight key is pressed', () => { render( , ); fireEvent.keyDown(document, { key: 'ArrowRight' }); expect(mockOnNext).toHaveBeenCalled(); }); it('calls onPrev when ArrowLeft key is pressed', () => { render( , ); fireEvent.keyDown(document, { key: 'ArrowLeft' }); expect(mockOnPrev).toHaveBeenCalled(); }); it('does not call onNext on ArrowRight when hasNext is false', () => { render( , ); fireEvent.keyDown(document, { key: 'ArrowRight' }); expect(mockOnNext).not.toHaveBeenCalled(); }); it('shows next button when hasNext is true', () => { render( , ); const nextButton = screen.getByLabelText('Next image'); expect(nextButton).toBeInTheDocument(); }); it('calls onNext when next button is clicked', () => { render( , ); const nextButton = screen.getByLabelText('Next image'); fireEvent.click(nextButton); expect(mockOnNext).toHaveBeenCalled(); }); it('shows prev button when hasPrev is true', () => { render( , ); const prevButton = screen.getByLabelText('Previous image'); expect(prevButton).toBeInTheDocument(); }); it('uses default alt text when alt is not provided', () => { render(); expect(screen.getByText('Image Preview')).toBeInTheDocument(); }); it('shows image counter when currentIndex and totalImages are provided', () => { render( , ); expect(screen.getByText('2 / 5')).toBeInTheDocument(); }); it('does not show image counter for single images', () => { render( , ); expect(screen.queryByText('1 / 1')).not.toBeInTheDocument(); }); it('toggles zoom on image click', () => { render( , ); const image = screen.getByAltText('Test'); // Initially in fit mode (cursor-zoom-in) expect(image.className).toContain('cursor-zoom-in'); // Click to zoom fireEvent.click(image); expect(image.className).toContain('cursor-zoom-out'); // Click to unzoom fireEvent.click(image); expect(image.className).toContain('cursor-zoom-in'); }); });