import React from 'react'; import { fireEvent, render, screen, waitFor } from '@testing-library/react'; import { beforeEach, describe, expect, it, vi } from 'vitest'; const apiMocks = vi.hoisted(() => ({ list: vi.fn(), upload: vi.fn(), delete: vi.fn(), })); vi.mock('../src/lib/knowledge-docs-api', () => ({ knowledgeDocsApi: apiMocks, })); vi.mock('../src/pages/Knowledge/copy', () => ({ useKnowledgeCopy: () => (path: string, params?: Record, fallback?: string) => { const dictionary: Record = { 'knowledge.title': 'Knowledge Docs', 'knowledge.subtitle': 'Manage docs', 'knowledge.documentsLabel': 'Documents', 'knowledge.storageLabel': 'Storage', 'knowledge.refresh': 'Refresh', 'knowledge.upload': 'Upload', 'knowledge.status.loading': 'Loading documents...', 'knowledge.status.uploading': 'Uploading...', 'knowledge.status.deleting': 'Deleting...', 'knowledge.status.uploadSuccess': 'Uploaded', 'knowledge.status.deleteSuccess': 'Deleted', 'knowledge.emptyTitle': 'No documents yet', 'knowledge.emptyDescription': 'Upload a file', 'knowledge.deleteDialog.title': 'Delete document?', 'knowledge.deleteDialog.confirm': 'Delete document', 'knowledge.deleteDialog.close': 'Close dialog', 'knowledge.common.cancel': 'Cancel', 'knowledge.table.name': 'Name', 'knowledge.table.size': 'Size', 'knowledge.table.modifiedAt': 'Modified At', 'knowledge.table.type': 'Type', 'knowledge.table.actions': 'Actions', 'knowledge.table.delete': 'Delete', }; if (path === 'knowledge.status.failed') { return `Knowledge docs request failed: ${params?.error ?? ''}`; } if (path === 'knowledge.deleteDialog.description') { return `This will permanently remove "${params?.name ?? ''}" from the local knowledge docs directory.`; } return dictionary[path] ?? fallback ?? path; }, })); import KnowledgePage from '../src/pages/Knowledge'; describe('KnowledgePage', () => { beforeEach(() => { apiMocks.list.mockReset(); apiMocks.upload.mockReset(); apiMocks.delete.mockReset(); }); it('loads and renders docs from the knowledge docs api', async () => { apiMocks.list.mockResolvedValue([ { name: 'guide.md', size: 1024, modifiedAt: '2026-04-18T10:00:00.000Z', type: 'md', }, ]); render(); expect(await screen.findByText('guide.md')).toBeTruthy(); expect(screen.getByText('MD')).toBeTruthy(); }); it('deletes a doc after confirmation', async () => { apiMocks.list.mockResolvedValue([ { name: 'guide.md', size: 1024, modifiedAt: '2026-04-18T10:00:00.000Z', type: 'md', }, ]); apiMocks.delete.mockResolvedValue(undefined); render(); const deleteButton = await screen.findByRole('button', { name: /delete/i }); fireEvent.click(deleteButton); fireEvent.click(screen.getByRole('button', { name: 'Delete document' })); await waitFor(() => { expect(apiMocks.delete).toHaveBeenCalledWith('guide.md'); }); }); });