import type { QA } from '@/models/datasets' import { render, screen } from '@testing-library/react' import { beforeEach, describe, expect, it, vi } from 'vitest' import { ChunkContainer, ChunkLabel, QAPreview } from '../chunk' vi.mock('../../base/icons/src/public/knowledge', () => ({ SelectionMod: (props: React.ComponentProps<'svg'>) => ( ), })) function createQA(overrides: Partial = {}): QA { return { question: 'What is Dify?', answer: 'Dify is an open-source LLM app development platform.', ...overrides, } } describe('ChunkLabel', () => { beforeEach(() => { vi.clearAllMocks() }) describe('Rendering', () => { it('should render the label text', () => { render() expect(screen.getByText('Chunk #1')).toBeInTheDocument() }) it('should render the character count with unit', () => { render() expect(screen.getByText('256 characters')).toBeInTheDocument() }) it('should render the SelectionMod icon', () => { render() expect(screen.getByTestId('selection-mod-icon')).toBeInTheDocument() }) it('should render a middle dot separator between label and count', () => { render() expect(screen.getByText('ยท')).toBeInTheDocument() }) }) describe('Props', () => { it('should display zero character count', () => { render() expect(screen.getByText('0 characters')).toBeInTheDocument() }) it('should display large character counts', () => { render() expect(screen.getByText('999999 characters')).toBeInTheDocument() }) }) describe('Edge Cases', () => { it('should render with empty label', () => { render() expect(screen.getByText('50 characters')).toBeInTheDocument() }) it('should render with special characters in label', () => { render() expect(screen.getByText('Chunk <#1> & \'test\'')).toBeInTheDocument() }) }) }) // Tests for ChunkContainer - wraps ChunkLabel with children content area describe('ChunkContainer', () => { beforeEach(() => { vi.clearAllMocks() }) describe('Rendering', () => { it('should render ChunkLabel with correct props', () => { render( Content here , ) expect(screen.getByText('Chunk #1')).toBeInTheDocument() expect(screen.getByText('200 characters')).toBeInTheDocument() }) it('should render children in the content area', () => { render(

Paragraph content

, ) expect(screen.getByText('Paragraph content')).toBeInTheDocument() }) it('should render the SelectionMod icon via ChunkLabel', () => { render( Content , ) expect(screen.getByTestId('selection-mod-icon')).toBeInTheDocument() }) }) describe('Structure', () => { it('should have space-y-2 on the outer container', () => { const { container } = render( Content, ) expect(container.firstElementChild).toHaveClass('space-y-2') }) it('should render children inside a styled content div', () => { render( Test child , ) const contentDiv = screen.getByText('Test child').parentElement expect(contentDiv).toHaveClass('body-md-regular', 'text-text-secondary') }) }) describe('Edge Cases', () => { it('should render without children', () => { const { container } = render( , ) expect(container.firstElementChild).toBeInTheDocument() expect(screen.getByText('Empty')).toBeInTheDocument() }) it('should render multiple children', () => { render( First Second , ) expect(screen.getByText('First')).toBeInTheDocument() expect(screen.getByText('Second')).toBeInTheDocument() }) it('should render with string children', () => { render( Plain text content , ) expect(screen.getByText('Plain text content')).toBeInTheDocument() }) }) }) // Tests for QAPreview - displays question and answer pair describe('QAPreview', () => { beforeEach(() => { vi.clearAllMocks() }) describe('Rendering', () => { it('should render the question text', () => { const qa = createQA() render() expect(screen.getByText('What is Dify?')).toBeInTheDocument() }) it('should render the answer text', () => { const qa = createQA() render() expect(screen.getByText('Dify is an open-source LLM app development platform.')).toBeInTheDocument() }) it('should render Q and A labels', () => { const qa = createQA() render() expect(screen.getByText('Q')).toBeInTheDocument() expect(screen.getByText('A')).toBeInTheDocument() }) }) describe('Structure', () => { it('should render Q label as a label element', () => { const qa = createQA() render() const qLabel = screen.getByText('Q') expect(qLabel.tagName).toBe('LABEL') }) it('should render A label as a label element', () => { const qa = createQA() render() const aLabel = screen.getByText('A') expect(aLabel.tagName).toBe('LABEL') }) it('should render question in a p element', () => { const qa = createQA() render() const questionEl = screen.getByText(qa.question) expect(questionEl.tagName).toBe('P') }) it('should render answer in a p element', () => { const qa = createQA() render() const answerEl = screen.getByText(qa.answer) expect(answerEl.tagName).toBe('P') }) it('should have the outer container with flex column layout', () => { const qa = createQA() const { container } = render() expect(container.firstElementChild).toHaveClass('flex', 'flex-col', 'gap-y-2') }) it('should apply text styling classes to question paragraph', () => { const qa = createQA() render() const questionEl = screen.getByText(qa.question) expect(questionEl).toHaveClass('body-md-regular', 'text-text-secondary') }) it('should apply text styling classes to answer paragraph', () => { const qa = createQA() render() const answerEl = screen.getByText(qa.answer) expect(answerEl).toHaveClass('body-md-regular', 'text-text-secondary') }) }) describe('Edge Cases', () => { it('should render with empty question', () => { const qa = createQA({ question: '' }) render() expect(screen.getByText('Q')).toBeInTheDocument() expect(screen.getByText('A')).toBeInTheDocument() }) it('should render with empty answer', () => { const qa = createQA({ answer: '' }) render() expect(screen.getByText('Q')).toBeInTheDocument() expect(screen.getByText(qa.question)).toBeInTheDocument() }) it('should render with long text', () => { const longText = 'x'.repeat(1000) const qa = createQA({ question: longText, answer: longText }) render() const elements = screen.getAllByText(longText) expect(elements).toHaveLength(2) }) it('should render with special characters in question and answer', () => { const qa = createQA({ question: 'What about & "quotes"?', answer: 'It handles \'single\' & "double" quotes.', }) render() expect(screen.getByText('What about & "quotes"?')).toBeInTheDocument() expect(screen.getByText('It handles \'single\' & "double" quotes.')).toBeInTheDocument() }) it('should render with multiline text', () => { const qa = createQA({ question: 'Line1\nLine2', answer: 'Answer1\nAnswer2', }) render() expect(screen.getByText(/Line1/)).toBeInTheDocument() expect(screen.getByText(/Answer1/)).toBeInTheDocument() }) }) })