"""Reject must leave files in place and not invent migrate destinations.""" from __future__ import annotations from pathlib import Path from fastapi.testclient import TestClient from app.main import app from app.storage import execute, fetch_one, to_json def _seed(root: Path, cats: Path) -> tuple[int, int, Path]: src = root / "skip_me.jpg" src.write_bytes(b"skip") run_id = execute( """ INSERT INTO runs ( root_repo, categories_root, confidence_threshold, status, total_images, processed_images, failed_images, cancel_requested, tagger_model ) VALUES (?, ?, 0.6, 'completed', 1, 1, 0, 0, 'wd_swinv2_v3') """, (str(root), str(cats)), ) item_id = execute( """ INSERT INTO items ( run_id, file_path, relative_path, primary_tag, primary_score, secondary_json, full_scores_json, suggested_destination, final_tag, final_destination, status, needs_review, review_reason ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) """, ( run_id, str(src), src.name, None, None, to_json([{"tag": "loli", "score": 0.4}]), to_json({}), None, None, None, "proposed", 1, "Below threshold", ), ) return run_id, item_id, src def test_reject_clears_destination_and_keeps_file(tmp_path: Path) -> None: root = tmp_path / "root" cats = tmp_path / "cats" root.mkdir() cats.mkdir() _run_id, item_id, src = _seed(root, cats) with TestClient(app) as client: resp = client.patch(f"/api/items/{item_id}", json={"status": "rejected"}) resp.raise_for_status() body = resp.json() assert body["status"] == "rejected" assert body["needs_review"] is False assert body["final_tag"] is None assert body["final_destination"] is None assert "Rejected" in (body["review_reason"] or "") assert src.exists() row = fetch_one("SELECT status, final_destination FROM items WHERE id = ?", (item_id,)) assert row["status"] == "rejected" assert row["final_destination"] is None mig = client.post( f"/api/runs/{_run_id}/migrate", json={"mode": "move", "create_missing_folders": True}, ) mig.raise_for_status() assert mig.json()["total_candidates"] == 0 assert src.exists() def test_batch_reject_does_not_assign_folder(tmp_path: Path) -> None: root = tmp_path / "root" cats = tmp_path / "cats" root.mkdir() cats.mkdir() run_id, item_id, src = _seed(root, cats) with TestClient(app) as client: resp = client.post( f"/api/runs/{run_id}/batch", json={"item_ids": [item_id], "status": "rejected"}, ) resp.raise_for_status() assert resp.json()["updated"] == 1 row = fetch_one( "SELECT status, final_tag, final_destination FROM items WHERE id = ?", (item_id,), ) assert row["status"] == "rejected" assert row["final_tag"] is None assert row["final_destination"] is None assert src.exists()