veza/apps/web/src/components/ui/LoadingState.test.tsx
senke 8365cbfa6f refactor: LoadingState delegates all spinner rendering to LoadingSpinner
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-12 22:23:16 +01:00

121 lines
3.8 KiB
TypeScript

import { describe, it, expect } from 'vitest';
import { render, screen } from '@testing-library/react';
import { LoadingState, LoadingStateWrapper } from './LoadingState';
describe('LoadingState', () => {
describe('spinner variant (default)', () => {
it('should render spinner when isLoading is true', () => {
render(<LoadingState isLoading />);
expect(screen.getByRole('status')).toBeInTheDocument();
});
it('should render default text', () => {
render(<LoadingState isLoading />);
expect(screen.getByText('Chargement...', { selector: 'p' })).toBeInTheDocument();
});
it('should render custom text', () => {
render(<LoadingState isLoading text="Loading data..." />);
expect(screen.getByText('Loading data...', { selector: 'p' })).toBeInTheDocument();
});
it('should render children when isLoading is false', () => {
render(
<LoadingState isLoading={false}>
<div>Content loaded</div>
</LoadingState>,
);
expect(screen.getByText('Content loaded')).toBeInTheDocument();
expect(screen.queryByRole('status')).not.toBeInTheDocument();
});
});
describe('inline variant', () => {
it('should render inline spinner with text', () => {
render(<LoadingState isLoading variant="inline" text="Saving..." />);
// The visible text span (not the sr-only from LoadingSpinner)
expect(screen.getByText('Saving...', { selector: 'span:not(.sr-only)' })).toBeInTheDocument();
});
});
describe('skeleton variant', () => {
it('should render skeleton placeholders', () => {
const { container } = render(<LoadingState isLoading variant="skeleton" />);
expect(container.querySelector('.animate-pulse')).toBeInTheDocument();
});
it('should render children as skeleton content', () => {
render(
<LoadingState isLoading variant="skeleton">
<div data-testid="skeleton-content">Skeleton child</div>
</LoadingState>,
);
expect(screen.getByTestId('skeleton-content')).toBeInTheDocument();
});
});
describe('minimal variant', () => {
it('should render minimal spinner with role status', () => {
render(<LoadingState isLoading variant="minimal" />);
expect(screen.getByRole('status')).toBeInTheDocument();
});
});
describe('showSkeleton prop', () => {
it('should show skeleton when showSkeleton is true', () => {
const { container } = render(<LoadingState showSkeleton variant="skeleton" />);
expect(container.querySelector('.animate-pulse')).toBeInTheDocument();
});
});
it('should apply custom className', () => {
const { container } = render(
<LoadingState isLoading className="custom-class" />,
);
expect(container.querySelector('.custom-class')).toBeInTheDocument();
});
});
describe('LoadingStateWrapper', () => {
it('should show loading state when isLoading is true', () => {
render(
<LoadingStateWrapper isLoading>
<div>Child content</div>
</LoadingStateWrapper>,
);
expect(screen.getByRole('status')).toBeInTheDocument();
expect(screen.queryByText('Child content')).not.toBeInTheDocument();
});
it('should show children when isLoading is false', () => {
render(
<LoadingStateWrapper isLoading={false}>
<div>Child content</div>
</LoadingStateWrapper>,
);
expect(screen.getByText('Child content')).toBeInTheDocument();
expect(screen.queryByRole('status')).not.toBeInTheDocument();
});
it('should support custom loading variant', () => {
render(
<LoadingStateWrapper isLoading loadingVariant="inline" text="Wait...">
<div>Child</div>
</LoadingStateWrapper>,
);
expect(screen.getByText('Wait...', { selector: 'span:not(.sr-only)' })).toBeInTheDocument();
});
});