mirror of https://github.com/langgenius/dify.git
test(billing): add human_input_email_delivery_enabled to billing utils tests; remove obsolete text generation result tests
This commit is contained in:
parent
3170e12b0a
commit
e405e801ce
|
|
@ -94,6 +94,7 @@ describe('billing utils', () => {
|
|||
knowledge_pipeline: {
|
||||
publish_enabled: false,
|
||||
},
|
||||
human_input_email_delivery_enabled: false,
|
||||
...overrides,
|
||||
})
|
||||
|
||||
|
|
|
|||
|
|
@ -1,133 +0,0 @@
|
|||
import type { FeedbackType } from '@/app/components/base/chat/chat/type'
|
||||
import { cleanup, render, screen } from '@testing-library/react'
|
||||
import { afterEach, describe, expect, it, vi } from 'vitest'
|
||||
import Result from './content'
|
||||
|
||||
// Only mock react-i18next for translations
|
||||
vi.mock('react-i18next', () => ({
|
||||
useTranslation: () => ({
|
||||
t: (key: string) => key,
|
||||
}),
|
||||
}))
|
||||
|
||||
// Mock copy-to-clipboard for the Header component
|
||||
vi.mock('copy-to-clipboard', () => ({
|
||||
default: vi.fn(() => true),
|
||||
}))
|
||||
|
||||
// Mock the format function from service/base
|
||||
vi.mock('@/service/base', () => ({
|
||||
format: (content: string) => content.replace(/\n/g, '<br>'),
|
||||
}))
|
||||
|
||||
afterEach(() => {
|
||||
cleanup()
|
||||
})
|
||||
|
||||
describe('Result (content)', () => {
|
||||
const mockOnFeedback = vi.fn()
|
||||
|
||||
const defaultProps = {
|
||||
content: 'Test content here',
|
||||
showFeedback: true,
|
||||
feedback: { rating: null } as FeedbackType,
|
||||
onFeedback: mockOnFeedback,
|
||||
}
|
||||
|
||||
beforeEach(() => {
|
||||
vi.clearAllMocks()
|
||||
})
|
||||
|
||||
describe('rendering', () => {
|
||||
it('should render the Header component', () => {
|
||||
render(<Result {...defaultProps} />)
|
||||
|
||||
// Header renders the result title
|
||||
expect(screen.getByText('generation.resultTitle')).toBeInTheDocument()
|
||||
})
|
||||
|
||||
it('should render content', () => {
|
||||
render(<Result {...defaultProps} />)
|
||||
|
||||
expect(screen.getByText('Test content here')).toBeInTheDocument()
|
||||
})
|
||||
|
||||
it('should render formatted content with line breaks', () => {
|
||||
render(
|
||||
<Result
|
||||
{...defaultProps}
|
||||
content={'Line 1\nLine 2'}
|
||||
/>,
|
||||
)
|
||||
|
||||
// The format function converts \n to <br>
|
||||
const contentDiv = document.querySelector('[class*="overflow-scroll"]')
|
||||
expect(contentDiv?.innerHTML).toContain('Line 1<br>Line 2')
|
||||
})
|
||||
|
||||
it('should have max height style', () => {
|
||||
render(<Result {...defaultProps} />)
|
||||
|
||||
const contentDiv = document.querySelector('[class*="overflow-scroll"]')
|
||||
expect(contentDiv).toHaveStyle({ maxHeight: '70vh' })
|
||||
})
|
||||
|
||||
it('should render with empty content', () => {
|
||||
render(
|
||||
<Result
|
||||
{...defaultProps}
|
||||
content=""
|
||||
/>,
|
||||
)
|
||||
|
||||
expect(screen.getByText('generation.resultTitle')).toBeInTheDocument()
|
||||
})
|
||||
|
||||
it('should render with HTML content safely', () => {
|
||||
render(
|
||||
<Result
|
||||
{...defaultProps}
|
||||
content="<script>alert('xss')</script>"
|
||||
/>,
|
||||
)
|
||||
|
||||
// Content is rendered via dangerouslySetInnerHTML
|
||||
const contentDiv = document.querySelector('[class*="overflow-scroll"]')
|
||||
expect(contentDiv).toBeInTheDocument()
|
||||
})
|
||||
})
|
||||
|
||||
describe('feedback props', () => {
|
||||
it('should pass showFeedback to Header', () => {
|
||||
render(
|
||||
<Result
|
||||
{...defaultProps}
|
||||
showFeedback={false}
|
||||
/>,
|
||||
)
|
||||
|
||||
// Feedback buttons should not be visible
|
||||
const feedbackArea = document.querySelector('[class*="space-x-1 rounded-lg border"]')
|
||||
expect(feedbackArea).not.toBeInTheDocument()
|
||||
})
|
||||
|
||||
it('should pass feedback to Header', () => {
|
||||
render(
|
||||
<Result
|
||||
{...defaultProps}
|
||||
feedback={{ rating: 'like' }}
|
||||
/>,
|
||||
)
|
||||
|
||||
// Like button should be highlighted
|
||||
const likeButton = document.querySelector('[class*="primary"]')
|
||||
expect(likeButton).toBeInTheDocument()
|
||||
})
|
||||
})
|
||||
|
||||
describe('memoization', () => {
|
||||
it('should be wrapped with React.memo', () => {
|
||||
expect((Result as unknown as { $$typeof: symbol }).$$typeof).toBe(Symbol.for('react.memo'))
|
||||
})
|
||||
})
|
||||
})
|
||||
|
|
@ -1,176 +0,0 @@
|
|||
import type { FeedbackType } from '@/app/components/base/chat/chat/type'
|
||||
import { cleanup, fireEvent, render, screen } from '@testing-library/react'
|
||||
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'
|
||||
import Header from './header'
|
||||
|
||||
// Only mock react-i18next for translations
|
||||
vi.mock('react-i18next', () => ({
|
||||
useTranslation: () => ({
|
||||
t: (key: string) => key,
|
||||
}),
|
||||
}))
|
||||
|
||||
// Mock copy-to-clipboard
|
||||
const mockCopy = vi.fn((_text: string) => true)
|
||||
vi.mock('copy-to-clipboard', () => ({
|
||||
default: (text: string) => mockCopy(text),
|
||||
}))
|
||||
|
||||
afterEach(() => {
|
||||
cleanup()
|
||||
})
|
||||
|
||||
describe('Header', () => {
|
||||
const mockOnFeedback = vi.fn()
|
||||
|
||||
const defaultProps = {
|
||||
result: 'Test result content',
|
||||
showFeedback: true,
|
||||
feedback: { rating: null } as FeedbackType,
|
||||
onFeedback: mockOnFeedback,
|
||||
}
|
||||
|
||||
beforeEach(() => {
|
||||
vi.clearAllMocks()
|
||||
})
|
||||
|
||||
describe('rendering', () => {
|
||||
it('should render the result title', () => {
|
||||
render(<Header {...defaultProps} />)
|
||||
|
||||
expect(screen.getByText('generation.resultTitle')).toBeInTheDocument()
|
||||
})
|
||||
|
||||
it('should render the copy button', () => {
|
||||
render(<Header {...defaultProps} />)
|
||||
|
||||
expect(screen.getByText('generation.copy')).toBeInTheDocument()
|
||||
})
|
||||
})
|
||||
|
||||
describe('copy functionality', () => {
|
||||
it('should copy result when copy button is clicked', () => {
|
||||
render(<Header {...defaultProps} />)
|
||||
|
||||
const copyButton = screen.getByText('generation.copy').closest('button')
|
||||
fireEvent.click(copyButton!)
|
||||
|
||||
expect(mockCopy).toHaveBeenCalledWith('Test result content')
|
||||
})
|
||||
})
|
||||
|
||||
describe('feedback buttons when showFeedback is true', () => {
|
||||
it('should show feedback buttons when no rating is given', () => {
|
||||
render(<Header {...defaultProps} />)
|
||||
|
||||
// Should show both thumbs up and down buttons
|
||||
const buttons = document.querySelectorAll('[class*="cursor-pointer"]')
|
||||
expect(buttons.length).toBeGreaterThan(0)
|
||||
})
|
||||
|
||||
it('should show like button highlighted when rating is like', () => {
|
||||
render(
|
||||
<Header
|
||||
{...defaultProps}
|
||||
feedback={{ rating: 'like' }}
|
||||
/>,
|
||||
)
|
||||
|
||||
// Should show the undo button for like
|
||||
const likeButton = document.querySelector('[class*="primary"]')
|
||||
expect(likeButton).toBeInTheDocument()
|
||||
})
|
||||
|
||||
it('should show dislike button highlighted when rating is dislike', () => {
|
||||
render(
|
||||
<Header
|
||||
{...defaultProps}
|
||||
feedback={{ rating: 'dislike' }}
|
||||
/>,
|
||||
)
|
||||
|
||||
// Should show the undo button for dislike
|
||||
const dislikeButton = document.querySelector('[class*="red"]')
|
||||
expect(dislikeButton).toBeInTheDocument()
|
||||
})
|
||||
|
||||
it('should call onFeedback with like when thumbs up is clicked', () => {
|
||||
render(<Header {...defaultProps} />)
|
||||
|
||||
// Find the thumbs up button (first one in the feedback area)
|
||||
const thumbButtons = document.querySelectorAll('[class*="cursor-pointer"]')
|
||||
const thumbsUp = Array.from(thumbButtons).find(btn =>
|
||||
btn.className.includes('rounded-md') && !btn.className.includes('primary'),
|
||||
)
|
||||
|
||||
if (thumbsUp) {
|
||||
fireEvent.click(thumbsUp)
|
||||
expect(mockOnFeedback).toHaveBeenCalledWith({ rating: 'like' })
|
||||
}
|
||||
})
|
||||
|
||||
it('should call onFeedback with dislike when thumbs down is clicked', () => {
|
||||
render(<Header {...defaultProps} />)
|
||||
|
||||
// Find the thumbs down button
|
||||
const thumbButtons = document.querySelectorAll('[class*="cursor-pointer"]')
|
||||
const thumbsDown = Array.from(thumbButtons).pop()
|
||||
|
||||
if (thumbsDown) {
|
||||
fireEvent.click(thumbsDown)
|
||||
expect(mockOnFeedback).toHaveBeenCalledWith({ rating: 'dislike' })
|
||||
}
|
||||
})
|
||||
|
||||
it('should call onFeedback with null when undo like is clicked', () => {
|
||||
render(
|
||||
<Header
|
||||
{...defaultProps}
|
||||
feedback={{ rating: 'like' }}
|
||||
/>,
|
||||
)
|
||||
|
||||
// When liked, clicking the like button again should undo it (has bg-primary-100 class)
|
||||
const likeButton = document.querySelector('[class*="bg-primary-100"]')
|
||||
expect(likeButton).toBeInTheDocument()
|
||||
fireEvent.click(likeButton!)
|
||||
expect(mockOnFeedback).toHaveBeenCalledWith({ rating: null })
|
||||
})
|
||||
|
||||
it('should call onFeedback with null when undo dislike is clicked', () => {
|
||||
render(
|
||||
<Header
|
||||
{...defaultProps}
|
||||
feedback={{ rating: 'dislike' }}
|
||||
/>,
|
||||
)
|
||||
|
||||
// When disliked, clicking the dislike button again should undo it (has bg-red-100 class)
|
||||
const dislikeButton = document.querySelector('[class*="bg-red-100"]')
|
||||
expect(dislikeButton).toBeInTheDocument()
|
||||
fireEvent.click(dislikeButton!)
|
||||
expect(mockOnFeedback).toHaveBeenCalledWith({ rating: null })
|
||||
})
|
||||
})
|
||||
|
||||
describe('feedback buttons when showFeedback is false', () => {
|
||||
it('should not show feedback buttons', () => {
|
||||
render(
|
||||
<Header
|
||||
{...defaultProps}
|
||||
showFeedback={false}
|
||||
/>,
|
||||
)
|
||||
|
||||
// Should not show feedback area buttons (only copy button)
|
||||
const feedbackArea = document.querySelector('[class*="space-x-1 rounded-lg border"]')
|
||||
expect(feedbackArea).not.toBeInTheDocument()
|
||||
})
|
||||
})
|
||||
|
||||
describe('memoization', () => {
|
||||
it('should be wrapped with React.memo', () => {
|
||||
expect((Header as unknown as { $$typeof: symbol }).$$typeof).toBe(Symbol.for('react.memo'))
|
||||
})
|
||||
})
|
||||
})
|
||||
Loading…
Reference in New Issue