import React from 'react' import { render, screen, fireEvent } from '@testing-library/react' import '@testing-library/jest-dom' import { Collapsible, CollapsibleTrigger, CollapsibleContent, collapsibleTriggerVariants, collapsibleContentVariants, } from '../collapsible' describe('Collapsible Components', () => { describe('Collapsible Component', () => { it('renders correctly with default props', () => { render( Toggle Content ) const collapsible = screen.getByTestId('collapsible') expect(collapsible).toBeInTheDocument() }) it('applies custom className', () => { render( Toggle Content ) const collapsible = screen.getByTestId('collapsible') expect(collapsible).toHaveClass('custom-class') }) it('forwards ref correctly', () => { const ref = React.createRef() render( Toggle Content ) expect(ref.current).toBeInstanceOf(HTMLDivElement) }) it('handles controlled state', () => { const onOpenChange = jest.fn() render( Toggle Content ) const trigger = screen.getByRole('button') fireEvent.click(trigger) expect(onOpenChange).toHaveBeenCalledWith(false) }) it('passes through HTML attributes', () => { render( Toggle Content ) const collapsible = screen.getByTestId('collapsible') expect(collapsible).toHaveAttribute('id', 'collapsible-1') }) }) describe('CollapsibleTrigger Component', () => { it('renders correctly with default props', () => { render( Toggle Content ) const trigger = screen.getByTestId('trigger') expect(trigger).toBeInTheDocument() expect(trigger).toHaveClass('flex') }) it('applies custom className', () => { render( Toggle Content ) const trigger = screen.getByTestId('trigger') expect(trigger).toHaveClass('custom-trigger') }) it('forwards ref correctly', () => { const ref = React.createRef() render( Toggle Content ) expect(ref.current).toBeInstanceOf(HTMLButtonElement) }) it('maintains displayName', () => { expect(CollapsibleTrigger.displayName).toBe('CollapsibleTrigger') }) it('renders default variant correctly', () => { render( Toggle Content ) const trigger = screen.getByTestId('trigger') expect(trigger).toHaveClass('text-foreground') }) it('renders ghost variant correctly', () => { render( Toggle Content ) const trigger = screen.getByTestId('trigger') expect(trigger).toHaveClass('rounded') }) it('renders outline variant correctly', () => { render( Toggle Content ) const trigger = screen.getByTestId('trigger') expect(trigger).toHaveClass('border') }) it('renders sm size correctly', () => { render( Toggle Content ) const trigger = screen.getByTestId('trigger') expect(trigger).toHaveClass('text-xs') }) it('renders default size correctly', () => { render( Toggle Content ) const trigger = screen.getByTestId('trigger') expect(trigger).toHaveClass('text-sm') }) it('renders md size correctly', () => { render( Toggle Content ) const trigger = screen.getByTestId('trigger') expect(trigger).toHaveClass('text-base') }) it('renders lg size correctly', () => { render( Toggle Content ) const trigger = screen.getByTestId('trigger') expect(trigger).toHaveClass('text-lg') }) it('renders chevron icon', () => { render( Toggle Content ) const trigger = screen.getByTestId('trigger') const chevron = trigger.querySelector('svg') expect(chevron).toBeInTheDocument() expect(chevron).toHaveClass('h-4') }) it('handles click events', () => { const onClick = jest.fn() render( Toggle Content ) const trigger = screen.getByTestId('trigger') fireEvent.click(trigger) expect(onClick).toHaveBeenCalled() }) it('passes through HTML attributes', () => { render( Toggle Content ) const trigger = screen.getByTestId('trigger') expect(trigger).toHaveAttribute('id', 'trigger-1') }) }) describe('CollapsibleContent Component', () => { it('renders correctly with default props', () => { render( Toggle Content ) const content = screen.getByTestId('content') expect(content).toBeInTheDocument() expect(content).toHaveClass('overflow-hidden') }) it('applies custom className', () => { render( Toggle Content ) const content = screen.getByTestId('content') expect(content).toHaveClass('custom-content') }) it('forwards ref correctly', () => { const ref = React.createRef() render( Toggle Content ) expect(ref.current).toBeInstanceOf(HTMLDivElement) }) it('maintains displayName', () => { expect(CollapsibleContent.displayName).toBe('CollapsibleContent') }) it('renders default variant correctly', () => { render( Toggle Content ) const content = screen.getByTestId('content') expect(content).toHaveClass('text-muted-foreground') }) it('renders ghost variant correctly', () => { render( Toggle Content ) const content = screen.getByTestId('content') expect(content).toHaveClass('rounded-b') }) it('renders outline variant correctly', () => { render( Toggle Content ) const content = screen.getByTestId('content') expect(content).toHaveClass('border') }) it('renders sm size correctly', () => { render( Toggle Content ) const content = screen.getByTestId('content') expect(content).toHaveClass('text-xs') }) it('renders default size correctly', () => { render( Toggle Content ) const content = screen.getByTestId('content') expect(content).toHaveClass('text-sm') }) it('renders md size correctly', () => { render( Toggle Content ) const content = screen.getByTestId('content') expect(content).toHaveClass('text-base') }) it('renders lg size correctly', () => { render( Toggle Content ) const content = screen.getByTestId('content') expect(content).toHaveClass('text-lg') }) it('renders content wrapper with padding', () => { render( Toggle Content ) const content = screen.getByTestId('content') const wrapper = content.querySelector('.p-4') expect(wrapper).toBeInTheDocument() expect(wrapper).toHaveTextContent('Content') }) it('passes through HTML attributes', () => { render( Toggle Content ) const content = screen.getByTestId('content') expect(content).toHaveAttribute('id', 'content-1') }) }) describe('Variant Functions', () => { it('collapsibleTriggerVariants generates correct classes', () => { expect(collapsibleTriggerVariants()).toContain('flex w-full items-center justify-between') expect(collapsibleTriggerVariants({ variant: 'ghost' })).toContain('rounded') expect(collapsibleTriggerVariants({ size: 'sm' })).toContain('text-xs py-2 px-3') }) it('collapsibleContentVariants generates correct classes', () => { expect(collapsibleContentVariants()).toContain('overflow-hidden transition-all') expect(collapsibleContentVariants({ variant: 'outline' })).toContain('border') expect(collapsibleContentVariants({ size: 'lg' })).toContain('text-lg') }) }) describe('Complex Combinations', () => { it('renders with all props and variants', () => { render( Toggle Content This is the collapsible content ) const collapsible = screen.getByTestId('collapsible') const trigger = screen.getByTestId('trigger') const content = screen.getByTestId('content') expect(collapsible).toHaveClass('custom-collapsible') expect(trigger).toHaveClass('custom-trigger') expect(content).toHaveClass('custom-content') }) it('handles toggle functionality', () => { render( Toggle Content ) const trigger = screen.getByTestId('trigger') // Initially closed expect(screen.queryByText('Content')).not.toBeInTheDocument() // Click to open fireEvent.click(trigger) expect(screen.getByText('Content')).toBeInTheDocument() // Click to close fireEvent.click(trigger) expect(screen.queryByText('Content')).not.toBeInTheDocument() }) it('renders multiple collapsibles independently', () => { render(
Toggle 1 Content 1 Toggle 2 Content 2
) const trigger1 = screen.getByTestId('trigger-1') const trigger2 = screen.getByTestId('trigger-2') // Open first collapsible fireEvent.click(trigger1) expect(screen.getByText('Content 1')).toBeInTheDocument() expect(screen.queryByText('Content 2')).not.toBeInTheDocument() // Open second collapsible fireEvent.click(trigger2) expect(screen.getByText('Content 1')).toBeInTheDocument() expect(screen.getByText('Content 2')).toBeInTheDocument() }) }) describe('Edge Cases', () => { it('handles empty content', () => { render( Toggle ) const content = screen.getByTestId('content') expect(content).toBeInTheDocument() }) it('handles complex nested content', () => { render( Toggle

Nested Title

Nested paragraph

  • Item 1
  • Item 2
) expect(screen.getByText('Nested Title')).toBeInTheDocument() expect(screen.getByText('Nested paragraph')).toBeInTheDocument() expect(screen.getByText('Item 1')).toBeInTheDocument() }) it('handles disabled state', () => { render( Toggle Content ) const trigger = screen.getByTestId('trigger') expect(trigger).toBeDisabled() }) it('handles null and undefined children', () => { render( Toggle {null} {undefined} Valid content ) expect(screen.getByText('Valid content')).toBeInTheDocument() }) }) })