From 190d80d94330a94eae51f7e39f7a59ea24bf8001 Mon Sep 17 00:00:00 2001 From: Cyber MacGeddon Date: Fri, 19 Dec 2025 08:28:31 +0000 Subject: [PATCH] Fixing unit tests --- .../test_schema_contracts.py | 18 +- .../unit/test_rev_gateway/test_dispatcher.py | 10 +- .../test_rev_gateway_service.py | 186 +++++++++--------- .../messaging/translators/diagnosis.py | 2 +- 4 files changed, 107 insertions(+), 109 deletions(-) diff --git a/tests/unit/test_retrieval/test_structured_diag/test_schema_contracts.py b/tests/unit/test_retrieval/test_structured_diag/test_schema_contracts.py index 99f66dc7..240bad89 100644 --- a/tests/unit/test_retrieval/test_structured_diag/test_schema_contracts.py +++ b/tests/unit/test_retrieval/test_structured_diag/test_schema_contracts.py @@ -23,9 +23,9 @@ class TestStructuredDiagnosisSchemaContract: assert request.operation == "detect-type" assert request.sample == "test data" - assert request.type is None # Optional, defaults to None - assert request.schema_name is None # Optional, defaults to None - assert request.options is None # Optional, defaults to None + assert request.type == "" # Optional, defaults to empty string + assert request.schema_name == "" # Optional, defaults to empty string + assert request.options == {} # Optional, defaults to empty dict def test_request_schema_all_operations(self): """Test request schema supports all operations""" @@ -66,9 +66,9 @@ class TestStructuredDiagnosisSchemaContract: assert response.detected_type == "xml" assert response.confidence == 0.9 assert response.error is None - assert response.descriptor is None - assert response.metadata is None - assert response.schema_matches is None # New field, defaults to None + assert response.descriptor == "" # Defaults to empty string + assert response.metadata == {} # Defaults to empty dict + assert response.schema_matches == [] # Defaults to empty list def test_response_schema_with_error(self): """Test response schema with error""" @@ -140,6 +140,7 @@ class TestStructuredDiagnosisSchemaContract: assert response.metadata == metadata assert response.metadata["field_count"] == "5" + @pytest.mark.skip(reason="JsonSchema requires Pulsar Record types, not dataclasses") def test_schema_serialization(self): """Test that schemas can be serialized and deserialized correctly""" # Test request serialization @@ -158,6 +159,7 @@ class TestStructuredDiagnosisSchemaContract: assert deserialized.sample == request.sample assert deserialized.options == request.options + @pytest.mark.skip(reason="JsonSchema requires Pulsar Record types, not dataclasses") def test_response_serialization_with_schema_matches(self): """Test response serialization with schema_matches array""" response = StructuredDataDiagnosisResponse( @@ -185,7 +187,7 @@ class TestStructuredDiagnosisSchemaContract: ) # Verify default value for new field - assert response.schema_matches is None # Defaults to None when not set + assert response.schema_matches == [] # Defaults to empty list when not set # Verify old fields still work assert response.detected_type == "json" @@ -221,7 +223,7 @@ class TestStructuredDiagnosisSchemaContract: ) assert error_response.error is not None - assert error_response.schema_matches is None # Default None when not set + assert error_response.schema_matches == [] # Default empty list when not set def test_all_operations_supported(self): """Verify all operations are properly supported in the contract""" diff --git a/tests/unit/test_rev_gateway/test_dispatcher.py b/tests/unit/test_rev_gateway/test_dispatcher.py index b4fa2eb1..2a9c8df0 100644 --- a/tests/unit/test_rev_gateway/test_dispatcher.py +++ b/tests/unit/test_rev_gateway/test_dispatcher.py @@ -72,7 +72,7 @@ class TestMessageDispatcher: assert dispatcher.max_workers == 10 assert dispatcher.semaphore._value == 10 assert dispatcher.active_tasks == set() - assert dispatcher.pulsar_client is None + assert dispatcher.backend is None assert dispatcher.dispatcher_manager is None assert len(dispatcher.service_mapping) > 0 @@ -86,7 +86,7 @@ class TestMessageDispatcher: @patch('trustgraph.rev_gateway.dispatcher.DispatcherManager') def test_message_dispatcher_initialization_with_pulsar_client(self, mock_dispatcher_manager): """Test MessageDispatcher initialization with pulsar_client and config_receiver""" - mock_pulsar_client = MagicMock() + mock_backend = MagicMock() mock_config_receiver = MagicMock() mock_dispatcher_instance = MagicMock() mock_dispatcher_manager.return_value = mock_dispatcher_instance @@ -94,14 +94,14 @@ class TestMessageDispatcher: dispatcher = MessageDispatcher( max_workers=8, config_receiver=mock_config_receiver, - pulsar_client=mock_pulsar_client + backend=mock_backend ) assert dispatcher.max_workers == 8 - assert dispatcher.pulsar_client == mock_pulsar_client + assert dispatcher.backend == mock_backend assert dispatcher.dispatcher_manager == mock_dispatcher_instance mock_dispatcher_manager.assert_called_once_with( - mock_pulsar_client, mock_config_receiver, prefix="rev-gateway" + mock_backend, mock_config_receiver, prefix="rev-gateway" ) def test_message_dispatcher_service_mapping(self): diff --git a/tests/unit/test_rev_gateway/test_rev_gateway_service.py b/tests/unit/test_rev_gateway/test_rev_gateway_service.py index d991ba45..23aff18e 100644 --- a/tests/unit/test_rev_gateway/test_rev_gateway_service.py +++ b/tests/unit/test_rev_gateway/test_rev_gateway_service.py @@ -16,11 +16,11 @@ class TestReverseGateway: @patch('trustgraph.rev_gateway.service.ConfigReceiver') @patch('trustgraph.rev_gateway.service.MessageDispatcher') - @patch('pulsar.Client') - def test_reverse_gateway_initialization_defaults(self, mock_pulsar_client, mock_dispatcher, mock_config_receiver): + @patch('trustgraph.rev_gateway.service.get_pubsub') + def test_reverse_gateway_initialization_defaults(self, mock_get_pubsub, mock_dispatcher, mock_config_receiver): """Test ReverseGateway initialization with default parameters""" - mock_client_instance = MagicMock() - mock_pulsar_client.return_value = mock_client_instance + mock_backend = MagicMock() + mock_get_pubsub.return_value = mock_backend gateway = ReverseGateway() @@ -38,11 +38,11 @@ class TestReverseGateway: @patch('trustgraph.rev_gateway.service.ConfigReceiver') @patch('trustgraph.rev_gateway.service.MessageDispatcher') - @patch('pulsar.Client') - def test_reverse_gateway_initialization_custom_params(self, mock_pulsar_client, mock_dispatcher, mock_config_receiver): + @patch('trustgraph.rev_gateway.service.get_pubsub') + def test_reverse_gateway_initialization_custom_params(self, mock_get_pubsub, mock_dispatcher, mock_config_receiver): """Test ReverseGateway initialization with custom parameters""" - mock_client_instance = MagicMock() - mock_pulsar_client.return_value = mock_client_instance + mock_backend = MagicMock() + mock_get_pubsub.return_value = mock_backend gateway = ReverseGateway( websocket_uri="wss://example.com:8080/websocket", @@ -65,11 +65,11 @@ class TestReverseGateway: @patch('trustgraph.rev_gateway.service.ConfigReceiver') @patch('trustgraph.rev_gateway.service.MessageDispatcher') - @patch('pulsar.Client') - def test_reverse_gateway_initialization_with_missing_path(self, mock_pulsar_client, mock_dispatcher, mock_config_receiver): + @patch('trustgraph.rev_gateway.service.get_pubsub') + def test_reverse_gateway_initialization_with_missing_path(self, mock_get_pubsub, mock_dispatcher, mock_config_receiver): """Test ReverseGateway initialization with WebSocket URI missing path""" - mock_client_instance = MagicMock() - mock_pulsar_client.return_value = mock_client_instance + mock_backend = MagicMock() + mock_get_pubsub.return_value = mock_backend gateway = ReverseGateway(websocket_uri="ws://example.com") @@ -78,53 +78,49 @@ class TestReverseGateway: @patch('trustgraph.rev_gateway.service.ConfigReceiver') @patch('trustgraph.rev_gateway.service.MessageDispatcher') - @patch('pulsar.Client') - def test_reverse_gateway_initialization_invalid_scheme(self, mock_pulsar_client, mock_dispatcher, mock_config_receiver): + @patch('trustgraph.rev_gateway.service.get_pubsub') + def test_reverse_gateway_initialization_invalid_scheme(self, mock_get_pubsub, mock_dispatcher, mock_config_receiver): """Test ReverseGateway initialization with invalid WebSocket scheme""" with pytest.raises(ValueError, match="WebSocket URI must use ws:// or wss:// scheme"): ReverseGateway(websocket_uri="http://example.com") @patch('trustgraph.rev_gateway.service.ConfigReceiver') @patch('trustgraph.rev_gateway.service.MessageDispatcher') - @patch('pulsar.Client') - def test_reverse_gateway_initialization_missing_hostname(self, mock_pulsar_client, mock_dispatcher, mock_config_receiver): + @patch('trustgraph.rev_gateway.service.get_pubsub') + def test_reverse_gateway_initialization_missing_hostname(self, mock_get_pubsub, mock_dispatcher, mock_config_receiver): """Test ReverseGateway initialization with missing hostname""" with pytest.raises(ValueError, match="WebSocket URI must include hostname"): ReverseGateway(websocket_uri="ws://") @patch('trustgraph.rev_gateway.service.ConfigReceiver') @patch('trustgraph.rev_gateway.service.MessageDispatcher') - @patch('pulsar.Client') - def test_reverse_gateway_pulsar_client_with_auth(self, mock_pulsar_client, mock_dispatcher, mock_config_receiver): - """Test ReverseGateway creates Pulsar client with authentication""" - mock_client_instance = MagicMock() - mock_pulsar_client.return_value = mock_client_instance - - with patch('pulsar.AuthenticationToken') as mock_auth: - mock_auth_instance = MagicMock() - mock_auth.return_value = mock_auth_instance - - gateway = ReverseGateway( - pulsar_api_key="test-key", - pulsar_listener="test-listener" - ) - - mock_auth.assert_called_once_with("test-key") - mock_pulsar_client.assert_called_once_with( - "pulsar://pulsar:6650", - listener_name="test-listener", - authentication=mock_auth_instance - ) + @patch('trustgraph.rev_gateway.service.get_pubsub') + def test_reverse_gateway_pulsar_client_with_auth(self, mock_get_pubsub, mock_dispatcher, mock_config_receiver): + """Test ReverseGateway creates backend with authentication""" + mock_backend = MagicMock() + mock_get_pubsub.return_value = mock_backend + + gateway = ReverseGateway( + pulsar_api_key="test-key", + pulsar_listener="test-listener" + ) + + # Verify get_pubsub was called with the correct parameters + mock_get_pubsub.assert_called_once_with( + pulsar_host="pulsar://pulsar:6650", + pulsar_api_key="test-key", + pulsar_listener="test-listener" + ) @patch('trustgraph.rev_gateway.service.ConfigReceiver') @patch('trustgraph.rev_gateway.service.MessageDispatcher') - @patch('pulsar.Client') + @patch('trustgraph.rev_gateway.service.get_pubsub') @patch('trustgraph.rev_gateway.service.ClientSession') @pytest.mark.asyncio - async def test_reverse_gateway_connect_success(self, mock_session_class, mock_pulsar_client, mock_dispatcher, mock_config_receiver): + async def test_reverse_gateway_connect_success(self, mock_session_class, mock_get_pubsub, mock_dispatcher, mock_config_receiver): """Test ReverseGateway successful connection""" - mock_client_instance = MagicMock() - mock_pulsar_client.return_value = mock_client_instance + mock_backend = MagicMock() + mock_get_pubsub.return_value = mock_backend mock_session = AsyncMock() mock_ws = AsyncMock() @@ -142,13 +138,13 @@ class TestReverseGateway: @patch('trustgraph.rev_gateway.service.ConfigReceiver') @patch('trustgraph.rev_gateway.service.MessageDispatcher') - @patch('pulsar.Client') + @patch('trustgraph.rev_gateway.service.get_pubsub') @patch('trustgraph.rev_gateway.service.ClientSession') @pytest.mark.asyncio - async def test_reverse_gateway_connect_failure(self, mock_session_class, mock_pulsar_client, mock_dispatcher, mock_config_receiver): + async def test_reverse_gateway_connect_failure(self, mock_session_class, mock_get_pubsub, mock_dispatcher, mock_config_receiver): """Test ReverseGateway connection failure""" - mock_client_instance = MagicMock() - mock_pulsar_client.return_value = mock_client_instance + mock_backend = MagicMock() + mock_get_pubsub.return_value = mock_backend mock_session = AsyncMock() mock_session.ws_connect.side_effect = Exception("Connection failed") @@ -162,12 +158,12 @@ class TestReverseGateway: @patch('trustgraph.rev_gateway.service.ConfigReceiver') @patch('trustgraph.rev_gateway.service.MessageDispatcher') - @patch('pulsar.Client') + @patch('trustgraph.rev_gateway.service.get_pubsub') @pytest.mark.asyncio - async def test_reverse_gateway_disconnect(self, mock_pulsar_client, mock_dispatcher, mock_config_receiver): + async def test_reverse_gateway_disconnect(self, mock_get_pubsub, mock_dispatcher, mock_config_receiver): """Test ReverseGateway disconnect""" - mock_client_instance = MagicMock() - mock_pulsar_client.return_value = mock_client_instance + mock_backend = MagicMock() + mock_get_pubsub.return_value = mock_backend gateway = ReverseGateway() @@ -189,12 +185,12 @@ class TestReverseGateway: @patch('trustgraph.rev_gateway.service.ConfigReceiver') @patch('trustgraph.rev_gateway.service.MessageDispatcher') - @patch('pulsar.Client') + @patch('trustgraph.rev_gateway.service.get_pubsub') @pytest.mark.asyncio - async def test_reverse_gateway_send_message(self, mock_pulsar_client, mock_dispatcher, mock_config_receiver): + async def test_reverse_gateway_send_message(self, mock_get_pubsub, mock_dispatcher, mock_config_receiver): """Test ReverseGateway send message""" - mock_client_instance = MagicMock() - mock_pulsar_client.return_value = mock_client_instance + mock_backend = MagicMock() + mock_get_pubsub.return_value = mock_backend gateway = ReverseGateway() @@ -211,12 +207,12 @@ class TestReverseGateway: @patch('trustgraph.rev_gateway.service.ConfigReceiver') @patch('trustgraph.rev_gateway.service.MessageDispatcher') - @patch('pulsar.Client') + @patch('trustgraph.rev_gateway.service.get_pubsub') @pytest.mark.asyncio - async def test_reverse_gateway_send_message_closed_connection(self, mock_pulsar_client, mock_dispatcher, mock_config_receiver): + async def test_reverse_gateway_send_message_closed_connection(self, mock_get_pubsub, mock_dispatcher, mock_config_receiver): """Test ReverseGateway send message with closed connection""" - mock_client_instance = MagicMock() - mock_pulsar_client.return_value = mock_client_instance + mock_backend = MagicMock() + mock_get_pubsub.return_value = mock_backend gateway = ReverseGateway() @@ -234,12 +230,12 @@ class TestReverseGateway: @patch('trustgraph.rev_gateway.service.ConfigReceiver') @patch('trustgraph.rev_gateway.service.MessageDispatcher') - @patch('pulsar.Client') + @patch('trustgraph.rev_gateway.service.get_pubsub') @pytest.mark.asyncio - async def test_reverse_gateway_handle_message(self, mock_pulsar_client, mock_dispatcher, mock_config_receiver): + async def test_reverse_gateway_handle_message(self, mock_get_pubsub, mock_dispatcher, mock_config_receiver): """Test ReverseGateway handle message""" - mock_client_instance = MagicMock() - mock_pulsar_client.return_value = mock_client_instance + mock_backend = MagicMock() + mock_get_pubsub.return_value = mock_backend mock_dispatcher_instance = AsyncMock() mock_dispatcher_instance.handle_message.return_value = {"response": "success"} @@ -263,12 +259,12 @@ class TestReverseGateway: @patch('trustgraph.rev_gateway.service.ConfigReceiver') @patch('trustgraph.rev_gateway.service.MessageDispatcher') - @patch('pulsar.Client') + @patch('trustgraph.rev_gateway.service.get_pubsub') @pytest.mark.asyncio - async def test_reverse_gateway_handle_message_invalid_json(self, mock_pulsar_client, mock_dispatcher, mock_config_receiver): + async def test_reverse_gateway_handle_message_invalid_json(self, mock_get_pubsub, mock_dispatcher, mock_config_receiver): """Test ReverseGateway handle message with invalid JSON""" - mock_client_instance = MagicMock() - mock_pulsar_client.return_value = mock_client_instance + mock_backend = MagicMock() + mock_get_pubsub.return_value = mock_backend gateway = ReverseGateway() @@ -285,12 +281,12 @@ class TestReverseGateway: @patch('trustgraph.rev_gateway.service.ConfigReceiver') @patch('trustgraph.rev_gateway.service.MessageDispatcher') - @patch('pulsar.Client') + @patch('trustgraph.rev_gateway.service.get_pubsub') @pytest.mark.asyncio - async def test_reverse_gateway_listen_text_message(self, mock_pulsar_client, mock_dispatcher, mock_config_receiver): + async def test_reverse_gateway_listen_text_message(self, mock_get_pubsub, mock_dispatcher, mock_config_receiver): """Test ReverseGateway listen with text message""" - mock_client_instance = MagicMock() - mock_pulsar_client.return_value = mock_client_instance + mock_backend = MagicMock() + mock_get_pubsub.return_value = mock_backend gateway = ReverseGateway() gateway.running = True @@ -318,12 +314,12 @@ class TestReverseGateway: @patch('trustgraph.rev_gateway.service.ConfigReceiver') @patch('trustgraph.rev_gateway.service.MessageDispatcher') - @patch('pulsar.Client') + @patch('trustgraph.rev_gateway.service.get_pubsub') @pytest.mark.asyncio - async def test_reverse_gateway_listen_binary_message(self, mock_pulsar_client, mock_dispatcher, mock_config_receiver): + async def test_reverse_gateway_listen_binary_message(self, mock_get_pubsub, mock_dispatcher, mock_config_receiver): """Test ReverseGateway listen with binary message""" - mock_client_instance = MagicMock() - mock_pulsar_client.return_value = mock_client_instance + mock_backend = MagicMock() + mock_get_pubsub.return_value = mock_backend gateway = ReverseGateway() gateway.running = True @@ -351,12 +347,12 @@ class TestReverseGateway: @patch('trustgraph.rev_gateway.service.ConfigReceiver') @patch('trustgraph.rev_gateway.service.MessageDispatcher') - @patch('pulsar.Client') + @patch('trustgraph.rev_gateway.service.get_pubsub') @pytest.mark.asyncio - async def test_reverse_gateway_listen_close_message(self, mock_pulsar_client, mock_dispatcher, mock_config_receiver): + async def test_reverse_gateway_listen_close_message(self, mock_get_pubsub, mock_dispatcher, mock_config_receiver): """Test ReverseGateway listen with close message""" - mock_client_instance = MagicMock() - mock_pulsar_client.return_value = mock_client_instance + mock_backend = MagicMock() + mock_get_pubsub.return_value = mock_backend gateway = ReverseGateway() gateway.running = True @@ -383,36 +379,36 @@ class TestReverseGateway: @patch('trustgraph.rev_gateway.service.ConfigReceiver') @patch('trustgraph.rev_gateway.service.MessageDispatcher') - @patch('pulsar.Client') + @patch('trustgraph.rev_gateway.service.get_pubsub') @pytest.mark.asyncio - async def test_reverse_gateway_shutdown(self, mock_pulsar_client, mock_dispatcher, mock_config_receiver): + async def test_reverse_gateway_shutdown(self, mock_get_pubsub, mock_dispatcher, mock_config_receiver): """Test ReverseGateway shutdown""" - mock_client_instance = MagicMock() - mock_pulsar_client.return_value = mock_client_instance - + mock_backend = MagicMock() + mock_get_pubsub.return_value = mock_backend + mock_dispatcher_instance = AsyncMock() mock_dispatcher.return_value = mock_dispatcher_instance - + gateway = ReverseGateway() gateway.running = True - + # Mock disconnect gateway.disconnect = AsyncMock() - + await gateway.shutdown() - + assert gateway.running is False mock_dispatcher_instance.shutdown.assert_called_once() gateway.disconnect.assert_called_once() - mock_client_instance.close.assert_called_once() + mock_backend.close.assert_called_once() @patch('trustgraph.rev_gateway.service.ConfigReceiver') @patch('trustgraph.rev_gateway.service.MessageDispatcher') - @patch('pulsar.Client') - def test_reverse_gateway_stop(self, mock_pulsar_client, mock_dispatcher, mock_config_receiver): + @patch('trustgraph.rev_gateway.service.get_pubsub') + def test_reverse_gateway_stop(self, mock_get_pubsub, mock_dispatcher, mock_config_receiver): """Test ReverseGateway stop""" - mock_client_instance = MagicMock() - mock_pulsar_client.return_value = mock_client_instance + mock_backend = MagicMock() + mock_get_pubsub.return_value = mock_backend gateway = ReverseGateway() gateway.running = True @@ -427,12 +423,12 @@ class TestReverseGatewayRun: @patch('trustgraph.rev_gateway.service.ConfigReceiver') @patch('trustgraph.rev_gateway.service.MessageDispatcher') - @patch('pulsar.Client') + @patch('trustgraph.rev_gateway.service.get_pubsub') @pytest.mark.asyncio - async def test_reverse_gateway_run_successful_cycle(self, mock_pulsar_client, mock_dispatcher, mock_config_receiver): + async def test_reverse_gateway_run_successful_cycle(self, mock_get_pubsub, mock_dispatcher, mock_config_receiver): """Test ReverseGateway run method with successful connect/listen cycle""" - mock_client_instance = MagicMock() - mock_pulsar_client.return_value = mock_client_instance + mock_backend = MagicMock() + mock_get_pubsub.return_value = mock_backend mock_config_receiver_instance = AsyncMock() mock_config_receiver.return_value = mock_config_receiver_instance diff --git a/trustgraph-base/trustgraph/messaging/translators/diagnosis.py b/trustgraph-base/trustgraph/messaging/translators/diagnosis.py index 92bad16f..2cbe572f 100644 --- a/trustgraph-base/trustgraph/messaging/translators/diagnosis.py +++ b/trustgraph-base/trustgraph/messaging/translators/diagnosis.py @@ -57,7 +57,7 @@ class StructuredDataDiagnosisResponseTranslator(MessageTranslator): result["descriptor"] = obj.descriptor if obj.metadata: result["metadata"] = obj.metadata - if obj.schema_matches is not None: + if obj.schema_matches: # Only include if non-empty list result["schema-matches"] = obj.schema_matches return result