veza/apps/web/src/components/ui/optimized-image.test.tsx

87 lines
2 KiB
TypeScript

import { render, screen, waitFor } from '@testing-library/react';
import { describe, it, expect, vi, beforeEach } from 'vitest';
import { OptimizedImage } from './optimized-image';
// Mock useIntersectionObserver
vi.mock('@/hooks/useIntersectionObserver', () => ({
useIntersectionObserver: () => ({ isIntersecting: true }),
}));
describe('OptimizedImage Component', () => {
beforeEach(() => {
vi.clearAllMocks();
});
it('renders image with src', async () => {
render(
<OptimizedImage
src="test.jpg"
alt="Test image"
/>
);
await waitFor(() => {
const image = screen.getByAltText('Test image');
expect(image).toBeInTheDocument();
});
});
it('renders placeholder while loading', () => {
render(
<OptimizedImage
src="test.jpg"
alt="Test"
placeholder={<div>Loading...</div>}
/>
);
// Placeholder might show briefly
expect(screen.getByAltText('Test')).toBeInTheDocument();
});
it('renders fallback on error', async () => {
render(
<OptimizedImage
src="invalid.jpg"
alt="Test"
fallback={<div>Image not available</div>}
/>
);
// Wait for error handling
await waitFor(() => {
// The component should handle errors gracefully
const image = screen.getByAltText('Test');
expect(image).toBeInTheDocument();
}, { timeout: 1000 });
});
it('applies custom className', () => {
const { container } = render(
<OptimizedImage
src="test.jpg"
alt="Test"
className="custom-class"
/>
);
const picture = container.querySelector('picture');
expect(picture).toHaveClass('custom-class');
});
it('renders with width and height', () => {
render(
<OptimizedImage
src="test.jpg"
alt="Test"
width={200}
height={200}
/>
);
const image = screen.getByAltText('Test');
expect(image).toHaveAttribute('width', '200');
expect(image).toHaveAttribute('height', '200');
});
});