4.4 KiB
| phase | plan | type |
|---|---|---|
| 18-api-route-tests | 4 | execute |
Purpose: Complete generate route test coverage with external provider mocking. Output: Tests for /api/generate Replicate and fal.ai paths with mocked fetch calls.
<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.mdRoute to test: @src/app/api/generate/route.ts
Existing tests to extend: @src/app/api/generate/tests/route.test.ts
Task 1: Add generate route tests for Replicate provider src/app/api/generate/__tests__/route.test.ts Add tests for /api/generate route Replicate path to existing test file: - POST: Generates image successfully via Replicate - POST: Generates video successfully via Replicate - POST: Returns 401 when Replicate API key missing - POST: Handles rate limit (429) from Replicate - POST: Handles prediction failure - POST: Handles prediction timeout (5 min max) - POST: Polls for prediction completion - POST: Returns video URL for large videos (>20MB)Mock global fetch for Replicate API calls:
// Model info fetch
mockFetch.mockResolvedValueOnce({
ok: true,
json: () => Promise.resolve({
latest_version: { id: "version123", openapi_schema: {} },
}),
});
// Create prediction
mockFetch.mockResolvedValueOnce({
ok: true,
json: () => Promise.resolve({
id: "prediction123",
status: "starting",
}),
});
// Poll prediction (succeeded)
mockFetch.mockResolvedValueOnce({
ok: true,
json: () => Promise.resolve({
id: "prediction123",
status: "succeeded",
output: ["https://replicate.delivery/output.png"],
}),
});
// Fetch output media
mockFetch.mockResolvedValueOnce({
ok: true,
headers: new Headers({ "content-type": "image/png" }),
arrayBuffer: () => Promise.resolve(new ArrayBuffer(1024)),
});
Test X-Replicate-API-Key header is passed correctly. Test dynamicInputs are passed to prediction input. npm test -- src/app/api/generate/tests/route.test.ts --testNamePattern="Replicate" Replicate provider tests pass covering success, polling, and error paths
Task 2: Add generate route tests for fal.ai provider src/app/api/generate/__tests__/route.test.ts Add tests for /api/generate route fal.ai path to existing test file: - POST: Generates image successfully via fal.ai (images array response) - POST: Generates video successfully via fal.ai (video object response) - POST: Works without API key (fal.ai allows unauthenticated) - POST: Handles rate limit (429) with and without key - POST: Handles various response formats (image, images, video, output) - POST: Returns video URL for large videos (>20MB) - POST: Filters empty dynamicInputs valuesMock global fetch for fal.ai API calls:
// Sync API call (fal.run)
mockFetch.mockResolvedValueOnce({
ok: true,
json: () => Promise.resolve({
images: [{ url: "https://fal.media/output.png" }],
}),
});
// Fetch output media
mockFetch.mockResolvedValueOnce({
ok: true,
headers: new Headers({ "content-type": "image/png" }),
arrayBuffer: () => Promise.resolve(new ArrayBuffer(1024)),
});
// Video response format
mockFetch.mockResolvedValueOnce({
ok: true,
json: () => Promise.resolve({
video: { url: "https://fal.media/output.mp4" },
}),
});
Test X-Fal-API-Key header is passed when provided. Test getFalInputMapping schema parsing (via behavior). npm test -- src/app/api/generate/tests/route.test.ts All generate route tests pass covering all three providers
Before declaring plan complete: - [ ] `npm test -- src/app/api/generate/__tests__/route.test.ts` passes - [ ] Tests cover Replicate and fal.ai provider paths - [ ] Polling logic tested for Replicate - [ ] Various response formats tested for fal.ai - [ ] No TypeScript errors<success_criteria>
- All tasks completed
- All verification checks pass
- All three providers thoroughly tested
- Error handling tested for each provider </success_criteria>