import React from 'react'; import { render, screen, fireEvent } from '@testing-library/react'; import { DEFAULT_SKILLS, DEFAULT_TOOLS, AGENTS, loadStoredSkills, saveStoredSkills, loadStoredTools, loadActiveAgentId, saveActiveAgentId, } from '@/pages/doormile/settings/agentStudio/agentRegistryData'; // Stub lucide-react ESM exports for Jest jest.mock('lucide-react', () => { return new Proxy( {}, { get: (target, prop) => { if (prop === '__esModule') return true; return (props) => ; }, } ); }); // Stub framer-motion layout animations for jsdom jest.mock('framer-motion', () => ({ motion: { div: ({ children, ...rest }) =>
{children}
, span: ({ children, ...rest }) => {children}, }, AnimatePresence: ({ children }) => <>{children}, })); import SkillCard from '@/pages/doormile/settings/agentStudio/SkillCard'; import SkillCardsGrid from '@/pages/doormile/settings/agentStudio/SkillCardsGrid'; import ToolRegistryView from '@/pages/doormile/settings/agentStudio/ToolRegistryView'; describe('Agent Studio — Data Layer & Persistence', () => { beforeEach(() => { localStorage.clear(); }); it('pre-seeds default agents and surfaces correctly', () => { expect(AGENTS.length).toBeGreaterThanOrEqual(2); expect(AGENTS.some((a) => a.name === 'MileTruth AI Agent')).toBe(true); expect(AGENTS.some((a) => a.name === 'MileTruth AI Dispatcher')).toBe(true); }); it('pre-seeds default skills matching reference image', () => { expect(DEFAULT_SKILLS.some((s) => s.title === 'MileTruth Skill Management')).toBe(true); expect(DEFAULT_SKILLS.some((s) => s.title === 'Learning Analysis')).toBe(true); const learningSkill = DEFAULT_SKILLS.find((s) => s.title === 'Learning Analysis'); expect(learningSkill.prompt).toBe('How is training progressing?'); expect(learningSkill.category).toBe('WORKFORCE'); }); it('persists modified skills to localStorage and restores them', () => { const customSkill = { id: 'custom-skill-1', title: 'Custom Automation Skill', category: 'LOGISTICS', scope: 'agent', enabled: true, description: 'Test custom capability', tools: ['create_single_order'], }; saveStoredSkills([customSkill]); const restored = loadStoredSkills(); expect(restored.length).toBe(1); expect(restored[0].title).toBe('Custom Automation Skill'); }); it('saves and loads active agent id', () => { saveActiveAgentId('miletruth-agent'); expect(loadActiveAgentId()).toBe('miletruth-agent'); }); }); describe('Agent Studio — SkillCard Component', () => { const sampleSkill = { id: 'test-skill-1', title: 'MileTruth Skill Management', category: 'AUTHORING', scope: 'agent', integration: 'MileTruth AI', enabled: true, description: 'Create workforce skills, training and verification in MileTruth AI.', prompt: 'How is training progressing?', tools: ['open_add_training'], }; it('renders title, description, category, and prompt trigger bubble', () => { render( {}} onDetails={() => {}} />); expect(screen.getByText('MileTruth Skill Management')).toBeInTheDocument(); expect( screen.getByText('Create workforce skills, training and verification in MileTruth AI.') ).toBeInTheDocument(); expect(screen.getByText('AUTHORING')).toBeInTheDocument(); expect(screen.getByText('"How is training progressing?"')).toBeInTheDocument(); expect(screen.getByText('MileTruth AI')).toBeInTheDocument(); }); it('fires onTest when Test in Playground is clicked', () => { const handleTest = jest.fn(); render( {}} />); const testBtn = screen.getByText('Test in Playground'); fireEvent.click(testBtn); expect(handleTest).toHaveBeenCalledWith(sampleSkill); }); it('fires onDetails when Details button is clicked', () => { const handleDetails = jest.fn(); render( {}} onDetails={handleDetails} />); const detailsBtn = screen.getByText('Details'); fireEvent.click(detailsBtn); expect(handleDetails).toHaveBeenCalledWith(sampleSkill); }); }); describe('Agent Studio — SkillCardsGrid Component', () => { it('renders skill cards and filters by search query', () => { render( {}} onOpenDetails={() => {}} onNewSkill={() => {}} /> ); expect(screen.getByText('MileTruth Skill Management')).toBeInTheDocument(); expect(screen.getByText('Learning Analysis')).toBeInTheDocument(); const searchInput = screen.getByPlaceholderText('Search skills, capabilities or pages...'); fireEvent.change(searchInput, { target: { value: 'Learning' } }); expect(screen.queryByText('MileTruth Skill Management')).not.toBeInTheDocument(); expect(screen.getByText('Learning Analysis')).toBeInTheDocument(); }); it('filters by category pill selection', () => { render( {}} onOpenDetails={() => {}} onNewSkill={() => {}} /> ); // Click 'Authoring' category pill const authoringPill = screen.getByText('Authoring'); fireEvent.click(authoringPill); expect(screen.getByText('MileTruth Skill Management')).toBeInTheDocument(); expect(screen.queryByText('Learning Analysis')).not.toBeInTheDocument(); }); it('triggers onNewSkill when clicking New skill button', () => { const handleNewSkill = jest.fn(); render( {}} onOpenDetails={() => {}} onNewSkill={handleNewSkill} /> ); const newSkillBtn = screen.getByText('New skill'); fireEvent.click(newSkillBtn); expect(handleNewSkill).toHaveBeenCalled(); }); }); describe('Agent Studio — ToolRegistryView Component', () => { it('renders tool registry table and displays argument schemas', () => { render(); expect(screen.getByText('open_add_skill_training')).toBeInTheDocument(); expect(screen.getByText('create_single_order')).toBeInTheDocument(); expect(screen.getByText('rebalance_riders')).toBeInTheDocument(); }); it('filters tool list by search input', () => { render(); const searchInput = screen.getByPlaceholderText( 'Filter tools by function name, category or description...' ); fireEvent.change(searchInput, { target: { value: 'rebalance' } }); expect(screen.getByText('rebalance_riders')).toBeInTheDocument(); expect(screen.queryByText('open_add_skill_training')).not.toBeInTheDocument(); }); });