A Python port of the Invisible Internet Project (I2P)
at main 91 lines 3.2 kB view raw
1"""Tests for SAM utility functions.""" 2 3import base64 4 5import pytest 6 7from i2p_sam.utils import parse_params, negotiate_version, generate_transient_destination 8 9 10class TestParseParams: 11 """Tests for parse_params().""" 12 13 def test_parse_params(self): 14 """Basic key=value parsing.""" 15 result = parse_params("MIN=3.0 MAX=3.3") 16 assert result == {"MIN": "3.0", "MAX": "3.3"} 17 18 def test_parse_params_quoted(self): 19 """Quoted values with spaces.""" 20 result = parse_params('ID="my session" STYLE=STREAM') 21 assert result["ID"] == "my session" 22 assert result["STYLE"] == "STREAM" 23 24 def test_parse_params_empty(self): 25 """Empty string returns empty dict.""" 26 assert parse_params("") == {} 27 28 def test_parse_params_single(self): 29 """Single key=value pair.""" 30 result = parse_params("RESULT=OK") 31 assert result == {"RESULT": "OK"} 32 33 def test_parse_params_preserves_case_in_values(self): 34 """Keys are uppercased, values preserve case.""" 35 result = parse_params("style=Stream") 36 assert result["STYLE"] == "Stream" 37 38 39class TestNegotiateVersion: 40 """Tests for negotiate_version().""" 41 42 def test_negotiate_version_exact(self): 43 """Exact match — client wants exactly 3.3.""" 44 result = negotiate_version("3.3", "3.3", ["3.0", "3.1", "3.2", "3.3"]) 45 assert result == "3.3" 46 47 def test_negotiate_version_range(self): 48 """Range negotiation — pick highest mutual version.""" 49 result = negotiate_version("3.0", "3.3", ["3.0", "3.1", "3.2", "3.3"]) 50 assert result == "3.3" 51 52 def test_negotiate_version_range_limited(self): 53 """Server supports fewer versions than client requests.""" 54 result = negotiate_version("3.0", "3.3", ["3.0", "3.1"]) 55 assert result == "3.1" 56 57 def test_negotiate_version_no_match(self): 58 """No overlap returns None.""" 59 result = negotiate_version("3.4", "3.5", ["3.0", "3.1", "3.2", "3.3"]) 60 assert result is None 61 62 def test_negotiate_version_client_below(self): 63 """Client max below server min.""" 64 result = negotiate_version("2.0", "2.9", ["3.0", "3.1", "3.2", "3.3"]) 65 assert result is None 66 67 68class TestGenerateTransientDestination: 69 """Tests for generate_transient_destination().""" 70 71 def test_generate_transient_destination(self): 72 """Produces valid I2P base64 string and non-empty raw bytes.""" 73 raw, b64 = generate_transient_destination() 74 assert isinstance(raw, bytes) 75 assert len(raw) > 0 76 assert isinstance(b64, str) 77 assert len(b64) > 0 78 # Verify b64 is decodable using I2P base64 alphabet (-~ instead of +/) 79 padding = 4 - (len(b64) % 4) 80 if padding != 4: 81 b64_padded = b64 + "=" * padding 82 else: 83 b64_padded = b64 84 decoded = base64.b64decode(b64_padded, altchars=b"-~") 85 assert decoded == raw 86 87 def test_generate_transient_destination_unique(self): 88 """Each call produces a different destination.""" 89 _, b64_1 = generate_transient_destination() 90 _, b64_2 = generate_transient_destination() 91 assert b64_1 != b64_2