138 lines
4.4 KiB
Python
138 lines
4.4 KiB
Python
import asyncio
|
|
|
|
from apps.web.vue3 import main as api
|
|
|
|
|
|
def test_build_subfamily_evidence_plan_keeps_confirmed_stage_boundary():
|
|
intent = {
|
|
"workflow_action_id": "build_subfamily_evidence",
|
|
"stages": ["domain", "motif", "phylogeny", "structure", "combo"],
|
|
"params": {
|
|
"workflowActionId": "build_subfamily_evidence",
|
|
"authorizedStages": [
|
|
"domain",
|
|
"motif",
|
|
"phylogeny",
|
|
"structure",
|
|
"combo",
|
|
],
|
|
},
|
|
}
|
|
|
|
stages = api._authorized_workflow_action_stages(intent)
|
|
|
|
assert stages == ["phylogeny", "motif", "domain", "structure", "combo"]
|
|
assert "identify" not in stages
|
|
assert "reference_classification" not in stages
|
|
|
|
|
|
def test_unbound_plan_does_not_invent_an_authorized_stage_boundary():
|
|
assert api._authorized_workflow_action_stages(
|
|
{"stages": ["identify", "phylogeny", "reference_classification"]}
|
|
) == []
|
|
|
|
|
|
def test_agent_plan_honors_authorized_workflow_action_without_keyword_reclassification(
|
|
monkeypatch,
|
|
):
|
|
authorized = ["domain", "motif", "phylogeny", "structure", "combo"]
|
|
intent = {
|
|
"gene_family": "SPL",
|
|
"target_species": ["Ft"],
|
|
"reference_species": ["At"],
|
|
"stages": authorized,
|
|
"primary_stage": "combo",
|
|
"workflow_action_id": "build_subfamily_evidence",
|
|
"params": {
|
|
"workflowActionId": "build_subfamily_evidence",
|
|
"authorizedStages": authorized,
|
|
"targetSpecies": ["Ft"],
|
|
"referenceSpecies": ["At"],
|
|
},
|
|
}
|
|
monkeypatch.setattr(
|
|
api,
|
|
"_reconcile_confirmed_gene_family_species",
|
|
lambda *args, **kwargs: {"applicable": False, "conflicts": []},
|
|
)
|
|
monkeypatch.setattr(
|
|
api, "_resolve_authoritative_gene_family", lambda *args, **kwargs: "SPL"
|
|
)
|
|
monkeypatch.setattr(
|
|
api,
|
|
"_resolve_subfamily_request_species_roles",
|
|
lambda *args, **kwargs: {
|
|
"classification_species": ["Ft"],
|
|
"reference_species": ["At"],
|
|
},
|
|
)
|
|
monkeypatch.setattr(
|
|
api,
|
|
"_latest_gene_family_scope_defaults",
|
|
lambda *args, **kwargs: {
|
|
"target_species": ["Ft"],
|
|
"reference_species": ["At"],
|
|
"comparative_species": [],
|
|
},
|
|
)
|
|
monkeypatch.setattr(
|
|
api,
|
|
"_load_identify_species_selection",
|
|
lambda *args, **kwargs: {
|
|
"groups": {
|
|
"target": [{"species": "Ft"}],
|
|
"reference": [{"species": "At"}],
|
|
"comparative": [],
|
|
}
|
|
},
|
|
)
|
|
monkeypatch.setattr(
|
|
api,
|
|
"_subfamily_state_for_targets",
|
|
lambda *args, **kwargs: {"overall": "not_classified", "by_species": {}},
|
|
)
|
|
monkeypatch.setattr(
|
|
api, "_identity_completed_stages_for_plan", lambda *args, **kwargs: []
|
|
)
|
|
monkeypatch.setattr(
|
|
api,
|
|
"_resolve_contextual_gene_family_request",
|
|
lambda *args, **kwargs: {
|
|
"family": "SPL",
|
|
"prefix": "Ft.SPL",
|
|
"stages": authorized,
|
|
"targetSpecies": ["Ft"],
|
|
"referenceSpecies": ["At"],
|
|
"comparativeSpecies": [],
|
|
"scopeMode": "target_plus_reference",
|
|
"contextGate": {"valid": False, "issues": []},
|
|
"context_route": "gene_family_default_scope",
|
|
"requiresConfirmedSubfamily": False,
|
|
"skipSubfamilyLabels": False,
|
|
"subfamilyState": {
|
|
"overall": "not_classified",
|
|
"by_species": {"Ft": {"status": "not_classified"}},
|
|
},
|
|
},
|
|
)
|
|
|
|
response = asyncio.run(
|
|
api.agent_plan(
|
|
api.AgentPlanRequest(
|
|
message="执行接下来的步骤",
|
|
session_id="authorized-action-test",
|
|
job_id="job-test",
|
|
prefix="Ft.SPL",
|
|
intent=intent,
|
|
)
|
|
)
|
|
)
|
|
|
|
expected = ["phylogeny", "motif", "domain", "structure", "combo"]
|
|
assert response["plan"]["all_stages"] == expected
|
|
assert response["plan"]["stages"] == expected
|
|
assert response["intent"]["workflow_action_id"] == "build_subfamily_evidence"
|
|
assert response["intent"]["params"]["authorizedStages"] == authorized
|
|
assert "reference_classification" not in response["plan"]["all_stages"]
|
|
assert "subfamily_confirm" not in response["plan"]["all_stages"]
|