"""Tests for IANA XML parsing functionality.""" import xml.etree.ElementTree as ET import pytest from sslysze_scan.iana_parser import ( extract_field_value, find_registry, get_element_text, is_unassigned, parse_xml_with_namespace_support, process_xref_elements, ) class TestParseXmlWithNamespace: """Tests for XML parsing with namespace detection.""" def test_parse_tls_parameters_with_namespace(self) -> None: """Test parsing TLS parameters XML with IANA namespace.""" xml_path = "tests/fixtures/iana_xml/tls-parameters-minimal.xml" root, ns = parse_xml_with_namespace_support(xml_path) assert root is not None assert ns is not None assert "iana" in ns assert ns["iana"] == "http://www.iana.org/assignments" def test_parse_nonexistent_file(self) -> None: """Test that parsing nonexistent file raises FileNotFoundError.""" with pytest.raises(FileNotFoundError): parse_xml_with_namespace_support("nonexistent.xml") class TestFindRegistry: """Tests for finding registry by ID.""" def test_find_cipher_suites_registry(self) -> None: """Test finding TLS cipher suites registry.""" xml_path = "tests/fixtures/iana_xml/tls-parameters-minimal.xml" root, ns = parse_xml_with_namespace_support(xml_path) registry = find_registry(root, "tls-parameters-4", ns) assert registry is not None assert registry.get("id") == "tls-parameters-4" def test_find_nonexistent_registry(self) -> None: """Test that finding nonexistent registry raises ValueError.""" xml_path = "tests/fixtures/iana_xml/tls-parameters-minimal.xml" root, ns = parse_xml_with_namespace_support(xml_path) with pytest.raises(ValueError, match="Registry with ID '.*' not found"): find_registry(root, "nonexistent-registry", ns) class TestGetElementText: """Tests for element text extraction.""" def test_get_element_text_with_namespace(self) -> None: """Test extracting text from element with namespace.""" xml_path = "tests/fixtures/iana_xml/tls-parameters-minimal.xml" root, ns = parse_xml_with_namespace_support(xml_path) registry = find_registry(root, "tls-parameters-4", ns) records = registry.findall("iana:record", ns) first_record = records[0] value = get_element_text(first_record, "value", ns) assert value == "0x13,0x01" description = get_element_text(first_record, "description", ns) assert description == "TLS_AES_128_GCM_SHA256" def test_get_element_text_nonexistent(self) -> None: """Test that nonexistent element returns empty string.""" xml_path = "tests/fixtures/iana_xml/tls-parameters-minimal.xml" root, ns = parse_xml_with_namespace_support(xml_path) registry = find_registry(root, "tls-parameters-4", ns) records = registry.findall("iana:record", ns) first_record = records[0] result = get_element_text(first_record, "nonexistent", ns) assert result == "" class TestProcessXrefElements: """Tests for xref element processing.""" def test_process_single_xref(self) -> None: """Test processing single xref element.""" xml_path = "tests/fixtures/iana_xml/tls-parameters-minimal.xml" root, ns = parse_xml_with_namespace_support(xml_path) registry = find_registry(root, "tls-parameters-4", ns) records = registry.findall("iana:record", ns) first_record = records[0] xref_str = process_xref_elements(first_record, ns) assert "rfc:rfc8446" in xref_str def test_process_no_xref(self) -> None: """Test processing record without xref elements.""" xml_str = """ 0x13,0x01 Test """ record = ET.fromstring(xml_str) ns = {"iana": "http://www.iana.org/assignments"} xref_str = process_xref_elements(record, ns) assert xref_str == "" class TestExtractFieldValue: """Tests for field value extraction.""" def test_extract_recommended_field(self) -> None: """Test extracting Recommended field.""" xml_path = "tests/fixtures/iana_xml/tls-parameters-minimal.xml" root, ns = parse_xml_with_namespace_support(xml_path) registry = find_registry(root, "tls-parameters-4", ns) records = registry.findall("iana:record", ns) first_record = records[0] rec = extract_field_value(first_record, "Recommended", ns) assert rec == "Y" def test_extract_rfc_draft_field(self) -> None: """Test extracting RFC/Draft field via xref processing.""" xml_path = "tests/fixtures/iana_xml/tls-parameters-minimal.xml" root, ns = parse_xml_with_namespace_support(xml_path) registry = find_registry(root, "tls-parameters-4", ns) records = registry.findall("iana:record", ns) first_record = records[0] rfc_draft = extract_field_value(first_record, "RFC/Draft", ns) assert "rfc:rfc8446" in rfc_draft class TestExtractUpdatedDate: """Tests for extracting updated date from XML.""" def test_extract_updated_from_tls_xml(self) -> None: """Test extracting updated date from TLS parameters XML.""" xml_path = "tests/fixtures/iana_xml/tls-parameters-minimal.xml" with open(xml_path, encoding="utf-8") as f: xml_content = f.read() lines = xml_content.split("\n")[:10] updated_line = [line for line in lines if "" in line] assert len(updated_line) == 1 assert "2025-12-03" in updated_line[0] class TestIsUnassigned: """Tests for unassigned entry detection.""" def test_is_unassigned_numeric_range(self) -> None: """Test detection of numeric range values.""" xml_str = """ 42-255 Unassigned """ record = ET.fromstring(xml_str) ns = {"iana": "http://www.iana.org/assignments"} assert is_unassigned(record, ns) is True def test_is_unassigned_hex_range(self) -> None: """Test detection of hex range values.""" xml_str = """ 0x0000-0x0200 Reserved for backward compatibility """ record = ET.fromstring(xml_str) ns = {"iana": "http://www.iana.org/assignments"} assert is_unassigned(record, ns) is True def test_is_unassigned_false(self) -> None: """Test that assigned entries return False.""" xml_path = "tests/fixtures/iana_xml/tls-parameters-minimal.xml" root, ns = parse_xml_with_namespace_support(xml_path) registry = find_registry(root, "tls-parameters-4", ns) records = registry.findall("iana:record", ns) first_record = records[0] assert is_unassigned(first_record, ns) is False