import { render, screen } from '@testing-library/react' import { beforeEach, describe, expect, it, vi } from 'vitest' import { Theme } from '@/types/app' import IconWithTooltip from './icon-with-tooltip' // Mock Tooltip component vi.mock('@/app/components/base/tooltip', () => ({ default: ({ children, popupContent, popupClassName, }: { children: React.ReactNode popupContent?: string popupClassName?: string }) => (
{children}
), })) // Mock icon components const MockLightIcon = ({ className }: { className?: string }) => (
Light Icon
) const MockDarkIcon = ({ className }: { className?: string }) => (
Dark Icon
) describe('IconWithTooltip', () => { beforeEach(() => { vi.clearAllMocks() }) describe('Rendering', () => { it('should render without crashing', () => { render( , ) expect(screen.getByTestId('tooltip')).toBeInTheDocument() }) it('should render Tooltip wrapper', () => { render( , ) expect(screen.getByTestId('tooltip')).toHaveAttribute('data-popup-content', 'Test tooltip') }) it('should apply correct popupClassName to Tooltip', () => { render( , ) const tooltip = screen.getByTestId('tooltip') expect(tooltip).toHaveAttribute('data-popup-classname') expect(tooltip.getAttribute('data-popup-classname')).toContain('border-components-panel-border') }) }) describe('Theme Handling', () => { it('should render light icon when theme is light', () => { render( , ) expect(screen.getByTestId('light-icon')).toBeInTheDocument() expect(screen.queryByTestId('dark-icon')).not.toBeInTheDocument() }) it('should render dark icon when theme is dark', () => { render( , ) expect(screen.getByTestId('dark-icon')).toBeInTheDocument() expect(screen.queryByTestId('light-icon')).not.toBeInTheDocument() }) it('should render light icon when theme is system (not dark)', () => { render( , ) // When theme is not 'dark', it should use light icon expect(screen.getByTestId('light-icon')).toBeInTheDocument() }) }) describe('Props', () => { it('should apply custom className to icon', () => { render( , ) const icon = screen.getByTestId('light-icon') expect(icon).toHaveClass('custom-class') }) it('should apply default h-5 w-5 class to icon', () => { render( , ) const icon = screen.getByTestId('light-icon') expect(icon).toHaveClass('h-5') expect(icon).toHaveClass('w-5') }) it('should merge custom className with default classes', () => { render( , ) const icon = screen.getByTestId('light-icon') expect(icon).toHaveClass('h-5') expect(icon).toHaveClass('w-5') expect(icon).toHaveClass('ml-2') }) it('should pass popupContent to Tooltip', () => { render( , ) expect(screen.getByTestId('tooltip')).toHaveAttribute( 'data-popup-content', 'Custom tooltip content', ) }) it('should handle undefined popupContent', () => { render( , ) expect(screen.getByTestId('tooltip')).toBeInTheDocument() }) }) describe('Memoization', () => { it('should be wrapped with React.memo', () => { // The component is exported as React.memo(IconWithTooltip) expect(IconWithTooltip).toBeDefined() // Check if it's a memo component expect(typeof IconWithTooltip).toBe('object') }) }) describe('Container Structure', () => { it('should render icon inside flex container', () => { const { container } = render( , ) const flexContainer = container.querySelector('.flex.shrink-0.items-center.justify-center') expect(flexContainer).toBeInTheDocument() }) }) describe('Edge Cases', () => { it('should handle empty className', () => { render( , ) expect(screen.getByTestId('light-icon')).toBeInTheDocument() }) it('should handle long popupContent', () => { const longContent = 'A'.repeat(500) render( , ) expect(screen.getByTestId('tooltip')).toHaveAttribute('data-popup-content', longContent) }) it('should handle special characters in popupContent', () => { const specialContent = ' & "quotes"' render( , ) expect(screen.getByTestId('tooltip')).toHaveAttribute('data-popup-content', specialContent) }) }) })