Media Gallery Tests — Control Map
E2E and unit coverage for /mediagallery: grid/table, upload, delete, folders, bulk actions, image editor save, batch resize/filter, video HLS playback + transcode.
On this page
Surface
| Area | Files |
|---|---|
| Shell | +page.svelte, +page.server.ts |
| Views | media-grid.svelte, media-table.svelte |
| Upload | upload-media/* (local + remote) |
| Modals | advanced search, focal, transcode, image editor |
Media content is environment-specific; tests seed via upload.
Gallery first paint: tiles use mediaDisplayUrl() (not the original); SSR rows are toGalleryListItem() allowlists (no advancedMetadata / embeddings); published-in-use ids come from getPublishedReferencedIds() (one index rebuild); Sharp/MediaService is imported only from upload/delete actions; image editor / details / table / advanced-search / tag-editor / drag-preview / folder-prompt shells load on demand.
Control → test matrix
| Control | Unit | Integration | E2E | Spec |
|---|---|---|---|---|
Load + media:read gate |
page.server | media API | shell | unit + gallery |
| Toolbar | — | — | ✅ | media-gallery-toolbar |
| Search / type filter | — | — | ✅ | mediagallery.spec |
| Grid / table toggle | — | — | ✅ | media-view-* |
| Upload image | — | media upload | ✅ | media-upload-input |
| Delete single | — | media delete | ✅ | grid actions |
| Image editor tools, compare, zoom | tool controls + shortcuts | — | ✅ | image-editor.spec walk |
| Image editor save (manipulate) | media-manipulation | baked rotate + crop | ✅ | image-editor.spec + media-manipulate.test.ts |
| Create virtual folder | — | system-virtual-folder | ✅ | folders-bulk.spec |
| Folder appear / navigate | — | — | ✅ | same |
| Selection mode + bulk bar | — | — | ✅ | folders-bulk.spec |
| Bulk download | — | bulk-download | ✅ | hits /api/media/bulk-download |
| Bulk delete (Del key) | — | deleteMedia | ✅ | confirm + batch toast |
| Remote URL upload page | — | remoteUpload action | ✅ | move-remote.spec |
| Remote URL ingest (success) | egress allowlist seam | MediaService.saveRemoteMedia |
✅ | remote-ingestion.spec (real loopback peer) |
| Remote URL reject (SSRF) | egress-guard unit | /api/media/remote |
✅ | remote-ingestion.spec + media-svg-ssrf |
| Selection + breadcrumb move | — | /api/media/move |
✅ | move-remote.spec |
| Drop to sidebar folder | media-dnd unit | /api/media/move |
✅ | move-remote.spec (pointer drag) |
| Large library batching | — | media list (100) | ✅ | large-library.spec (60 → 70 on scroll) |
| Pre-upload optimization | canvas-image-optimizer | media upload | ✅ | upload-optimization.spec (stored dimensions) |
| Batch resize/filter | batch handler unit | /api/media/batch-process |
✅ | batch-processing.spec + media-batch-transcode.test |
| Video playback / HLS | transcode handler unit | /api/media/transcode |
✅ | video-transcode.spec (player + dialog payload) |
Drop row (2026-09-22):
@thisux/sveltedndruns in pointer mode (document-levelpointermove/pointerup+elementFromPointat release), and the sidebar rows only become droppables while a drag is in flight (externalDrop.enabled = isMediaDragActiveinmedia-folders.svelte). The spec therefore drivespage.mouse.down()→move()→up()and assertsdata-media-drop-targetmid-drag; probing that attribute before the gesture always returned empty and fell back to the current-folder breadcrumb, whose drop is a documented no-op.
Associated tests
- mediagallery.spec.ts — shell, search, views, upload, single delete
- image-editor.spec.ts — open, every tool, compare, zoom, discard, save
- Integration:
tests/integration/api/media-manipulate.test.ts— upload, rotate, crop, focal point on the stored file - folders-bulk.spec.ts — folders + multi-select bulk
- large-library.spec.ts — 70 assets, 60-tile batch, scroll appends the rest
- upload-optimization.spec.ts — 2400×1600 source stored at ≤1920 wide
- batch-processing.spec.ts — selection → mounted batch panel → 320 px stored width
- video-transcode.spec.ts — direct + HLS players, transcode dialog payload
- Unit:
tests/unit/api/media-batch-transcode.test.ts— batch limits/publish gate +503 FFMPEG_UNAVAILABLE - Integration:
tests/integration/api/media-batch-process.test.ts— real Sharp resize/filter baked into the file - remote-ingestion.spec.ts — loopback peer ingest + SSRF rejection
- mediagallery-page-server.test.ts
- Integration:
tests/integration/api/media.test.ts
Run
bun run test:unit -- tests/unit/routes/mediagallery-page-server.test.ts
bun x playwright test tests/e2e/routes/mediagallery