import React from 'react' import { render, screen, fireEvent } from '@testing-library/react' import '@testing-library/jest-dom' import { Alert, AlertTitle, AlertDescription } from '../alert' describe('Alert Components', () => { describe('Alert Component', () => { describe('Basic Rendering', () => { it('renders correctly with default props', () => { render(Test alert) const alert = screen.getByTestId('alert') expect(alert).toBeInTheDocument() expect(alert).toHaveAttribute('role', 'alert') expect(alert).toHaveTextContent('Test alert') }) it('applies custom className', () => { render(Test) const alert = screen.getByTestId('alert') expect(alert).toHaveClass('custom-alert') }) it('forwards ref correctly', () => { const ref = React.createRef() render(Test) expect(ref.current).toBeInstanceOf(HTMLDivElement) }) it('maintains displayName', () => { expect(Alert.displayName).toBe('Alert') }) }) describe('Variants', () => { it('renders default variant correctly', () => { render(Test) const alert = screen.getByTestId('alert') expect(alert).toHaveClass('bg-background') expect(alert).toHaveClass('text-foreground') expect(alert).toHaveClass('border-border') }) it('renders primary variant correctly', () => { render(Test) const alert = screen.getByTestId('alert') expect(alert).toHaveClass('bg-primary/10') expect(alert).toHaveClass('text-primary') expect(alert).toHaveClass('border-primary/30') }) it('renders success variant correctly', () => { render(Test) const alert = screen.getByTestId('alert') expect(alert).toHaveClass('bg-success/10') expect(alert).toHaveClass('text-success') expect(alert).toHaveClass('border-success/30') }) it('renders warning variant correctly', () => { render(Test) const alert = screen.getByTestId('alert') expect(alert).toHaveClass('bg-warning/10') expect(alert).toHaveClass('text-warning') expect(alert).toHaveClass('border-warning/30') }) it('renders error variant correctly', () => { render(Test) const alert = screen.getByTestId('alert') expect(alert).toHaveClass('bg-destructive/10') expect(alert).toHaveClass('text-destructive') expect(alert).toHaveClass('border-destructive/30') }) it('renders info variant correctly', () => { render(Test) const alert = screen.getByTestId('alert') expect(alert).toHaveClass('bg-blue-500/10') expect(alert).toHaveClass('text-blue-500') expect(alert).toHaveClass('border-blue-500/30') }) it('uses default variant as default', () => { render(Test) const alert = screen.getByTestId('alert') expect(alert).toHaveClass('bg-background') expect(alert).toHaveClass('text-foreground') }) }) describe('Sizes', () => { it('renders sm size correctly', () => { render(Test) const alert = screen.getByTestId('alert') expect(alert).toHaveClass('py-2') expect(alert).toHaveClass('text-xs') }) it('renders default size correctly', () => { render(Test) const alert = screen.getByTestId('alert') expect(alert).toHaveClass('py-3') expect(alert).toHaveClass('text-sm') }) it('renders lg size correctly', () => { render(Test) const alert = screen.getByTestId('alert') expect(alert).toHaveClass('py-4') expect(alert).toHaveClass('text-base') }) it('uses default size as default', () => { render(Test) const alert = screen.getByTestId('alert') expect(alert).toHaveClass('py-3') expect(alert).toHaveClass('text-sm') }) }) describe('Radius', () => { it('renders none radius correctly', () => { render(Test) const alert = screen.getByTestId('alert') expect(alert).toHaveClass('rounded-none') }) it('renders sm radius correctly', () => { render(Test) const alert = screen.getByTestId('alert') expect(alert).toHaveClass('rounded-sm') }) it('renders default radius correctly', () => { render(Test) const alert = screen.getByTestId('alert') expect(alert).toHaveClass('rounded-md') }) it('renders lg radius correctly', () => { render(Test) const alert = screen.getByTestId('alert') expect(alert).toHaveClass('rounded-lg') }) it('renders full radius correctly', () => { render(Test) const alert = screen.getByTestId('alert') expect(alert).toHaveClass('rounded-full') }) it('uses default radius as default', () => { render(Test) const alert = screen.getByTestId('alert') expect(alert).toHaveClass('rounded-md') }) }) describe('Icons', () => { it('renders default icon for default variant', () => { render(Test) const alert = screen.getByTestId('alert') const icon = alert.querySelector('svg') expect(icon).toBeInTheDocument() expect(icon).toHaveClass('h-5', 'w-5') }) it('renders check icon for success variant', () => { render(Test) const alert = screen.getByTestId('alert') const icon = alert.querySelector('svg') expect(icon).toBeInTheDocument() }) it('renders triangle icon for warning variant', () => { render(Test) const alert = screen.getByTestId('alert') const icon = alert.querySelector('svg') expect(icon).toBeInTheDocument() }) it('renders circle icon for error variant', () => { render(Test) const alert = screen.getByTestId('alert') const icon = alert.querySelector('svg') expect(icon).toBeInTheDocument() }) it('renders info icon for info variant', () => { render(Test) const alert = screen.getByTestId('alert') const icon = alert.querySelector('svg') expect(icon).toBeInTheDocument() }) it('hides icon when hideIcon is true', () => { render(Test) const alert = screen.getByTestId('alert') const icon = alert.querySelector('svg') expect(icon).not.toBeInTheDocument() }) it('shows icon when hideIcon is false', () => { render(Test) const alert = screen.getByTestId('alert') const icon = alert.querySelector('svg') expect(icon).toBeInTheDocument() }) }) describe('Closable Functionality', () => { it('does not render close button by default', () => { render(Test) const alert = screen.getByTestId('alert') const closeButton = alert.querySelector('button') expect(closeButton).not.toBeInTheDocument() }) it('renders close button when closable is true', () => { const handleClose = jest.fn() render(Test) const alert = screen.getByTestId('alert') const closeButton = alert.querySelector('button') expect(closeButton).toBeInTheDocument() expect(closeButton).toHaveAttribute('aria-label', 'Kapat') }) it('does not render close button when closable is true but onClose is not provided', () => { render(Test) const alert = screen.getByTestId('alert') const closeButton = alert.querySelector('button') expect(closeButton).not.toBeInTheDocument() }) it('calls onClose when close button is clicked', () => { const handleClose = jest.fn() render(Test) const alert = screen.getByTestId('alert') const closeButton = alert.querySelector('button') fireEvent.click(closeButton!) expect(handleClose).toHaveBeenCalledTimes(1) }) it('applies withClose styling when closable', () => { const handleClose = jest.fn() render(Test) const alert = screen.getByTestId('alert') expect(alert).toHaveClass('pr-10') }) it('close button has correct styling', () => { const handleClose = jest.fn() render(Test) const alert = screen.getByTestId('alert') const closeButton = alert.querySelector('button') expect(closeButton).toHaveClass('absolute') expect(closeButton).toHaveClass('right-3') expect(closeButton).toHaveClass('top-3') expect(closeButton).toHaveClass('h-6') expect(closeButton).toHaveClass('w-6') }) }) describe('Accessibility', () => { it('has correct role attribute', () => { render(Test) const alert = screen.getByTestId('alert') expect(alert).toHaveAttribute('role', 'alert') }) it('supports custom ARIA attributes', () => { render(Test) const alert = screen.getByTestId('alert') expect(alert).toHaveAttribute('aria-label', 'Custom alert') }) it('close button has accessible label', () => { const handleClose = jest.fn() render(Test) const alert = screen.getByTestId('alert') const closeButton = alert.querySelector('button') expect(closeButton).toHaveAttribute('aria-label', 'Kapat') }) }) }) describe('AlertTitle Component', () => { it('renders correctly with default props', () => { render(Alert Title) const title = screen.getByTestId('alert-title') expect(title).toBeInTheDocument() expect(title.tagName).toBe('H5') expect(title).toHaveTextContent('Alert Title') }) it('applies custom className', () => { render(Title) const title = screen.getByTestId('alert-title') expect(title).toHaveClass('custom-title') }) it('has correct default styling', () => { render(Title) const title = screen.getByTestId('alert-title') expect(title).toHaveClass('font-semibold') expect(title).toHaveClass('leading-tight') expect(title).toHaveClass('tracking-tight') expect(title).toHaveClass('mb-1') }) it('forwards ref correctly', () => { const ref = React.createRef() render(Title) expect(ref.current).toBeInstanceOf(HTMLHeadingElement) }) it('maintains displayName', () => { expect(AlertTitle.displayName).toBe('AlertTitle') }) it('passes through HTML attributes', () => { render(Title) const title = screen.getByTestId('alert-title') expect(title).toHaveAttribute('id', 'alert-title-1') }) }) describe('AlertDescription Component', () => { it('renders correctly with default props', () => { render(Alert Description) const description = screen.getByTestId('alert-description') expect(description).toBeInTheDocument() expect(description.tagName).toBe('DIV') expect(description).toHaveTextContent('Alert Description') }) it('applies custom className', () => { render(Description) const description = screen.getByTestId('alert-description') expect(description).toHaveClass('custom-description') }) it('has correct default styling', () => { render(Description) const description = screen.getByTestId('alert-description') expect(description).toHaveClass('text-sm') expect(description).toHaveClass('leading-5') expect(description).toHaveClass('text-muted-foreground') }) it('forwards ref correctly', () => { const ref = React.createRef() render(Description) expect(ref.current).toBeInstanceOf(HTMLDivElement) }) it('maintains displayName', () => { expect(AlertDescription.displayName).toBe('AlertDescription') }) it('passes through HTML attributes', () => { render(Description) const description = screen.getByTestId('alert-description') expect(description).toHaveAttribute('id', 'alert-desc-1') }) }) describe('Complex Combinations', () => { it('renders alert with title and description', () => { render( Success! Your action was completed successfully. ) const alert = screen.getByTestId('alert') expect(alert).toHaveClass('bg-success/10') expect(alert).toHaveClass('py-4') expect(screen.getByText('Success!')).toBeInTheDocument() expect(screen.getByText('Your action was completed successfully.')).toBeInTheDocument() }) it('renders closable alert with all props', () => { const handleClose = jest.fn() render( Error Something went wrong. ) const alert = screen.getByTestId('alert') expect(alert).toHaveClass('bg-destructive/10') expect(alert).toHaveClass('py-2') expect(alert).toHaveClass('rounded-lg') expect(alert).toHaveClass('pr-10') expect(alert).toHaveClass('custom-alert') const closeButton = alert.querySelector('button') expect(closeButton).toBeInTheDocument() fireEvent.click(closeButton!) expect(handleClose).toHaveBeenCalled() }) it('renders alert without icon and with custom content', () => { render(
Custom Warning This is a custom warning message.
) const alert = screen.getByTestId('alert') expect(alert.querySelector('svg')).not.toBeInTheDocument() expect(screen.getByText('Custom Warning')).toBeInTheDocument() expect(screen.getByText('Action Button')).toBeInTheDocument() }) }) describe('Edge Cases', () => { it('passes through HTML attributes', () => { render(Test) const alert = screen.getByTestId('alert') expect(alert).toHaveAttribute('id', 'alert-1') expect(alert).toHaveAttribute('data-custom', 'value') }) it('handles empty content gracefully', () => { render() const alert = screen.getByTestId('alert') expect(alert).toBeInTheDocument() expect(alert).toHaveAttribute('role', 'alert') }) it('handles null children gracefully', () => { render({null}) const alert = screen.getByTestId('alert') expect(alert).toBeInTheDocument() }) it('handles multiple close button clicks', () => { const handleClose = jest.fn() render(Test) const alert = screen.getByTestId('alert') const closeButton = alert.querySelector('button') fireEvent.click(closeButton!) fireEvent.click(closeButton!) fireEvent.click(closeButton!) expect(handleClose).toHaveBeenCalledTimes(3) }) it('renders with all variants and sizes combination', () => { const variants = ['default', 'primary', 'success', 'warning', 'error', 'info'] as const const sizes = ['sm', 'default', 'lg'] as const variants.forEach((variant, variantIndex) => { sizes.forEach((size, sizeIndex) => { const testId = `alert-${variant}-${size}` render(Test {variant} {size}) const alert = screen.getByTestId(testId) expect(alert).toBeInTheDocument() }) }) }) }) })