"""Tests for troubleshooting decision rules.""" from __future__ import annotations import os from pathlib import Path os.environ.setdefault("SECRET_KEY", "test-secret-key-for-unit-tests-only") _test_dir = Path(__file__).resolve().parent _backend_root = _test_dir.parent _rules_file = _backend_root / "rules" / "troubleshooting.yaml" if not _rules_file.is_file(): _rules_file = _backend_root.parent / "rules" / "troubleshooting.yaml" os.environ["TROUBLESHOOTING_RULES_PATH"] = str(_rules_file) from app.services.troubleshooting_rules import ( # noqa: E402 invalidate_rules_cache, load_rules, match_rule, select_devices_for_issue, ) def _devices(): return [ {"catalog_key": "proxmox", "name": "pve"}, {"catalog_key": "pfsense", "name": "fw"}, {"catalog_key": "docker_vm", "name": "docker"}, {"catalog_key": "asterisk_geneseasx", "name": "voip"}, ] def test_match_no_registration_rule(): invalidate_rules_cache() rule = match_rule("SIP phones down", "Phone won't register on crew VLAN") assert rule is not None assert rule.id == "no-registration" assert "pfsense" in rule.devices def test_match_broad_health(): invalidate_rules_cache() rule = match_rule("Full check", "health check of all systems") assert rule is not None assert rule.broad is True def test_task4_issue_selects_proxmox_only(): """Scoped VM task must not trigger full-stack sweep.""" invalidate_rules_cache() selected, rule = select_devices_for_issue( _devices(), "Check status of all running VMs and provide config for each VM", title="Proxmox VM status", ) keys = [d["catalog_key"] for d in selected] assert keys == ["proxmox"] assert rule is None or rule.id == "proxmox-vm-inventory" def test_multi_device_status_includes_all_named(): """Issue naming two devices must diagnose both even when a single-device rule matches.""" invalidate_rules_cache() selected, rule = select_devices_for_issue( _devices(), "check status of proxmox and pfsense", title="Irinas box", ) keys = [d["catalog_key"] for d in selected] assert keys == ["proxmox", "pfsense"] assert rule is not None assert rule.id == "proxmox-vm-inventory" def test_unmatched_issue_selects_nothing(): invalidate_rules_cache() selected, _rule = select_devices_for_issue( _devices(), "something completely unrelated with no device keywords", title="Mystery", ) assert selected == [] def test_broad_issue_selects_all_devices(): invalidate_rules_cache() selected, rule = select_devices_for_issue( _devices(), "Run a full stack health check on everything", title="Weekly audit", ) assert rule is not None assert rule.broad is True assert len(selected) == 4 def test_select_devices_order(): invalidate_rules_cache() selected, rule = select_devices_for_issue( _devices(), "one-way audio on SIP calls", title="VoIP issue", ) assert rule is not None assert rule.id == "one-way-audio" keys = [d["catalog_key"] for d in selected] assert keys == ["pfsense", "asterisk_geneseasx"] def test_load_rules_has_device_keywords(): invalidate_rules_cache() data = load_rules(force=True) assert "asterisk_geneseasx" in data.get("device_keywords", {})