diff --git a/web/app/components/billing/utils/index.spec.ts b/web/app/components/billing/utils/index.spec.ts
index 03a159c18a..d85155d6ff 100644
--- a/web/app/components/billing/utils/index.spec.ts
+++ b/web/app/components/billing/utils/index.spec.ts
@@ -94,6 +94,7 @@ describe('billing utils', () => {
knowledge_pipeline: {
publish_enabled: false,
},
+ human_input_email_delivery_enabled: false,
...overrides,
})
diff --git a/web/app/components/share/text-generation/result/content.spec.tsx b/web/app/components/share/text-generation/result/content.spec.tsx
deleted file mode 100644
index 242ae7aa5f..0000000000
--- a/web/app/components/share/text-generation/result/content.spec.tsx
+++ /dev/null
@@ -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, '
'),
-}))
-
-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()
-
- // Header renders the result title
- expect(screen.getByText('generation.resultTitle')).toBeInTheDocument()
- })
-
- it('should render content', () => {
- render()
-
- expect(screen.getByText('Test content here')).toBeInTheDocument()
- })
-
- it('should render formatted content with line breaks', () => {
- render(
- ,
- )
-
- // The format function converts \n to
- const contentDiv = document.querySelector('[class*="overflow-scroll"]')
- expect(contentDiv?.innerHTML).toContain('Line 1
Line 2')
- })
-
- it('should have max height style', () => {
- render()
-
- const contentDiv = document.querySelector('[class*="overflow-scroll"]')
- expect(contentDiv).toHaveStyle({ maxHeight: '70vh' })
- })
-
- it('should render with empty content', () => {
- render(
- ,
- )
-
- expect(screen.getByText('generation.resultTitle')).toBeInTheDocument()
- })
-
- it('should render with HTML content safely', () => {
- render(
- ,
- )
-
- // 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(
- ,
- )
-
- // 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(
- ,
- )
-
- // 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'))
- })
- })
-})
diff --git a/web/app/components/share/text-generation/result/header.spec.tsx b/web/app/components/share/text-generation/result/header.spec.tsx
deleted file mode 100644
index b2ef0fadc4..0000000000
--- a/web/app/components/share/text-generation/result/header.spec.tsx
+++ /dev/null
@@ -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()
-
- expect(screen.getByText('generation.resultTitle')).toBeInTheDocument()
- })
-
- it('should render the copy button', () => {
- render()
-
- expect(screen.getByText('generation.copy')).toBeInTheDocument()
- })
- })
-
- describe('copy functionality', () => {
- it('should copy result when copy button is clicked', () => {
- render()
-
- 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()
-
- // 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(
- ,
- )
-
- // 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(
- ,
- )
-
- // 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()
-
- // 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()
-
- // 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(
- ,
- )
-
- // 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(
- ,
- )
-
- // 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(
- ,
- )
-
- // 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'))
- })
- })
-})