mirror of https://github.com/langgenius/dify.git
269 lines
8.4 KiB
TypeScript
269 lines
8.4 KiB
TypeScript
import { fireEvent, render, screen } from '@testing-library/react'
|
|
import { describe, expect, it, vi } from 'vitest'
|
|
import { DataType } from '../types'
|
|
import CreateContent from './create-content'
|
|
|
|
type ModalLikeWrapProps = {
|
|
children: React.ReactNode
|
|
title: string
|
|
onClose?: () => void
|
|
onConfirm: () => void
|
|
beforeHeader?: React.ReactNode
|
|
}
|
|
|
|
type OptionCardProps = {
|
|
title: string
|
|
selected: boolean
|
|
onSelect: () => void
|
|
}
|
|
|
|
type FieldProps = {
|
|
label: string
|
|
children: React.ReactNode
|
|
}
|
|
|
|
// Mock ModalLikeWrap
|
|
vi.mock('../../../base/modal-like-wrap', () => ({
|
|
default: ({ children, title, onClose, onConfirm, beforeHeader }: ModalLikeWrapProps) => (
|
|
<div data-testid="modal-wrap">
|
|
<div data-testid="modal-title">{title}</div>
|
|
{!!beforeHeader && <div data-testid="before-header">{beforeHeader}</div>}
|
|
<div data-testid="modal-content">{children}</div>
|
|
<button data-testid="close-btn" onClick={onClose}>Close</button>
|
|
<button data-testid="confirm-btn" onClick={onConfirm}>Confirm</button>
|
|
</div>
|
|
),
|
|
}))
|
|
|
|
// Mock OptionCard
|
|
vi.mock('../../../workflow/nodes/_base/components/option-card', () => ({
|
|
default: ({ title, selected, onSelect }: OptionCardProps) => (
|
|
<button
|
|
data-testid={`option-${title.toLowerCase()}`}
|
|
data-selected={selected}
|
|
onClick={onSelect}
|
|
>
|
|
{title}
|
|
</button>
|
|
),
|
|
}))
|
|
|
|
// Mock Field
|
|
vi.mock('./field', () => ({
|
|
default: ({ label, children }: FieldProps) => (
|
|
<div data-testid="field">
|
|
<label data-testid="field-label">{label}</label>
|
|
{children}
|
|
</div>
|
|
),
|
|
}))
|
|
|
|
describe('CreateContent', () => {
|
|
describe('Rendering', () => {
|
|
it('should render without crashing', () => {
|
|
const handleSave = vi.fn()
|
|
render(<CreateContent onSave={handleSave} />)
|
|
expect(screen.getByTestId('modal-wrap')).toBeInTheDocument()
|
|
})
|
|
|
|
it('should render modal title', () => {
|
|
const handleSave = vi.fn()
|
|
render(<CreateContent onSave={handleSave} />)
|
|
expect(screen.getByTestId('modal-title')).toBeInTheDocument()
|
|
})
|
|
|
|
it('should render type selection options', () => {
|
|
const handleSave = vi.fn()
|
|
render(<CreateContent onSave={handleSave} />)
|
|
expect(screen.getByTestId('option-string')).toBeInTheDocument()
|
|
expect(screen.getByTestId('option-number')).toBeInTheDocument()
|
|
expect(screen.getByTestId('option-time')).toBeInTheDocument()
|
|
})
|
|
|
|
it('should render name input field', () => {
|
|
const handleSave = vi.fn()
|
|
render(<CreateContent onSave={handleSave} />)
|
|
expect(screen.getByRole('textbox')).toBeInTheDocument()
|
|
})
|
|
|
|
it('should render confirm button', () => {
|
|
const handleSave = vi.fn()
|
|
render(<CreateContent onSave={handleSave} />)
|
|
expect(screen.getByTestId('confirm-btn')).toBeInTheDocument()
|
|
})
|
|
|
|
it('should render close button', () => {
|
|
const handleSave = vi.fn()
|
|
render(<CreateContent onSave={handleSave} />)
|
|
expect(screen.getByTestId('close-btn')).toBeInTheDocument()
|
|
})
|
|
})
|
|
|
|
describe('Type Selection', () => {
|
|
it('should default to string type', () => {
|
|
const handleSave = vi.fn()
|
|
render(<CreateContent onSave={handleSave} />)
|
|
expect(screen.getByTestId('option-string')).toHaveAttribute('data-selected', 'true')
|
|
})
|
|
|
|
it('should select number type when clicked', () => {
|
|
const handleSave = vi.fn()
|
|
render(<CreateContent onSave={handleSave} />)
|
|
|
|
fireEvent.click(screen.getByTestId('option-number'))
|
|
|
|
expect(screen.getByTestId('option-number')).toHaveAttribute('data-selected', 'true')
|
|
})
|
|
|
|
it('should select time type when clicked', () => {
|
|
const handleSave = vi.fn()
|
|
render(<CreateContent onSave={handleSave} />)
|
|
|
|
fireEvent.click(screen.getByTestId('option-time'))
|
|
|
|
expect(screen.getByTestId('option-time')).toHaveAttribute('data-selected', 'true')
|
|
})
|
|
|
|
it('should deselect previous type when new type is selected', () => {
|
|
const handleSave = vi.fn()
|
|
render(<CreateContent onSave={handleSave} />)
|
|
|
|
// Initially string is selected
|
|
expect(screen.getByTestId('option-string')).toHaveAttribute('data-selected', 'true')
|
|
|
|
// Select number
|
|
fireEvent.click(screen.getByTestId('option-number'))
|
|
|
|
expect(screen.getByTestId('option-string')).toHaveAttribute('data-selected', 'false')
|
|
expect(screen.getByTestId('option-number')).toHaveAttribute('data-selected', 'true')
|
|
})
|
|
})
|
|
|
|
describe('Name Input', () => {
|
|
it('should update name when typing', () => {
|
|
const handleSave = vi.fn()
|
|
render(<CreateContent onSave={handleSave} />)
|
|
|
|
const input = screen.getByRole('textbox')
|
|
fireEvent.change(input, { target: { value: 'new_field' } })
|
|
|
|
expect(input).toHaveValue('new_field')
|
|
})
|
|
|
|
it('should start with empty name', () => {
|
|
const handleSave = vi.fn()
|
|
render(<CreateContent onSave={handleSave} />)
|
|
|
|
expect(screen.getByRole('textbox')).toHaveValue('')
|
|
})
|
|
})
|
|
|
|
describe('User Interactions', () => {
|
|
it('should call onSave with type and name when confirmed', () => {
|
|
const handleSave = vi.fn()
|
|
render(<CreateContent onSave={handleSave} />)
|
|
|
|
const input = screen.getByRole('textbox')
|
|
fireEvent.change(input, { target: { value: 'test_field' } })
|
|
fireEvent.click(screen.getByTestId('confirm-btn'))
|
|
|
|
expect(handleSave).toHaveBeenCalledWith({
|
|
type: DataType.string,
|
|
name: 'test_field',
|
|
})
|
|
})
|
|
|
|
it('should call onSave with correct type after changing type', () => {
|
|
const handleSave = vi.fn()
|
|
render(<CreateContent onSave={handleSave} />)
|
|
|
|
fireEvent.click(screen.getByTestId('option-number'))
|
|
const input = screen.getByRole('textbox')
|
|
fireEvent.change(input, { target: { value: 'num_field' } })
|
|
fireEvent.click(screen.getByTestId('confirm-btn'))
|
|
|
|
expect(handleSave).toHaveBeenCalledWith({
|
|
type: DataType.number,
|
|
name: 'num_field',
|
|
})
|
|
})
|
|
|
|
it('should call onClose when close button is clicked', () => {
|
|
const handleSave = vi.fn()
|
|
const handleClose = vi.fn()
|
|
render(<CreateContent onSave={handleSave} onClose={handleClose} />)
|
|
|
|
fireEvent.click(screen.getByTestId('close-btn'))
|
|
|
|
expect(handleClose).toHaveBeenCalled()
|
|
})
|
|
})
|
|
|
|
describe('Back Button', () => {
|
|
it('should show back button when hasBack is true', () => {
|
|
const handleSave = vi.fn()
|
|
render(<CreateContent onSave={handleSave} hasBack />)
|
|
|
|
expect(screen.getByTestId('before-header')).toBeInTheDocument()
|
|
})
|
|
|
|
it('should not show back button when hasBack is false', () => {
|
|
const handleSave = vi.fn()
|
|
render(<CreateContent onSave={handleSave} hasBack={false} />)
|
|
|
|
expect(screen.queryByTestId('before-header')).not.toBeInTheDocument()
|
|
})
|
|
|
|
it('should call onBack when back button is clicked', () => {
|
|
const handleSave = vi.fn()
|
|
const handleBack = vi.fn()
|
|
render(<CreateContent onSave={handleSave} hasBack onBack={handleBack} />)
|
|
|
|
const backButton = screen.getByTestId('before-header')
|
|
// Find the clickable element inside
|
|
const clickable = backButton.querySelector('.cursor-pointer') || backButton.firstChild
|
|
if (clickable)
|
|
fireEvent.click(clickable)
|
|
|
|
// The back functionality is tested through the actual implementation
|
|
expect(screen.getByTestId('before-header')).toBeInTheDocument()
|
|
})
|
|
})
|
|
|
|
describe('Edge Cases', () => {
|
|
it('should handle empty name submission', () => {
|
|
const handleSave = vi.fn()
|
|
render(<CreateContent onSave={handleSave} />)
|
|
|
|
fireEvent.click(screen.getByTestId('confirm-btn'))
|
|
|
|
expect(handleSave).toHaveBeenCalledWith({
|
|
type: DataType.string,
|
|
name: '',
|
|
})
|
|
})
|
|
|
|
it('should handle type cycling', () => {
|
|
const handleSave = vi.fn()
|
|
render(<CreateContent onSave={handleSave} />)
|
|
|
|
// Cycle through all types
|
|
fireEvent.click(screen.getByTestId('option-number'))
|
|
fireEvent.click(screen.getByTestId('option-time'))
|
|
fireEvent.click(screen.getByTestId('option-string'))
|
|
|
|
expect(screen.getByTestId('option-string')).toHaveAttribute('data-selected', 'true')
|
|
})
|
|
|
|
it('should handle special characters in name', () => {
|
|
const handleSave = vi.fn()
|
|
render(<CreateContent onSave={handleSave} />)
|
|
|
|
const input = screen.getByRole('textbox')
|
|
fireEvent.change(input, { target: { value: 'test_field_123' } })
|
|
|
|
expect(input).toHaveValue('test_field_123')
|
|
})
|
|
})
|
|
})
|