/** * GrowerAdvisoryAgent Tests * Tests for the grower advisory and recommendation system */ import { GrowerAdvisoryAgent, getGrowerAdvisoryAgent, } from '../../../lib/agents/GrowerAdvisoryAgent'; describe('GrowerAdvisoryAgent', () => { let agent: GrowerAdvisoryAgent; beforeEach(() => { agent = new GrowerAdvisoryAgent(); }); describe('Initialization', () => { it('should create agent with correct configuration', () => { expect(agent.config.id).toBe('grower-advisory-agent'); expect(agent.config.name).toBe('Grower Advisory Agent'); expect(agent.config.enabled).toBe(true); expect(agent.config.priority).toBe('high'); }); it('should have correct interval (5 minutes)', () => { expect(agent.config.intervalMs).toBe(300000); }); it('should start in idle status', () => { expect(agent.status).toBe('idle'); }); it('should have empty metrics initially', () => { const metrics = agent.getMetrics(); expect(metrics.tasksCompleted).toBe(0); expect(metrics.tasksFailed).toBe(0); expect(metrics.errors).toEqual([]); }); }); describe('Grower Profile Management', () => { it('should register a grower profile', () => { const profile = createGrowerProfile('grower-1'); agent.registerGrowerProfile(profile); const retrieved = agent.getGrowerProfile('grower-1'); expect(retrieved).not.toBeNull(); expect(retrieved?.growerId).toBe('grower-1'); }); it('should return null for unknown grower', () => { const retrieved = agent.getGrowerProfile('unknown-grower'); expect(retrieved).toBeNull(); }); it('should update existing profile', () => { const profile1 = createGrowerProfile('grower-1'); profile1.experienceLevel = 'beginner'; agent.registerGrowerProfile(profile1); const profile2 = createGrowerProfile('grower-1'); profile2.experienceLevel = 'expert'; agent.registerGrowerProfile(profile2); const retrieved = agent.getGrowerProfile('grower-1'); expect(retrieved?.experienceLevel).toBe('expert'); }); }); describe('Recommendations', () => { it('should return empty recommendations for unknown grower', () => { const recs = agent.getRecommendations('unknown-grower'); expect(recs).toEqual([]); }); it('should get recommendations after profile registration', () => { const profile = createGrowerProfile('grower-1'); agent.registerGrowerProfile(profile); // Recommendations are generated during runOnce const recs = agent.getRecommendations('grower-1'); expect(Array.isArray(recs)).toBe(true); }); }); describe('Rotation Advice', () => { it('should return null for unknown grower', () => { const advice = agent.getRotationAdvice('unknown-grower'); expect(advice).toBeNull(); }); }); describe('Market Opportunities', () => { it('should return array of opportunities', () => { const opps = agent.getOpportunities(); expect(Array.isArray(opps)).toBe(true); }); }); describe('Grower Performance', () => { it('should return null for unknown grower', () => { const perf = agent.getPerformance('unknown-grower'); expect(perf).toBeNull(); }); }); describe('Seasonal Alerts', () => { it('should return array of seasonal alerts', () => { const alerts = agent.getSeasonalAlerts(); expect(Array.isArray(alerts)).toBe(true); }); }); describe('Agent Lifecycle', () => { it('should start and change status to running', async () => { await agent.start(); expect(agent.status).toBe('running'); await agent.stop(); }); it('should stop and change status to idle', async () => { await agent.start(); await agent.stop(); expect(agent.status).toBe('idle'); }); it('should pause when running', async () => { await agent.start(); agent.pause(); expect(agent.status).toBe('paused'); await agent.stop(); }); it('should resume after pause', async () => { await agent.start(); agent.pause(); agent.resume(); expect(agent.status).toBe('running'); await agent.stop(); }); }); describe('Singleton', () => { it('should return same instance from getGrowerAdvisoryAgent', () => { const agent1 = getGrowerAdvisoryAgent(); const agent2 = getGrowerAdvisoryAgent(); expect(agent1).toBe(agent2); }); }); describe('Alerts', () => { it('should return alerts array', () => { const alerts = agent.getAlerts(); expect(Array.isArray(alerts)).toBe(true); }); }); describe('Task Execution', () => { it('should execute runOnce successfully', async () => { const profile = createGrowerProfile('grower-1'); agent.registerGrowerProfile(profile); const result = await agent.runOnce(); expect(result).not.toBeNull(); expect(result?.status).toBe('completed'); expect(result?.type).toBe('grower_advisory'); }); it('should report metrics in task result', async () => { const profile = createGrowerProfile('grower-1'); agent.registerGrowerProfile(profile); const result = await agent.runOnce(); expect(result?.result).toHaveProperty('growersAdvised'); expect(result?.result).toHaveProperty('recommendationsGenerated'); expect(result?.result).toHaveProperty('opportunitiesIdentified'); expect(result?.result).toHaveProperty('alertsGenerated'); }); it('should count registered growers', async () => { agent.registerGrowerProfile(createGrowerProfile('grower-1')); agent.registerGrowerProfile(createGrowerProfile('grower-2')); agent.registerGrowerProfile(createGrowerProfile('grower-3')); const result = await agent.runOnce(); expect(result?.result?.growersAdvised).toBe(3); }); }); }); // Helper function to create test grower profiles function createGrowerProfile( growerId: string, lat: number = 40.7128, lon: number = -74.006 ) { return { growerId, growerName: `Test Grower ${growerId}`, location: { latitude: lat, longitude: lon }, availableSpaceSqm: 100, specializations: ['lettuce', 'tomato'], certifications: ['organic'], experienceLevel: 'intermediate' as const, preferredCrops: ['lettuce', 'tomato', 'basil'], growingHistory: [ { cropType: 'lettuce', successRate: 85, avgYield: 4.5 }, { cropType: 'tomato', successRate: 75, avgYield: 8.0 }, ], }; }