from datetime import datetime from unittest.mock import patch from lib import firewall class TestParseForwardPorts: def test_single_entry(self): result = firewall._parse_forward_ports("port=443/proto=tcp") assert result == ["port=443/proto=tcp"] def test_multiple_entries(self): result = firewall._parse_forward_ports( "port=443/proto=tcp port=80/proto=tcp/toaddr=10.0.0.1/toport=8080" ) assert len(result) == 2 assert result[0] == "port=443/proto=tcp" def test_empty_string(self): assert firewall._parse_forward_ports("") == [] class TestGetActiveZones: @patch("lib.firewall._run") def test_parses_active_zones(self, mock_run): mock_run.return_value = "public\n eth0\ninternal\n eth1\n eth2" result = firewall.get_active_zones() assert result == { "public": ["eth0"], "internal": ["eth1", "eth2"], } @patch("lib.firewall._run") def test_empty_output(self, mock_run): mock_run.return_value = "" result = firewall.get_active_zones() assert result == {} @patch("lib.firewall._run") def test_zone_with_no_interfaces(self, mock_run): mock_run.return_value = "dmz" result = firewall.get_active_zones() assert result == {"dmz": []} class TestGetZoneInfo: @patch("lib.firewall._run") def test_parses_zone_info(self, mock_run): mock_run.return_value = ( "target: default\n" "interfaces: eth0\n" "sources: \n" "services: ssh dhcp\n" "ports: 8080/tcp\n" "protocols: \n" "forward-ports: \n" "masquerade: yes\n" "ics: no\n" "rich-rules: \n" "icmp-blocks: \n" "module: \n" ) result = firewall.get_zone_info("public") assert result["name"] == "public" assert result["services"] == ["ssh", "dhcp"] assert result["ports"] == ["8080/tcp"] assert result["masquerade"] is True assert result["interfaces"] == ["eth0"] assert result["sources"] == [] assert result["rich-rules"] == [] class TestGetInterfaces: @patch("lib.firewall._run") def test_parses_interfaces(self, mock_run): mock_run.return_value = ( "1: lo: mtu 65536\n" "2: eth0: mtu 1500\n" "3: eth1: mtu 1500\n" ) result = firewall.get_interfaces() assert result == ["lo", "eth0", "eth1"] class TestGetRichRules: @patch("lib.firewall._run") def test_single_rule(self, mock_run): mock_run.return_value = ( 'rule family="ipv4" port protocol="tcp" port="443" accept;' ) result = firewall.get_rich_rules("public") assert len(result) == 1 @patch("lib.firewall._run") def test_empty_rules(self, mock_run): mock_run.return_value = "" result = firewall.get_rich_rules("public") assert result == [] @patch("lib.firewall._run") def test_multiline_rule(self, mock_run): mock_run.return_value = ( 'rule family="ipv4"\n source address="10.0.0.0/24"\n reject;' ) result = firewall.get_rich_rules("public") assert len(result) == 1 assert "10.0.0.0/24" in result[0] class TestNowIso: def test_returns_iso_string(self): result = firewall._now_iso() datetime.fromisoformat(result) assert "+" in result class TestAddForwardPort: @patch("lib.firewall._run") def test_forward_port_basic(self, mock_run): mock_run.return_value = "" firewall.add_forward_port("public", 443, "tcp", toaddr="10.0.0.5", toport=8080) calls = [c[0][0] for c in mock_run.call_args_list] assert any("--add-forward-port=" in str(c) for c in calls) @patch("lib.firewall._run") def test_forward_port_port_only(self, mock_run): mock_run.return_value = "" firewall.add_forward_port("public", 80, "tcp", toport=8080) class TestGetState: @patch("lib.firewall.get_available_zones") @patch("lib.firewall.get_zone_info") @patch("lib.firewall.get_active_zones") @patch("lib.firewall.get_interfaces") @patch("lib.firewall.get_services") @patch("lib.firewall.get_rich_rules") def test_returns_full_state( self, mock_rich, mock_services, mock_ifaces, mock_active, mock_zone_info, mock_available, ): mock_available.return_value = ["public", "internal"] mock_active.return_value = {"public": ["eth0"]} mock_ifaces.return_value = ["eth0", "eth1"] mock_services.return_value = ["ssh", "http"] mock_zone_info.return_value = {"name": "public", "services": []} mock_rich.return_value = [] result = firewall.get_state() assert "zones" in result assert "active_zones" in result assert "timestamp" in result