from __future__ import annotations import json from pathlib import Path import pytest from fastapi.testclient import TestClient from app.core.models import Job from app.core.registry import _jobs from app.core.registry import persist as persist_registry from app.core.registry import restore as restore_registry @pytest.fixture(autouse=True) def _isolate_registry(): _jobs.clear() yield _jobs.clear() def test_persist_and_restore_terminal_job(tmp_path: Path): job = Job( id="abcdefabcdef", status="done", progress=1.0, stage_message="Done", title="Saved song", stems=[{"name": "vocals", "url": "/api/jobs/abcdefabcdef/stems/vocals.wav"}], selected_stems=["vocals"], ) _jobs[job.id] = job persist_registry(tmp_path) _jobs.clear() restore_registry(tmp_path) restored = _jobs[job.id] assert restored.status == "done" assert restored.title == "Saved song" assert restored.stems == job.stems assert restored.cancel_requested is False def test_restore_recovers_orphan_done_job_from_stems(tmp_path: Path): job_dir = tmp_path / "abcdefabcdee" stems_dir = job_dir / "stems" stems_dir.mkdir(parents=True) (stems_dir / "vocals.wav").write_bytes(b"RIFF") (stems_dir / "drums.wav").write_bytes(b"RIFF") (job_dir / "metadata.json").write_text(json.dumps({"title": "Test Song"}), encoding="utf-8") restore_registry(tmp_path) restored = _jobs["abcdefabcdee"] assert restored.status == "done" assert restored.progress == 1.0 assert restored.title == "Test Song" assert {stem["name"] for stem in restored.stems} == {"vocals", "drums"} def test_restore_skips_orphan_without_metadata(tmp_path: Path): stems_dir = tmp_path / "abcdefabcde0" / "stems" stems_dir.mkdir(parents=True) (stems_dir / "vocals.wav").write_bytes(b"RIFF") restore_registry(tmp_path) assert "abcdefabcde0" not in _jobs def test_restored_job_serves_stems(tmp_path: Path, monkeypatch): stems_dir = tmp_path / "abcdefabcded" / "stems" stems_dir.mkdir(parents=True) (stems_dir / "vocals.wav").write_bytes(b"RIFF1234") data = { "version": 1, "jobs": [ Job( id="abcdefabcded", status="done", title="Test Song", stems=[{"name": "vocals", "url": "/api/jobs/abcdefabcded/stems/vocals.wav"}], selected_stems=["vocals"], ).to_record() ], } (tmp_path / "registry.json").write_text(json.dumps(data), encoding="utf-8") monkeypatch.setattr("app.api.stems.JOBS_DIR", tmp_path) restore_registry(tmp_path) from app.main import app with TestClient(app) as client: state = client.get("/api/jobs/abcdefabcded") assert state.status_code == 200 assert state.json()["status"] == "done" stem = client.get("/api/jobs/abcdefabcded/stems/vocals.wav") assert stem.status_code == 200 assert stem.content == b"RIFF1234" def test_delete_updates_persisted_registry(tmp_path: Path, monkeypatch): job = Job(id="abcdefabcdec", status="done") _jobs[job.id] = job job_dir = tmp_path / job.id job_dir.mkdir(parents=True) persist_registry(tmp_path) monkeypatch.setattr("app.api.jobs.JOBS_DIR", tmp_path) from app.main import app with TestClient(app) as client: response = client.delete(f"/api/jobs/{job.id}") assert response.status_code == 200 assert not job_dir.exists() data = json.loads((tmp_path / "registry.json").read_text(encoding="utf-8")) assert data["jobs"] == []