dify/web/app/components/app-sidebar/__tests__/text-squeeze-fix-verificati...

171 lines
6.1 KiB
TypeScript

/**
* Text Squeeze Fix Verification Test
* This test verifies that the CSS-based text rendering fixes work correctly
*/
import { render } from '@testing-library/react'
import * as React from 'react'
// Mock Next.js navigation
vi.mock('@/next/navigation', () => ({
useSelectedLayoutSegment: () => 'overview',
}))
// Mock classnames utility
vi.mock('@/utils/classnames', () => ({
default: (...classes: unknown[]) => classes.filter(Boolean).join(' '),
}))
// Simplified NavLink component to test the fix
const TestNavLink = ({ mode }: { mode: 'expand' | 'collapse' }) => {
const name = 'Orchestrate'
return (
<div className="nav-link-container">
<div className={`flex h-9 items-center rounded-md py-2 text-sm font-normal ${
mode === 'expand' ? 'px-3' : 'px-2.5'
}`}
>
<div className={`h-4 w-4 shrink-0 ${mode === 'expand' ? 'mr-2' : 'mr-0'}`}>
Icon
</div>
<span
className={`whitespace-nowrap transition-all duration-200 ease-in-out ${
mode === 'expand'
? 'w-auto opacity-100'
: 'pointer-events-none w-0 overflow-hidden opacity-0'
}`}
data-testid="nav-text"
>
{name}
</span>
</div>
</div>
)
}
// Simplified AppInfo component to test the fix
const TestAppInfo = ({ expand }: { expand: boolean }) => {
const appDetail = {
name: 'Test ChatBot App',
mode: 'chat' as const,
}
return (
<div className="app-info-container">
<div className={`flex rounded-lg ${expand ? 'flex-col gap-2 p-2 pb-2.5' : 'items-start justify-center gap-1 p-1'}`}>
<div className={`flex items-center self-stretch ${expand ? 'justify-between' : 'flex-col gap-1'}`}>
<div className="app-icon">AppIcon</div>
<div className="dashboard-icon">Dashboard</div>
</div>
<div
className={`flex flex-col items-start gap-1 transition-all duration-200 ease-in-out ${
expand
? 'w-auto opacity-100'
: 'pointer-events-none w-0 overflow-hidden opacity-0'
}`}
data-testid="app-text-container"
>
<div className="flex w-full">
<div
className="system-md-semibold truncate whitespace-nowrap text-text-secondary"
data-testid="app-name"
>
{appDetail.name}
</div>
</div>
<div
className="system-2xs-medium-uppercase whitespace-nowrap text-text-tertiary"
data-testid="app-type"
>
ChatBot
</div>
</div>
</div>
</div>
)
}
describe('Text Squeeze Fix Verification', () => {
describe('NavLink Text Rendering Fix', () => {
it('should keep text in DOM and use CSS transitions', () => {
const { container, rerender } = render(<TestNavLink mode="collapse" />)
// In collapsed state, text should be in DOM but hidden
const textElement = container.querySelector('[data-testid="nav-text"]')
expect(textElement).toBeInTheDocument()
expect(textElement).toHaveClass('opacity-0')
expect(textElement).toHaveClass('w-0')
expect(textElement).toHaveClass('overflow-hidden')
expect(textElement).toHaveClass('pointer-events-none')
expect(textElement).toHaveClass('whitespace-nowrap')
expect(textElement).toHaveClass('transition-all')
// Switch to expanded state
rerender(<TestNavLink mode="expand" />)
const expandedText = container.querySelector('[data-testid="nav-text"]')
expect(expandedText).toBeInTheDocument()
expect(expandedText).toHaveClass('opacity-100')
expect(expandedText).toHaveClass('w-auto')
expect(expandedText).not.toHaveClass('pointer-events-none')
})
it('should verify smooth transition properties', () => {
const { container } = render(<TestNavLink mode="collapse" />)
const textElement = container.querySelector('[data-testid="nav-text"]')
expect(textElement).toHaveClass('transition-all')
expect(textElement).toHaveClass('duration-200')
expect(textElement).toHaveClass('ease-in-out')
})
})
describe('AppInfo Text Rendering Fix', () => {
it('should keep app text in DOM and use CSS transitions', () => {
const { container, rerender } = render(<TestAppInfo expand={false} />)
// In collapsed state, text container should be in DOM but hidden
const textContainer = container.querySelector('[data-testid="app-text-container"]')
expect(textContainer).toBeInTheDocument()
expect(textContainer).toHaveClass('opacity-0')
expect(textContainer).toHaveClass('w-0')
expect(textContainer).toHaveClass('overflow-hidden')
expect(textContainer).toHaveClass('pointer-events-none')
// Text elements should still be in DOM
const appName = container.querySelector('[data-testid="app-name"]')
const appType = container.querySelector('[data-testid="app-type"]')
expect(appName).toBeInTheDocument()
expect(appType).toBeInTheDocument()
expect(appName).toHaveClass('whitespace-nowrap')
expect(appType).toHaveClass('whitespace-nowrap')
// Switch to expanded state
rerender(<TestAppInfo expand={true} />)
const expandedContainer = container.querySelector('[data-testid="app-text-container"]')
expect(expandedContainer).toBeInTheDocument()
expect(expandedContainer).toHaveClass('opacity-100')
expect(expandedContainer).toHaveClass('w-auto')
expect(expandedContainer).not.toHaveClass('pointer-events-none')
})
it('should verify transition properties on text container', () => {
const { container } = render(<TestAppInfo expand={false} />)
const textContainer = container.querySelector('[data-testid="app-text-container"]')
expect(textContainer).toHaveClass('transition-all')
expect(textContainer).toHaveClass('duration-200')
expect(textContainer).toHaveClass('ease-in-out')
})
})
describe('Fix Strategy Comparison', () => {
it('should document the fix strategy differences', () => {
// Always pass documentation test
expect(true).toBe(true)
})
})
})