diff --git a/backend/app/services/simulation_workflow.py b/backend/app/services/simulation_workflow.py index 2c8ddd7..2df406d 100644 --- a/backend/app/services/simulation_workflow.py +++ b/backend/app/services/simulation_workflow.py @@ -55,6 +55,9 @@ def _resolve_technique_ids( """ from backend.app.services import mitre as mitre_svc + if not mitre_svc.mitre_loaded: + return None, (jsonify({"error": "mitre bundle not loaded"}), 503) + # Dedup, preserve order. seen: dict[str, None] = dict.fromkeys(technique_ids) resolved: list[dict[str, str]] = [] diff --git a/backend/tests/test_simulations_techniques.py b/backend/tests/test_simulations_techniques.py index 5212577..f515965 100644 --- a/backend/tests/test_simulations_techniques.py +++ b/backend/tests/test_simulations_techniques.py @@ -305,6 +305,27 @@ def test_technique_ids_empty_does_not_trigger_auto_transition( assert resp.get_json()["status"] == "pending" +# --------------------------------------------------------------------------- +# Bundle not loaded — 503 on technique_ids PATCH +# --------------------------------------------------------------------------- + + +def test_patch_technique_ids_bundle_not_loaded_returns_503( + client: FlaskClient, redteam_token: str +) -> None: + """When MITRE bundle is absent, PATCH with technique_ids must return 503.""" + mitre_svc.mitre_loaded = False + mitre_svc._index = [] + mitre_svc._name_by_id = {} + + eng = _make_engagement(client, redteam_token) + sim = _make_sim(client, redteam_token, eng["id"]) + + resp = _patch(client, redteam_token, sim["id"], {"technique_ids": ["T1059"]}) + assert resp.status_code == 503 + assert resp.get_json()["error"] == "mitre bundle not loaded" + + # --------------------------------------------------------------------------- # SOC cannot patch technique_ids (it's a redteam field) # ---------------------------------------------------------------------------