From a0ccf37a928d618d863212f7f71b1c04d0a9b498 Mon Sep 17 00:00:00 2001 From: mukundkumarjha Date: Thu, 1 Jan 2026 19:56:01 +0530 Subject: [PATCH 1/2] unit test for 'endpoint.py' Signed-off-by: mukundkumarjha --- CHANGELOG.md | 1 + tests/unit/endpoint_test.py | 75 +++++++++++++++++++++++++++++++++++++ 2 files changed, 76 insertions(+) create mode 100644 tests/unit/endpoint_test.py diff --git a/CHANGELOG.md b/CHANGELOG.md index 0f7adef8f..7ff7a4d6d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,7 @@ This changelog is based on [Keep a Changelog](https://keepachangelog.com/en/1.1. ## [Unreleased] ### Added +- Added unit test for 'endpoint.py' to increase coverage. - Automated assignment guard for `advanced` issues; requires completion of at least one `good first issue` and one `intermediate` issue before assignment (exempts maintainers, committers, and triage members). (#1142) - Added Hbar object support for TransferTransaction HBAR transfers: - Methods now accept `Union[int, Hbar]` for amount parameters with immediate normalization to tinybars diff --git a/tests/unit/endpoint_test.py b/tests/unit/endpoint_test.py new file mode 100644 index 000000000..4db0e4ed6 --- /dev/null +++ b/tests/unit/endpoint_test.py @@ -0,0 +1,75 @@ +import pytest +from unittest.mock import MagicMock +from src.hiero_sdk_python.address_book.endpoint import Endpoint + +pytestmark = pytest.mark.unit + +def test_getter_setter(): + + ''' Test for Endpoint constructor''' + + endpoint = Endpoint(address=None, port=None, domain_name=None) + endpoint.set_address(b'127.0.1.1') + endpoint.set_port(77777) + endpoint.set_domain_name("redpanda.com") + + assert endpoint.get_address() == b'127.0.1.1' + assert endpoint.get_port() == 77777 + assert endpoint.get_domain_name() == "redpanda.com" + +@pytest.mark.parametrize("input_port, expected_port", [ + (0, 50211), + (50111, 50211), + (80, 80) +]) + +def test_from_proto_port_mapping(input_port, expected_port): + + ''' Tests the logic that converts a Protobuf ServiceEndpoint into an Endpoint object.''' + + mock_proto = MagicMock() + mock_proto.port = input_port + mock_proto.ipAddressV4 = b"127.0.1.1" + mock_proto.domain_name = "redpanda.com" + + endpoint = Endpoint._from_proto(mock_proto) + assert endpoint.get_port() == expected_port + +def test_to_proto(): + + '''Verifies that an Endpoint instance can be correctly serialized back into + a Protobuf ServiceEndpoint object with all fields intact.''' + + endpoint = Endpoint(address=b'127.0.1.1', port=77777, domain_name="redpanda.com") + proto = endpoint._to_proto() + assert proto.ipAddressV4 == b'127.0.1.1' + assert proto.port == 77777 + assert proto.domain_name == "redpanda.com" + +def test_str(): + + ''' Tests the human-readable string representation of the Endpoint. ''' + + endpoint = Endpoint(address=b'127.0.1.1', port=77777, domain_name="redpanda.com") + assert str(endpoint) == '127.0.1.1:77777' + +def test_from_dict_error(): + + '''Validates 'Guard Clause' error handling''' + + invalid_data = {"port": 77777} + with pytest.raises(ValueError, match="JSON data must contain"): + Endpoint.from_dict(invalid_data) + +def test_from_dict_success(): + ''' Tests successful creation of an Endpoint from a dictionary (JSON format) ''' + data = { + "ip_address_v4": "127.0.0.1", + "port": 77777, + "domain_name": "redpanda.com" + } + endpoint = Endpoint.from_dict(data) + + assert endpoint.get_address() == b"127.0.0.1" + assert endpoint.get_port() == 77777 + assert endpoint.get_domain_name() == "redpanda.com" \ No newline at end of file From 627b8d9732ec5d49673c7203bdb34df89f60b286 Mon Sep 17 00:00:00 2001 From: mukundkumarjha Date: Fri, 2 Jan 2026 13:15:24 +0530 Subject: [PATCH 2/2] Created tests for endpoint.py to increase test coverage Signed-off-by: mukundkumarjha --- tests/unit/endpoint_test.py | 74 +++++++++++++++++++++++++++++-------- 1 file changed, 59 insertions(+), 15 deletions(-) diff --git a/tests/unit/endpoint_test.py b/tests/unit/endpoint_test.py index 4db0e4ed6..35f7c62d0 100644 --- a/tests/unit/endpoint_test.py +++ b/tests/unit/endpoint_test.py @@ -4,36 +4,66 @@ pytestmark = pytest.mark.unit -def test_getter_setter(): - ''' Test for Endpoint constructor''' +def test_getter_setter(): # type: ignore + """Test for Endpoint constructor, getters, and setters with fluent interface.""" + endpoint = Endpoint(address=None, port=None, domain_name=None) - endpoint.set_address(b'127.0.1.1') - endpoint.set_port(77777) - endpoint.set_domain_name("redpanda.com") - + + # Test fluent interface (method chaining) + result = endpoint.set_address(b'127.0.1.1') + assert result is endpoint, "set_address should return self for method chaining" + + result = endpoint.set_port(77777) + assert result is endpoint, "set_port should return self for method chaining" + + result = endpoint.set_domain_name("redpanda.com") + assert result is endpoint, "set_domain_name should return self for method chaining" + + # Protect against breaking changes - verify attributes exist + assert hasattr(endpoint, 'get_address'), "Missing get_address method" + assert hasattr(endpoint, 'get_port'), "Missing get_port method" + assert hasattr(endpoint, 'get_domain_name'), "Missing get_domain_name method" + assert endpoint.get_address() == b'127.0.1.1' assert endpoint.get_port() == 77777 assert endpoint.get_domain_name() == "redpanda.com" + +def test_constructor_with_values(): + """Test Endpoint constructor with actual values.""" + endpoint = Endpoint(address=b'192.168.1.1', port=8080, domain_name="example.com") + + assert endpoint.get_address() == b'192.168.1.1' + assert endpoint.get_port() == 8080 + assert endpoint.get_domain_name() == "example.com" + @pytest.mark.parametrize("input_port, expected_port", [ - (0, 50211), - (50111, 50211), - (80, 80) + (0, 50211), # Default port mapping when port is 0 + (50111, 50211), # Legacy port 50111 maps to new port 50211 + (80, 80) # Standard ports pass through unchanged ]) def test_from_proto_port_mapping(input_port, expected_port): - - ''' Tests the logic that converts a Protobuf ServiceEndpoint into an Endpoint object.''' + """Tests the logic that converts a Protobuf ServiceEndpoint into an Endpoint object.""" mock_proto = MagicMock() mock_proto.port = input_port mock_proto.ipAddressV4 = b"127.0.1.1" mock_proto.domain_name = "redpanda.com" - + endpoint = Endpoint._from_proto(mock_proto) + + # Verify port mapping assert endpoint.get_port() == expected_port + + # Verify all fields are mapped correctly + assert endpoint.get_address() == b"127.0.1.1", "Address should be mapped from proto" + assert endpoint.get_domain_name() == "redpanda.com", "Domain name should be mapped from proto" + + # Protect against breaking changes - verify return type + assert isinstance(endpoint, Endpoint), "Should return Endpoint instance" def test_to_proto(): @@ -48,10 +78,24 @@ def test_to_proto(): def test_str(): - ''' Tests the human-readable string representation of the Endpoint. ''' - + """Tests the human-readable string representation of the Endpoint.""" + endpoint = Endpoint(address=b'127.0.1.1', port=77777, domain_name="redpanda.com") - assert str(endpoint) == '127.0.1.1:77777' + result = str(endpoint) + + # Verify return type + assert isinstance(result, str), "String representation should return a string" + assert result == '127.0.1.1:77777' + + +def test_str_with_none_values(): + """Test string representation when address or port is None.""" + endpoint = Endpoint(address=b"", port=None, domain_name="example.com") + result = str(endpoint) + + assert isinstance(result, str), "Should return string even with None values" + # Verify it doesn't raise an exception and returns something meaningful + assert result is not None and len(result) > 0, "Should produce non-empty string representation" def test_from_dict_error():