"""Test identity normalization per specification. From spec ยง2.3: - strip trailing spaces and newlines - no case folding - empty-after-strip stored blank Padded and unpadded renderings of the same field yield byte-identical stored values. """ import pytest import sys from pathlib import Path sys.path.insert(0, str(Path(__file__).parent.parent / "src")) from fenris.collector import normalize_identity def test_strip_trailing_spaces(): """Trailing spaces are stripped.""" identity = {"subnqn": "nqn.2014-08.org.nvmexpress:uuid:12345678 "} result = normalize_identity(identity) assert result == "nqn.2014-08.org.nvmexpress:uuid:12345678" def test_strip_trailing_newlines(): """Trailing newlines are stripped.""" identity = {"subnqn": "nqn.2014-08.org.nvmexpress:uuid:12345678\n"} result = normalize_identity(identity) assert result == "nqn.2014-08.org.nvmexpress:uuid:12345678" def test_strip_trailing_spaces_and_newlines(): """Trailing spaces and newlines are stripped.""" identity = {"subnqn": "nqn.2014-08.org.nvmexpress:uuid:12345678 \n\n"} result = normalize_identity(identity) assert result == "nqn.2014-08.org.nvmexpress:uuid:12345678" def test_no_case_folding(): """Case is preserved - no case folding.""" identity = {"subnqn": "NQN.2014-08.ORG.NVMEXPRESS:UUID:12345678"} result = normalize_identity(identity) assert result == "NQN.2014-08.ORG.NVMEXPRESS:UUID:12345678" def test_empty_after_strip_stored_blank(): """Empty after strip is stored as blank string.""" identity = {"subnqn": " \n\n "} result = normalize_identity(identity) assert result == "" def test_fallback_to_model_serial(): """When subnqn is empty, falls back to model|serial.""" identity = { "subnqn": "", "mn": "Samsung SSD 970 EVO Plus 1TB", "sn": "S4EWNX0N123456", } result = normalize_identity(identity) assert result == "Samsung SSD 970 EVO Plus 1TB|S4EWNX0N123456" def test_fallback_model_serial_normalized(): """Model and serial are also normalized.""" identity = { "subnqn": "", "mn": "Samsung SSD 970 EVO Plus 1TB\n", "sn": "S4EWNX0N123456 ", } result = normalize_identity(identity) assert result == "Samsung SSD 970 EVO Plus 1TB|S4EWNX0N123456" def test_all_keys_blank_returns_blank(): """When all keys are blank, returns blank (degraded identity).""" identity = { "subnqn": "", "mn": "", "sn": "", } result = normalize_identity(identity) assert result == "" def test_byte_identical_for_padded_unpadded(): """Padded and unpadded renderings yield byte-identical values.""" padded = {"subnqn": "nqn.2014-08.org.nvmexpress:uuid:12345678 \n"} unpadded = {"subnqn": "nqn.2014-08.org.nvmexpress:uuid:12345678"} result_padded = normalize_identity(padded) result_unpadded = normalize_identity(unpadded) assert result_padded == result_unpadded assert result_padded == "nqn.2014-08.org.nvmexpress:uuid:12345678"