import { describe, expect, it } from 'vitest'; import { buildStockAnalysisPrompt, parseStockAnalysisResponse, } from '@/lib/actions/stock-analysis.helpers'; describe('stock-analysis.helpers', () => { it('builds a prompt with consolidated stock context', () => { const prompt = buildStockAnalysisPrompt({ symbol: 'AAPL', quote: { c: 198.12, d: 2.11, dp: 1.08, h: 199.2, l: 195.8, o: 196.1, pc: 196.01, }, profile: { name: 'Apple Inc.', exchange: 'NASDAQ', finnhubIndustry: 'Technology', marketCapitalization: 3100000, country: 'US', currency: 'USD', ipo: '1980-12-12', weburl: 'https://apple.com', }, basicFinancials: { metric: { peBasicExclExtraTTM: 31.2, epsTTM: 6.4, beta: 1.1, '52WeekHigh': 200, '52WeekLow': 164, '52WeekPriceReturnDaily': 12.5, targetPrice: 210, }, }, sentimentInsights: { symbol: 'AAPL', companyName: 'Apple Inc.', averageBuzz: 74.2, bullishAverage: 62.1, sourceAlignment: 'Bullish alignment', availableSources: 3, sources: [], }, recentHeadlines: [ { headline: 'Apple expands services bundle', summary: 'Investors are watching recurring revenue trends.', source: 'Reuters', datetime: 1717171717, }, ], }); expect(prompt).toContain('"symbol": "AAPL"'); expect(prompt).toContain('"companyName": "Apple Inc."'); expect(prompt).toContain('"currentPrice": "$198.12"'); expect(prompt).toContain('"peRatio": "31.20x"'); expect(prompt).toContain('"sourceAlignment": "Bullish alignment"'); expect(prompt).toContain('Apple expands services bundle'); }); it('parses fenced json responses', () => { const analysis = parseStockAnalysisResponse( '```json\n{"stance":"Bullish","confidence":"High","summary":"Momentum and fundamentals remain supportive.","keyDrivers":["Revenue mix is improving"],"risks":["Valuation is elevated"],"watchItems":["Next earnings execution"]}\n```', 'AAPL', 'Apple Inc.', ); expect(analysis).not.toBeNull(); expect(analysis?.stance).toBe('Bullish'); expect(analysis?.confidence).toBe('High'); expect(analysis?.keyDrivers).toEqual(['Revenue mix is improving']); }); it('falls back to plain text when the model does not return json', () => { const analysis = parseStockAnalysisResponse( 'The setup is balanced: momentum is positive, but valuation limits upside.', 'AAPL', 'Apple Inc.', ); expect(analysis).not.toBeNull(); expect(analysis?.stance).toBe('Neutral'); expect(analysis?.confidence).toBe('Low'); expect(analysis?.summary).toContain('valuation limits upside'); }); });