284 lines
5.8 KiB
Markdown
284 lines
5.8 KiB
Markdown
# 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
|