Files
snippet-pastebin/tests/unit/components/ui/sidebar-menu/SidebarMenuSubButton.test.tsx
johndoe6345789 d2e3cef2ee test: Add 1200+ tests for quality validator and UI components
- Created comprehensive test suites for quality validator module (430+ tests)
  * index.test.ts: QualityValidator main module
  * reporters/*.test.ts: ReporterBase and all reporters
  * scoring/*.test.ts: Scoring engine with edge cases
  * utils/*.test.ts: Validators, formatters, FileChangeDetector

- Added UI component tests for sidebar menu and templates (800+ tests)
  * SidebarMenuButton, SidebarMenuSubButton, etc.
  * DashboardTemplate, BlogTemplate
  * ContentPreviewCardsSection, FormFieldsSection

- Coverage improvements:
  * Statements: 56.62% → 60.93% (+4.31%)
  * Functions: 76.76% → 79.82% (+3.06%)
  * Branches: 84.37% → 85.92% (+1.55%)
  * Tests passing: 5,512 (added 363 new passing tests)

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-01-21 02:46:17 +00:00

502 lines
14 KiB
TypeScript

import React from 'react'
import { render, screen } from '@/test-utils'
import userEvent from '@testing-library/user-event'
import { SidebarMenuSubButton } from '@/components/ui/sidebar-menu/SidebarMenuSubButton'
describe('SidebarMenuSubButton', () => {
beforeEach(() => {
jest.clearAllMocks()
})
describe('Rendering', () => {
it('should render as anchor element by default', () => {
render(
<SidebarMenuSubButton href="#">
Sub Menu Item
</SidebarMenuSubButton>
)
const link = screen.getByTestId('sidebar-menu-sub-button')
expect(link.tagName).toBe('A')
})
it('should render as div when asChild is true', () => {
render(
<SidebarMenuSubButton asChild>
Sub Menu Item
</SidebarMenuSubButton>
)
const element = screen.getByTestId('sidebar-menu-sub-button')
expect(element.tagName).toBe('DIV')
})
it('should display children content', () => {
render(
<SidebarMenuSubButton href="#">
Test Content
</SidebarMenuSubButton>
)
expect(screen.getByText('Test Content')).toBeInTheDocument()
})
it('should have data-slot attribute', () => {
render(
<SidebarMenuSubButton href="#">
Sub Menu
</SidebarMenuSubButton>
)
const link = screen.getByTestId('sidebar-menu-sub-button')
expect(link).toHaveAttribute('data-slot', 'sidebar-menu-sub-button')
})
it('should have data-sidebar attribute', () => {
render(
<SidebarMenuSubButton href="#">
Sub Menu
</SidebarMenuSubButton>
)
const link = screen.getByTestId('sidebar-menu-sub-button')
expect(link).toHaveAttribute('data-sidebar', 'menu-sub-button')
})
it('should have data-testid attribute', () => {
render(
<SidebarMenuSubButton href="#">
Sub Menu
</SidebarMenuSubButton>
)
const link = screen.getByTestId('sidebar-menu-sub-button')
expect(link).toHaveAttribute('data-testid', 'sidebar-menu-sub-button')
})
})
describe('Props', () => {
it('should set isActive data attribute', () => {
render(
<SidebarMenuSubButton href="#" isActive={true}>
Sub Menu
</SidebarMenuSubButton>
)
const link = screen.getByTestId('sidebar-menu-sub-button')
expect(link).toHaveAttribute('data-active', 'true')
})
it('should set size data attribute', () => {
render(
<SidebarMenuSubButton href="#" size="sm">
Sub Menu
</SidebarMenuSubButton>
)
const link = screen.getByTestId('sidebar-menu-sub-button')
expect(link).toHaveAttribute('data-size', 'sm')
})
it('should accept className prop', () => {
render(
<SidebarMenuSubButton href="#" className="custom-class">
Sub Menu
</SidebarMenuSubButton>
)
const link = screen.getByTestId('sidebar-menu-sub-button')
expect(link).toHaveClass('custom-class')
})
it('should accept href prop', () => {
render(
<SidebarMenuSubButton href="/test-path">
Sub Menu
</SidebarMenuSubButton>
)
const link = screen.getByTestId('sidebar-menu-sub-button')
expect(link).toHaveAttribute('href', '/test-path')
})
})
describe('Sizes', () => {
it('should render medium size by default', () => {
render(
<SidebarMenuSubButton href="#">
Sub Menu
</SidebarMenuSubButton>
)
const link = screen.getByTestId('sidebar-menu-sub-button')
expect(link).toHaveClass('h-7')
})
it('should render small size', () => {
render(
<SidebarMenuSubButton href="#" size="sm">
Sub Menu
</SidebarMenuSubButton>
)
const link = screen.getByTestId('sidebar-menu-sub-button')
expect(link).toHaveClass('text-xs')
})
it('should render medium size with proper text class', () => {
render(
<SidebarMenuSubButton href="#" size="md">
Sub Menu
</SidebarMenuSubButton>
)
const link = screen.getByTestId('sidebar-menu-sub-button')
expect(link).toHaveClass('text-sm')
})
})
describe('Active State', () => {
it('should apply active styling when isActive is true', () => {
render(
<SidebarMenuSubButton href="#" isActive={true}>
Sub Menu
</SidebarMenuSubButton>
)
const link = screen.getByTestId('sidebar-menu-sub-button')
expect(link).toHaveClass('bg-gray-300')
})
it('should not apply active styling when isActive is false', () => {
render(
<SidebarMenuSubButton href="#" isActive={false}>
Sub Menu
</SidebarMenuSubButton>
)
const link = screen.getByTestId('sidebar-menu-sub-button')
expect(link).not.toHaveClass('bg-gray-300')
})
it('should set aria-current when active', () => {
render(
<SidebarMenuSubButton href="#" isActive={true}>
Sub Menu
</SidebarMenuSubButton>
)
const link = screen.getByTestId('sidebar-menu-sub-button')
expect(link).toHaveAttribute('aria-current', 'page')
})
it('should not set aria-current when not active', () => {
render(
<SidebarMenuSubButton href="#" isActive={false}>
Sub Menu
</SidebarMenuSubButton>
)
const link = screen.getByTestId('sidebar-menu-sub-button')
expect(link).not.toHaveAttribute('aria-current')
})
})
describe('Styling', () => {
it('should have flex layout', () => {
render(
<SidebarMenuSubButton href="#">
Sub Menu
</SidebarMenuSubButton>
)
const link = screen.getByTestId('sidebar-menu-sub-button')
expect(link).toHaveClass('flex')
})
it('should have items center', () => {
render(
<SidebarMenuSubButton href="#">
Sub Menu
</SidebarMenuSubButton>
)
const link = screen.getByTestId('sidebar-menu-sub-button')
expect(link).toHaveClass('items-center')
})
it('should have gap-2', () => {
render(
<SidebarMenuSubButton href="#">
Sub Menu
</SidebarMenuSubButton>
)
const link = screen.getByTestId('sidebar-menu-sub-button')
expect(link).toHaveClass('gap-2')
})
it('should have rounded-md', () => {
render(
<SidebarMenuSubButton href="#">
Sub Menu
</SidebarMenuSubButton>
)
const link = screen.getByTestId('sidebar-menu-sub-button')
expect(link).toHaveClass('rounded-md')
})
it('should have padding-x', () => {
render(
<SidebarMenuSubButton href="#">
Sub Menu
</SidebarMenuSubButton>
)
const link = screen.getByTestId('sidebar-menu-sub-button')
expect(link).toHaveClass('px-2')
})
it('should have overflow hidden', () => {
render(
<SidebarMenuSubButton href="#">
Sub Menu
</SidebarMenuSubButton>
)
const link = screen.getByTestId('sidebar-menu-sub-button')
expect(link).toHaveClass('overflow-hidden')
})
it('should have min-width-0', () => {
render(
<SidebarMenuSubButton href="#">
Sub Menu
</SidebarMenuSubButton>
)
const link = screen.getByTestId('sidebar-menu-sub-button')
expect(link).toHaveClass('min-w-0')
})
it('should have focus-visible ring', () => {
render(
<SidebarMenuSubButton href="#">
Sub Menu
</SidebarMenuSubButton>
)
const link = screen.getByTestId('sidebar-menu-sub-button')
expect(link).toHaveClass('focus-visible:ring-2')
})
})
describe('Hover States', () => {
it('should have hover background light', () => {
render(
<SidebarMenuSubButton href="#">
Sub Menu
</SidebarMenuSubButton>
)
const link = screen.getByTestId('sidebar-menu-sub-button')
expect(link).toHaveClass('hover:bg-gray-200')
})
it('should have active background', () => {
render(
<SidebarMenuSubButton href="#">
Sub Menu
</SidebarMenuSubButton>
)
const link = screen.getByTestId('sidebar-menu-sub-button')
expect(link).toHaveClass('active:bg-gray-300')
})
})
describe('Dark Mode', () => {
it('should have dark mode hover state', () => {
render(
<SidebarMenuSubButton href="#">
Sub Menu
</SidebarMenuSubButton>
)
const link = screen.getByTestId('sidebar-menu-sub-button')
expect(link).toHaveClass('dark:hover:bg-gray-700')
})
it('should have dark mode active state', () => {
render(
<SidebarMenuSubButton href="#">
Sub Menu
</SidebarMenuSubButton>
)
const link = screen.getByTestId('sidebar-menu-sub-button')
expect(link).toHaveClass('dark:active:bg-gray-600')
})
it('should have dark mode background when active', () => {
render(
<SidebarMenuSubButton href="#" isActive={true}>
Sub Menu
</SidebarMenuSubButton>
)
const link = screen.getByTestId('sidebar-menu-sub-button')
expect(link).toHaveClass('dark:bg-gray-600')
})
})
describe('SVG Icon Styling', () => {
it('should style SVG icons', () => {
render(
<SidebarMenuSubButton href="#">
<svg data-testid="test-icon">Icon</svg>
</SidebarMenuSubButton>
)
const link = screen.getByTestId('sidebar-menu-sub-button')
expect(link).toHaveClass('[&>svg]:w-4')
})
})
describe('Content Truncation', () => {
it('should truncate text content', () => {
render(
<SidebarMenuSubButton href="#">
<span>Text</span>
</SidebarMenuSubButton>
)
const link = screen.getByTestId('sidebar-menu-sub-button')
expect(link).toHaveClass('[&>span:last-child]:truncate')
})
})
describe('Accessibility', () => {
it('should be keyboard accessible', async () => {
const user = userEvent.setup()
render(
<SidebarMenuSubButton href="#">
Sub Menu
</SidebarMenuSubButton>
)
const link = screen.getByTestId('sidebar-menu-sub-button')
await user.tab()
expect(link).toHaveFocus()
})
it('should have proper semantic HTML', () => {
render(
<SidebarMenuSubButton href="#">
Sub Menu
</SidebarMenuSubButton>
)
const link = screen.getByTestId('sidebar-menu-sub-button')
expect(link.tagName).toBe('A')
})
it('should handle disabled state with aria-disabled', () => {
render(
<SidebarMenuSubButton href="#" aria-disabled={true}>
Sub Menu
</SidebarMenuSubButton>
)
const link = screen.getByTestId('sidebar-menu-sub-button')
expect(link).toHaveAttribute('aria-disabled', 'true')
expect(link).toHaveClass('aria-disabled:opacity-50')
})
})
describe('Collapsible Sidebar', () => {
it('should be hidden when sidebar is icon-only', () => {
render(
<SidebarMenuSubButton href="#">
Sub Menu
</SidebarMenuSubButton>
)
const link = screen.getByTestId('sidebar-menu-sub-button')
expect(link).toHaveClass('group-data-[collapsible=icon]:hidden')
})
})
describe('Disabled State', () => {
it('should have disabled pointer-events', () => {
render(
<SidebarMenuSubButton href="#" aria-disabled={true}>
Sub Menu
</SidebarMenuSubButton>
)
const link = screen.getByTestId('sidebar-menu-sub-button')
expect(link).toHaveClass('aria-disabled:pointer-events-none')
})
it('should have disabled opacity', () => {
render(
<SidebarMenuSubButton href="#" aria-disabled={true}>
Sub Menu
</SidebarMenuSubButton>
)
const link = screen.getByTestId('sidebar-menu-sub-button')
expect(link).toHaveClass('aria-disabled:opacity-50')
})
})
describe('Navigation', () => {
it('should support href navigation', () => {
render(
<SidebarMenuSubButton href="/dashboard">
Dashboard
</SidebarMenuSubButton>
)
const link = screen.getByTestId('sidebar-menu-sub-button')
expect(link).toHaveAttribute('href', '/dashboard')
})
it('should support external href', () => {
render(
<SidebarMenuSubButton href="https://example.com">
External Link
</SidebarMenuSubButton>
)
const link = screen.getByTestId('sidebar-menu-sub-button')
expect(link).toHaveAttribute('href', 'https://example.com')
})
})
describe('Click Handlers', () => {
it('should handle click events', async () => {
const user = userEvent.setup()
const onClick = jest.fn()
render(
<SidebarMenuSubButton href="#" onClick={onClick}>
Sub Menu
</SidebarMenuSubButton>
)
const link = screen.getByTestId('sidebar-menu-sub-button')
await user.click(link)
expect(onClick).toHaveBeenCalled()
})
})
describe('Combination Props', () => {
it('should work with multiple props', () => {
render(
<SidebarMenuSubButton
href="/test"
isActive={true}
size="sm"
className="my-custom"
>
Sub Menu
</SidebarMenuSubButton>
)
const link = screen.getByTestId('sidebar-menu-sub-button')
expect(link).toHaveAttribute('data-active', 'true')
expect(link).toHaveAttribute('href', '/test')
expect(link).toHaveClass('my-custom')
})
})
describe('Snapshot Tests', () => {
it('should match snapshot with default props', () => {
const { container } = render(
<SidebarMenuSubButton href="#">
Sub Menu Item
</SidebarMenuSubButton>
)
expect(container.firstChild).toMatchSnapshot()
})
it('should match snapshot with active state', () => {
const { container } = render(
<SidebarMenuSubButton href="#" isActive={true}>
Sub Menu Item
</SidebarMenuSubButton>
)
expect(container.firstChild).toMatchSnapshot()
})
it('should match snapshot with small size', () => {
const { container } = render(
<SidebarMenuSubButton href="#" size="sm">
Sub Menu Item
</SidebarMenuSubButton>
)
expect(container.firstChild).toMatchSnapshot()
})
})
})