#!/usr/bin/env python3 """Tests for evidence-first firewall sync behavior.""" from __future__ import annotations import unittest from unittest.mock import patch from app.firewall import MikrotikFirewall class _FakeFirewall(MikrotikFirewall): def __init__(self): super().__init__(router_ip="0.0.0.0", username="x", password="x") self.calls: list[str] = [] def get_address_list_ipv4(self, name: str) -> set[str]: self.calls.append(f"v4:{name}") if name == "Blocked": return {"9.9.9.9/32"} if name == "Init7": return {"77.74.80.0/21"} return set() def get_address_list_ipv6(self, name: str) -> set[str]: self.calls.append(f"v6:{name}") if name == "Blocked": return set() if name == "Init7": return {"2001:1620::/30"} return set() class FirewallSyncEvidenceTest(unittest.TestCase): def test_sync_loads_router_status_before_computing_changes(self): fw = _FakeFirewall() # type: ignore[assignment] fw.save_state_report = lambda *args, **kwargs: "noop" with patch("app.firewall.cumulative_blocklist", return_value=({"8.8.8.8/32"}, set())): changes = fw.sync_blocklist(["8.8.8.8/32"], [], dry_run=True) self.assertIn("v4:Blocked", fw.calls) self.assertIn("v6:Blocked", fw.calls) self.assertIn("v4:Init7", fw.calls) self.assertIn("v6:Init7", fw.calls) self.assertEqual(changes["added_ipv4"], ["8.8.8.8/32"]) self.assertEqual(changes["removed_ipv4"], ["9.9.9.9/32"]) def test_sync_evaluates_against_loaded_current_status(self): fw = _FakeFirewall() # type: ignore[assignment] fw.save_state_report = lambda *args, **kwargs: "noop" with patch("app.firewall.cumulative_blocklist", return_value=({"9.9.9.9/32"}, set())): changes = fw.sync_blocklist(["9.9.9.9/32"], [], dry_run=True) self.assertEqual(changes["added_ipv4"], []) self.assertEqual(changes["removed_ipv4"], []) if __name__ == "__main__": unittest.main()