feat(2): immich P3 2nd functional test (asset-processing: metadata extraction + library statistics) + PARITY/DECISIONS for immich postgres-backup recipe-PR

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-05-30 00:08:10 +01:00
parent 4f0eeb54bd
commit ecd770b9ca
3 changed files with 161 additions and 8 deletions

View File

@ -7,18 +7,30 @@ Reference corpus: `references/recipe-maintainer/recipe-info/immich/tests/` (heal
|---|---|---|
| `health_check.py` | `tests/immich/functional/test_health_check.py::test_immich_returns_200` | HTTP 200/301/302 from `/` (immich web SPA served). |
## Recipe-specific functional tests (P3, ≥2 — characteristic behavior)
## Recipe-specific functional tests (P3, ≥2 separate tests — characteristic behavior)
1. **`test_asset_upload.py::test_immich_upload_asset_readback_and_thumbnail`** — the §4.3
create-an-object + read-it-back + characteristic feature: admin-sign-up → login → **upload an
asset** (`POST /api/assets` multipart, 201 created with unique content) → **read it back**
create-an-object + read-it-back: admin-sign-up → login → **upload an asset**
(`POST /api/assets` multipart, 201 created with unique content) → **read it back**
(`GET /api/assets/{id}` → 200, type IMAGE) → **immich generated a thumbnail/derivative**
(`GET /api/assets/{id}/thumbnail` → 200, polled for the async generation). Real assertions on
stored app state + the generated derivative — immich's whole purpose (photo ingest + derivatives).
This single test covers BOTH the create+read-back floor AND the distinctive derivative-generation
feature (≥2 characteristic behaviors). Verified against immich app version 2.7.5.
(`GET /api/assets/{id}/thumbnail` → 200, polled for the async generation). Asserts stored app
state + the generated derivative — immich's whole purpose (photo ingest + derivatives).
2. **`test_asset_processing.py::test_immich_processes_uploaded_asset_metadata_and_statistics`** —
immich's **asset-processing pipeline**, a distinct microservice path from thumbnailing: after
upload, poll `GET /api/assets/{id}` until the **metadata-extraction** job populated `exifInfo`
with the image dimensions (exifImageWidth/Height == 1 for the 1x1 PNG) → **proves the extraction
pipeline ran**; then `GET /api/assets/statistics` → the asset is **catalogued into the owner's
library** (images/total >= 1). Real assertions on processed state, not a 200 stand-in.
Both verified against immich app version 2.7.5.
Backup data-integrity (P4): Phase-1d/1e lifecycle overlays — `ops.py` seeds a postgres `ci_marker`
(postgres/immich DB, backupbot-labelled); `test_upgrade/backup/restore.py` assert it survives.
(postgres/immich DB); `test_upgrade/backup/restore.py` assert it survives. **P4 requires the
recipe-PR `recipe-maintainers/immich#1`** — the *published* recipe backed up NO database
(`backupbot.backup` sat only on the `app` service with all its volumes excluded; the
`database`/postgres service had no backup hook), so a restore yielded an empty DB. The PR adds a
`database`-service `/pg_backup.sh` config-mount + backupbot pre/restore hooks (matrix-synapse
convention); with it the ci_marker survives the recipe's real backup→restore. See DECISIONS.md
"immich postgres backup recipe-PR".
## Non-ports (documented — §7.1)
- **`oidc_login.py`** — authentik-specific in the corpus. Per the operator SSO policy (DECISIONS