--- phase: 18-api-route-tests plan: 01 type: execute --- Add tests for workflow and save-generation API routes covering file I/O operations. Purpose: Establish API route testing patterns with file system mocking for subsequent plans. Output: Test files for workflow and save-generation routes with fs mocking patterns. ~/.claude/get-shit-done/workflows/execute-phase.md ~/.claude/get-shit-done/templates/summary.md @.planning/PROJECT.md @.planning/ROADMAP.md @.planning/STATE.md **Routes to test:** @src/app/api/workflow/route.ts @src/app/api/save-generation/route.ts **Test patterns reference:** @src/store/utils/__tests__/localStorage.test.ts @vitest.config.ts Task 1: Create workflow route tests src/app/api/workflow/__tests__/route.test.ts Create tests for /api/workflow route covering: - POST: Save workflow - validates required fields, creates directories, writes JSON - POST: Rejects missing directoryPath/filename/workflow - POST: Rejects non-directory paths - POST: Handles directory creation for inputs/generations - GET: Validates directory existence - GET: Returns exists: false for non-existent paths Mock fs/promises (stat, mkdir, writeFile, readdir) with vi.mock. Mock NextRequest/NextResponse using vitest patterns. Use vi.spyOn for fs methods to control return values per test. Pattern for mocking Next.js API routes: ```typescript import { describe, it, expect, vi, beforeEach } from "vitest"; import { NextRequest } from "next/server"; import * as fs from "fs/promises"; vi.mock("fs/promises"); // Create mock request helper function createMockRequest(body: unknown, method = "POST") { return { json: vi.fn().mockResolvedValue(body), nextUrl: { searchParams: new URLSearchParams() }, } as unknown as NextRequest; } ``` Do NOT mock the entire route module - import and call POST/GET directly. npm test -- src/app/api/workflow/__tests__/route.test.ts All workflow route tests pass covering POST save and GET validation Task 2: Create save-generation route tests src/app/api/save-generation/__tests__/route.test.ts Create tests for /api/save-generation route covering: - POST: Saves base64 image with hash-based filename - POST: Saves base64 video with hash-based filename - POST: Deduplicates existing files by hash suffix - POST: Rejects missing directoryPath or content - POST: Rejects non-directory paths - POST: Handles data URL with various MIME types - POST: Handles HTTP URLs (mock fetch for external URL) Mock fs/promises (stat, mkdir, writeFile, readdir) with vi.mock. Mock global fetch for HTTP URL handling. Use crypto.createHash for consistent hash generation in tests. Test the deduplication logic: 1. Mock readdir to return file with matching hash suffix 2. Verify no writeFile called, isDuplicate: true returned Test hash generation: 1. Provide known content, verify hash in filename 2. Use crypto.createHash('md5').update(buffer).digest('hex') to compute expected hash npm test -- src/app/api/save-generation/__tests__/route.test.ts All save-generation route tests pass covering save, deduplication, and validation Before declaring plan complete: - [ ] `npm test -- src/app/api/workflow/__tests__/route.test.ts` passes - [ ] `npm test -- src/app/api/save-generation/__tests__/route.test.ts` passes - [ ] Both test files use consistent mocking patterns - [ ] No TypeScript errors in test files - All tasks completed - All verification checks pass - Tests cover validation, success, and error paths - Mocking patterns established for fs and fetch After completion, create `.planning/phases/18-api-route-tests/18-01-SUMMARY.md`