from pathlib import Path import json import sys ROOT = Path(__file__).resolve().parents[2] if str(ROOT) not in sys.path: sys.path.insert(0, str(ROOT)) def test_subfamily_review_resolves_same_scope_combo_from_manifest(monkeypatch, tmp_path): from apps.web.vue3 import main as web_main job_id = "job_scope_evidence" final_dir = tmp_path / "workspace" / job_id / "final" final_dir.mkdir(parents=True) monkeypatch.setattr(web_main, "WORKSPACE_ROOT", tmp_path / "workspace") monkeypatch.setattr(web_main, "INPUT_ROOT", tmp_path / "input") web_main.INPUT_ROOT.mkdir(parents=True, exist_ok=True) combo_png = final_dir / "Lc.SPL.target_plus_reference.combo.png" combo_png.write_bytes(b"fake png bytes") tree_png = final_dir / "Target.SPL.target-Lc.ref-At.subfamily_prediction.reference_classification.tree.png" tree_png.write_bytes(b"fake tree png") manifest = { "manifest_version": "1.0", "stage": "reference_classification", "status": "success", "prefix": "Lc.SPL", "output_prefix": "Target.SPL.target-Lc.ref-At.subfamily_prediction", "scope_id": "SPL.target-Lc.ref-At.target_plus_reference", "analysis_route": "subfamily_prediction", "per_species_results": [{"species": "Lc", "combo": str(combo_png), "tree": str(tree_png)}], "artifacts": {}, } (final_dir / "Target.SPL.target-Lc.ref-At.subfamily_prediction.reference_classification.manifest.json").write_text( json.dumps(manifest), encoding="utf-8" ) assets, missing = web_main._subfamily_evidence_assets(job_id, "Target.SPL.target-Lc.ref-At.subfamily_prediction") combo_assets = [asset for asset in assets if asset.get("group") == "rect_combo"] assert combo_assets assert combo_assets[0]["name"] == "Lc.SPL.target_plus_reference.combo.png" assert "rect_combo" not in missing