diff --git a/frontend/__tests__/unit/components/LoadingSpinner.test.tsx b/frontend/__tests__/unit/components/LoadingSpinner.test.tsx new file mode 100644 index 0000000000..eaff3d04e5 --- /dev/null +++ b/frontend/__tests__/unit/components/LoadingSpinner.test.tsx @@ -0,0 +1,72 @@ +import { render, screen } from '@testing-library/react' +import LoadingSpinner from 'components/LoadingSpinner' + +jest.mock('next/image', () => ({ + __esModule: true, + // eslint-disable-next-line @next/next/no-img-element, jsx-a11y/alt-text + default: (props) => , +})) + +describe('', () => { + it('renders without crashing', () => { + render() + const images = screen.getAllByAltText('Loading indicator') + expect(images.length).toBe(2) // One for light, one for dark + }) + + it('handles invalid imageUrl input gracefully', () => { + // With the original component, we test that it works with undefined/null + render() + const images = screen.getAllByAltText('Loading indicator') + expect(images.length).toBe(2) + // Should fallback to default images when no valid input is provided + expect(images[0].getAttribute('src')).toContain('white') + expect(images[1].getAttribute('src')).toContain('black') + }) + it('has appropriate alt text for accessibility', () => { + render() + const images = screen.getAllByAltText('Loading indicator') + expect(images.length).toBe(2) + }) + it('applies correct Tailwind classes for dark/light mode', () => { + render() + const images = screen.getAllByAltText('Loading indicator') + + // First image should be for dark mode (hidden in light, visible in dark) + expect(images[0]).toHaveClass('hidden', 'rounded-full', 'dark:block') + + // Second image should be for light mode (visible in light, hidden in dark) + expect(images[1]).toHaveClass('rounded-full', 'dark:hidden') + }) + + it('renders default image if no imageUrl is provided', () => { + render() + const images = screen.getAllByAltText('Loading indicator') + expect(images[0].getAttribute('src')).toContain('white') // dark image + expect(images[1].getAttribute('src')).toContain('black') // light image + }) + + it('renders custom image when imageUrl is provided', () => { + const customUrl = '/img/spinner_white.png' + render() + const images = screen.getAllByAltText('Loading indicator') + expect(images[0].getAttribute('src')).toBe(customUrl) // Should use the exact custom URL + expect(images[1].getAttribute('src')).toBe('/img/spinner_black.png') // Should transform white to black + }) + + it('renders spinner container with correct styles', () => { + render() + const fadeContainer = document.querySelector('.animate-fade-in-out') + expect(fadeContainer).toBeInTheDocument() + expect(fadeContainer?.className).toContain('animate-fade-in-out') + }) + + it('has appropriate alt text and accessibility image role', () => { + render() + const images = screen.getAllByAltText('Loading indicator') + expect(images[0]).toBeInTheDocument() + expect(images[0].tagName.toLowerCase()).toBe('img') + expect(images[1]).toBeInTheDocument() + expect(images[1].tagName.toLowerCase()).toBe('img') + }) +})