# Cluster Folders API - Testing Guide ## API Endpoint `GET /api/clusters/[id]/folders` ## Test Scenarios ### Test 1: Virtual Root (No Path) **Request:** ``` GET /api/clusters/1/folders ``` **Expected Response:** ```json { "isVirtualRoot": true, "libraries": [ { "id": 1, "path": "/mnt/media/library1", "itemCount": 245, "totalSize": 16434124800, "videoCount": 245, "photoCount": 0, "textCount": 0 } ], "total": 1, "limit": 50, "offset": 0, "hasMore": false } ``` **Success Criteria:** - ✅ Returns `isVirtualRoot: true` - ✅ Lists all libraries in cluster with statistics - ✅ Shows itemCount, totalSize, videoCount, photoCount, textCount --- ### Test 2: Library Root Folder **Request:** ``` GET /api/clusters/1/folders?path=/mnt/media/library1 ``` **Expected Response:** ```json { "isVirtualRoot": false, "currentPath": "/mnt/media/library1", "libraryRoot": "/mnt/media/library1", "libraryId": 1, "items": [ { "name": "Movies", "path": "/mnt/media/library1/Movies", "isDirectory": true, "size": 0, "itemCount": 45 }, { "name": "video.mp4", "path": "/mnt/media/library1/video.mp4", "isDirectory": false, "id": 123, "type": "video", "size": 1258291200, "thumbnail": "/api/videos/123/thumbnail", "avg_rating": 4.5, "star_count": 8, "bookmark_count": 2, "title": "My Video" } ], "total": 2, "limit": 50, "offset": 0, "hasMore": false } ``` **Success Criteria:** - ✅ Returns folder contents (directories + files) - ✅ Directories show `itemCount` - ✅ Media files include database metadata (ratings, bookmarks) - ✅ Items sorted: folders first, then files --- ### Test 3: Subfolder Navigation **Request:** ``` GET /api/clusters/1/folders?path=/mnt/media/library1/Movies/2023 ``` **Expected Response:** ```json { "isVirtualRoot": false, "currentPath": "/mnt/media/library1/Movies/2023", "libraryRoot": "/mnt/media/library1", "libraryId": 1, "items": [ { "name": "January", "path": "/mnt/media/library1/Movies/2023/January", "isDirectory": true, "size": 0, "itemCount": 15 } ], "total": 1, "limit": 50, "offset": 0, "hasMore": false } ``` **Success Criteria:** - ✅ Navigates into subfolders correctly - ✅ Maintains library context (`libraryRoot`, `libraryId`) --- ### Test 4: Invalid Cluster **Request:** ``` GET /api/clusters/99999/folders ``` **Expected Response:** ```json { "error": "Cluster not found" } ``` **Status Code:** `404` **Success Criteria:** - ✅ Returns 404 for non-existent cluster - ✅ Error message is descriptive --- ### Test 5: Path Outside Cluster **Request:** ``` GET /api/clusters/1/folders?path=/other/path/not/in/cluster ``` **Expected Response:** ```json { "error": "Path does not belong to this cluster" } ``` **Status Code:** `403` **Success Criteria:** - ✅ Returns 403 for unauthorized paths - ✅ Prevents access to paths outside cluster libraries --- ### Test 6: Non-existent Path **Request:** ``` GET /api/clusters/1/folders?path=/mnt/media/library1/NonExistentFolder ``` **Expected Response:** ```json { "error": "Path does not exist" } ``` **Status Code:** `404` **Success Criteria:** - ✅ Returns 404 for paths that don't exist on filesystem --- ### Test 7: Pagination **Request:** ``` GET /api/clusters/1/folders?path=/mnt/media/library1&limit=2&offset=0 ``` **Expected Response:** ```json { "isVirtualRoot": false, "currentPath": "/mnt/media/library1", "items": [/* first 2 items */], "total": 50, "limit": 2, "offset": 0, "hasMore": true } ``` **Success Criteria:** - ✅ Returns only requested number of items - ✅ `hasMore: true` when more items available - ✅ `total` shows actual total count --- ## Manual Testing Steps ### Using curl: 1. **Test Virtual Root:** ```bash curl http://localhost:3000/api/clusters/1/folders ``` 2. **Test Library Folder:** ```bash curl "http://localhost:3000/api/clusters/1/folders?path=/mnt/media/library1" ``` 3. **Test Subfolder:** ```bash curl "http://localhost:3000/api/clusters/1/folders?path=/mnt/media/library1/Movies" ``` 4. **Test Invalid Path (should get 403):** ```bash curl "http://localhost:3000/api/clusters/1/folders?path=/invalid/path" ``` ### Using Browser DevTools: 1. Open cluster page in browser 2. Open DevTools → Network tab 3. Navigate to Folders tab 4. Observe API requests and responses 5. Click folders to drill down 6. Verify responses match expected format --- ## Expected Behavior Summary | Scenario | Response Type | Key Fields | |----------|--------------|------------| | No path | Virtual Root | `isVirtualRoot: true`, `libraries[]` | | Valid path | Folder Contents | `items[]`, `libraryRoot`, `currentPath` | | Invalid cluster | Error | `error: "Cluster not found"`, 404 | | Path outside cluster | Error | `error: "Path does not belong..."`, 403 | | Non-existent path | Error | `error: "Path does not exist"`, 404 | | Path is file | Error | `error: "Path is not a directory"`, 400 | --- ## Implementation Verification Checklist - [x] API endpoint created at `/api/clusters/[id]/folders/route.ts` - [x] Virtual root handler returns library list with stats - [x] Folder contents handler returns directories + files - [x] Path validation prevents access outside cluster - [x] Media items include database metadata (ratings, bookmarks) - [x] Directories show item counts - [x] Pagination support implemented - [x] Error handling (403, 404, 400, 500) - [x] Sorting (folders first, then files, alphabetical) - [x] TypeScript compilation successful - [ ] Manual testing with real cluster data - [ ] Frontend integration (Phase 2) --- **Phase 1 Status:** ✅ **COMPLETE - Backend API Ready** **Next Phase:** Phase 2 - ClusterFolderView Component Implementation