mirror of
https://github.com/langgenius/dify.git
synced 2026-04-16 02:16:57 +08:00
107 lines
3.5 KiB
TypeScript
107 lines
3.5 KiB
TypeScript
import type { FileUpload } from '@/app/components/base/features/types'
|
|
import { render, screen, waitFor } from '@testing-library/react'
|
|
import userEvent from '@testing-library/user-event'
|
|
import { beforeEach, describe, expect, it, vi } from 'vitest'
|
|
import FileUploaderInAttachmentWrapper from '@/app/components/base/file-uploader/file-uploader-in-attachment'
|
|
import FileUploaderInChatInput from '@/app/components/base/file-uploader/file-uploader-in-chat-input'
|
|
import { FileContextProvider } from '@/app/components/base/file-uploader/store'
|
|
import { TransferMethod } from '@/types/app'
|
|
|
|
const mockUploadRemoteFileInfo = vi.fn()
|
|
|
|
vi.mock('@/next/navigation', () => ({
|
|
useParams: () => ({}),
|
|
}))
|
|
|
|
vi.mock('@/service/common', () => ({
|
|
uploadRemoteFileInfo: (...args: unknown[]) => mockUploadRemoteFileInfo(...args),
|
|
}))
|
|
|
|
const createFileConfig = (overrides: Partial<FileUpload> = {}): FileUpload => ({
|
|
enabled: true,
|
|
allowed_file_types: ['document'],
|
|
allowed_file_extensions: [],
|
|
allowed_file_upload_methods: [TransferMethod.remote_url],
|
|
number_limits: 5,
|
|
preview_config: {
|
|
enabled: false,
|
|
mode: 'current_page',
|
|
file_type_list: [],
|
|
},
|
|
...overrides,
|
|
} as FileUpload)
|
|
|
|
const renderChatInput = (fileConfig: FileUpload, readonly = false) => {
|
|
return render(
|
|
<FileContextProvider>
|
|
<FileUploaderInChatInput fileConfig={fileConfig} readonly={readonly} />
|
|
</FileContextProvider>,
|
|
)
|
|
}
|
|
|
|
describe('Base File Uploader Flow', () => {
|
|
beforeEach(() => {
|
|
vi.clearAllMocks()
|
|
mockUploadRemoteFileInfo.mockResolvedValue({
|
|
id: 'remote-file-1',
|
|
mime_type: 'application/pdf',
|
|
size: 2048,
|
|
name: 'guide.pdf',
|
|
url: 'https://cdn.example.com/guide.pdf',
|
|
})
|
|
})
|
|
|
|
it('uploads a remote file from the attachment wrapper and pushes the updated file list to consumers', async () => {
|
|
const user = userEvent.setup()
|
|
const onChange = vi.fn()
|
|
|
|
render(
|
|
<FileUploaderInAttachmentWrapper
|
|
value={[]}
|
|
onChange={onChange}
|
|
fileConfig={createFileConfig()}
|
|
/>,
|
|
)
|
|
|
|
await user.click(screen.getByRole('button', { name: /fileUploader\.pasteFileLink/i }))
|
|
await user.type(screen.getByPlaceholderText(/fileUploader\.pasteFileLinkInputPlaceholder/i), 'https://example.com/guide.pdf')
|
|
await user.click(screen.getByRole('button', { name: /operation\.ok/i }))
|
|
|
|
await waitFor(() => {
|
|
expect(mockUploadRemoteFileInfo).toHaveBeenCalledWith('https://example.com/guide.pdf', false)
|
|
})
|
|
|
|
await waitFor(() => {
|
|
expect(onChange).toHaveBeenLastCalledWith([
|
|
expect.objectContaining({
|
|
name: 'https://example.com/guide.pdf',
|
|
uploadedId: 'remote-file-1',
|
|
url: 'https://cdn.example.com/guide.pdf',
|
|
progress: 100,
|
|
}),
|
|
])
|
|
})
|
|
|
|
expect(screen.getByText('https://example.com/guide.pdf')).toBeInTheDocument()
|
|
})
|
|
|
|
it('opens the link picker from chat input and keeps the trigger disabled in readonly mode', async () => {
|
|
const user = userEvent.setup()
|
|
const fileConfig = createFileConfig()
|
|
|
|
const { unmount } = renderChatInput(fileConfig)
|
|
|
|
const activeTrigger = screen.getByRole('button')
|
|
expect(activeTrigger).toBeEnabled()
|
|
|
|
await user.click(activeTrigger)
|
|
expect(screen.getByPlaceholderText(/fileUploader\.pasteFileLinkInputPlaceholder/i)).toBeInTheDocument()
|
|
expect(screen.queryByText(/fileUploader\.uploadFromComputer/i)).not.toBeInTheDocument()
|
|
|
|
unmount()
|
|
renderChatInput(fileConfig, true)
|
|
|
|
expect(screen.getByRole('button')).toBeDisabled()
|
|
})
|
|
})
|