You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

3.7 KiB

phase plan type
18-api-route-tests 2 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.

<execution_context> ~/.claude/get-shit-done/workflows/execute-phase.md ~/.claude/get-shit-done/templates/summary.md </execution_context>

@.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:

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:

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:

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

<success_criteria>

  • All tasks completed
  • All verification checks pass
  • Both provider paths tested
  • API mocking patterns work correctly </success_criteria>
After completion, create `.planning/phases/18-api-route-tests/18-02-SUMMARY.md`