"""Tests for I2CP Tier 1 message types.""" import struct import pytest from i2p_client.i2cp_messages import ( I2CPMessage, DisconnectMessage, GetBandwidthLimitsMessage, BandwidthLimitsMessage, DestLookupMessage, DestReplyMessage, ReportAbuseMessage, ) class TestDisconnectMessage: def test_roundtrip(self): msg = DisconnectMessage("session expired") wire = msg.to_wire() msg2 = I2CPMessage.from_wire(wire) assert isinstance(msg2, DisconnectMessage) assert msg2.reason == "session expired" def test_empty_reason(self): msg = DisconnectMessage("") wire = msg.to_wire() msg2 = I2CPMessage.from_wire(wire) assert msg2.reason == "" class TestGetBandwidthLimitsMessage: def test_roundtrip(self): msg = GetBandwidthLimitsMessage() wire = msg.to_wire() msg2 = I2CPMessage.from_wire(wire) assert isinstance(msg2, GetBandwidthLimitsMessage) def test_empty_payload(self): msg = GetBandwidthLimitsMessage() assert msg.payload_bytes() == b"" class TestBandwidthLimitsMessage: def test_roundtrip(self): limits = list(range(16)) msg = BandwidthLimitsMessage(limits) wire = msg.to_wire() msg2 = I2CPMessage.from_wire(wire) assert isinstance(msg2, BandwidthLimitsMessage) assert msg2.limits == limits def test_named_accessors(self): limits = [100, 200, 300, 0, 400] + [0] * 11 msg = BandwidthLimitsMessage(limits) assert msg.client_inbound == 100 assert msg.client_outbound == 200 assert msg.router_inbound == 300 assert msg.router_outbound == 400 def test_payload_size(self): msg = BandwidthLimitsMessage([0] * 16) assert len(msg.payload_bytes()) == 64 def test_wrong_count_raises(self): with pytest.raises(ValueError): BandwidthLimitsMessage([1, 2, 3]) class TestDestLookupMessage: def test_roundtrip(self): h = b"\xab" * 32 msg = DestLookupMessage(h) wire = msg.to_wire() msg2 = I2CPMessage.from_wire(wire) assert isinstance(msg2, DestLookupMessage) assert msg2.dest_hash == h def test_wrong_size_raises(self): with pytest.raises(ValueError): DestLookupMessage(b"\x00" * 16) class TestDestReplyMessage: def test_success(self): dest_data = b"\x01" * 387 msg = DestReplyMessage(destination_data=dest_data) wire = msg.to_wire() msg2 = I2CPMessage.from_wire(wire) assert msg2.destination_data == dest_data def test_hash_failure(self): h = b"\x02" * 32 msg = DestReplyMessage(hash_data=h) wire = msg.to_wire() msg2 = I2CPMessage.from_wire(wire) assert msg2.hash_data == h def test_empty_failure(self): msg = DestReplyMessage() wire = msg.to_wire() msg2 = I2CPMessage.from_wire(wire) assert msg2.destination_data is None assert msg2.hash_data is None class TestReportAbuseMessage: def test_roundtrip(self): msg = ReportAbuseMessage(session_id=5, severity=3, reason="spam", message_id=999) wire = msg.to_wire() msg2 = I2CPMessage.from_wire(wire) assert isinstance(msg2, ReportAbuseMessage) assert msg2.session_id == 5 assert msg2.severity == 3 assert msg2.reason == "spam" assert msg2.message_id == 999 def test_empty_reason(self): msg = ReportAbuseMessage(0, 0, "", 0) wire = msg.to_wire() msg2 = I2CPMessage.from_wire(wire) assert msg2.reason == ""