--- phase: 18-api-route-tests plan: 02 type: execute --- Add tests for LLM API route covering Google and OpenAI provider paths. Purpose: Test text generation API with provider mocking patterns. Output: Comprehensive tests for /api/llm route with mocked external APIs. ~/.claude/get-shit-done/workflows/execute-phase.md ~/.claude/get-shit-done/templates/summary.md @.planning/PROJECT.md @.planning/ROADMAP.md @.planning/STATE.md **Route to test:** @src/app/api/llm/route.ts **Test patterns from previous plan:** @src/app/api/workflow/__tests__/route.test.ts Task 1: Create LLM route tests for Google provider src/app/api/llm/__tests__/route.test.ts Create tests for /api/llm route Google provider path: - POST: Generates text with Google/Gemini successfully - POST: Handles multimodal input (images + prompt) - POST: Rejects missing prompt - POST: Rejects missing API key (no env var, no header) - POST: Returns 429 on rate limit errors - POST: Returns 500 on API errors Mock @google/genai GoogleGenAI class: ```typescript vi.mock("@google/genai", () => ({ GoogleGenAI: vi.fn().mockImplementation(() => ({ models: { generateContent: vi.fn().mockResolvedValue({ text: "Generated response text", }), }, })), })); ``` Mock process.env.GEMINI_API_KEY for auth tests. Test X-Gemini-API-Key header takes precedence over env var. Test request structure: ```typescript const mockRequest = { json: vi.fn().mockResolvedValue({ prompt: "Test prompt", provider: "google", model: "gemini-2.5-flash", temperature: 0.7, maxTokens: 1024, }), headers: new Headers(), } as unknown as NextRequest; ``` npm test -- src/app/api/llm/__tests__/route.test.ts --testNamePattern="google" Google provider tests pass covering success, validation, and error paths Task 2: Add LLM route tests for OpenAI provider src/app/api/llm/__tests__/route.test.ts Add tests for /api/llm route OpenAI provider path to existing test file: - POST: Generates text with OpenAI successfully - POST: Handles vision input (images + prompt) - POST: Rejects unknown provider - POST: Rejects missing OpenAI API key - POST: Returns 429 on rate limit errors - POST: Handles OpenAI API error responses Mock global fetch for OpenAI API calls: ```typescript const mockFetch = vi.fn(); global.fetch = mockFetch; // Success response mockFetch.mockResolvedValueOnce({ ok: true, json: () => Promise.resolve({ choices: [{ message: { content: "OpenAI response" } }], }), }); // Error response mockFetch.mockResolvedValueOnce({ ok: false, status: 401, json: () => Promise.resolve({ error: { message: "Invalid API key" }, }), }); ``` Test X-OpenAI-API-Key header takes precedence over env var. Test that correct model ID is sent to OpenAI API. npm test -- src/app/api/llm/__tests__/route.test.ts All LLM route tests pass covering both providers Before declaring plan complete: - [ ] `npm test -- src/app/api/llm/__tests__/route.test.ts` passes - [ ] Tests cover Google and OpenAI providers - [ ] Error handling tested (rate limits, API errors, missing keys) - [ ] No TypeScript errors - All tasks completed - All verification checks pass - Both provider paths tested - API mocking patterns work correctly After completion, create `.planning/phases/18-api-route-tests/18-02-SUMMARY.md`