mirror of
https://github.com/langgenius/dify.git
synced 2026-05-15 13:02:19 -04:00
Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: jyong <718720800@qq.com> Co-authored-by: Yansong Zhang <916125788@qq.com> Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com> Co-authored-by: hj24 <mambahj24@gmail.com> Co-authored-by: hj24 <huangjian@dify.ai> Co-authored-by: Joel <iamjoel007@gmail.com> Co-authored-by: Stephen Zhou <38493346+hyoban@users.noreply.github.com> Co-authored-by: CodingOnStar <hanxujiang@dify.com> Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: 非法操作 <hjlarry@163.com> Co-authored-by: Ayush Baluni <73417844+aayushbaluni@users.noreply.github.com> Co-authored-by: yyh <92089059+lyzno1@users.noreply.github.com> Co-authored-by: jimcody1995 <jjimcody@gmail.com> Co-authored-by: James <63717587+jamesrayammons@users.noreply.github.com> Co-authored-by: Yunlu Wen <yunlu.wen@dify.ai> Co-authored-by: Stephen Zhou <hi@hyoban.cc> Co-authored-by: Coding On Star <447357187@qq.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: jerryzai <jerryzh8710@protonmail.com> Co-authored-by: NVIDIAN <speedy.hpc@hotmail.com> Co-authored-by: ai-hpc <ai-hpc@users.noreply.github.com> Co-authored-by: Asuka Minato <i@asukaminato.eu.org> Co-authored-by: Junghwan <70629228+shaun0927@users.noreply.github.com> Co-authored-by: HeYinKazune <70251095+HeYin-OS@users.noreply.github.com> Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> Co-authored-by: yyh <yuanyouhuilyz@gmail.com> Co-authored-by: Jingyi <jingyi.qi@dify.ai> Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com> Co-authored-by: sxxtony <166789813+sxxtony@users.noreply.github.com>
175 lines
5.7 KiB
TypeScript
175 lines
5.7 KiB
TypeScript
import { render, screen } from '@testing-library/react'
|
|
import { beforeEach, describe, expect, it, vi } from 'vitest'
|
|
import PreviewContainer from '../container'
|
|
|
|
// Tests for PreviewContainer - a layout wrapper with header and scrollable main area
|
|
describe('PreviewContainer', () => {
|
|
beforeEach(() => {
|
|
vi.clearAllMocks()
|
|
})
|
|
|
|
describe('Rendering', () => {
|
|
it('should render header content in a header element', () => {
|
|
render(<PreviewContainer header={<span>Header Title</span>}>Body</PreviewContainer>)
|
|
|
|
expect(screen.getByText('Header Title'))!.toBeInTheDocument()
|
|
const headerEl = screen.getByText('Header Title').closest('header')
|
|
expect(headerEl)!.toBeInTheDocument()
|
|
})
|
|
|
|
it('should render children in a main element', () => {
|
|
render(<PreviewContainer header="Header">Main content</PreviewContainer>)
|
|
|
|
const mainEl = screen.getByRole('main')
|
|
expect(mainEl)!.toHaveTextContent('Main content')
|
|
})
|
|
|
|
it('should render both header and children simultaneously', () => {
|
|
render(
|
|
<PreviewContainer header={<h2>My Header</h2>}>
|
|
<p>Body paragraph</p>
|
|
</PreviewContainer>,
|
|
)
|
|
|
|
expect(screen.getByText('My Header'))!.toBeInTheDocument()
|
|
expect(screen.getByText('Body paragraph'))!.toBeInTheDocument()
|
|
})
|
|
|
|
it('should render without children', () => {
|
|
render(<PreviewContainer header="Header" />)
|
|
|
|
expect(screen.getByRole('main'))!.toBeInTheDocument()
|
|
expect(screen.getByRole('main').childElementCount).toBe(0)
|
|
})
|
|
})
|
|
|
|
describe('Props', () => {
|
|
it('should apply className to the outer wrapper div', () => {
|
|
const { container } = render(
|
|
<PreviewContainer header="Header" className="outer-class">Content</PreviewContainer>,
|
|
)
|
|
|
|
expect(container.firstElementChild)!.toHaveClass('outer-class')
|
|
})
|
|
|
|
it('should apply mainClassName to the main element', () => {
|
|
render(
|
|
<PreviewContainer header="Header" mainClassName="custom-main">Content</PreviewContainer>,
|
|
)
|
|
|
|
const mainEl = screen.getByRole('main')
|
|
expect(mainEl)!.toHaveClass('custom-main')
|
|
// Default classes should still be present
|
|
// Default classes should still be present
|
|
expect(mainEl)!.toHaveClass('w-full', 'grow', 'overflow-y-auto', 'px-6', 'py-5')
|
|
})
|
|
|
|
it('should forward ref to the inner container div', () => {
|
|
const ref = vi.fn()
|
|
render(
|
|
<PreviewContainer header="Header" ref={ref}>Content</PreviewContainer>,
|
|
)
|
|
|
|
expect(ref).toHaveBeenCalled()
|
|
const refArg = ref.mock.calls[0]![0]
|
|
expect(refArg).toBeInstanceOf(HTMLDivElement)
|
|
})
|
|
|
|
it('should pass rest props to the inner container div', () => {
|
|
render(
|
|
<PreviewContainer header="Header" data-testid="inner-container" id="container-1">
|
|
Content
|
|
</PreviewContainer>,
|
|
)
|
|
|
|
const inner = screen.getByTestId('inner-container')
|
|
expect(inner)!.toHaveAttribute('id', 'container-1')
|
|
})
|
|
|
|
it('should render ReactNode as header', () => {
|
|
render(
|
|
<PreviewContainer header={<div data-testid="complex-header"><span>Complex</span></div>}>
|
|
Content
|
|
</PreviewContainer>,
|
|
)
|
|
|
|
expect(screen.getByTestId('complex-header'))!.toBeInTheDocument()
|
|
expect(screen.getByText('Complex'))!.toBeInTheDocument()
|
|
})
|
|
})
|
|
|
|
// Layout structure tests
|
|
describe('Layout Structure', () => {
|
|
it('should have header with border-b styling', () => {
|
|
render(<PreviewContainer header="Header">Content</PreviewContainer>)
|
|
|
|
const headerEl = screen.getByText('Header').closest('header')
|
|
expect(headerEl)!.toHaveClass('border-b', 'border-divider-subtle')
|
|
})
|
|
|
|
it('should have inner div with flex column layout', () => {
|
|
render(
|
|
<PreviewContainer header="Header" data-testid="inner">Content</PreviewContainer>,
|
|
)
|
|
|
|
const inner = screen.getByTestId('inner')
|
|
expect(inner)!.toHaveClass('flex', 'h-full', 'w-full', 'flex-col')
|
|
})
|
|
|
|
it('should have main with overflow-y-auto for scrolling', () => {
|
|
render(<PreviewContainer header="Header">Content</PreviewContainer>)
|
|
|
|
expect(screen.getByRole('main'))!.toHaveClass('overflow-y-auto')
|
|
})
|
|
})
|
|
|
|
// DisplayName test
|
|
describe('DisplayName', () => {
|
|
it('should have correct displayName', () => {
|
|
expect(PreviewContainer.displayName).toBe('PreviewContainer')
|
|
})
|
|
})
|
|
|
|
describe('Edge Cases', () => {
|
|
it('should render with empty string header', () => {
|
|
render(<PreviewContainer header="">Content</PreviewContainer>)
|
|
|
|
const headerEl = screen.getByRole('banner')
|
|
expect(headerEl)!.toBeInTheDocument()
|
|
})
|
|
|
|
it('should render with null children', () => {
|
|
render(<PreviewContainer header="Header">{null}</PreviewContainer>)
|
|
|
|
expect(screen.getByRole('main'))!.toBeInTheDocument()
|
|
})
|
|
|
|
it('should render with multiple children', () => {
|
|
render(
|
|
<PreviewContainer header="Header">
|
|
<div>Child 1</div>
|
|
<div>Child 2</div>
|
|
<div>Child 3</div>
|
|
</PreviewContainer>,
|
|
)
|
|
|
|
expect(screen.getByText('Child 1'))!.toBeInTheDocument()
|
|
expect(screen.getByText('Child 2'))!.toBeInTheDocument()
|
|
expect(screen.getByText('Child 3'))!.toBeInTheDocument()
|
|
})
|
|
|
|
it('should not crash on re-render with different props', () => {
|
|
const { rerender } = render(
|
|
<PreviewContainer header="First" className="a">Content A</PreviewContainer>,
|
|
)
|
|
|
|
rerender(
|
|
<PreviewContainer header="Second" className="b" mainClassName="new-main">Content B</PreviewContainer>,
|
|
)
|
|
|
|
expect(screen.getByText('Second'))!.toBeInTheDocument()
|
|
expect(screen.getByText('Content B'))!.toBeInTheDocument()
|
|
})
|
|
})
|
|
})
|