mirror of
https://github.com/langgenius/dify.git
synced 2026-04-21 19:27:40 +08:00
2699 lines
87 KiB
TypeScript
2699 lines
87 KiB
TypeScript
import type { Datasource } from '@/app/components/rag-pipeline/components/panel/test-run/types'
|
|
import type { DataSourceNodeType } from '@/app/components/workflow/nodes/data-source/types'
|
|
import type { Node } from '@/app/components/workflow/types'
|
|
import type { NotionPage } from '@/models/common'
|
|
import type { CrawlResultItem, CustomFile, DocumentItem, FileItem } from '@/models/datasets'
|
|
import type { InitialDocumentDetail, OnlineDriveFile } from '@/models/pipeline'
|
|
import { act, fireEvent, render, renderHook, screen } from '@testing-library/react'
|
|
import * as React from 'react'
|
|
import { BlockEnum } from '@/app/components/workflow/types'
|
|
import { DatasourceType } from '@/models/pipeline'
|
|
import { TransferMethod } from '@/types/app'
|
|
import {
|
|
useAddDocumentsSteps,
|
|
useDatasourceActions,
|
|
useDatasourceOptions,
|
|
useDatasourceUIState,
|
|
useLocalFile,
|
|
useOnlineDocument,
|
|
useOnlineDrive,
|
|
useWebsiteCrawl,
|
|
} from './hooks'
|
|
import { StepOneContent, StepThreeContent, StepTwoContent } from './steps'
|
|
import { StepOnePreview, StepTwoPreview } from './steps/preview-panel'
|
|
import {
|
|
buildLocalFileDatasourceInfo,
|
|
buildOnlineDocumentDatasourceInfo,
|
|
buildOnlineDriveDatasourceInfo,
|
|
buildWebsiteCrawlDatasourceInfo,
|
|
} from './utils/datasource-info-builder'
|
|
|
|
// ==========================================
|
|
// Mock External Dependencies Only
|
|
// ==========================================
|
|
|
|
// Mock context providers
|
|
const mockPlan = {
|
|
usage: { vectorSpace: 50 },
|
|
total: { vectorSpace: 100 },
|
|
type: 'professional',
|
|
}
|
|
|
|
vi.mock('@/context/provider-context', () => ({
|
|
useProviderContextSelector: (selector: (state: { plan: typeof mockPlan, enableBilling: boolean }) => unknown) =>
|
|
selector({ plan: mockPlan, enableBilling: true }),
|
|
}))
|
|
|
|
vi.mock('@/context/dataset-detail', () => ({
|
|
useDatasetDetailContextWithSelector: (selector: (state: { dataset: { pipeline_id: string } }) => unknown) =>
|
|
selector({ dataset: { pipeline_id: 'test-pipeline-id' } }),
|
|
}))
|
|
|
|
// Mock API services
|
|
const mockRunPublishedPipeline = vi.fn()
|
|
vi.mock('@/service/use-pipeline', () => ({
|
|
usePublishedPipelineInfo: () => ({
|
|
data: {
|
|
graph: {
|
|
nodes: [
|
|
{
|
|
id: 'node-1',
|
|
data: {
|
|
type: 'data-source',
|
|
title: 'Local File',
|
|
provider_type: DatasourceType.localFile,
|
|
plugin_id: 'plugin-1',
|
|
fileExtensions: ['.txt', '.pdf'],
|
|
},
|
|
},
|
|
],
|
|
},
|
|
},
|
|
isFetching: false,
|
|
}),
|
|
useRunPublishedPipeline: () => ({
|
|
mutateAsync: mockRunPublishedPipeline,
|
|
isIdle: true,
|
|
isPending: false,
|
|
}),
|
|
}))
|
|
|
|
vi.mock('@/service/use-common', () => ({
|
|
useFileUploadConfig: () => ({
|
|
data: {
|
|
file_size_limit: 15,
|
|
batch_count_limit: 5,
|
|
},
|
|
}),
|
|
}))
|
|
|
|
// Mock amplitude tracking
|
|
vi.mock('@/app/components/base/amplitude', () => ({
|
|
trackEvent: vi.fn(),
|
|
}))
|
|
|
|
// Mock next/navigation
|
|
vi.mock('next/navigation', () => ({
|
|
useParams: () => ({ datasetId: 'test-dataset-id' }),
|
|
useRouter: () => ({
|
|
push: vi.fn(),
|
|
replace: vi.fn(),
|
|
back: vi.fn(),
|
|
}),
|
|
usePathname: () => '/datasets/test-dataset-id/documents/create-from-pipeline',
|
|
}))
|
|
|
|
// Mock next/link
|
|
vi.mock('next/link', () => ({
|
|
default: ({ children, href }: { children: React.ReactNode, href: string }) => (
|
|
<a href={href}>{children}</a>
|
|
),
|
|
}))
|
|
|
|
// Mock billing components (external dependencies)
|
|
vi.mock('@/app/components/billing/vector-space-full', () => ({
|
|
default: () => <div data-testid="vector-space-full">Vector Space Full</div>,
|
|
}))
|
|
|
|
vi.mock('@/app/components/billing/plan-upgrade-modal', () => ({
|
|
default: ({ show, onClose }: { show: boolean, onClose: () => void }) => (
|
|
show
|
|
? (
|
|
<div data-testid="plan-upgrade-modal">
|
|
<button data-testid="close-modal" onClick={onClose}>Close</button>
|
|
</div>
|
|
)
|
|
: null
|
|
),
|
|
}))
|
|
|
|
vi.mock('@/app/components/datasets/create/step-one/upgrade-card', () => ({
|
|
default: () => <div data-testid="upgrade-card">Upgrade Card</div>,
|
|
}))
|
|
|
|
// Mock zustand store
|
|
// eslint-disable-next-line ts/no-explicit-any
|
|
type MockDataSourceStore = any
|
|
|
|
const mockStoreState = {
|
|
localFileList: [] as FileItem[],
|
|
currentLocalFile: undefined as CustomFile | undefined,
|
|
setCurrentLocalFile: vi.fn(),
|
|
documentsData: [] as { workspace_id: string, pages: { page_id: string }[] }[],
|
|
onlineDocuments: [] as (NotionPage & { workspace_id: string })[],
|
|
currentDocument: undefined as (NotionPage & { workspace_id: string }) | undefined,
|
|
setDocumentsData: vi.fn(),
|
|
setSearchValue: vi.fn(),
|
|
setSelectedPagesId: vi.fn(),
|
|
setOnlineDocuments: vi.fn(),
|
|
setCurrentDocument: vi.fn(),
|
|
websitePages: [] as CrawlResultItem[],
|
|
currentWebsite: undefined as CrawlResultItem | undefined,
|
|
setCurrentWebsite: vi.fn(),
|
|
setPreviewIndex: vi.fn(),
|
|
setStep: vi.fn(),
|
|
setCrawlResult: vi.fn(),
|
|
setWebsitePages: vi.fn(),
|
|
onlineDriveFileList: [] as OnlineDriveFile[],
|
|
selectedFileIds: [] as string[],
|
|
setOnlineDriveFileList: vi.fn(),
|
|
setBucket: vi.fn(),
|
|
setPrefix: vi.fn(),
|
|
setKeywords: vi.fn(),
|
|
setSelectedFileIds: vi.fn(),
|
|
previewLocalFileRef: { current: undefined },
|
|
previewOnlineDocumentRef: { current: undefined },
|
|
previewWebsitePageRef: { current: undefined },
|
|
previewOnlineDriveFileRef: { current: undefined },
|
|
currentCredentialId: '',
|
|
setCurrentCredentialId: vi.fn(),
|
|
currentNodeIdRef: { current: '' },
|
|
bucket: '',
|
|
}
|
|
|
|
vi.mock('./data-source/store', () => ({
|
|
useDataSourceStore: () => ({
|
|
getState: () => mockStoreState,
|
|
}),
|
|
useDataSourceStoreWithSelector: (selector: (state: typeof mockStoreState) => unknown) => selector(mockStoreState),
|
|
}))
|
|
|
|
vi.mock('./data-source/store/provider', () => ({
|
|
default: ({ children }: { children: React.ReactNode }) => <>{children}</>,
|
|
}))
|
|
|
|
// ==========================================
|
|
// Test Data Factories
|
|
// ==========================================
|
|
|
|
const createMockDatasource = (overrides?: Partial<Datasource>): Datasource => ({
|
|
nodeId: 'node-1',
|
|
nodeData: {
|
|
type: 'data-source',
|
|
title: 'Local File',
|
|
desc: '',
|
|
provider_type: DatasourceType.localFile,
|
|
plugin_id: 'plugin-1',
|
|
provider_name: 'local',
|
|
datasource_name: 'local-file',
|
|
datasource_label: 'Local File',
|
|
fileExtensions: ['.txt', '.pdf'],
|
|
} as unknown as DataSourceNodeType,
|
|
...overrides,
|
|
})
|
|
|
|
const createMockFile = (overrides?: Partial<CustomFile>): CustomFile => ({
|
|
id: 'file-1',
|
|
name: 'test.txt',
|
|
type: 'text/plain',
|
|
size: 1024,
|
|
extension: '.txt',
|
|
mime_type: 'text/plain',
|
|
...overrides,
|
|
} as CustomFile)
|
|
|
|
const createMockFileItem = (overrides?: Partial<FileItem>): FileItem => ({
|
|
file: createMockFile(),
|
|
progress: 100,
|
|
...overrides,
|
|
} as FileItem)
|
|
|
|
const createMockNotionPage = (overrides?: Partial<NotionPage & { workspace_id: string }>): NotionPage & { workspace_id: string } => ({
|
|
page_id: 'page-1',
|
|
page_name: 'Test Page',
|
|
page_icon: null,
|
|
type: 'page',
|
|
workspace_id: 'workspace-1',
|
|
...overrides,
|
|
} as NotionPage & { workspace_id: string })
|
|
|
|
const createMockCrawlResult = (overrides?: Partial<CrawlResultItem>): CrawlResultItem => ({
|
|
source_url: 'https://example.com',
|
|
title: 'Test Page',
|
|
markdown: '# Test',
|
|
description: 'A test page',
|
|
...overrides,
|
|
} as CrawlResultItem)
|
|
|
|
const createMockOnlineDriveFile = (overrides?: Partial<OnlineDriveFile>): OnlineDriveFile => ({
|
|
id: 'drive-file-1',
|
|
name: 'test-file.pdf',
|
|
type: 'file',
|
|
...overrides,
|
|
} as OnlineDriveFile)
|
|
|
|
// ==========================================
|
|
// Hook Tests - useAddDocumentsSteps
|
|
// ==========================================
|
|
describe('useAddDocumentsSteps', () => {
|
|
it('should initialize with step 1', () => {
|
|
const { result } = renderHook(() => useAddDocumentsSteps())
|
|
expect(result.current.currentStep).toBe(1)
|
|
})
|
|
|
|
it('should return 3 steps', () => {
|
|
const { result } = renderHook(() => useAddDocumentsSteps())
|
|
expect(result.current.steps).toHaveLength(3)
|
|
})
|
|
|
|
it('should increment step when handleNextStep is called', () => {
|
|
const { result } = renderHook(() => useAddDocumentsSteps())
|
|
|
|
act(() => {
|
|
result.current.handleNextStep()
|
|
})
|
|
|
|
expect(result.current.currentStep).toBe(2)
|
|
})
|
|
|
|
it('should decrement step when handleBackStep is called', () => {
|
|
const { result } = renderHook(() => useAddDocumentsSteps())
|
|
|
|
act(() => {
|
|
result.current.handleNextStep()
|
|
result.current.handleBackStep()
|
|
})
|
|
|
|
expect(result.current.currentStep).toBe(1)
|
|
})
|
|
|
|
it('should maintain callback reference stability (handleNextStep)', () => {
|
|
const { result, rerender } = renderHook(() => useAddDocumentsSteps())
|
|
const firstRef = result.current.handleNextStep
|
|
rerender()
|
|
expect(result.current.handleNextStep).toBe(firstRef)
|
|
})
|
|
|
|
it('should maintain callback reference stability (handleBackStep)', () => {
|
|
const { result, rerender } = renderHook(() => useAddDocumentsSteps())
|
|
const firstRef = result.current.handleBackStep
|
|
rerender()
|
|
expect(result.current.handleBackStep).toBe(firstRef)
|
|
})
|
|
})
|
|
|
|
// ==========================================
|
|
// Hook Tests - useDatasourceUIState
|
|
// ==========================================
|
|
describe('useDatasourceUIState', () => {
|
|
const defaultParams = {
|
|
datasource: undefined as Datasource | undefined,
|
|
allFileLoaded: false,
|
|
localFileListLength: 0,
|
|
onlineDocumentsLength: 0,
|
|
websitePagesLength: 0,
|
|
selectedFileIdsLength: 0,
|
|
onlineDriveFileList: [] as OnlineDriveFile[],
|
|
isVectorSpaceFull: false,
|
|
enableBilling: true,
|
|
currentWorkspacePagesLength: 0,
|
|
fileUploadConfig: { file_size_limit: 15, batch_count_limit: 5 },
|
|
}
|
|
|
|
describe('nextBtnDisabled', () => {
|
|
it('should return true when no datasource is selected', () => {
|
|
const { result } = renderHook(() => useDatasourceUIState(defaultParams))
|
|
expect(result.current.nextBtnDisabled).toBe(true)
|
|
})
|
|
|
|
it('should return true for localFile when no files are loaded', () => {
|
|
const { result } = renderHook(() => useDatasourceUIState({
|
|
...defaultParams,
|
|
datasource: createMockDatasource(),
|
|
allFileLoaded: false,
|
|
localFileListLength: 0,
|
|
}))
|
|
expect(result.current.nextBtnDisabled).toBe(true)
|
|
})
|
|
|
|
it('should return false for localFile when files are loaded', () => {
|
|
const { result } = renderHook(() => useDatasourceUIState({
|
|
...defaultParams,
|
|
datasource: createMockDatasource(),
|
|
allFileLoaded: true,
|
|
localFileListLength: 1,
|
|
}))
|
|
expect(result.current.nextBtnDisabled).toBe(false)
|
|
})
|
|
|
|
it('should return true for onlineDocument when no documents are selected', () => {
|
|
const { result } = renderHook(() => useDatasourceUIState({
|
|
...defaultParams,
|
|
datasource: createMockDatasource({
|
|
nodeData: {
|
|
...createMockDatasource().nodeData,
|
|
provider_type: DatasourceType.onlineDocument,
|
|
},
|
|
}),
|
|
onlineDocumentsLength: 0,
|
|
}))
|
|
expect(result.current.nextBtnDisabled).toBe(true)
|
|
})
|
|
|
|
it('should return false for onlineDocument when documents are selected', () => {
|
|
const { result } = renderHook(() => useDatasourceUIState({
|
|
...defaultParams,
|
|
datasource: createMockDatasource({
|
|
nodeData: {
|
|
...createMockDatasource().nodeData,
|
|
provider_type: DatasourceType.onlineDocument,
|
|
},
|
|
}),
|
|
onlineDocumentsLength: 1,
|
|
}))
|
|
expect(result.current.nextBtnDisabled).toBe(false)
|
|
})
|
|
})
|
|
|
|
describe('isShowVectorSpaceFull', () => {
|
|
it('should return false when vector space is not full', () => {
|
|
const { result } = renderHook(() => useDatasourceUIState({
|
|
...defaultParams,
|
|
datasource: createMockDatasource(),
|
|
allFileLoaded: true,
|
|
isVectorSpaceFull: false,
|
|
}))
|
|
expect(result.current.isShowVectorSpaceFull).toBe(false)
|
|
})
|
|
|
|
it('should return true when vector space is full and billing is enabled', () => {
|
|
const { result } = renderHook(() => useDatasourceUIState({
|
|
...defaultParams,
|
|
datasource: createMockDatasource(),
|
|
allFileLoaded: true,
|
|
isVectorSpaceFull: true,
|
|
enableBilling: true,
|
|
}))
|
|
expect(result.current.isShowVectorSpaceFull).toBe(true)
|
|
})
|
|
|
|
it('should return false when vector space is full but billing is disabled', () => {
|
|
const { result } = renderHook(() => useDatasourceUIState({
|
|
...defaultParams,
|
|
datasource: createMockDatasource(),
|
|
allFileLoaded: true,
|
|
isVectorSpaceFull: true,
|
|
enableBilling: false,
|
|
}))
|
|
expect(result.current.isShowVectorSpaceFull).toBe(false)
|
|
})
|
|
})
|
|
|
|
describe('showSelect', () => {
|
|
it('should return false for localFile datasource', () => {
|
|
const { result } = renderHook(() => useDatasourceUIState({
|
|
...defaultParams,
|
|
datasource: createMockDatasource(),
|
|
}))
|
|
expect(result.current.showSelect).toBe(false)
|
|
})
|
|
|
|
it('should return true for onlineDocument when pages exist', () => {
|
|
const { result } = renderHook(() => useDatasourceUIState({
|
|
...defaultParams,
|
|
datasource: createMockDatasource({
|
|
nodeData: {
|
|
...createMockDatasource().nodeData,
|
|
provider_type: DatasourceType.onlineDocument,
|
|
},
|
|
}),
|
|
currentWorkspacePagesLength: 5,
|
|
}))
|
|
expect(result.current.showSelect).toBe(true)
|
|
})
|
|
|
|
it('should return true for onlineDrive when non-bucket files exist', () => {
|
|
const { result } = renderHook(() => useDatasourceUIState({
|
|
...defaultParams,
|
|
datasource: createMockDatasource({
|
|
nodeData: {
|
|
...createMockDatasource().nodeData,
|
|
provider_type: DatasourceType.onlineDrive,
|
|
},
|
|
}),
|
|
onlineDriveFileList: [createMockOnlineDriveFile()],
|
|
}))
|
|
expect(result.current.showSelect).toBe(true)
|
|
})
|
|
|
|
it('should return false for onlineDrive when only buckets exist', () => {
|
|
const { result } = renderHook(() => useDatasourceUIState({
|
|
...defaultParams,
|
|
datasource: createMockDatasource({
|
|
nodeData: {
|
|
...createMockDatasource().nodeData,
|
|
provider_type: DatasourceType.onlineDrive,
|
|
},
|
|
}),
|
|
onlineDriveFileList: [createMockOnlineDriveFile({ type: 'bucket' as OnlineDriveFile['type'] })],
|
|
}))
|
|
expect(result.current.showSelect).toBe(false)
|
|
})
|
|
})
|
|
|
|
describe('tip', () => {
|
|
it('should return empty string for localFile', () => {
|
|
const { result } = renderHook(() => useDatasourceUIState({
|
|
...defaultParams,
|
|
datasource: createMockDatasource(),
|
|
}))
|
|
expect(result.current.tip).toBe('')
|
|
})
|
|
|
|
it('should return translation key for onlineDocument', () => {
|
|
const { result } = renderHook(() => useDatasourceUIState({
|
|
...defaultParams,
|
|
datasource: createMockDatasource({
|
|
nodeData: {
|
|
...createMockDatasource().nodeData,
|
|
provider_type: DatasourceType.onlineDocument,
|
|
},
|
|
}),
|
|
}))
|
|
expect(result.current.tip).toContain('datasetPipeline.addDocuments.selectOnlineDocumentTip')
|
|
})
|
|
})
|
|
})
|
|
|
|
// ==========================================
|
|
// Utility Functions Tests - datasource-info-builder
|
|
// ==========================================
|
|
describe('datasource-info-builder', () => {
|
|
describe('buildLocalFileDatasourceInfo', () => {
|
|
it('should build correct info for local file', () => {
|
|
const file = createMockFile()
|
|
const result = buildLocalFileDatasourceInfo(file, 'cred-1')
|
|
|
|
expect(result).toEqual({
|
|
related_id: 'file-1',
|
|
name: 'test.txt',
|
|
type: 'text/plain',
|
|
size: 1024,
|
|
extension: '.txt',
|
|
mime_type: 'text/plain',
|
|
url: '',
|
|
transfer_method: TransferMethod.local_file,
|
|
credential_id: 'cred-1',
|
|
})
|
|
})
|
|
|
|
it('should handle file with undefined id', () => {
|
|
const file = createMockFile({ id: undefined })
|
|
const result = buildLocalFileDatasourceInfo(file, 'cred-1')
|
|
expect(result.related_id).toBeUndefined()
|
|
})
|
|
})
|
|
|
|
describe('buildOnlineDocumentDatasourceInfo', () => {
|
|
it('should build correct info for online document', () => {
|
|
const page = createMockNotionPage()
|
|
const result = buildOnlineDocumentDatasourceInfo(page, 'cred-1')
|
|
|
|
expect(result.workspace_id).toBe('workspace-1')
|
|
expect(result.credential_id).toBe('cred-1')
|
|
expect(result.page).toBeDefined()
|
|
expect((result.page as NotionPage).page_id).toBe('page-1')
|
|
})
|
|
|
|
it('should exclude workspace_id from page object', () => {
|
|
const page = createMockNotionPage()
|
|
const result = buildOnlineDocumentDatasourceInfo(page, 'cred-1')
|
|
|
|
expect((result.page as Record<string, unknown>).workspace_id).toBeUndefined()
|
|
})
|
|
})
|
|
|
|
describe('buildWebsiteCrawlDatasourceInfo', () => {
|
|
it('should build correct info for website crawl', () => {
|
|
const page = createMockCrawlResult()
|
|
const result = buildWebsiteCrawlDatasourceInfo(page, 'cred-1')
|
|
|
|
expect(result.source_url).toBe('https://example.com')
|
|
expect(result.credential_id).toBe('cred-1')
|
|
})
|
|
|
|
it('should spread all page properties', () => {
|
|
const page = createMockCrawlResult({ title: 'Custom Title' })
|
|
const result = buildWebsiteCrawlDatasourceInfo(page, 'cred-1')
|
|
|
|
expect(result.title).toBe('Custom Title')
|
|
})
|
|
})
|
|
|
|
describe('buildOnlineDriveDatasourceInfo', () => {
|
|
it('should build correct info for online drive', () => {
|
|
const file = createMockOnlineDriveFile()
|
|
const result = buildOnlineDriveDatasourceInfo(file, 'my-bucket', 'cred-1')
|
|
|
|
expect(result).toEqual({
|
|
bucket: 'my-bucket',
|
|
id: 'drive-file-1',
|
|
name: 'test-file.pdf',
|
|
type: 'file',
|
|
credential_id: 'cred-1',
|
|
})
|
|
})
|
|
})
|
|
})
|
|
|
|
// ==========================================
|
|
// Step Components Tests (with real components)
|
|
// ==========================================
|
|
describe('StepOneContent', () => {
|
|
const defaultProps = {
|
|
datasource: undefined as Datasource | undefined,
|
|
datasourceType: undefined as string | undefined,
|
|
pipelineNodes: [] as Node<DataSourceNodeType>[],
|
|
supportBatchUpload: true,
|
|
localFileListLength: 0,
|
|
isShowVectorSpaceFull: false,
|
|
showSelect: false,
|
|
totalOptions: undefined as number | undefined,
|
|
selectedOptions: undefined as number | undefined,
|
|
tip: '',
|
|
nextBtnDisabled: true,
|
|
onSelectDataSource: vi.fn(),
|
|
onCredentialChange: vi.fn(),
|
|
onSelectAll: vi.fn(),
|
|
onNextStep: vi.fn(),
|
|
}
|
|
|
|
beforeEach(() => {
|
|
vi.clearAllMocks()
|
|
})
|
|
|
|
it('should render VectorSpaceFull when isShowVectorSpaceFull is true', () => {
|
|
render(<StepOneContent {...defaultProps} isShowVectorSpaceFull={true} />)
|
|
expect(screen.getByTestId('vector-space-full')).toBeInTheDocument()
|
|
})
|
|
|
|
it('should not render VectorSpaceFull when isShowVectorSpaceFull is false', () => {
|
|
render(<StepOneContent {...defaultProps} isShowVectorSpaceFull={false} />)
|
|
expect(screen.queryByTestId('vector-space-full')).not.toBeInTheDocument()
|
|
})
|
|
|
|
it('should render UpgradeCard when conditions are met', () => {
|
|
render(
|
|
<StepOneContent
|
|
{...defaultProps}
|
|
datasource={createMockDatasource()}
|
|
supportBatchUpload={false}
|
|
datasourceType={DatasourceType.localFile}
|
|
localFileListLength={2}
|
|
/>,
|
|
)
|
|
expect(screen.getByTestId('upgrade-card')).toBeInTheDocument()
|
|
})
|
|
|
|
it('should not render UpgradeCard when supportBatchUpload is true', () => {
|
|
render(
|
|
<StepOneContent
|
|
{...defaultProps}
|
|
datasource={createMockDatasource()}
|
|
supportBatchUpload={true}
|
|
datasourceType={DatasourceType.localFile}
|
|
localFileListLength={2}
|
|
/>,
|
|
)
|
|
expect(screen.queryByTestId('upgrade-card')).not.toBeInTheDocument()
|
|
})
|
|
|
|
it('should call onNextStep when next button is clicked', () => {
|
|
const onNextStep = vi.fn()
|
|
render(<StepOneContent {...defaultProps} nextBtnDisabled={false} onNextStep={onNextStep} />)
|
|
|
|
// Find button with translation key text (using regex for flexibility)
|
|
const nextButton = screen.getByRole('button', { name: /datasetCreation.stepOne.button/i })
|
|
fireEvent.click(nextButton)
|
|
|
|
expect(onNextStep).toHaveBeenCalled()
|
|
})
|
|
|
|
it('should disable next button when nextBtnDisabled is true', () => {
|
|
render(<StepOneContent {...defaultProps} nextBtnDisabled={true} />)
|
|
|
|
const nextButton = screen.getByRole('button', { name: /datasetCreation.stepOne.button/i })
|
|
expect(nextButton).toBeDisabled()
|
|
})
|
|
})
|
|
|
|
describe('StepTwoContent', () => {
|
|
// Mock ProcessDocuments since it has complex dependencies
|
|
vi.mock('./process-documents', () => ({
|
|
default: React.forwardRef(({ dataSourceNodeId, isRunning, onProcess, onPreview, onSubmit, onBack }: {
|
|
dataSourceNodeId: string
|
|
isRunning: boolean
|
|
onProcess: () => void
|
|
onPreview: () => void
|
|
onSubmit: (data: Record<string, unknown>) => void
|
|
onBack: () => void
|
|
}, ref: React.Ref<{ submit: () => void }>) => {
|
|
React.useImperativeHandle(ref, () => ({
|
|
submit: () => onSubmit({ test: 'data' }),
|
|
}))
|
|
return (
|
|
<div data-testid="process-documents">
|
|
<span data-testid="datasource-node-id">{dataSourceNodeId}</span>
|
|
<span data-testid="is-running">{isRunning.toString()}</span>
|
|
<button data-testid="process-btn" onClick={onProcess}>Process</button>
|
|
<button data-testid="preview-btn" onClick={onPreview}>Preview</button>
|
|
<button data-testid="back-btn" onClick={onBack}>Back</button>
|
|
</div>
|
|
)
|
|
}),
|
|
}))
|
|
|
|
const defaultProps = {
|
|
formRef: { current: null } as unknown as React.RefObject<{ submit: () => void }>,
|
|
dataSourceNodeId: 'node-1',
|
|
isRunning: false,
|
|
onProcess: vi.fn(),
|
|
onPreview: vi.fn(),
|
|
onSubmit: vi.fn(),
|
|
onBack: vi.fn(),
|
|
}
|
|
|
|
beforeEach(() => {
|
|
vi.clearAllMocks()
|
|
})
|
|
|
|
it('should render ProcessDocuments component', () => {
|
|
render(<StepTwoContent {...defaultProps} />)
|
|
expect(screen.getByTestId('process-documents')).toBeInTheDocument()
|
|
})
|
|
|
|
it('should pass dataSourceNodeId to ProcessDocuments', () => {
|
|
render(<StepTwoContent {...defaultProps} dataSourceNodeId="custom-node" />)
|
|
expect(screen.getByTestId('datasource-node-id')).toHaveTextContent('custom-node')
|
|
})
|
|
|
|
it('should pass isRunning to ProcessDocuments', () => {
|
|
render(<StepTwoContent {...defaultProps} isRunning={true} />)
|
|
expect(screen.getByTestId('is-running')).toHaveTextContent('true')
|
|
})
|
|
|
|
it('should call onProcess when process button is clicked', () => {
|
|
const onProcess = vi.fn()
|
|
render(<StepTwoContent {...defaultProps} onProcess={onProcess} />)
|
|
|
|
fireEvent.click(screen.getByTestId('process-btn'))
|
|
|
|
expect(onProcess).toHaveBeenCalled()
|
|
})
|
|
|
|
it('should call onBack when back button is clicked', () => {
|
|
const onBack = vi.fn()
|
|
render(<StepTwoContent {...defaultProps} onBack={onBack} />)
|
|
|
|
fireEvent.click(screen.getByTestId('back-btn'))
|
|
|
|
expect(onBack).toHaveBeenCalled()
|
|
})
|
|
})
|
|
|
|
describe('StepThreeContent', () => {
|
|
// Mock Processing since it has complex dependencies
|
|
vi.mock('./processing', () => ({
|
|
default: ({ batchId, documents }: { batchId: string, documents: unknown[] }) => (
|
|
<div data-testid="processing">
|
|
<span data-testid="batch-id">{batchId}</span>
|
|
<span data-testid="documents-count">{documents.length}</span>
|
|
</div>
|
|
),
|
|
}))
|
|
|
|
it('should render Processing component', () => {
|
|
render(<StepThreeContent batchId="batch-123" documents={[]} />)
|
|
expect(screen.getByTestId('processing')).toBeInTheDocument()
|
|
})
|
|
|
|
it('should pass batchId to Processing', () => {
|
|
render(<StepThreeContent batchId="batch-123" documents={[]} />)
|
|
expect(screen.getByTestId('batch-id')).toHaveTextContent('batch-123')
|
|
})
|
|
|
|
it('should pass documents count to Processing', () => {
|
|
const documents = [{ id: '1' }, { id: '2' }]
|
|
render(<StepThreeContent batchId="batch-123" documents={documents as InitialDocumentDetail[]} />)
|
|
expect(screen.getByTestId('documents-count')).toHaveTextContent('2')
|
|
})
|
|
})
|
|
|
|
// ==========================================
|
|
// Preview Panel Tests
|
|
// ==========================================
|
|
describe('StepOnePreview', () => {
|
|
// Mock preview components
|
|
vi.mock('./preview/file-preview', () => ({
|
|
default: ({ file, hidePreview }: { file: CustomFile, hidePreview: () => void }) => (
|
|
<div data-testid="file-preview">
|
|
<span data-testid="file-name">{file.name}</span>
|
|
<button data-testid="hide-preview" onClick={hidePreview}>Hide</button>
|
|
</div>
|
|
),
|
|
}))
|
|
|
|
vi.mock('./preview/online-document-preview', () => ({
|
|
default: ({ datasourceNodeId, currentPage, hidePreview }: {
|
|
datasourceNodeId: string
|
|
currentPage: NotionPage & { workspace_id: string }
|
|
hidePreview: () => void
|
|
}) => (
|
|
<div data-testid="online-document-preview">
|
|
<span data-testid="node-id">{datasourceNodeId}</span>
|
|
<span data-testid="page-id">{currentPage.page_id}</span>
|
|
<button data-testid="hide-preview" onClick={hidePreview}>Hide</button>
|
|
</div>
|
|
),
|
|
}))
|
|
|
|
vi.mock('./preview/web-preview', () => ({
|
|
default: ({ currentWebsite, hidePreview }: { currentWebsite: CrawlResultItem, hidePreview: () => void }) => (
|
|
<div data-testid="web-preview">
|
|
<span data-testid="url">{currentWebsite.source_url}</span>
|
|
<button data-testid="hide-preview" onClick={hidePreview}>Hide</button>
|
|
</div>
|
|
),
|
|
}))
|
|
|
|
const defaultProps = {
|
|
datasource: undefined as Datasource | undefined,
|
|
currentLocalFile: undefined as CustomFile | undefined,
|
|
currentDocument: undefined as (NotionPage & { workspace_id: string }) | undefined,
|
|
currentWebsite: undefined as CrawlResultItem | undefined,
|
|
hidePreviewLocalFile: vi.fn(),
|
|
hidePreviewOnlineDocument: vi.fn(),
|
|
hideWebsitePreview: vi.fn(),
|
|
}
|
|
|
|
beforeEach(() => {
|
|
vi.clearAllMocks()
|
|
})
|
|
|
|
it('should not render any preview when no file is selected', () => {
|
|
const { container } = render(<StepOnePreview {...defaultProps} />)
|
|
expect(container.querySelector('[data-testid="file-preview"]')).not.toBeInTheDocument()
|
|
expect(container.querySelector('[data-testid="online-document-preview"]')).not.toBeInTheDocument()
|
|
expect(container.querySelector('[data-testid="web-preview"]')).not.toBeInTheDocument()
|
|
})
|
|
|
|
it('should render FilePreview when currentLocalFile is set', () => {
|
|
render(
|
|
<StepOnePreview
|
|
{...defaultProps}
|
|
currentLocalFile={createMockFile()}
|
|
/>,
|
|
)
|
|
expect(screen.getByTestId('file-preview')).toBeInTheDocument()
|
|
expect(screen.getByTestId('file-name')).toHaveTextContent('test.txt')
|
|
})
|
|
|
|
it('should render OnlineDocumentPreview when currentDocument is set', () => {
|
|
render(
|
|
<StepOnePreview
|
|
{...defaultProps}
|
|
datasource={createMockDatasource()}
|
|
currentDocument={createMockNotionPage()}
|
|
/>,
|
|
)
|
|
expect(screen.getByTestId('online-document-preview')).toBeInTheDocument()
|
|
})
|
|
|
|
it('should render WebsitePreview when currentWebsite is set', () => {
|
|
render(
|
|
<StepOnePreview
|
|
{...defaultProps}
|
|
currentWebsite={createMockCrawlResult()}
|
|
/>,
|
|
)
|
|
expect(screen.getByTestId('web-preview')).toBeInTheDocument()
|
|
})
|
|
|
|
it('should call hidePreviewLocalFile when hide button is clicked', () => {
|
|
const hidePreviewLocalFile = vi.fn()
|
|
render(
|
|
<StepOnePreview
|
|
{...defaultProps}
|
|
currentLocalFile={createMockFile()}
|
|
hidePreviewLocalFile={hidePreviewLocalFile}
|
|
/>,
|
|
)
|
|
|
|
fireEvent.click(screen.getByTestId('hide-preview'))
|
|
|
|
expect(hidePreviewLocalFile).toHaveBeenCalled()
|
|
})
|
|
})
|
|
|
|
describe('StepTwoPreview', () => {
|
|
// Mock ChunkPreview
|
|
vi.mock('./preview/chunk-preview', () => ({
|
|
default: ({ dataSourceType, isIdle, isPending, onPreview }: {
|
|
dataSourceType: string
|
|
isIdle: boolean
|
|
isPending: boolean
|
|
onPreview: () => void
|
|
}) => (
|
|
<div data-testid="chunk-preview">
|
|
<span data-testid="datasource-type">{dataSourceType}</span>
|
|
<span data-testid="is-idle">{isIdle.toString()}</span>
|
|
<span data-testid="is-pending">{isPending.toString()}</span>
|
|
<button data-testid="preview-btn" onClick={onPreview}>Preview</button>
|
|
</div>
|
|
),
|
|
}))
|
|
|
|
const defaultProps = {
|
|
datasourceType: DatasourceType.localFile as string | undefined,
|
|
localFileList: [] as FileItem[],
|
|
onlineDocuments: [] as (NotionPage & { workspace_id: string })[],
|
|
websitePages: [] as CrawlResultItem[],
|
|
selectedOnlineDriveFileList: [] as OnlineDriveFile[],
|
|
isIdle: true,
|
|
isPendingPreview: false,
|
|
estimateData: undefined,
|
|
onPreview: vi.fn(),
|
|
handlePreviewFileChange: vi.fn(),
|
|
handlePreviewOnlineDocumentChange: vi.fn(),
|
|
handlePreviewWebsitePageChange: vi.fn(),
|
|
handlePreviewOnlineDriveFileChange: vi.fn(),
|
|
}
|
|
|
|
beforeEach(() => {
|
|
vi.clearAllMocks()
|
|
})
|
|
|
|
it('should render ChunkPreview component', () => {
|
|
render(<StepTwoPreview {...defaultProps} />)
|
|
expect(screen.getByTestId('chunk-preview')).toBeInTheDocument()
|
|
})
|
|
|
|
it('should pass datasourceType to ChunkPreview', () => {
|
|
render(<StepTwoPreview {...defaultProps} datasourceType={DatasourceType.onlineDocument} />)
|
|
expect(screen.getByTestId('datasource-type')).toHaveTextContent(DatasourceType.onlineDocument)
|
|
})
|
|
|
|
it('should pass isIdle to ChunkPreview', () => {
|
|
render(<StepTwoPreview {...defaultProps} isIdle={false} />)
|
|
expect(screen.getByTestId('is-idle')).toHaveTextContent('false')
|
|
})
|
|
|
|
it('should pass isPendingPreview to ChunkPreview', () => {
|
|
render(<StepTwoPreview {...defaultProps} isPendingPreview={true} />)
|
|
expect(screen.getByTestId('is-pending')).toHaveTextContent('true')
|
|
})
|
|
|
|
it('should call onPreview when preview button is clicked', () => {
|
|
const onPreview = vi.fn()
|
|
render(<StepTwoPreview {...defaultProps} onPreview={onPreview} />)
|
|
|
|
fireEvent.click(screen.getByTestId('preview-btn'))
|
|
|
|
expect(onPreview).toHaveBeenCalled()
|
|
})
|
|
})
|
|
|
|
// ==========================================
|
|
// Edge Cases Tests
|
|
// ==========================================
|
|
describe('Edge Cases', () => {
|
|
describe('Empty States', () => {
|
|
it('should handle undefined datasource in useDatasourceUIState', () => {
|
|
const { result } = renderHook(() => useDatasourceUIState({
|
|
datasource: undefined,
|
|
allFileLoaded: false,
|
|
localFileListLength: 0,
|
|
onlineDocumentsLength: 0,
|
|
websitePagesLength: 0,
|
|
selectedFileIdsLength: 0,
|
|
onlineDriveFileList: [],
|
|
isVectorSpaceFull: false,
|
|
enableBilling: true,
|
|
currentWorkspacePagesLength: 0,
|
|
fileUploadConfig: { file_size_limit: 15, batch_count_limit: 5 },
|
|
}))
|
|
|
|
expect(result.current.datasourceType).toBeUndefined()
|
|
expect(result.current.nextBtnDisabled).toBe(true)
|
|
})
|
|
})
|
|
|
|
describe('Boundary Conditions', () => {
|
|
it('should handle zero file size limit', () => {
|
|
const { result } = renderHook(() => useDatasourceUIState({
|
|
datasource: createMockDatasource({
|
|
nodeData: {
|
|
...createMockDatasource().nodeData,
|
|
provider_type: DatasourceType.onlineDrive,
|
|
},
|
|
}),
|
|
allFileLoaded: false,
|
|
localFileListLength: 0,
|
|
onlineDocumentsLength: 0,
|
|
websitePagesLength: 0,
|
|
selectedFileIdsLength: 0,
|
|
onlineDriveFileList: [],
|
|
isVectorSpaceFull: false,
|
|
enableBilling: true,
|
|
currentWorkspacePagesLength: 0,
|
|
fileUploadConfig: { file_size_limit: 0, batch_count_limit: 0 },
|
|
}))
|
|
|
|
expect(result.current.tip).toContain('datasetPipeline.addDocuments.selectOnlineDriveTip')
|
|
})
|
|
|
|
it('should handle very large file counts', () => {
|
|
const { result } = renderHook(() => useDatasourceUIState({
|
|
datasource: createMockDatasource(),
|
|
allFileLoaded: true,
|
|
localFileListLength: 10000,
|
|
onlineDocumentsLength: 0,
|
|
websitePagesLength: 0,
|
|
selectedFileIdsLength: 0,
|
|
onlineDriveFileList: [],
|
|
isVectorSpaceFull: false,
|
|
enableBilling: true,
|
|
currentWorkspacePagesLength: 0,
|
|
fileUploadConfig: { file_size_limit: 15, batch_count_limit: 5 },
|
|
}))
|
|
|
|
expect(result.current.nextBtnDisabled).toBe(false)
|
|
})
|
|
})
|
|
|
|
describe('File with special characters', () => {
|
|
it('should handle file name with special characters', () => {
|
|
const file = createMockFile({ name: 'test<>&"\'file.txt' })
|
|
const result = buildLocalFileDatasourceInfo(file, 'cred-1')
|
|
expect(result.name).toBe('test<>&"\'file.txt')
|
|
})
|
|
|
|
it('should handle unicode file names', () => {
|
|
const file = createMockFile({ name: '测试文件🚀.txt' })
|
|
const result = buildLocalFileDatasourceInfo(file, 'cred-1')
|
|
expect(result.name).toBe('测试文件🚀.txt')
|
|
})
|
|
})
|
|
})
|
|
|
|
// ==========================================
|
|
// Component Memoization Tests
|
|
// ==========================================
|
|
describe('Component Memoization', () => {
|
|
it('StepOneContent should be memoized', async () => {
|
|
const StepOneContentModule = await import('./steps/step-one-content')
|
|
expect(StepOneContentModule.default.$$typeof).toBe(Symbol.for('react.memo'))
|
|
})
|
|
|
|
it('StepTwoContent should be memoized', async () => {
|
|
const StepTwoContentModule = await import('./steps/step-two-content')
|
|
expect(StepTwoContentModule.default.$$typeof).toBe(Symbol.for('react.memo'))
|
|
})
|
|
|
|
it('StepThreeContent should be memoized', async () => {
|
|
const StepThreeContentModule = await import('./steps/step-three-content')
|
|
expect(StepThreeContentModule.default.$$typeof).toBe(Symbol.for('react.memo'))
|
|
})
|
|
|
|
it('StepOnePreview should be memoized', () => {
|
|
expect(StepOnePreview.$$typeof).toBe(Symbol.for('react.memo'))
|
|
})
|
|
|
|
it('StepTwoPreview should be memoized', () => {
|
|
expect(StepTwoPreview.$$typeof).toBe(Symbol.for('react.memo'))
|
|
})
|
|
})
|
|
|
|
// ==========================================
|
|
// Hook Callback Stability Tests
|
|
// ==========================================
|
|
describe('Hook Callback Stability', () => {
|
|
describe('useDatasourceUIState memoization', () => {
|
|
it('should maintain stable reference for datasourceType when dependencies unchanged', () => {
|
|
const params = {
|
|
datasource: createMockDatasource(),
|
|
allFileLoaded: true,
|
|
localFileListLength: 1,
|
|
onlineDocumentsLength: 0,
|
|
websitePagesLength: 0,
|
|
selectedFileIdsLength: 0,
|
|
onlineDriveFileList: [] as OnlineDriveFile[],
|
|
isVectorSpaceFull: false,
|
|
enableBilling: true,
|
|
currentWorkspacePagesLength: 0,
|
|
fileUploadConfig: { file_size_limit: 15, batch_count_limit: 5 },
|
|
}
|
|
|
|
const { result, rerender } = renderHook(() => useDatasourceUIState(params))
|
|
const firstType = result.current.datasourceType
|
|
|
|
rerender()
|
|
|
|
expect(result.current.datasourceType).toBe(firstType)
|
|
})
|
|
})
|
|
})
|
|
|
|
// ==========================================
|
|
// Store Hooks Tests
|
|
// ==========================================
|
|
describe('Store Hooks', () => {
|
|
describe('useLocalFile', () => {
|
|
it('should return localFileList from store', () => {
|
|
mockStoreState.localFileList = [createMockFileItem()]
|
|
const { result } = renderHook(() => useLocalFile())
|
|
expect(result.current.localFileList).toHaveLength(1)
|
|
})
|
|
|
|
it('should compute allFileLoaded correctly when all files have ids', () => {
|
|
mockStoreState.localFileList = [createMockFileItem()]
|
|
const { result } = renderHook(() => useLocalFile())
|
|
expect(result.current.allFileLoaded).toBe(true)
|
|
})
|
|
|
|
it('should compute allFileLoaded as false when no files', () => {
|
|
mockStoreState.localFileList = []
|
|
const { result } = renderHook(() => useLocalFile())
|
|
expect(result.current.allFileLoaded).toBe(false)
|
|
})
|
|
})
|
|
|
|
describe('useOnlineDocument', () => {
|
|
it('should return onlineDocuments from store', () => {
|
|
mockStoreState.onlineDocuments = [createMockNotionPage()]
|
|
const { result } = renderHook(() => useOnlineDocument())
|
|
expect(result.current.onlineDocuments).toHaveLength(1)
|
|
})
|
|
|
|
it('should compute PagesMapAndSelectedPagesId correctly', () => {
|
|
mockStoreState.documentsData = [{
|
|
workspace_id: 'ws-1',
|
|
pages: [{ page_id: 'page-1' }],
|
|
}]
|
|
const { result } = renderHook(() => useOnlineDocument())
|
|
expect(result.current.PagesMapAndSelectedPagesId['page-1']).toBeDefined()
|
|
})
|
|
})
|
|
|
|
describe('useWebsiteCrawl', () => {
|
|
it('should return websitePages from store', () => {
|
|
mockStoreState.websitePages = [createMockCrawlResult()]
|
|
const { result } = renderHook(() => useWebsiteCrawl())
|
|
expect(result.current.websitePages).toHaveLength(1)
|
|
})
|
|
})
|
|
|
|
describe('useOnlineDrive', () => {
|
|
it('should return onlineDriveFileList from store', () => {
|
|
mockStoreState.onlineDriveFileList = [createMockOnlineDriveFile()]
|
|
const { result } = renderHook(() => useOnlineDrive())
|
|
expect(result.current.onlineDriveFileList).toHaveLength(1)
|
|
})
|
|
|
|
it('should compute selectedOnlineDriveFileList correctly', () => {
|
|
mockStoreState.onlineDriveFileList = [
|
|
createMockOnlineDriveFile({ id: 'file-1' }),
|
|
createMockOnlineDriveFile({ id: 'file-2' }),
|
|
]
|
|
mockStoreState.selectedFileIds = ['file-1']
|
|
const { result } = renderHook(() => useOnlineDrive())
|
|
expect(result.current.selectedOnlineDriveFileList).toHaveLength(1)
|
|
expect(result.current.selectedOnlineDriveFileList[0].id).toBe('file-1')
|
|
})
|
|
})
|
|
})
|
|
|
|
// ==========================================
|
|
// All Datasource Types Tests
|
|
// ==========================================
|
|
describe('All Datasource Types', () => {
|
|
const datasourceTypes = [
|
|
{ type: DatasourceType.localFile, name: 'Local File' },
|
|
{ type: DatasourceType.onlineDocument, name: 'Online Document' },
|
|
{ type: DatasourceType.websiteCrawl, name: 'Website Crawl' },
|
|
{ type: DatasourceType.onlineDrive, name: 'Online Drive' },
|
|
]
|
|
|
|
describe.each(datasourceTypes)('$name datasource type', ({ type }) => {
|
|
it(`should handle ${type} in useDatasourceUIState`, () => {
|
|
const { result } = renderHook(() => useDatasourceUIState({
|
|
datasource: createMockDatasource({
|
|
nodeData: {
|
|
...createMockDatasource().nodeData,
|
|
provider_type: type,
|
|
},
|
|
}),
|
|
allFileLoaded: type === DatasourceType.localFile,
|
|
localFileListLength: type === DatasourceType.localFile ? 1 : 0,
|
|
onlineDocumentsLength: type === DatasourceType.onlineDocument ? 1 : 0,
|
|
websitePagesLength: type === DatasourceType.websiteCrawl ? 1 : 0,
|
|
selectedFileIdsLength: type === DatasourceType.onlineDrive ? 1 : 0,
|
|
onlineDriveFileList: type === DatasourceType.onlineDrive ? [createMockOnlineDriveFile()] : [],
|
|
isVectorSpaceFull: false,
|
|
enableBilling: true,
|
|
currentWorkspacePagesLength: type === DatasourceType.onlineDocument ? 1 : 0,
|
|
fileUploadConfig: { file_size_limit: 15, batch_count_limit: 5 },
|
|
}))
|
|
|
|
expect(result.current.datasourceType).toBe(type)
|
|
expect(result.current.nextBtnDisabled).toBe(false)
|
|
})
|
|
})
|
|
})
|
|
|
|
// ==========================================
|
|
// useDatasourceOptions Hook Tests
|
|
// ==========================================
|
|
describe('useDatasourceOptions', () => {
|
|
it('should return empty array when no pipeline nodes', () => {
|
|
const { result } = renderHook(() => useDatasourceOptions([]))
|
|
expect(result.current).toEqual([])
|
|
})
|
|
|
|
it('should filter and map data source nodes', () => {
|
|
const mockNodes: Node<DataSourceNodeType>[] = [
|
|
{
|
|
id: 'node-1',
|
|
type: 'data-source',
|
|
position: { x: 0, y: 0 },
|
|
data: {
|
|
type: BlockEnum.DataSource,
|
|
title: 'Local File Source',
|
|
provider_type: DatasourceType.localFile,
|
|
plugin_id: 'plugin-1',
|
|
} as DataSourceNodeType,
|
|
},
|
|
{
|
|
id: 'node-2',
|
|
type: 'other',
|
|
position: { x: 0, y: 0 },
|
|
data: {
|
|
type: BlockEnum.Start,
|
|
title: 'Start Node',
|
|
} as unknown as DataSourceNodeType,
|
|
},
|
|
]
|
|
|
|
const { result } = renderHook(() => useDatasourceOptions(mockNodes))
|
|
expect(result.current).toHaveLength(1)
|
|
expect(result.current[0].label).toBe('Local File Source')
|
|
expect(result.current[0].value).toBe('node-1')
|
|
})
|
|
|
|
it('should return multiple options for multiple data source nodes', () => {
|
|
const mockNodes: Node<DataSourceNodeType>[] = [
|
|
{
|
|
id: 'node-1',
|
|
type: 'data-source',
|
|
position: { x: 0, y: 0 },
|
|
data: {
|
|
type: BlockEnum.DataSource,
|
|
title: 'Source 1',
|
|
provider_type: DatasourceType.localFile,
|
|
plugin_id: 'plugin-1',
|
|
} as DataSourceNodeType,
|
|
},
|
|
{
|
|
id: 'node-2',
|
|
type: 'data-source',
|
|
position: { x: 0, y: 0 },
|
|
data: {
|
|
type: BlockEnum.DataSource,
|
|
title: 'Source 2',
|
|
provider_type: DatasourceType.onlineDocument,
|
|
plugin_id: 'plugin-2',
|
|
} as DataSourceNodeType,
|
|
},
|
|
]
|
|
|
|
const { result } = renderHook(() => useDatasourceOptions(mockNodes))
|
|
expect(result.current).toHaveLength(2)
|
|
})
|
|
})
|
|
|
|
// ==========================================
|
|
// useDatasourceActions Hook Tests
|
|
// ==========================================
|
|
describe('useDatasourceActions', () => {
|
|
const createMockDataSourceStore = () => ({
|
|
getState: () => ({
|
|
...mockStoreState,
|
|
previewLocalFileRef: { current: createMockFile() },
|
|
previewOnlineDocumentRef: { current: createMockNotionPage() },
|
|
previewWebsitePageRef: { current: createMockCrawlResult() },
|
|
previewOnlineDriveFileRef: { current: createMockOnlineDriveFile() },
|
|
currentCredentialId: 'cred-1',
|
|
bucket: 'test-bucket',
|
|
localFileList: [createMockFileItem()],
|
|
onlineDocuments: [createMockNotionPage()],
|
|
websitePages: [createMockCrawlResult()],
|
|
selectedFileIds: ['file-1'],
|
|
onlineDriveFileList: [createMockOnlineDriveFile({ id: 'file-1' })],
|
|
setCurrentCredentialId: vi.fn(),
|
|
currentNodeIdRef: { current: '' },
|
|
setOnlineDocuments: vi.fn(),
|
|
setSelectedFileIds: vi.fn(),
|
|
setSelectedPagesId: vi.fn(),
|
|
}),
|
|
})
|
|
|
|
const defaultParams = {
|
|
datasource: createMockDatasource(),
|
|
datasourceType: DatasourceType.localFile,
|
|
pipelineId: 'pipeline-1',
|
|
dataSourceStore: createMockDataSourceStore() as MockDataSourceStore,
|
|
setEstimateData: vi.fn(),
|
|
setBatchId: vi.fn(),
|
|
setDocuments: vi.fn(),
|
|
handleNextStep: vi.fn(),
|
|
PagesMapAndSelectedPagesId: { 'page-1': createMockNotionPage() },
|
|
currentWorkspacePages: [{ page_id: 'page-1' }],
|
|
clearOnlineDocumentData: vi.fn(),
|
|
clearWebsiteCrawlData: vi.fn(),
|
|
clearOnlineDriveData: vi.fn(),
|
|
setDatasource: vi.fn(),
|
|
}
|
|
|
|
beforeEach(() => {
|
|
vi.clearAllMocks()
|
|
})
|
|
|
|
it('should return initial state and callbacks', () => {
|
|
const { result } = renderHook(() => useDatasourceActions(defaultParams))
|
|
|
|
expect(result.current.isPreview).toBeDefined()
|
|
expect(result.current.formRef).toBeDefined()
|
|
expect(result.current.isIdle).toBe(true)
|
|
expect(result.current.isPending).toBe(false)
|
|
expect(typeof result.current.onClickProcess).toBe('function')
|
|
expect(typeof result.current.onClickPreview).toBe('function')
|
|
expect(typeof result.current.handleSubmit).toBe('function')
|
|
})
|
|
|
|
it('should set isPreview to false when onClickProcess is called', () => {
|
|
const { result } = renderHook(() => useDatasourceActions(defaultParams))
|
|
|
|
act(() => {
|
|
result.current.onClickProcess()
|
|
})
|
|
|
|
expect(result.current.isPreview.current).toBe(false)
|
|
})
|
|
|
|
it('should set isPreview to true when onClickPreview is called', () => {
|
|
const { result } = renderHook(() => useDatasourceActions(defaultParams))
|
|
|
|
act(() => {
|
|
result.current.onClickPreview()
|
|
})
|
|
|
|
expect(result.current.isPreview.current).toBe(true)
|
|
})
|
|
|
|
it('should call handlePreviewFileChange and trigger preview', () => {
|
|
const { result } = renderHook(() => useDatasourceActions(defaultParams))
|
|
const mockFile = { id: 'file-1', name: 'test.txt' } as unknown as DocumentItem
|
|
|
|
act(() => {
|
|
result.current.handlePreviewFileChange(mockFile)
|
|
})
|
|
|
|
expect(result.current.isPreview.current).toBe(true)
|
|
})
|
|
|
|
it('should call handlePreviewOnlineDocumentChange and trigger preview', () => {
|
|
const { result } = renderHook(() => useDatasourceActions(defaultParams))
|
|
const mockPage = createMockNotionPage()
|
|
|
|
act(() => {
|
|
result.current.handlePreviewOnlineDocumentChange(mockPage)
|
|
})
|
|
|
|
expect(result.current.isPreview.current).toBe(true)
|
|
})
|
|
|
|
it('should call handlePreviewWebsiteChange and trigger preview', () => {
|
|
const { result } = renderHook(() => useDatasourceActions(defaultParams))
|
|
const mockWebsite = createMockCrawlResult()
|
|
|
|
act(() => {
|
|
result.current.handlePreviewWebsiteChange(mockWebsite)
|
|
})
|
|
|
|
expect(result.current.isPreview.current).toBe(true)
|
|
})
|
|
|
|
it('should call handlePreviewOnlineDriveFileChange and trigger preview', () => {
|
|
const { result } = renderHook(() => useDatasourceActions(defaultParams))
|
|
const mockFile = createMockOnlineDriveFile()
|
|
|
|
act(() => {
|
|
result.current.handlePreviewOnlineDriveFileChange(mockFile)
|
|
})
|
|
|
|
expect(result.current.isPreview.current).toBe(true)
|
|
})
|
|
|
|
it('should handle select all for online document', () => {
|
|
const params = {
|
|
...defaultParams,
|
|
datasourceType: DatasourceType.onlineDocument,
|
|
dataSourceStore: {
|
|
getState: () => ({
|
|
...mockStoreState,
|
|
onlineDocuments: [],
|
|
setOnlineDocuments: vi.fn(),
|
|
setSelectedPagesId: vi.fn(),
|
|
}),
|
|
} as MockDataSourceStore,
|
|
}
|
|
|
|
const { result } = renderHook(() => useDatasourceActions(params))
|
|
|
|
act(() => {
|
|
result.current.handleSelectAll()
|
|
})
|
|
|
|
// Verify the callback was executed (no error thrown)
|
|
expect(true).toBe(true)
|
|
})
|
|
|
|
it('should handle select all for online drive', () => {
|
|
const params = {
|
|
...defaultParams,
|
|
datasourceType: DatasourceType.onlineDrive,
|
|
dataSourceStore: {
|
|
getState: () => ({
|
|
...mockStoreState,
|
|
onlineDriveFileList: [createMockOnlineDriveFile({ id: 'file-1' })],
|
|
selectedFileIds: [],
|
|
setSelectedFileIds: vi.fn(),
|
|
}),
|
|
} as MockDataSourceStore,
|
|
}
|
|
|
|
const { result } = renderHook(() => useDatasourceActions(params))
|
|
|
|
act(() => {
|
|
result.current.handleSelectAll()
|
|
})
|
|
|
|
expect(true).toBe(true)
|
|
})
|
|
|
|
it('should handle switch data source', () => {
|
|
const setDatasource = vi.fn()
|
|
const params = {
|
|
...defaultParams,
|
|
setDatasource,
|
|
}
|
|
|
|
const { result } = renderHook(() => useDatasourceActions(params))
|
|
const newDatasource = createMockDatasource({ nodeId: 'node-2' })
|
|
|
|
act(() => {
|
|
result.current.handleSwitchDataSource(newDatasource)
|
|
})
|
|
|
|
expect(setDatasource).toHaveBeenCalledWith(newDatasource)
|
|
})
|
|
|
|
it('should handle credential change', () => {
|
|
const { result } = renderHook(() => useDatasourceActions(defaultParams))
|
|
|
|
act(() => {
|
|
result.current.handleCredentialChange('new-cred-id')
|
|
})
|
|
|
|
// Should not throw error
|
|
expect(true).toBe(true)
|
|
})
|
|
|
|
it('should clear online document data when switching datasource', () => {
|
|
const clearOnlineDocumentData = vi.fn()
|
|
const params = {
|
|
...defaultParams,
|
|
clearOnlineDocumentData,
|
|
}
|
|
|
|
const { result } = renderHook(() => useDatasourceActions(params))
|
|
const newDatasource = createMockDatasource({
|
|
nodeData: {
|
|
...createMockDatasource().nodeData,
|
|
provider_type: DatasourceType.onlineDocument,
|
|
},
|
|
})
|
|
|
|
act(() => {
|
|
result.current.handleSwitchDataSource(newDatasource)
|
|
})
|
|
|
|
expect(clearOnlineDocumentData).toHaveBeenCalled()
|
|
})
|
|
|
|
it('should clear website crawl data when switching datasource', () => {
|
|
const clearWebsiteCrawlData = vi.fn()
|
|
const params = {
|
|
...defaultParams,
|
|
clearWebsiteCrawlData,
|
|
}
|
|
|
|
const { result } = renderHook(() => useDatasourceActions(params))
|
|
const newDatasource = createMockDatasource({
|
|
nodeData: {
|
|
...createMockDatasource().nodeData,
|
|
provider_type: DatasourceType.websiteCrawl,
|
|
},
|
|
})
|
|
|
|
act(() => {
|
|
result.current.handleSwitchDataSource(newDatasource)
|
|
})
|
|
|
|
expect(clearWebsiteCrawlData).toHaveBeenCalled()
|
|
})
|
|
|
|
it('should clear online drive data when switching datasource', () => {
|
|
const clearOnlineDriveData = vi.fn()
|
|
const params = {
|
|
...defaultParams,
|
|
clearOnlineDriveData,
|
|
}
|
|
|
|
const { result } = renderHook(() => useDatasourceActions(params))
|
|
const newDatasource = createMockDatasource({
|
|
nodeData: {
|
|
...createMockDatasource().nodeData,
|
|
provider_type: DatasourceType.onlineDrive,
|
|
},
|
|
})
|
|
|
|
act(() => {
|
|
result.current.handleSwitchDataSource(newDatasource)
|
|
})
|
|
|
|
expect(clearOnlineDriveData).toHaveBeenCalled()
|
|
})
|
|
})
|
|
|
|
// ==========================================
|
|
// Store Hooks - Additional Coverage Tests
|
|
// ==========================================
|
|
describe('Store Hooks - Callbacks', () => {
|
|
beforeEach(() => {
|
|
vi.clearAllMocks()
|
|
// Reset mock store state
|
|
mockStoreState.localFileList = []
|
|
mockStoreState.documentsData = []
|
|
mockStoreState.onlineDocuments = []
|
|
mockStoreState.websitePages = []
|
|
mockStoreState.onlineDriveFileList = []
|
|
mockStoreState.selectedFileIds = []
|
|
})
|
|
|
|
describe('useLocalFile callbacks', () => {
|
|
it('should call hidePreviewLocalFile callback', () => {
|
|
const { result } = renderHook(() => useLocalFile())
|
|
|
|
act(() => {
|
|
result.current.hidePreviewLocalFile()
|
|
})
|
|
|
|
expect(mockStoreState.setCurrentLocalFile).toHaveBeenCalledWith(undefined)
|
|
})
|
|
})
|
|
|
|
describe('useOnlineDocument callbacks', () => {
|
|
it('should return currentWorkspace from documentsData', () => {
|
|
mockStoreState.documentsData = [{ workspace_id: 'ws-1', pages: [] }]
|
|
const { result } = renderHook(() => useOnlineDocument())
|
|
|
|
expect(result.current.currentWorkspace).toBeDefined()
|
|
expect(result.current.currentWorkspace?.workspace_id).toBe('ws-1')
|
|
})
|
|
|
|
it('should call hidePreviewOnlineDocument callback', () => {
|
|
const { result } = renderHook(() => useOnlineDocument())
|
|
|
|
act(() => {
|
|
result.current.hidePreviewOnlineDocument()
|
|
})
|
|
|
|
expect(mockStoreState.setCurrentDocument).toHaveBeenCalledWith(undefined)
|
|
})
|
|
|
|
it('should call clearOnlineDocumentData callback', () => {
|
|
const { result } = renderHook(() => useOnlineDocument())
|
|
|
|
act(() => {
|
|
result.current.clearOnlineDocumentData()
|
|
})
|
|
|
|
expect(mockStoreState.setDocumentsData).toHaveBeenCalledWith([])
|
|
expect(mockStoreState.setSearchValue).toHaveBeenCalledWith('')
|
|
expect(mockStoreState.setOnlineDocuments).toHaveBeenCalledWith([])
|
|
expect(mockStoreState.setCurrentDocument).toHaveBeenCalledWith(undefined)
|
|
})
|
|
})
|
|
|
|
describe('useWebsiteCrawl callbacks', () => {
|
|
it('should call hideWebsitePreview callback', () => {
|
|
const { result } = renderHook(() => useWebsiteCrawl())
|
|
|
|
act(() => {
|
|
result.current.hideWebsitePreview()
|
|
})
|
|
|
|
expect(mockStoreState.setCurrentWebsite).toHaveBeenCalledWith(undefined)
|
|
expect(mockStoreState.setPreviewIndex).toHaveBeenCalledWith(-1)
|
|
})
|
|
|
|
it('should call clearWebsiteCrawlData callback', () => {
|
|
const { result } = renderHook(() => useWebsiteCrawl())
|
|
|
|
act(() => {
|
|
result.current.clearWebsiteCrawlData()
|
|
})
|
|
|
|
expect(mockStoreState.setStep).toHaveBeenCalled()
|
|
expect(mockStoreState.setCrawlResult).toHaveBeenCalledWith(undefined)
|
|
expect(mockStoreState.setCurrentWebsite).toHaveBeenCalledWith(undefined)
|
|
expect(mockStoreState.setWebsitePages).toHaveBeenCalledWith([])
|
|
expect(mockStoreState.setPreviewIndex).toHaveBeenCalledWith(-1)
|
|
})
|
|
})
|
|
|
|
describe('useOnlineDrive callbacks', () => {
|
|
it('should call clearOnlineDriveData callback', () => {
|
|
const { result } = renderHook(() => useOnlineDrive())
|
|
|
|
act(() => {
|
|
result.current.clearOnlineDriveData()
|
|
})
|
|
|
|
expect(mockStoreState.setOnlineDriveFileList).toHaveBeenCalledWith([])
|
|
expect(mockStoreState.setBucket).toHaveBeenCalledWith('')
|
|
expect(mockStoreState.setPrefix).toHaveBeenCalledWith([])
|
|
expect(mockStoreState.setKeywords).toHaveBeenCalledWith('')
|
|
expect(mockStoreState.setSelectedFileIds).toHaveBeenCalledWith([])
|
|
})
|
|
})
|
|
})
|
|
|
|
// ==========================================
|
|
// StepOneContent - All Datasource Types
|
|
// ==========================================
|
|
describe('StepOneContent - All Datasource Types', () => {
|
|
// Mock data source components
|
|
vi.mock('./data-source/local-file', () => ({
|
|
default: () => <div data-testid="local-file-component">Local File</div>,
|
|
}))
|
|
|
|
vi.mock('./data-source/online-documents', () => ({
|
|
default: () => <div data-testid="online-documents-component">Online Documents</div>,
|
|
}))
|
|
|
|
vi.mock('./data-source/website-crawl', () => ({
|
|
default: () => <div data-testid="website-crawl-component">Website Crawl</div>,
|
|
}))
|
|
|
|
vi.mock('./data-source/online-drive', () => ({
|
|
default: () => <div data-testid="online-drive-component">Online Drive</div>,
|
|
}))
|
|
|
|
const defaultProps = {
|
|
datasource: undefined as Datasource | undefined,
|
|
datasourceType: undefined as string | undefined,
|
|
pipelineNodes: [] as Node<DataSourceNodeType>[],
|
|
supportBatchUpload: true,
|
|
localFileListLength: 0,
|
|
isShowVectorSpaceFull: false,
|
|
showSelect: false,
|
|
totalOptions: undefined as number | undefined,
|
|
selectedOptions: undefined as number | undefined,
|
|
tip: '',
|
|
nextBtnDisabled: true,
|
|
onSelectDataSource: vi.fn(),
|
|
onCredentialChange: vi.fn(),
|
|
onSelectAll: vi.fn(),
|
|
onNextStep: vi.fn(),
|
|
}
|
|
|
|
it('should render OnlineDocuments when datasourceType is onlineDocument', () => {
|
|
render(
|
|
<StepOneContent
|
|
{...defaultProps}
|
|
datasource={createMockDatasource({
|
|
nodeData: {
|
|
...createMockDatasource().nodeData,
|
|
provider_type: DatasourceType.onlineDocument,
|
|
},
|
|
})}
|
|
datasourceType={DatasourceType.onlineDocument}
|
|
/>,
|
|
)
|
|
expect(screen.getByTestId('online-documents-component')).toBeInTheDocument()
|
|
})
|
|
|
|
it('should render WebsiteCrawl when datasourceType is websiteCrawl', () => {
|
|
render(
|
|
<StepOneContent
|
|
{...defaultProps}
|
|
datasource={createMockDatasource({
|
|
nodeData: {
|
|
...createMockDatasource().nodeData,
|
|
provider_type: DatasourceType.websiteCrawl,
|
|
},
|
|
})}
|
|
datasourceType={DatasourceType.websiteCrawl}
|
|
/>,
|
|
)
|
|
expect(screen.getByTestId('website-crawl-component')).toBeInTheDocument()
|
|
})
|
|
|
|
it('should render OnlineDrive when datasourceType is onlineDrive', () => {
|
|
render(
|
|
<StepOneContent
|
|
{...defaultProps}
|
|
datasource={createMockDatasource({
|
|
nodeData: {
|
|
...createMockDatasource().nodeData,
|
|
provider_type: DatasourceType.onlineDrive,
|
|
},
|
|
})}
|
|
datasourceType={DatasourceType.onlineDrive}
|
|
/>,
|
|
)
|
|
expect(screen.getByTestId('online-drive-component')).toBeInTheDocument()
|
|
})
|
|
|
|
it('should render LocalFile when datasourceType is localFile', () => {
|
|
render(
|
|
<StepOneContent
|
|
{...defaultProps}
|
|
datasource={createMockDatasource()}
|
|
datasourceType={DatasourceType.localFile}
|
|
/>,
|
|
)
|
|
expect(screen.getByTestId('local-file-component')).toBeInTheDocument()
|
|
})
|
|
})
|
|
|
|
// ==========================================
|
|
// StepTwoPreview - with localFileList
|
|
// ==========================================
|
|
describe('StepTwoPreview - File List Mapping', () => {
|
|
it('should correctly map localFileList to localFiles', () => {
|
|
const fileList = [
|
|
createMockFileItem({ file: createMockFile({ id: 'f1', name: 'file1.txt' }) }),
|
|
createMockFileItem({ file: createMockFile({ id: 'f2', name: 'file2.txt' }) }),
|
|
]
|
|
|
|
render(
|
|
<StepTwoPreview
|
|
datasourceType={DatasourceType.localFile}
|
|
localFileList={fileList}
|
|
onlineDocuments={[]}
|
|
websitePages={[]}
|
|
selectedOnlineDriveFileList={[]}
|
|
isIdle={true}
|
|
isPendingPreview={false}
|
|
estimateData={undefined}
|
|
onPreview={vi.fn()}
|
|
handlePreviewFileChange={vi.fn()}
|
|
handlePreviewOnlineDocumentChange={vi.fn()}
|
|
handlePreviewWebsitePageChange={vi.fn()}
|
|
handlePreviewOnlineDriveFileChange={vi.fn()}
|
|
/>,
|
|
)
|
|
|
|
// ChunkPreview should be rendered
|
|
expect(screen.getByTestId('chunk-preview')).toBeInTheDocument()
|
|
})
|
|
})
|
|
|
|
// ==========================================
|
|
// useDatasourceActions - Additional Coverage
|
|
// ==========================================
|
|
describe('useDatasourceActions - Async Functions', () => {
|
|
beforeEach(() => {
|
|
vi.clearAllMocks()
|
|
mockRunPublishedPipeline.mockReset()
|
|
})
|
|
|
|
const createMockDataSourceStoreForAsync = (datasourceType: string) => ({
|
|
getState: () => ({
|
|
previewLocalFileRef: { current: datasourceType === DatasourceType.localFile ? createMockFile() : undefined },
|
|
previewOnlineDocumentRef: { current: datasourceType === DatasourceType.onlineDocument ? createMockNotionPage() : undefined },
|
|
previewWebsitePageRef: { current: datasourceType === DatasourceType.websiteCrawl ? createMockCrawlResult() : undefined },
|
|
previewOnlineDriveFileRef: { current: datasourceType === DatasourceType.onlineDrive ? createMockOnlineDriveFile() : undefined },
|
|
currentCredentialId: 'cred-1',
|
|
bucket: 'test-bucket',
|
|
localFileList: [createMockFileItem()],
|
|
onlineDocuments: [createMockNotionPage()],
|
|
websitePages: [createMockCrawlResult()],
|
|
selectedFileIds: ['file-1'],
|
|
onlineDriveFileList: [createMockOnlineDriveFile({ id: 'file-1' })],
|
|
setCurrentCredentialId: vi.fn(),
|
|
currentNodeIdRef: { current: '' },
|
|
setOnlineDocuments: vi.fn(),
|
|
setSelectedFileIds: vi.fn(),
|
|
setSelectedPagesId: vi.fn(),
|
|
}),
|
|
})
|
|
|
|
it('should call handleSubmit with preview mode', () => {
|
|
const setEstimateData = vi.fn()
|
|
const params = {
|
|
datasource: createMockDatasource(),
|
|
datasourceType: DatasourceType.localFile,
|
|
pipelineId: 'pipeline-1',
|
|
dataSourceStore: createMockDataSourceStoreForAsync(DatasourceType.localFile) as MockDataSourceStore,
|
|
setEstimateData,
|
|
setBatchId: vi.fn(),
|
|
setDocuments: vi.fn(),
|
|
handleNextStep: vi.fn(),
|
|
PagesMapAndSelectedPagesId: {},
|
|
currentWorkspacePages: [],
|
|
clearOnlineDocumentData: vi.fn(),
|
|
clearWebsiteCrawlData: vi.fn(),
|
|
clearOnlineDriveData: vi.fn(),
|
|
setDatasource: vi.fn(),
|
|
}
|
|
|
|
const { result } = renderHook(() => useDatasourceActions(params))
|
|
|
|
act(() => {
|
|
result.current.onClickPreview()
|
|
result.current.handleSubmit({ test: 'data' })
|
|
})
|
|
|
|
// Should have triggered preview
|
|
expect(result.current.isPreview.current).toBe(true)
|
|
})
|
|
|
|
it('should call handleSubmit with process mode', () => {
|
|
const setBatchId = vi.fn()
|
|
const setDocuments = vi.fn()
|
|
const handleNextStep = vi.fn()
|
|
const params = {
|
|
datasource: createMockDatasource(),
|
|
datasourceType: DatasourceType.localFile,
|
|
pipelineId: 'pipeline-1',
|
|
dataSourceStore: createMockDataSourceStoreForAsync(DatasourceType.localFile) as MockDataSourceStore,
|
|
setEstimateData: vi.fn(),
|
|
setBatchId,
|
|
setDocuments,
|
|
handleNextStep,
|
|
PagesMapAndSelectedPagesId: {},
|
|
currentWorkspacePages: [],
|
|
clearOnlineDocumentData: vi.fn(),
|
|
clearWebsiteCrawlData: vi.fn(),
|
|
clearOnlineDriveData: vi.fn(),
|
|
setDatasource: vi.fn(),
|
|
}
|
|
|
|
const { result } = renderHook(() => useDatasourceActions(params))
|
|
|
|
act(() => {
|
|
result.current.onClickProcess()
|
|
result.current.handleSubmit({ test: 'data' })
|
|
})
|
|
|
|
// Should have triggered process
|
|
expect(result.current.isPreview.current).toBe(false)
|
|
})
|
|
|
|
it('should not call API when datasource is undefined', () => {
|
|
const params = {
|
|
datasource: undefined,
|
|
datasourceType: DatasourceType.localFile,
|
|
pipelineId: 'pipeline-1',
|
|
dataSourceStore: createMockDataSourceStoreForAsync(DatasourceType.localFile) as MockDataSourceStore,
|
|
setEstimateData: vi.fn(),
|
|
setBatchId: vi.fn(),
|
|
setDocuments: vi.fn(),
|
|
handleNextStep: vi.fn(),
|
|
PagesMapAndSelectedPagesId: {},
|
|
currentWorkspacePages: [],
|
|
clearOnlineDocumentData: vi.fn(),
|
|
clearWebsiteCrawlData: vi.fn(),
|
|
clearOnlineDriveData: vi.fn(),
|
|
setDatasource: vi.fn(),
|
|
}
|
|
|
|
const { result } = renderHook(() => useDatasourceActions(params))
|
|
|
|
act(() => {
|
|
result.current.handleSubmit({ test: 'data' })
|
|
})
|
|
|
|
expect(mockRunPublishedPipeline).not.toHaveBeenCalled()
|
|
})
|
|
|
|
it('should not call API when pipelineId is undefined', () => {
|
|
const params = {
|
|
datasource: createMockDatasource(),
|
|
datasourceType: DatasourceType.localFile,
|
|
pipelineId: undefined,
|
|
dataSourceStore: createMockDataSourceStoreForAsync(DatasourceType.localFile) as MockDataSourceStore,
|
|
setEstimateData: vi.fn(),
|
|
setBatchId: vi.fn(),
|
|
setDocuments: vi.fn(),
|
|
handleNextStep: vi.fn(),
|
|
PagesMapAndSelectedPagesId: {},
|
|
currentWorkspacePages: [],
|
|
clearOnlineDocumentData: vi.fn(),
|
|
clearWebsiteCrawlData: vi.fn(),
|
|
clearOnlineDriveData: vi.fn(),
|
|
setDatasource: vi.fn(),
|
|
}
|
|
|
|
const { result } = renderHook(() => useDatasourceActions(params))
|
|
|
|
act(() => {
|
|
result.current.handleSubmit({ test: 'data' })
|
|
})
|
|
|
|
expect(mockRunPublishedPipeline).not.toHaveBeenCalled()
|
|
})
|
|
|
|
it('should build preview info for online document type', () => {
|
|
const params = {
|
|
datasource: createMockDatasource({
|
|
nodeData: {
|
|
...createMockDatasource().nodeData,
|
|
provider_type: DatasourceType.onlineDocument,
|
|
},
|
|
}),
|
|
datasourceType: DatasourceType.onlineDocument,
|
|
pipelineId: 'pipeline-1',
|
|
dataSourceStore: createMockDataSourceStoreForAsync(DatasourceType.onlineDocument) as MockDataSourceStore,
|
|
setEstimateData: vi.fn(),
|
|
setBatchId: vi.fn(),
|
|
setDocuments: vi.fn(),
|
|
handleNextStep: vi.fn(),
|
|
PagesMapAndSelectedPagesId: {},
|
|
currentWorkspacePages: [],
|
|
clearOnlineDocumentData: vi.fn(),
|
|
clearWebsiteCrawlData: vi.fn(),
|
|
clearOnlineDriveData: vi.fn(),
|
|
setDatasource: vi.fn(),
|
|
}
|
|
|
|
const { result } = renderHook(() => useDatasourceActions(params))
|
|
|
|
act(() => {
|
|
result.current.onClickPreview()
|
|
result.current.handleSubmit({ test: 'data' })
|
|
})
|
|
|
|
expect(result.current.isPreview.current).toBe(true)
|
|
})
|
|
|
|
it('should build preview info for website crawl type', () => {
|
|
const params = {
|
|
datasource: createMockDatasource({
|
|
nodeData: {
|
|
...createMockDatasource().nodeData,
|
|
provider_type: DatasourceType.websiteCrawl,
|
|
},
|
|
}),
|
|
datasourceType: DatasourceType.websiteCrawl,
|
|
pipelineId: 'pipeline-1',
|
|
dataSourceStore: createMockDataSourceStoreForAsync(DatasourceType.websiteCrawl) as MockDataSourceStore,
|
|
setEstimateData: vi.fn(),
|
|
setBatchId: vi.fn(),
|
|
setDocuments: vi.fn(),
|
|
handleNextStep: vi.fn(),
|
|
PagesMapAndSelectedPagesId: {},
|
|
currentWorkspacePages: [],
|
|
clearOnlineDocumentData: vi.fn(),
|
|
clearWebsiteCrawlData: vi.fn(),
|
|
clearOnlineDriveData: vi.fn(),
|
|
setDatasource: vi.fn(),
|
|
}
|
|
|
|
const { result } = renderHook(() => useDatasourceActions(params))
|
|
|
|
act(() => {
|
|
result.current.onClickPreview()
|
|
result.current.handleSubmit({ test: 'data' })
|
|
})
|
|
|
|
expect(result.current.isPreview.current).toBe(true)
|
|
})
|
|
|
|
it('should build preview info for online drive type', () => {
|
|
const params = {
|
|
datasource: createMockDatasource({
|
|
nodeData: {
|
|
...createMockDatasource().nodeData,
|
|
provider_type: DatasourceType.onlineDrive,
|
|
},
|
|
}),
|
|
datasourceType: DatasourceType.onlineDrive,
|
|
pipelineId: 'pipeline-1',
|
|
dataSourceStore: createMockDataSourceStoreForAsync(DatasourceType.onlineDrive) as MockDataSourceStore,
|
|
setEstimateData: vi.fn(),
|
|
setBatchId: vi.fn(),
|
|
setDocuments: vi.fn(),
|
|
handleNextStep: vi.fn(),
|
|
PagesMapAndSelectedPagesId: {},
|
|
currentWorkspacePages: [],
|
|
clearOnlineDocumentData: vi.fn(),
|
|
clearWebsiteCrawlData: vi.fn(),
|
|
clearOnlineDriveData: vi.fn(),
|
|
setDatasource: vi.fn(),
|
|
}
|
|
|
|
const { result } = renderHook(() => useDatasourceActions(params))
|
|
|
|
act(() => {
|
|
result.current.onClickPreview()
|
|
result.current.handleSubmit({ test: 'data' })
|
|
})
|
|
|
|
expect(result.current.isPreview.current).toBe(true)
|
|
})
|
|
|
|
it('should toggle select all for online document - deselect all when already selected', () => {
|
|
const setOnlineDocuments = vi.fn()
|
|
const setSelectedPagesId = vi.fn()
|
|
const params = {
|
|
datasource: createMockDatasource({
|
|
nodeData: {
|
|
...createMockDatasource().nodeData,
|
|
provider_type: DatasourceType.onlineDocument,
|
|
},
|
|
}),
|
|
datasourceType: DatasourceType.onlineDocument,
|
|
pipelineId: 'pipeline-1',
|
|
dataSourceStore: {
|
|
getState: () => ({
|
|
...mockStoreState,
|
|
onlineDocuments: [createMockNotionPage()],
|
|
setOnlineDocuments,
|
|
setSelectedPagesId,
|
|
}),
|
|
} as MockDataSourceStore,
|
|
setEstimateData: vi.fn(),
|
|
setBatchId: vi.fn(),
|
|
setDocuments: vi.fn(),
|
|
handleNextStep: vi.fn(),
|
|
PagesMapAndSelectedPagesId: { 'page-1': createMockNotionPage() },
|
|
currentWorkspacePages: [{ page_id: 'page-1' }],
|
|
clearOnlineDocumentData: vi.fn(),
|
|
clearWebsiteCrawlData: vi.fn(),
|
|
clearOnlineDriveData: vi.fn(),
|
|
setDatasource: vi.fn(),
|
|
}
|
|
|
|
const { result } = renderHook(() => useDatasourceActions(params))
|
|
|
|
act(() => {
|
|
result.current.handleSelectAll()
|
|
})
|
|
|
|
// Should deselect all since documents.length >= allIds.length
|
|
expect(setOnlineDocuments).toHaveBeenCalledWith([])
|
|
})
|
|
|
|
it('should toggle select all for online drive - deselect all when already selected', () => {
|
|
const setSelectedFileIds = vi.fn()
|
|
const params = {
|
|
datasource: createMockDatasource({
|
|
nodeData: {
|
|
...createMockDatasource().nodeData,
|
|
provider_type: DatasourceType.onlineDrive,
|
|
},
|
|
}),
|
|
datasourceType: DatasourceType.onlineDrive,
|
|
pipelineId: 'pipeline-1',
|
|
dataSourceStore: {
|
|
getState: () => ({
|
|
...mockStoreState,
|
|
onlineDriveFileList: [createMockOnlineDriveFile({ id: 'file-1' })],
|
|
selectedFileIds: ['file-1'],
|
|
setSelectedFileIds,
|
|
}),
|
|
} as MockDataSourceStore,
|
|
setEstimateData: vi.fn(),
|
|
setBatchId: vi.fn(),
|
|
setDocuments: vi.fn(),
|
|
handleNextStep: vi.fn(),
|
|
PagesMapAndSelectedPagesId: {},
|
|
currentWorkspacePages: [],
|
|
clearOnlineDocumentData: vi.fn(),
|
|
clearWebsiteCrawlData: vi.fn(),
|
|
clearOnlineDriveData: vi.fn(),
|
|
setDatasource: vi.fn(),
|
|
}
|
|
|
|
const { result } = renderHook(() => useDatasourceActions(params))
|
|
|
|
act(() => {
|
|
result.current.handleSelectAll()
|
|
})
|
|
|
|
// Should deselect all since selectedFileIds.length >= allKeys.length
|
|
expect(setSelectedFileIds).toHaveBeenCalledWith([])
|
|
})
|
|
|
|
it('should clear data when credential changes with datasource', () => {
|
|
const clearOnlineDocumentData = vi.fn()
|
|
const params = {
|
|
datasource: createMockDatasource({
|
|
nodeData: {
|
|
...createMockDatasource().nodeData,
|
|
provider_type: DatasourceType.onlineDocument,
|
|
},
|
|
}),
|
|
datasourceType: DatasourceType.onlineDocument,
|
|
pipelineId: 'pipeline-1',
|
|
dataSourceStore: {
|
|
getState: () => ({
|
|
...mockStoreState,
|
|
setCurrentCredentialId: vi.fn(),
|
|
}),
|
|
} as MockDataSourceStore,
|
|
setEstimateData: vi.fn(),
|
|
setBatchId: vi.fn(),
|
|
setDocuments: vi.fn(),
|
|
handleNextStep: vi.fn(),
|
|
PagesMapAndSelectedPagesId: {},
|
|
currentWorkspacePages: [],
|
|
clearOnlineDocumentData,
|
|
clearWebsiteCrawlData: vi.fn(),
|
|
clearOnlineDriveData: vi.fn(),
|
|
setDatasource: vi.fn(),
|
|
}
|
|
|
|
const { result } = renderHook(() => useDatasourceActions(params))
|
|
|
|
act(() => {
|
|
result.current.handleCredentialChange('new-cred')
|
|
})
|
|
|
|
expect(clearOnlineDocumentData).toHaveBeenCalled()
|
|
})
|
|
})
|
|
|
|
// ==========================================
|
|
// useDatasourceActions - onSuccess Callbacks
|
|
// ==========================================
|
|
describe('useDatasourceActions - API Success Callbacks', () => {
|
|
beforeEach(() => {
|
|
vi.clearAllMocks()
|
|
})
|
|
|
|
it('should call setEstimateData on preview success', async () => {
|
|
const setEstimateData = vi.fn()
|
|
const mockResponse = {
|
|
data: { outputs: { chunks: 10, tokens: 100 } },
|
|
}
|
|
|
|
// Create a mock that calls onSuccess
|
|
const mockMutateAsync = vi.fn().mockImplementation((_params, options) => {
|
|
options?.onSuccess?.(mockResponse)
|
|
return Promise.resolve(mockResponse)
|
|
})
|
|
|
|
vi.mocked(mockRunPublishedPipeline).mockImplementation(mockMutateAsync)
|
|
|
|
const params = {
|
|
datasource: createMockDatasource(),
|
|
datasourceType: DatasourceType.localFile,
|
|
pipelineId: 'pipeline-1',
|
|
dataSourceStore: {
|
|
getState: () => ({
|
|
...mockStoreState,
|
|
previewLocalFileRef: { current: createMockFile() },
|
|
currentCredentialId: 'cred-1',
|
|
localFileList: [createMockFileItem()],
|
|
}),
|
|
} as MockDataSourceStore,
|
|
setEstimateData,
|
|
setBatchId: vi.fn(),
|
|
setDocuments: vi.fn(),
|
|
handleNextStep: vi.fn(),
|
|
PagesMapAndSelectedPagesId: {},
|
|
currentWorkspacePages: [],
|
|
clearOnlineDocumentData: vi.fn(),
|
|
clearWebsiteCrawlData: vi.fn(),
|
|
clearOnlineDriveData: vi.fn(),
|
|
setDatasource: vi.fn(),
|
|
}
|
|
|
|
const { result } = renderHook(() => useDatasourceActions(params))
|
|
|
|
await act(async () => {
|
|
result.current.isPreview.current = true
|
|
await result.current.handleSubmit({ test: 'data' })
|
|
})
|
|
|
|
expect(setEstimateData).toHaveBeenCalledWith(mockResponse.data.outputs)
|
|
})
|
|
|
|
it('should call setBatchId, setDocuments, handleNextStep on process success', async () => {
|
|
const setBatchId = vi.fn()
|
|
const setDocuments = vi.fn()
|
|
const handleNextStep = vi.fn()
|
|
const mockResponse = {
|
|
batch: 'batch-123',
|
|
documents: [{ id: 'doc-1' }],
|
|
}
|
|
|
|
const mockMutateAsync = vi.fn().mockImplementation((_params, options) => {
|
|
options?.onSuccess?.(mockResponse)
|
|
return Promise.resolve(mockResponse)
|
|
})
|
|
|
|
vi.mocked(mockRunPublishedPipeline).mockImplementation(mockMutateAsync)
|
|
|
|
const params = {
|
|
datasource: createMockDatasource(),
|
|
datasourceType: DatasourceType.localFile,
|
|
pipelineId: 'pipeline-1',
|
|
dataSourceStore: {
|
|
getState: () => ({
|
|
...mockStoreState,
|
|
previewLocalFileRef: { current: createMockFile() },
|
|
currentCredentialId: 'cred-1',
|
|
localFileList: [createMockFileItem()],
|
|
}),
|
|
} as MockDataSourceStore,
|
|
setEstimateData: vi.fn(),
|
|
setBatchId,
|
|
setDocuments,
|
|
handleNextStep,
|
|
PagesMapAndSelectedPagesId: {},
|
|
currentWorkspacePages: [],
|
|
clearOnlineDocumentData: vi.fn(),
|
|
clearWebsiteCrawlData: vi.fn(),
|
|
clearOnlineDriveData: vi.fn(),
|
|
setDatasource: vi.fn(),
|
|
}
|
|
|
|
const { result } = renderHook(() => useDatasourceActions(params))
|
|
|
|
await act(async () => {
|
|
result.current.isPreview.current = false
|
|
await result.current.handleSubmit({ test: 'data' })
|
|
})
|
|
|
|
expect(setBatchId).toHaveBeenCalledWith('batch-123')
|
|
expect(setDocuments).toHaveBeenCalledWith([{ id: 'doc-1' }])
|
|
expect(handleNextStep).toHaveBeenCalled()
|
|
})
|
|
|
|
it('should handle empty batch and documents in process response', async () => {
|
|
const setBatchId = vi.fn()
|
|
const setDocuments = vi.fn()
|
|
const handleNextStep = vi.fn()
|
|
const mockResponse = {} // Empty response
|
|
|
|
const mockMutateAsync = vi.fn().mockImplementation((_params, options) => {
|
|
options?.onSuccess?.(mockResponse)
|
|
return Promise.resolve(mockResponse)
|
|
})
|
|
|
|
vi.mocked(mockRunPublishedPipeline).mockImplementation(mockMutateAsync)
|
|
|
|
const params = {
|
|
datasource: createMockDatasource(),
|
|
datasourceType: DatasourceType.localFile,
|
|
pipelineId: 'pipeline-1',
|
|
dataSourceStore: {
|
|
getState: () => ({
|
|
...mockStoreState,
|
|
previewLocalFileRef: { current: createMockFile() },
|
|
currentCredentialId: 'cred-1',
|
|
localFileList: [createMockFileItem()],
|
|
}),
|
|
} as MockDataSourceStore,
|
|
setEstimateData: vi.fn(),
|
|
setBatchId,
|
|
setDocuments,
|
|
handleNextStep,
|
|
PagesMapAndSelectedPagesId: {},
|
|
currentWorkspacePages: [],
|
|
clearOnlineDocumentData: vi.fn(),
|
|
clearWebsiteCrawlData: vi.fn(),
|
|
clearOnlineDriveData: vi.fn(),
|
|
setDatasource: vi.fn(),
|
|
}
|
|
|
|
const { result } = renderHook(() => useDatasourceActions(params))
|
|
|
|
await act(async () => {
|
|
result.current.isPreview.current = false
|
|
await result.current.handleSubmit({ test: 'data' })
|
|
})
|
|
|
|
expect(setBatchId).toHaveBeenCalledWith('')
|
|
expect(setDocuments).toHaveBeenCalledWith([])
|
|
expect(handleNextStep).toHaveBeenCalled()
|
|
})
|
|
})
|
|
|
|
// ==========================================
|
|
// useDatasourceActions - buildProcessDatasourceInfo Coverage
|
|
// ==========================================
|
|
describe('useDatasourceActions - Process Mode for All Datasource Types', () => {
|
|
beforeEach(() => {
|
|
vi.clearAllMocks()
|
|
})
|
|
|
|
it('should build process info for onlineDocument type', async () => {
|
|
const setBatchId = vi.fn()
|
|
const setDocuments = vi.fn()
|
|
const handleNextStep = vi.fn()
|
|
const mockResponse = { batch: 'batch-1', documents: [] }
|
|
|
|
const mockMutateAsync = vi.fn().mockImplementation((_params, options) => {
|
|
options?.onSuccess?.(mockResponse)
|
|
return Promise.resolve(mockResponse)
|
|
})
|
|
vi.mocked(mockRunPublishedPipeline).mockImplementation(mockMutateAsync)
|
|
|
|
const params = {
|
|
datasource: createMockDatasource({
|
|
nodeData: {
|
|
...createMockDatasource().nodeData,
|
|
provider_type: DatasourceType.onlineDocument,
|
|
},
|
|
}),
|
|
datasourceType: DatasourceType.onlineDocument,
|
|
pipelineId: 'pipeline-1',
|
|
dataSourceStore: {
|
|
getState: () => ({
|
|
...mockStoreState,
|
|
currentCredentialId: 'cred-1',
|
|
onlineDocuments: [createMockNotionPage()],
|
|
}),
|
|
} as MockDataSourceStore,
|
|
setEstimateData: vi.fn(),
|
|
setBatchId,
|
|
setDocuments,
|
|
handleNextStep,
|
|
PagesMapAndSelectedPagesId: {},
|
|
currentWorkspacePages: [],
|
|
clearOnlineDocumentData: vi.fn(),
|
|
clearWebsiteCrawlData: vi.fn(),
|
|
clearOnlineDriveData: vi.fn(),
|
|
setDatasource: vi.fn(),
|
|
}
|
|
|
|
const { result } = renderHook(() => useDatasourceActions(params))
|
|
|
|
await act(async () => {
|
|
result.current.isPreview.current = false
|
|
await result.current.handleSubmit({ test: 'data' })
|
|
})
|
|
|
|
expect(mockMutateAsync).toHaveBeenCalled()
|
|
expect(setBatchId).toHaveBeenCalled()
|
|
})
|
|
|
|
it('should build process info for websiteCrawl type', async () => {
|
|
const setBatchId = vi.fn()
|
|
const setDocuments = vi.fn()
|
|
const handleNextStep = vi.fn()
|
|
const mockResponse = { batch: 'batch-1', documents: [] }
|
|
|
|
const mockMutateAsync = vi.fn().mockImplementation((_params, options) => {
|
|
options?.onSuccess?.(mockResponse)
|
|
return Promise.resolve(mockResponse)
|
|
})
|
|
vi.mocked(mockRunPublishedPipeline).mockImplementation(mockMutateAsync)
|
|
|
|
const params = {
|
|
datasource: createMockDatasource({
|
|
nodeData: {
|
|
...createMockDatasource().nodeData,
|
|
provider_type: DatasourceType.websiteCrawl,
|
|
},
|
|
}),
|
|
datasourceType: DatasourceType.websiteCrawl,
|
|
pipelineId: 'pipeline-1',
|
|
dataSourceStore: {
|
|
getState: () => ({
|
|
...mockStoreState,
|
|
currentCredentialId: 'cred-1',
|
|
websitePages: [createMockCrawlResult()],
|
|
}),
|
|
} as MockDataSourceStore,
|
|
setEstimateData: vi.fn(),
|
|
setBatchId,
|
|
setDocuments,
|
|
handleNextStep,
|
|
PagesMapAndSelectedPagesId: {},
|
|
currentWorkspacePages: [],
|
|
clearOnlineDocumentData: vi.fn(),
|
|
clearWebsiteCrawlData: vi.fn(),
|
|
clearOnlineDriveData: vi.fn(),
|
|
setDatasource: vi.fn(),
|
|
}
|
|
|
|
const { result } = renderHook(() => useDatasourceActions(params))
|
|
|
|
await act(async () => {
|
|
result.current.isPreview.current = false
|
|
await result.current.handleSubmit({ test: 'data' })
|
|
})
|
|
|
|
expect(mockMutateAsync).toHaveBeenCalled()
|
|
expect(setBatchId).toHaveBeenCalled()
|
|
})
|
|
|
|
it('should build process info for onlineDrive type', async () => {
|
|
const setBatchId = vi.fn()
|
|
const setDocuments = vi.fn()
|
|
const handleNextStep = vi.fn()
|
|
const mockResponse = { batch: 'batch-1', documents: [] }
|
|
|
|
const mockMutateAsync = vi.fn().mockImplementation((_params, options) => {
|
|
options?.onSuccess?.(mockResponse)
|
|
return Promise.resolve(mockResponse)
|
|
})
|
|
vi.mocked(mockRunPublishedPipeline).mockImplementation(mockMutateAsync)
|
|
|
|
const params = {
|
|
datasource: createMockDatasource({
|
|
nodeData: {
|
|
...createMockDatasource().nodeData,
|
|
provider_type: DatasourceType.onlineDrive,
|
|
},
|
|
}),
|
|
datasourceType: DatasourceType.onlineDrive,
|
|
pipelineId: 'pipeline-1',
|
|
dataSourceStore: {
|
|
getState: () => ({
|
|
...mockStoreState,
|
|
currentCredentialId: 'cred-1',
|
|
bucket: 'test-bucket',
|
|
selectedFileIds: ['file-1'],
|
|
onlineDriveFileList: [createMockOnlineDriveFile({ id: 'file-1' })],
|
|
}),
|
|
} as MockDataSourceStore,
|
|
setEstimateData: vi.fn(),
|
|
setBatchId,
|
|
setDocuments,
|
|
handleNextStep,
|
|
PagesMapAndSelectedPagesId: {},
|
|
currentWorkspacePages: [],
|
|
clearOnlineDocumentData: vi.fn(),
|
|
clearWebsiteCrawlData: vi.fn(),
|
|
clearOnlineDriveData: vi.fn(),
|
|
setDatasource: vi.fn(),
|
|
}
|
|
|
|
const { result } = renderHook(() => useDatasourceActions(params))
|
|
|
|
await act(async () => {
|
|
result.current.isPreview.current = false
|
|
await result.current.handleSubmit({ test: 'data' })
|
|
})
|
|
|
|
expect(mockMutateAsync).toHaveBeenCalled()
|
|
expect(setBatchId).toHaveBeenCalled()
|
|
})
|
|
|
|
it('should return early in preview mode when datasource is undefined', async () => {
|
|
const setEstimateData = vi.fn()
|
|
const mockMutateAsync = vi.fn()
|
|
vi.mocked(mockRunPublishedPipeline).mockImplementation(mockMutateAsync)
|
|
|
|
const params = {
|
|
datasource: undefined, // undefined datasource
|
|
datasourceType: DatasourceType.localFile,
|
|
pipelineId: 'pipeline-1',
|
|
dataSourceStore: {
|
|
getState: () => ({ ...mockStoreState }),
|
|
} as MockDataSourceStore,
|
|
setEstimateData,
|
|
setBatchId: vi.fn(),
|
|
setDocuments: vi.fn(),
|
|
handleNextStep: vi.fn(),
|
|
PagesMapAndSelectedPagesId: {},
|
|
currentWorkspacePages: [],
|
|
clearOnlineDocumentData: vi.fn(),
|
|
clearWebsiteCrawlData: vi.fn(),
|
|
clearOnlineDriveData: vi.fn(),
|
|
setDatasource: vi.fn(),
|
|
}
|
|
|
|
const { result } = renderHook(() => useDatasourceActions(params))
|
|
|
|
await act(async () => {
|
|
result.current.isPreview.current = true
|
|
await result.current.handleSubmit({ test: 'data' })
|
|
})
|
|
|
|
// Should not call API when datasource is undefined
|
|
expect(mockMutateAsync).not.toHaveBeenCalled()
|
|
expect(setEstimateData).not.toHaveBeenCalled()
|
|
})
|
|
|
|
it('should return early in preview mode when pipelineId is undefined', async () => {
|
|
const setEstimateData = vi.fn()
|
|
const mockMutateAsync = vi.fn()
|
|
vi.mocked(mockRunPublishedPipeline).mockImplementation(mockMutateAsync)
|
|
|
|
const params = {
|
|
datasource: createMockDatasource(),
|
|
datasourceType: DatasourceType.localFile,
|
|
pipelineId: undefined, // undefined pipelineId
|
|
dataSourceStore: {
|
|
getState: () => ({ ...mockStoreState }),
|
|
} as MockDataSourceStore,
|
|
setEstimateData,
|
|
setBatchId: vi.fn(),
|
|
setDocuments: vi.fn(),
|
|
handleNextStep: vi.fn(),
|
|
PagesMapAndSelectedPagesId: {},
|
|
currentWorkspacePages: [],
|
|
clearOnlineDocumentData: vi.fn(),
|
|
clearWebsiteCrawlData: vi.fn(),
|
|
clearOnlineDriveData: vi.fn(),
|
|
setDatasource: vi.fn(),
|
|
}
|
|
|
|
const { result } = renderHook(() => useDatasourceActions(params))
|
|
|
|
await act(async () => {
|
|
result.current.isPreview.current = true
|
|
await result.current.handleSubmit({ test: 'data' })
|
|
})
|
|
|
|
// Should not call API when pipelineId is undefined
|
|
expect(mockMutateAsync).not.toHaveBeenCalled()
|
|
expect(setEstimateData).not.toHaveBeenCalled()
|
|
})
|
|
|
|
it('should skip file if not found in onlineDriveFileList', async () => {
|
|
const setBatchId = vi.fn()
|
|
const mockResponse = { batch: 'batch-1', documents: [] }
|
|
|
|
const mockMutateAsync = vi.fn().mockImplementation((_params, options) => {
|
|
options?.onSuccess?.(mockResponse)
|
|
return Promise.resolve(mockResponse)
|
|
})
|
|
vi.mocked(mockRunPublishedPipeline).mockImplementation(mockMutateAsync)
|
|
|
|
const params = {
|
|
datasource: createMockDatasource({
|
|
nodeData: {
|
|
...createMockDatasource().nodeData,
|
|
provider_type: DatasourceType.onlineDrive,
|
|
},
|
|
}),
|
|
datasourceType: DatasourceType.onlineDrive,
|
|
pipelineId: 'pipeline-1',
|
|
dataSourceStore: {
|
|
getState: () => ({
|
|
...mockStoreState,
|
|
currentCredentialId: 'cred-1',
|
|
bucket: 'test-bucket',
|
|
selectedFileIds: ['non-existent-file'],
|
|
onlineDriveFileList: [createMockOnlineDriveFile({ id: 'file-1' })],
|
|
}),
|
|
} as MockDataSourceStore,
|
|
setEstimateData: vi.fn(),
|
|
setBatchId,
|
|
setDocuments: vi.fn(),
|
|
handleNextStep: vi.fn(),
|
|
PagesMapAndSelectedPagesId: {},
|
|
currentWorkspacePages: [],
|
|
clearOnlineDocumentData: vi.fn(),
|
|
clearWebsiteCrawlData: vi.fn(),
|
|
clearOnlineDriveData: vi.fn(),
|
|
setDatasource: vi.fn(),
|
|
}
|
|
|
|
const { result } = renderHook(() => useDatasourceActions(params))
|
|
|
|
await act(async () => {
|
|
result.current.isPreview.current = false
|
|
await result.current.handleSubmit({ test: 'data' })
|
|
})
|
|
|
|
// Should still call API but with empty datasource_info_list
|
|
expect(mockMutateAsync).toHaveBeenCalled()
|
|
})
|
|
})
|
|
|
|
// ==========================================
|
|
// useDatasourceActions - Edge Case Branches
|
|
// ==========================================
|
|
describe('useDatasourceActions - Edge Case Branches', () => {
|
|
beforeEach(() => {
|
|
vi.clearAllMocks()
|
|
})
|
|
|
|
it('should handle selectAll when currentWorkspacePages is undefined', () => {
|
|
const setOnlineDocuments = vi.fn()
|
|
const setSelectedPagesId = vi.fn()
|
|
|
|
const params = {
|
|
datasource: createMockDatasource({
|
|
nodeData: {
|
|
...createMockDatasource().nodeData,
|
|
provider_type: DatasourceType.onlineDocument,
|
|
},
|
|
}),
|
|
datasourceType: DatasourceType.onlineDocument,
|
|
pipelineId: 'pipeline-1',
|
|
dataSourceStore: {
|
|
getState: () => ({
|
|
...mockStoreState,
|
|
onlineDocuments: [],
|
|
setOnlineDocuments,
|
|
setSelectedPagesId,
|
|
}),
|
|
} as MockDataSourceStore,
|
|
setEstimateData: vi.fn(),
|
|
setBatchId: vi.fn(),
|
|
setDocuments: vi.fn(),
|
|
handleNextStep: vi.fn(),
|
|
PagesMapAndSelectedPagesId: {},
|
|
currentWorkspacePages: undefined, // undefined currentWorkspacePages
|
|
clearOnlineDocumentData: vi.fn(),
|
|
clearWebsiteCrawlData: vi.fn(),
|
|
clearOnlineDriveData: vi.fn(),
|
|
setDatasource: vi.fn(),
|
|
}
|
|
|
|
const { result } = renderHook(() => useDatasourceActions(params))
|
|
|
|
act(() => {
|
|
result.current.handleSelectAll()
|
|
})
|
|
|
|
// Should use empty array when currentWorkspacePages is undefined
|
|
// Since allIds.length is 0 and onlineDocuments.length is 0, it should deselect
|
|
expect(setOnlineDocuments).toHaveBeenCalledWith([])
|
|
})
|
|
|
|
it('should not clear data when datasource is undefined in handleCredentialChange', () => {
|
|
const clearOnlineDocumentData = vi.fn()
|
|
|
|
const params = {
|
|
datasource: undefined, // undefined datasource
|
|
datasourceType: DatasourceType.onlineDocument,
|
|
pipelineId: 'pipeline-1',
|
|
dataSourceStore: {
|
|
getState: () => ({
|
|
...mockStoreState,
|
|
setCurrentCredentialId: vi.fn(),
|
|
}),
|
|
} as MockDataSourceStore,
|
|
setEstimateData: vi.fn(),
|
|
setBatchId: vi.fn(),
|
|
setDocuments: vi.fn(),
|
|
handleNextStep: vi.fn(),
|
|
PagesMapAndSelectedPagesId: {},
|
|
currentWorkspacePages: [],
|
|
clearOnlineDocumentData,
|
|
clearWebsiteCrawlData: vi.fn(),
|
|
clearOnlineDriveData: vi.fn(),
|
|
setDatasource: vi.fn(),
|
|
}
|
|
|
|
const { result } = renderHook(() => useDatasourceActions(params))
|
|
|
|
act(() => {
|
|
result.current.handleCredentialChange('new-cred')
|
|
})
|
|
|
|
// Should not call clearOnlineDocumentData when datasource is undefined
|
|
expect(clearOnlineDocumentData).not.toHaveBeenCalled()
|
|
})
|
|
})
|
|
|
|
// ==========================================
|
|
// Hooks Index Re-exports Test
|
|
// ==========================================
|
|
describe('Hooks Index Re-exports', () => {
|
|
it('should export useAddDocumentsSteps', async () => {
|
|
const hooksModule = await import('./hooks')
|
|
expect(hooksModule.useAddDocumentsSteps).toBeDefined()
|
|
})
|
|
|
|
it('should export useDatasourceActions', async () => {
|
|
const hooksModule = await import('./hooks')
|
|
expect(hooksModule.useDatasourceActions).toBeDefined()
|
|
})
|
|
|
|
it('should export useDatasourceOptions', async () => {
|
|
const hooksModule = await import('./hooks')
|
|
expect(hooksModule.useDatasourceOptions).toBeDefined()
|
|
})
|
|
|
|
it('should export useLocalFile', async () => {
|
|
const hooksModule = await import('./hooks')
|
|
expect(hooksModule.useLocalFile).toBeDefined()
|
|
})
|
|
|
|
it('should export useOnlineDocument', async () => {
|
|
const hooksModule = await import('./hooks')
|
|
expect(hooksModule.useOnlineDocument).toBeDefined()
|
|
})
|
|
|
|
it('should export useOnlineDrive', async () => {
|
|
const hooksModule = await import('./hooks')
|
|
expect(hooksModule.useOnlineDrive).toBeDefined()
|
|
})
|
|
|
|
it('should export useWebsiteCrawl', async () => {
|
|
const hooksModule = await import('./hooks')
|
|
expect(hooksModule.useWebsiteCrawl).toBeDefined()
|
|
})
|
|
|
|
it('should export useDatasourceUIState', async () => {
|
|
const hooksModule = await import('./hooks')
|
|
expect(hooksModule.useDatasourceUIState).toBeDefined()
|
|
})
|
|
})
|
|
|
|
// ==========================================
|
|
// Steps Index Re-exports Test
|
|
// ==========================================
|
|
describe('Steps Index Re-exports', () => {
|
|
it('should export StepOneContent', async () => {
|
|
const stepsModule = await import('./steps')
|
|
expect(stepsModule.StepOneContent).toBeDefined()
|
|
})
|
|
|
|
it('should export StepTwoContent', async () => {
|
|
const stepsModule = await import('./steps')
|
|
expect(stepsModule.StepTwoContent).toBeDefined()
|
|
})
|
|
|
|
it('should export StepThreeContent', async () => {
|
|
const stepsModule = await import('./steps')
|
|
expect(stepsModule.StepThreeContent).toBeDefined()
|
|
})
|
|
})
|