78 lines
3.0 KiB
Python
78 lines
3.0 KiB
Python
import asyncio
|
|||
|
|
import json
|
||
|
|
import os
|
||
|
|
from pathlib import Path
|
||
|
|
|
||
|
|
|
||
|
|
def test_result_browser_prefers_latest_manifest_and_shows_subfamily_evidence(monkeypatch, tmp_path):
|
||
|
|
from apps.web.vue3 import main as web_main
|
||
|
|
|
||
|
|
workspace_root = tmp_path / "workspace"
|
||
|
|
final_dir = workspace_root / "job-results" / "final"
|
||
|
|
final_dir.mkdir(parents=True)
|
||
|
|
image = final_dir / "Target.PEBP.target-Os.ref-At.subfamily_evidence.motif.png"
|
||
|
|
image.write_bytes(b"png")
|
||
|
|
|
||
|
|
success = final_dir / "Target.PEBP.target-Os.ref-At.subfamily_evidence.motif.manifest.json"
|
||
|
|
success.write_text(
|
||
|
|
json.dumps(
|
||
|
|
{
|
||
|
|
"stage": "motif",
|
||
|
|
"status": "success",
|
||
|
|
"prefix": "Os.PEBP",
|
||
|
|
"output_prefix": "Target.PEBP.target-Os.ref-At.subfamily_evidence",
|
||
|
|
"scope_id": "PEBP.target-Os.ref-At.target_plus_reference",
|
||
|
|
"scope_mode": "target_plus_reference",
|
||
|
|
"analysis_route": "subfamily_evidence",
|
||
|
|
"result_group": "motif_subfamily_evidence",
|
||
|
|
"elapsed_sec": 3.0,
|
||
|
|
"artifacts": {
|
||
|
|
"motif_plot_png": {
|
||
|
|
"artifact": "motif_plot",
|
||
|
|
"path": f"final/{image.name}",
|
||
|
|
"type": "image",
|
||
|
|
}
|
||
|
|
},
|
||
|
|
}
|
||
|
|
),
|
||
|
|
encoding="utf-8",
|
||
|
|
)
|
||
|
|
failed = final_dir / "Os.PEBP.target_only.motif.manifest.json"
|
||
|
|
failed.write_text(
|
||
|
|
json.dumps(
|
||
|
|
{
|
||
|
|
"stage": "motif",
|
||
|
|
"status": "failed",
|
||
|
|
"prefix": "Os.PEBP",
|
||
|
|
"scope_id": "PEBP.target-Os.target_only",
|
||
|
|
"analysis_route": "multi_species",
|
||
|
|
"parameters": {"error": "old failed attempt"},
|
||
|
|
"artifacts": {},
|
||
|
|
}
|
||
|
|
),
|
||
|
|
encoding="utf-8",
|
||
|
|
)
|
||
|
|
os.utime(failed, (1, 1))
|
||
|
|
os.utime(success, (2, 2))
|
||
|
|
|
||
|
|
monkeypatch.setattr(web_main, "WORKSPACE_ROOT", workspace_root)
|
||
|
|
result = asyncio.run(web_main.get_results(job_id="job-results", stage="motif"))
|
||
|
|
|
||
|
|
assert result["motif"]["status"] == "success"
|
||
|
|
assert image.name in json.dumps(result["motif"], ensure_ascii=False)
|
||
|
|
|
||
|
|
|
||
|
|
def test_result_panel_has_three_persistent_workflow_groups():
|
||
|
|
html = (Path(__file__).resolve().parents[2] / "apps/web/vue3/index.html").read_text(encoding="utf-8")
|
||
|
|
|
||
|
|
assert "RNA-seq" in html
|
||
|
|
assert "基因家族" in html
|
||
|
|
assert "WGS2GWAS(遗传变异与群体分析)" in html
|
||
|
|
assert "const resultGroups = computed" in html
|
||
|
|
assert "const groupStages = stages.filter(stage => resultGroupNameForStage(stage.name) === group.name);" in html
|
||
|
|
assert "wgsPopulationGwasResultRank(a.name) - wgsPopulationGwasResultRank(b.name)" in html
|
||
|
|
assert "name: 'wgs_qc'" in html
|
||
|
|
assert "name: 'wgs_maf_missing_filter'" in html
|
||
|
|
assert "await refreshResults(completedJobId, stageName);" in html
|
||
|
|
assert "await refreshResults(latestConversation.job_id);" in html
|