UNPKG

lorehub

Version:

Capture and surface the collective wisdom of your codebase

136 lines 6.05 kB
import { describe, it, expect, vi, beforeEach } from 'vitest'; import React from 'react'; import { render } from 'ink-testing-library'; import { AddFact } from './AddFact.js'; import { Database } from '../../db/database.js'; // Mock database vi.mock('../../db/database.js'); // Mock getProjectInfo to avoid async loading import { getProjectInfo } from '../utils/project.js'; vi.mock('../utils/project.js', () => ({ getProjectInfo: vi.fn(), })); describe('AddFact Component', () => { const mockProject = { id: 'proj-123', name: 'test-project', path: '/test/path', isMonorepo: false, provinces: ['api', 'worker'], lastSeen: new Date(), createdAt: new Date(), }; const mockDb = { findRealmByPath: vi.fn().mockReturnValue(mockProject), createRealm: vi.fn().mockReturnValue(mockProject), createLore: vi.fn().mockImplementation((input) => ({ ...input, id: 'lore-123', createdAt: new Date(), updatedAt: new Date(), })), checkForDuplicates: vi.fn().mockResolvedValue([]), updateRealmLastSeen: vi.fn().mockReturnValue(mockProject), close: vi.fn(), }; beforeEach(() => { vi.clearAllMocks(); // Default mock for getProjectInfo getProjectInfo.mockResolvedValue({ name: 'test-project', path: '/test/path', gitRemote: null, isMonorepo: false, services: [], }); }); it('should render fact creation form', async () => { const { lastFrame } = render(React.createElement(AddFact, { db: mockDb, projectPath: "/test/path", initialContent: "" })); // Wait for component to load await new Promise(resolve => setTimeout(resolve, 50)); expect(lastFrame()).toContain('Add New Lore'); expect(lastFrame()).toContain('test-project - /test/path'); expect(lastFrame()).toContain('Content'); }); it('should show fact type selector', async () => { const { lastFrame } = render(React.createElement(AddFact, { db: mockDb, projectPath: "/test/path", initialContent: "Test fact" })); // Wait for component to load await new Promise(resolve => setTimeout(resolve, 50)); expect(lastFrame()).toContain('Type'); expect(lastFrame()).toContain('Decree - Architectural or technical choice'); }); it('should allow navigation between fields', async () => { const { lastFrame, stdin } = render(React.createElement(AddFact, { db: mockDb, projectPath: "/test/path", initialContent: "" })); // Wait for component to load await new Promise(resolve => setTimeout(resolve, 50)); // Initial state - focus on content expect(lastFrame()).toContain('Content'); // Press tab to move to type stdin.write('\t'); expect(lastFrame()).toContain('Type'); // Press tab to move to why stdin.write('\t'); expect(lastFrame()).toContain('Why'); }); it('should handle monorepo service selection', async () => { const monorepoProject = { ...mockProject, isMonorepo: true, provinces: ['auth', 'api', 'worker', 'web'], }; // Mock getProjectInfo for monorepo getProjectInfo.mockResolvedValue({ name: 'test-project', path: '/test/path', gitRemote: null, isMonorepo: true, services: ['auth', 'api', 'worker', 'web'], }); mockDb.findRealmByPath = vi.fn().mockReturnValue(monorepoProject); const { lastFrame } = render(React.createElement(AddFact, { db: mockDb, projectPath: "/test/path", initialContent: "" })); // Wait for component to load await new Promise(resolve => setTimeout(resolve, 100)); const frame = lastFrame(); // Check if it's a monorepo form by looking for service-related text expect(frame).toMatch(/Province|All provinces/); }); it('should show confidence slider', async () => { const { lastFrame } = render(React.createElement(AddFact, { db: mockDb, projectPath: "/test/path", initialContent: "" })); // Wait for component to load await new Promise(resolve => setTimeout(resolve, 50)); expect(lastFrame()).toContain('Confidence:'); expect(lastFrame()).toMatch(/\d+%/); // Should show percentage }); it.skip('should create fact on submit', async () => { // Skipping this test as it requires complex mocking of Ink's interactive components // The functionality is tested through integration tests }); it('should handle project creation for new projects', async () => { // Mock getProjectInfo for new project getProjectInfo.mockResolvedValue({ name: 'new-project', path: '/new/project', gitRemote: null, isMonorepo: false, services: [], }); mockDb.findRealmByPath = vi.fn().mockReturnValue(null); const { lastFrame } = render(React.createElement(AddFact, { db: mockDb, projectPath: "/new/project", initialContent: "" })); // Wait for component to load await new Promise(resolve => setTimeout(resolve, 50)); expect(mockDb.createRealm).toHaveBeenCalledWith(expect.objectContaining({ path: '/new/project', name: 'new-project', })); expect(lastFrame()).toContain('Add New Lore'); }); it.skip('should show success message after creation', async () => { // Skipping this test as it requires complex mocking of Ink's interactive components // The functionality is tested through integration tests }); it.skip('should handle errors gracefully', async () => { // Skipping this test as it requires complex mocking of Ink's interactive components // The functionality is tested through integration tests }); }); //# sourceMappingURL=AddFact.test.js.map