import { render, screen } from '@testing-library/react' import { beforeEach, describe, expect, it, vi } from 'vitest' // Import the mock to control it in tests import useTheme from '@/hooks/use-theme' import { ToolTypeEnum } from '../../workflow/block-selector/types' import Empty from './empty' // Mock useTheme hook vi.mock('@/hooks/use-theme', () => ({ default: vi.fn(() => ({ theme: 'light' })), })) describe('Empty', () => { beforeEach(() => { vi.clearAllMocks() vi.mocked(useTheme).mockReturnValue({ theme: 'light' } as ReturnType) }) // Tests for basic rendering scenarios describe('Rendering', () => { it('should render without crashing', () => { render() expect(screen.getByText('No tools available')).toBeInTheDocument() }) it('should render placeholder icon', () => { render() // NoToolPlaceholder should be rendered const container = document.querySelector('.flex.flex-col') expect(container).toBeInTheDocument() }) it('should render fallback title when no type provided', () => { render() expect(screen.getByText('No tools available')).toBeInTheDocument() }) }) // Tests for different type prop values describe('Type Props', () => { it('should render with Custom type and include link to /tools?category=api', () => { render() const link = document.querySelector('a[href="/tools?category=api"]') expect(link).toBeInTheDocument() expect(link).toHaveAttribute('target', '_blank') }) it('should render with MCP type and include link to /tools?category=mcp', () => { render() const link = document.querySelector('a[href="/tools?category=mcp"]') expect(link).toBeInTheDocument() expect(link).toHaveAttribute('target', '_blank') }) it('should render arrow icon for types with links', () => { render() // Check for RiArrowRightUpLine icon (has class h-3 w-3) const arrowIcon = document.querySelector('.h-3.w-3') expect(arrowIcon).toBeInTheDocument() }) it('should not render link for BuiltIn type', () => { render() const link = document.querySelector('a') expect(link).not.toBeInTheDocument() }) it('should not render link for Workflow type', () => { render() const link = document.querySelector('a') expect(link).not.toBeInTheDocument() }) }) // Tests for isAgent prop describe('isAgent Prop', () => { it('should render as agent without link', () => { render() // When isAgent is true, no link should be rendered const link = document.querySelector('a') expect(link).not.toBeInTheDocument() }) it('should not render tip text when isAgent is true', () => { render() // Arrow icon should not be present when isAgent is true const arrowIcon = document.querySelector('.h-3.w-3') expect(arrowIcon).not.toBeInTheDocument() }) }) // Tests for theme-based styling describe('Theme Support', () => { it('should not apply invert class in light theme', () => { vi.mocked(useTheme).mockReturnValue({ theme: 'light' } as ReturnType) render() // The NoToolPlaceholder should not have 'invert' class in light mode // We check the first svg or container within the component const placeholder = document.querySelector('.flex.flex-col > *:first-child') expect(placeholder).not.toHaveClass('invert') }) it('should apply invert class in dark theme', () => { vi.mocked(useTheme).mockReturnValue({ theme: 'dark' } as ReturnType) render() // The NoToolPlaceholder should have 'invert' class in dark mode const placeholder = document.querySelector('.invert') expect(placeholder).toBeInTheDocument() }) }) // Tests for translation key handling describe('Translation Keys', () => { it('should use correct translation namespace for tools', () => { render() // The component should render translation keys with 'tools' namespace // Translation mock returns the key itself expect(screen.getByText(/addToolModal\.custom\.title/i)).toBeInTheDocument() }) it('should render tip text for types with hasTitle', () => { render() // Should show the tip text with translation key expect(screen.getByText(/addToolModal\.custom\.tip/i)).toBeInTheDocument() }) }) // Tests for edge cases describe('Edge Cases', () => { it('should handle undefined type gracefully', () => { render() expect(screen.getByText('No tools available')).toBeInTheDocument() }) it('should handle All type without link', () => { render() const link = document.querySelector('a') expect(link).not.toBeInTheDocument() }) }) // Tests for link styling describe('Link Styling', () => { it('should apply hover styling classes to link', () => { render() const link = document.querySelector('a') expect(link).toHaveClass('cursor-pointer') expect(link).toHaveClass('hover:text-text-accent') }) it('should render div instead of link when hasLink is false', () => { render() // No anchor tags should be rendered const anchors = document.querySelectorAll('a') expect(anchors.length).toBe(0) }) }) })