From 9661736a658ee75376fc6f6562fbf8b2e2000b11 Mon Sep 17 00:00:00 2001 From: Cyber MacGeddon Date: Sat, 12 Jul 2025 11:21:08 +0100 Subject: [PATCH] Gateway tests --- .../unit/test_gateway/test_dispatch_config.py | 87 ++++++++++++++++++ .../test_gateway/test_dispatch_serialize.py | 89 +++++++++++++++++++ .../test_gateway/test_endpoint_constant.py | 55 ++++++++++++ .../test_gateway/test_endpoint_metrics.py | 60 +++++++++++++ .../test_gateway/test_endpoint_variable.py | 53 +++++++++++ 5 files changed, 344 insertions(+) create mode 100644 tests/unit/test_gateway/test_dispatch_config.py create mode 100644 tests/unit/test_gateway/test_dispatch_serialize.py create mode 100644 tests/unit/test_gateway/test_endpoint_constant.py create mode 100644 tests/unit/test_gateway/test_endpoint_metrics.py create mode 100644 tests/unit/test_gateway/test_endpoint_variable.py diff --git a/tests/unit/test_gateway/test_dispatch_config.py b/tests/unit/test_gateway/test_dispatch_config.py new file mode 100644 index 00000000..de6a23da --- /dev/null +++ b/tests/unit/test_gateway/test_dispatch_config.py @@ -0,0 +1,87 @@ +""" +Tests for Gateway Config Dispatch +""" + +import pytest +from unittest.mock import MagicMock, patch + +from trustgraph.gateway.dispatch.config import ConfigRequestor + + +class TestConfigRequestor: + """Test cases for ConfigRequestor class""" + + @patch('trustgraph.gateway.dispatch.config.TranslatorRegistry') + def test_config_requestor_initialization(self, mock_translator_registry): + """Test ConfigRequestor initialization""" + # Mock translators + mock_request_translator = MagicMock() + mock_response_translator = MagicMock() + mock_translator_registry.get_request_translator.return_value = mock_request_translator + mock_translator_registry.get_response_translator.return_value = mock_response_translator + + # Mock dependencies + mock_pulsar_client = MagicMock() + + requestor = ConfigRequestor( + pulsar_client=mock_pulsar_client, + consumer="test-consumer", + subscriber="test-subscriber", + timeout=60 + ) + + # Verify translator setup + mock_translator_registry.get_request_translator.assert_called_once_with("config") + mock_translator_registry.get_response_translator.assert_called_once_with("config") + + assert requestor.request_translator == mock_request_translator + assert requestor.response_translator == mock_response_translator + + @patch('trustgraph.gateway.dispatch.config.TranslatorRegistry') + def test_config_requestor_to_request(self, mock_translator_registry): + """Test ConfigRequestor to_request method""" + # Mock translators + mock_request_translator = MagicMock() + mock_translator_registry.get_request_translator.return_value = mock_request_translator + mock_translator_registry.get_response_translator.return_value = MagicMock() + + # Setup translator response + mock_request_translator.to_pulsar.return_value = "translated_request" + + requestor = ConfigRequestor( + pulsar_client=MagicMock(), + consumer="test-consumer", + subscriber="test-subscriber" + ) + + # Call to_request + result = requestor.to_request({"test": "body"}) + + # Verify translator was called correctly + mock_request_translator.to_pulsar.assert_called_once_with({"test": "body"}) + assert result == "translated_request" + + @patch('trustgraph.gateway.dispatch.config.TranslatorRegistry') + def test_config_requestor_from_response(self, mock_translator_registry): + """Test ConfigRequestor from_response method""" + # Mock translators + mock_response_translator = MagicMock() + mock_translator_registry.get_request_translator.return_value = MagicMock() + mock_translator_registry.get_response_translator.return_value = mock_response_translator + + # Setup translator response + mock_response_translator.from_response_with_completion.return_value = "translated_response" + + requestor = ConfigRequestor( + pulsar_client=MagicMock(), + consumer="test-consumer", + subscriber="test-subscriber" + ) + + # Call from_response + mock_message = MagicMock() + result = requestor.from_response(mock_message) + + # Verify translator was called correctly + mock_response_translator.from_response_with_completion.assert_called_once_with(mock_message) + assert result == "translated_response" \ No newline at end of file diff --git a/tests/unit/test_gateway/test_dispatch_serialize.py b/tests/unit/test_gateway/test_dispatch_serialize.py new file mode 100644 index 00000000..e117629b --- /dev/null +++ b/tests/unit/test_gateway/test_dispatch_serialize.py @@ -0,0 +1,89 @@ +""" +Tests for Gateway Dispatch Serialization +""" + +import pytest +from unittest.mock import MagicMock + +from trustgraph.gateway.dispatch.serialize import to_value, to_subgraph, serialize_value +from trustgraph.schema import Value, Triple + + +class TestDispatchSerialize: + """Test cases for dispatch serialization functions""" + + def test_to_value_with_uri(self): + """Test to_value function with URI""" + input_data = {"v": "http://example.com/resource", "e": True} + + result = to_value(input_data) + + assert isinstance(result, Value) + assert result.value == "http://example.com/resource" + assert result.is_uri is True + + def test_to_value_with_literal(self): + """Test to_value function with literal value""" + input_data = {"v": "literal string", "e": False} + + result = to_value(input_data) + + assert isinstance(result, Value) + assert result.value == "literal string" + assert result.is_uri is False + + def test_to_subgraph_with_multiple_triples(self): + """Test to_subgraph function with multiple triples""" + input_data = [ + { + "s": {"v": "subject1", "e": True}, + "p": {"v": "predicate1", "e": True}, + "o": {"v": "object1", "e": False} + }, + { + "s": {"v": "subject2", "e": False}, + "p": {"v": "predicate2", "e": True}, + "o": {"v": "object2", "e": True} + } + ] + + result = to_subgraph(input_data) + + assert len(result) == 2 + assert all(isinstance(triple, Triple) for triple in result) + + # Check first triple + assert result[0].s.value == "subject1" + assert result[0].s.is_uri is True + assert result[0].p.value == "predicate1" + assert result[0].p.is_uri is True + assert result[0].o.value == "object1" + assert result[0].o.is_uri is False + + # Check second triple + assert result[1].s.value == "subject2" + assert result[1].s.is_uri is False + + def test_to_subgraph_with_empty_list(self): + """Test to_subgraph function with empty input""" + input_data = [] + + result = to_subgraph(input_data) + + assert result == [] + + def test_serialize_value_with_uri(self): + """Test serialize_value function with URI value""" + value = Value(value="http://example.com/test", is_uri=True) + + result = serialize_value(value) + + assert result == {"v": "http://example.com/test", "e": True} + + def test_serialize_value_with_literal(self): + """Test serialize_value function with literal value""" + value = Value(value="test literal", is_uri=False) + + result = serialize_value(value) + + assert result == {"v": "test literal", "e": False} \ No newline at end of file diff --git a/tests/unit/test_gateway/test_endpoint_constant.py b/tests/unit/test_gateway/test_endpoint_constant.py new file mode 100644 index 00000000..f208c967 --- /dev/null +++ b/tests/unit/test_gateway/test_endpoint_constant.py @@ -0,0 +1,55 @@ +""" +Tests for Gateway Constant Endpoint +""" + +import pytest +from unittest.mock import MagicMock, AsyncMock +from aiohttp import web + +from trustgraph.gateway.endpoint.constant_endpoint import ConstantEndpoint + + +class TestConstantEndpoint: + """Test cases for ConstantEndpoint class""" + + def test_constant_endpoint_initialization(self): + """Test ConstantEndpoint initialization""" + mock_auth = MagicMock() + mock_dispatcher = MagicMock() + + endpoint = ConstantEndpoint( + endpoint_path="/api/test", + auth=mock_auth, + dispatcher=mock_dispatcher + ) + + assert endpoint.path == "/api/test" + assert endpoint.auth == mock_auth + assert endpoint.dispatcher == mock_dispatcher + assert endpoint.operation == "service" + + @pytest.mark.asyncio + async def test_constant_endpoint_start_method(self): + """Test ConstantEndpoint start method (should be no-op)""" + mock_auth = MagicMock() + mock_dispatcher = MagicMock() + + endpoint = ConstantEndpoint("/api/test", mock_auth, mock_dispatcher) + + # start() should complete without error + await endpoint.start() + + def test_add_routes_registers_post_handler(self): + """Test add_routes method registers POST route""" + mock_auth = MagicMock() + mock_dispatcher = MagicMock() + mock_app = MagicMock() + + endpoint = ConstantEndpoint("/api/test", mock_auth, mock_dispatcher) + endpoint.add_routes(mock_app) + + # Verify add_routes was called with POST route + mock_app.add_routes.assert_called_once() + # The call should include web.post with the path and handler + call_args = mock_app.add_routes.call_args[0][0] + assert len(call_args) == 1 # One route added \ No newline at end of file diff --git a/tests/unit/test_gateway/test_endpoint_metrics.py b/tests/unit/test_gateway/test_endpoint_metrics.py new file mode 100644 index 00000000..bacf551d --- /dev/null +++ b/tests/unit/test_gateway/test_endpoint_metrics.py @@ -0,0 +1,60 @@ +""" +Tests for Gateway Metrics Endpoint +""" + +import pytest +from unittest.mock import MagicMock + +from trustgraph.gateway.endpoint.metrics import MetricsEndpoint + + +class TestMetricsEndpoint: + """Test cases for MetricsEndpoint class""" + + def test_metrics_endpoint_initialization(self): + """Test MetricsEndpoint initialization""" + mock_auth = MagicMock() + + endpoint = MetricsEndpoint( + prometheus_url="http://prometheus:9090", + endpoint_path="/metrics", + auth=mock_auth + ) + + assert endpoint.prometheus_url == "http://prometheus:9090" + assert endpoint.path == "/metrics" + assert endpoint.auth == mock_auth + assert endpoint.operation == "service" + + @pytest.mark.asyncio + async def test_metrics_endpoint_start_method(self): + """Test MetricsEndpoint start method (should be no-op)""" + mock_auth = MagicMock() + + endpoint = MetricsEndpoint( + prometheus_url="http://localhost:9090", + endpoint_path="/metrics", + auth=mock_auth + ) + + # start() should complete without error + await endpoint.start() + + def test_add_routes_registers_get_handler(self): + """Test add_routes method registers GET route with wildcard path""" + mock_auth = MagicMock() + mock_app = MagicMock() + + endpoint = MetricsEndpoint( + prometheus_url="http://prometheus:9090", + endpoint_path="/metrics", + auth=mock_auth + ) + + endpoint.add_routes(mock_app) + + # Verify add_routes was called with GET route + mock_app.add_routes.assert_called_once() + # The call should include web.get with wildcard path pattern + call_args = mock_app.add_routes.call_args[0][0] + assert len(call_args) == 1 # One route added \ No newline at end of file diff --git a/tests/unit/test_gateway/test_endpoint_variable.py b/tests/unit/test_gateway/test_endpoint_variable.py new file mode 100644 index 00000000..ffaf4e9a --- /dev/null +++ b/tests/unit/test_gateway/test_endpoint_variable.py @@ -0,0 +1,53 @@ +""" +Tests for Gateway Variable Endpoint +""" + +import pytest +from unittest.mock import MagicMock + +from trustgraph.gateway.endpoint.variable_endpoint import VariableEndpoint + + +class TestVariableEndpoint: + """Test cases for VariableEndpoint class""" + + def test_variable_endpoint_initialization(self): + """Test VariableEndpoint initialization""" + mock_auth = MagicMock() + mock_dispatcher = MagicMock() + + endpoint = VariableEndpoint( + endpoint_path="/api/variable", + auth=mock_auth, + dispatcher=mock_dispatcher + ) + + assert endpoint.path == "/api/variable" + assert endpoint.auth == mock_auth + assert endpoint.dispatcher == mock_dispatcher + assert endpoint.operation == "service" + + @pytest.mark.asyncio + async def test_variable_endpoint_start_method(self): + """Test VariableEndpoint start method (should be no-op)""" + mock_auth = MagicMock() + mock_dispatcher = MagicMock() + + endpoint = VariableEndpoint("/api/var", mock_auth, mock_dispatcher) + + # start() should complete without error + await endpoint.start() + + def test_add_routes_registers_post_handler(self): + """Test add_routes method registers POST route""" + mock_auth = MagicMock() + mock_dispatcher = MagicMock() + mock_app = MagicMock() + + endpoint = VariableEndpoint("/api/variable", mock_auth, mock_dispatcher) + endpoint.add_routes(mock_app) + + # Verify add_routes was called with POST route + mock_app.add_routes.assert_called_once() + call_args = mock_app.add_routes.call_args[0][0] + assert len(call_args) == 1 # One route added \ No newline at end of file