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 }) => ( {children} ), })) // Mock billing components (external dependencies) vi.mock('@/app/components/billing/vector-space-full', () => ({ default: () =>
Vector Space Full
, })) vi.mock('@/app/components/billing/plan-upgrade-modal', () => ({ default: ({ show, onClose }: { show: boolean, onClose: () => void }) => ( show ? (
) : null ), })) vi.mock('@/app/components/datasets/create/step-one/upgrade-card', () => ({ default: () =>
Upgrade Card
, })) // 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 => ({ 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 => ({ 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 => ({ file: createMockFile(), progress: 100, ...overrides, } as FileItem) const createMockNotionPage = (overrides?: Partial): 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 => ({ source_url: 'https://example.com', title: 'Test Page', markdown: '# Test', description: 'A test page', ...overrides, } as CrawlResultItem) const createMockOnlineDriveFile = (overrides?: Partial): 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).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[], 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() expect(screen.getByTestId('vector-space-full')).toBeInTheDocument() }) it('should not render VectorSpaceFull when isShowVectorSpaceFull is false', () => { render() expect(screen.queryByTestId('vector-space-full')).not.toBeInTheDocument() }) it('should render UpgradeCard when conditions are met', () => { render( , ) expect(screen.getByTestId('upgrade-card')).toBeInTheDocument() }) it('should not render UpgradeCard when supportBatchUpload is true', () => { render( , ) expect(screen.queryByTestId('upgrade-card')).not.toBeInTheDocument() }) it('should call onNextStep when next button is clicked', () => { const onNextStep = vi.fn() render() // 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() 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) => void onBack: () => void }, ref: React.Ref<{ submit: () => void }>) => { React.useImperativeHandle(ref, () => ({ submit: () => onSubmit({ test: 'data' }), })) return (
{dataSourceNodeId} {isRunning.toString()}
) }), })) 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() expect(screen.getByTestId('process-documents')).toBeInTheDocument() }) it('should pass dataSourceNodeId to ProcessDocuments', () => { render() expect(screen.getByTestId('datasource-node-id')).toHaveTextContent('custom-node') }) it('should pass isRunning to ProcessDocuments', () => { render() expect(screen.getByTestId('is-running')).toHaveTextContent('true') }) it('should call onProcess when process button is clicked', () => { const onProcess = vi.fn() render() fireEvent.click(screen.getByTestId('process-btn')) expect(onProcess).toHaveBeenCalled() }) it('should call onBack when back button is clicked', () => { const onBack = vi.fn() render() 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[] }) => (
{batchId} {documents.length}
), })) it('should render Processing component', () => { render() expect(screen.getByTestId('processing')).toBeInTheDocument() }) it('should pass batchId to Processing', () => { render() expect(screen.getByTestId('batch-id')).toHaveTextContent('batch-123') }) it('should pass documents count to Processing', () => { const documents = [{ id: '1' }, { id: '2' }] render() 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 }) => (
{file.name}
), })) vi.mock('./preview/online-document-preview', () => ({ default: ({ datasourceNodeId, currentPage, hidePreview }: { datasourceNodeId: string currentPage: NotionPage & { workspace_id: string } hidePreview: () => void }) => (
{datasourceNodeId} {currentPage.page_id}
), })) vi.mock('./preview/web-preview', () => ({ default: ({ currentWebsite, hidePreview }: { currentWebsite: CrawlResultItem, hidePreview: () => void }) => (
{currentWebsite.source_url}
), })) 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() 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( , ) expect(screen.getByTestId('file-preview')).toBeInTheDocument() expect(screen.getByTestId('file-name')).toHaveTextContent('test.txt') }) it('should render OnlineDocumentPreview when currentDocument is set', () => { render( , ) expect(screen.getByTestId('online-document-preview')).toBeInTheDocument() }) it('should render WebsitePreview when currentWebsite is set', () => { render( , ) expect(screen.getByTestId('web-preview')).toBeInTheDocument() }) it('should call hidePreviewLocalFile when hide button is clicked', () => { const hidePreviewLocalFile = vi.fn() render( , ) 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 }) => (
{dataSourceType} {isIdle.toString()} {isPending.toString()}
), })) 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() expect(screen.getByTestId('chunk-preview')).toBeInTheDocument() }) it('should pass datasourceType to ChunkPreview', () => { render() expect(screen.getByTestId('datasource-type')).toHaveTextContent(DatasourceType.onlineDocument) }) it('should pass isIdle to ChunkPreview', () => { render() expect(screen.getByTestId('is-idle')).toHaveTextContent('false') }) it('should pass isPendingPreview to ChunkPreview', () => { render() expect(screen.getByTestId('is-pending')).toHaveTextContent('true') }) it('should call onPreview when preview button is clicked', () => { const onPreview = vi.fn() render() 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[] = [ { 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[] = [ { 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: () =>
Local File
, })) vi.mock('./data-source/online-documents', () => ({ default: () =>
Online Documents
, })) vi.mock('./data-source/website-crawl', () => ({ default: () =>
Website Crawl
, })) vi.mock('./data-source/online-drive', () => ({ default: () =>
Online Drive
, })) const defaultProps = { datasource: undefined as Datasource | undefined, datasourceType: undefined as string | undefined, pipelineNodes: [] as Node[], 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( , ) expect(screen.getByTestId('online-documents-component')).toBeInTheDocument() }) it('should render WebsiteCrawl when datasourceType is websiteCrawl', () => { render( , ) expect(screen.getByTestId('website-crawl-component')).toBeInTheDocument() }) it('should render OnlineDrive when datasourceType is onlineDrive', () => { render( , ) expect(screen.getByTestId('online-drive-component')).toBeInTheDocument() }) it('should render LocalFile when datasourceType is localFile', () => { render( , ) 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( , ) // 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() }) })