mirror of
https://github.com/trustgraph-ai/trustgraph.git
synced 2026-07-22 03:31:02 +02:00
Gateway tests
This commit is contained in:
parent
9661736a65
commit
4e71679e5a
6 changed files with 733 additions and 0 deletions
165
tests/unit/test_gateway/test_dispatch_mux.py
Normal file
165
tests/unit/test_gateway/test_dispatch_mux.py
Normal file
|
|
@ -0,0 +1,165 @@
|
|||
"""
|
||||
Tests for Gateway Dispatch Mux
|
||||
"""
|
||||
|
||||
import pytest
|
||||
import asyncio
|
||||
from unittest.mock import MagicMock, AsyncMock
|
||||
|
||||
from trustgraph.gateway.dispatch.mux import Mux, MAX_QUEUE_SIZE
|
||||
|
||||
|
||||
class TestMux:
|
||||
"""Test cases for Mux class"""
|
||||
|
||||
def test_mux_initialization(self):
|
||||
"""Test Mux initialization"""
|
||||
mock_dispatcher_manager = MagicMock()
|
||||
mock_ws = MagicMock()
|
||||
mock_running = MagicMock()
|
||||
|
||||
mux = Mux(
|
||||
dispatcher_manager=mock_dispatcher_manager,
|
||||
ws=mock_ws,
|
||||
running=mock_running
|
||||
)
|
||||
|
||||
assert mux.dispatcher_manager == mock_dispatcher_manager
|
||||
assert mux.ws == mock_ws
|
||||
assert mux.running == mock_running
|
||||
assert isinstance(mux.q, asyncio.Queue)
|
||||
assert mux.q.maxsize == MAX_QUEUE_SIZE
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_mux_destroy_with_websocket(self):
|
||||
"""Test Mux destroy method with websocket"""
|
||||
mock_dispatcher_manager = MagicMock()
|
||||
mock_ws = AsyncMock()
|
||||
mock_running = MagicMock()
|
||||
|
||||
mux = Mux(
|
||||
dispatcher_manager=mock_dispatcher_manager,
|
||||
ws=mock_ws,
|
||||
running=mock_running
|
||||
)
|
||||
|
||||
# Call destroy
|
||||
await mux.destroy()
|
||||
|
||||
# Verify running.stop was called
|
||||
mock_running.stop.assert_called_once()
|
||||
|
||||
# Verify websocket close was called
|
||||
mock_ws.close.assert_called_once()
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_mux_destroy_without_websocket(self):
|
||||
"""Test Mux destroy method without websocket"""
|
||||
mock_dispatcher_manager = MagicMock()
|
||||
mock_running = MagicMock()
|
||||
|
||||
mux = Mux(
|
||||
dispatcher_manager=mock_dispatcher_manager,
|
||||
ws=None,
|
||||
running=mock_running
|
||||
)
|
||||
|
||||
# Call destroy
|
||||
await mux.destroy()
|
||||
|
||||
# Verify running.stop was called
|
||||
mock_running.stop.assert_called_once()
|
||||
# No websocket to close
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_mux_receive_valid_message(self):
|
||||
"""Test Mux receive method with valid message"""
|
||||
mock_dispatcher_manager = MagicMock()
|
||||
mock_ws = MagicMock()
|
||||
mock_running = MagicMock()
|
||||
|
||||
mux = Mux(
|
||||
dispatcher_manager=mock_dispatcher_manager,
|
||||
ws=mock_ws,
|
||||
running=mock_running
|
||||
)
|
||||
|
||||
# Mock message with valid JSON
|
||||
mock_msg = MagicMock()
|
||||
mock_msg.json.return_value = {
|
||||
"request": {"type": "test"},
|
||||
"id": "test-id-123"
|
||||
}
|
||||
|
||||
# Call receive
|
||||
await mux.receive(mock_msg)
|
||||
|
||||
# Verify json was called
|
||||
mock_msg.json.assert_called_once()
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_mux_receive_message_without_request(self):
|
||||
"""Test Mux receive method with message missing request field"""
|
||||
mock_dispatcher_manager = MagicMock()
|
||||
mock_ws = MagicMock()
|
||||
mock_running = MagicMock()
|
||||
|
||||
mux = Mux(
|
||||
dispatcher_manager=mock_dispatcher_manager,
|
||||
ws=mock_ws,
|
||||
running=mock_running
|
||||
)
|
||||
|
||||
# Mock message without request field
|
||||
mock_msg = MagicMock()
|
||||
mock_msg.json.return_value = {
|
||||
"id": "test-id-123"
|
||||
}
|
||||
|
||||
# receive method should handle the RuntimeError internally
|
||||
# Based on the code, it seems to catch exceptions
|
||||
await mux.receive(mock_msg)
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_mux_receive_message_without_id(self):
|
||||
"""Test Mux receive method with message missing id field"""
|
||||
mock_dispatcher_manager = MagicMock()
|
||||
mock_ws = MagicMock()
|
||||
mock_running = MagicMock()
|
||||
|
||||
mux = Mux(
|
||||
dispatcher_manager=mock_dispatcher_manager,
|
||||
ws=mock_ws,
|
||||
running=mock_running
|
||||
)
|
||||
|
||||
# Mock message without id field
|
||||
mock_msg = MagicMock()
|
||||
mock_msg.json.return_value = {
|
||||
"request": {"type": "test"}
|
||||
}
|
||||
|
||||
# receive method should handle the RuntimeError internally
|
||||
await mux.receive(mock_msg)
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_mux_receive_invalid_json(self):
|
||||
"""Test Mux receive method with invalid JSON"""
|
||||
mock_dispatcher_manager = MagicMock()
|
||||
mock_ws = MagicMock()
|
||||
mock_running = MagicMock()
|
||||
|
||||
mux = Mux(
|
||||
dispatcher_manager=mock_dispatcher_manager,
|
||||
ws=mock_ws,
|
||||
running=mock_running
|
||||
)
|
||||
|
||||
# Mock message with invalid JSON
|
||||
mock_msg = MagicMock()
|
||||
mock_msg.json.side_effect = ValueError("Invalid JSON")
|
||||
|
||||
# receive method should handle the ValueError internally
|
||||
await mux.receive(mock_msg)
|
||||
|
||||
mock_msg.json.assert_called_once()
|
||||
115
tests/unit/test_gateway/test_dispatch_requestor.py
Normal file
115
tests/unit/test_gateway/test_dispatch_requestor.py
Normal file
|
|
@ -0,0 +1,115 @@
|
|||
"""
|
||||
Tests for Gateway Service Requestor
|
||||
"""
|
||||
|
||||
import pytest
|
||||
from unittest.mock import MagicMock, AsyncMock, patch
|
||||
|
||||
from trustgraph.gateway.dispatch.requestor import ServiceRequestor
|
||||
|
||||
|
||||
class TestServiceRequestor:
|
||||
"""Test cases for ServiceRequestor class"""
|
||||
|
||||
@patch('trustgraph.gateway.dispatch.requestor.Publisher')
|
||||
@patch('trustgraph.gateway.dispatch.requestor.Subscriber')
|
||||
def test_service_requestor_initialization(self, mock_subscriber, mock_publisher):
|
||||
"""Test ServiceRequestor initialization"""
|
||||
mock_pulsar_client = MagicMock()
|
||||
mock_request_schema = MagicMock()
|
||||
mock_response_schema = MagicMock()
|
||||
|
||||
requestor = ServiceRequestor(
|
||||
pulsar_client=mock_pulsar_client,
|
||||
request_queue="test-request-queue",
|
||||
request_schema=mock_request_schema,
|
||||
response_queue="test-response-queue",
|
||||
response_schema=mock_response_schema,
|
||||
subscription="test-subscription",
|
||||
consumer_name="test-consumer",
|
||||
timeout=300
|
||||
)
|
||||
|
||||
# Verify Publisher was created correctly
|
||||
mock_publisher.assert_called_once_with(
|
||||
mock_pulsar_client, "test-request-queue", schema=mock_request_schema
|
||||
)
|
||||
|
||||
# Verify Subscriber was created correctly
|
||||
mock_subscriber.assert_called_once_with(
|
||||
mock_pulsar_client, "test-response-queue",
|
||||
"test-subscription", "test-consumer", mock_response_schema
|
||||
)
|
||||
|
||||
assert requestor.timeout == 300
|
||||
assert requestor.running is True
|
||||
|
||||
@patch('trustgraph.gateway.dispatch.requestor.Publisher')
|
||||
@patch('trustgraph.gateway.dispatch.requestor.Subscriber')
|
||||
def test_service_requestor_with_defaults(self, mock_subscriber, mock_publisher):
|
||||
"""Test ServiceRequestor initialization with default parameters"""
|
||||
mock_pulsar_client = MagicMock()
|
||||
mock_request_schema = MagicMock()
|
||||
mock_response_schema = MagicMock()
|
||||
|
||||
requestor = ServiceRequestor(
|
||||
pulsar_client=mock_pulsar_client,
|
||||
request_queue="test-queue",
|
||||
request_schema=mock_request_schema,
|
||||
response_queue="response-queue",
|
||||
response_schema=mock_response_schema
|
||||
)
|
||||
|
||||
# Verify default values
|
||||
mock_subscriber.assert_called_once_with(
|
||||
mock_pulsar_client, "response-queue",
|
||||
"api-gateway", "api-gateway", mock_response_schema
|
||||
)
|
||||
assert requestor.timeout == 600 # Default timeout
|
||||
|
||||
@patch('trustgraph.gateway.dispatch.requestor.Publisher')
|
||||
@patch('trustgraph.gateway.dispatch.requestor.Subscriber')
|
||||
@pytest.mark.asyncio
|
||||
async def test_service_requestor_start(self, mock_subscriber, mock_publisher):
|
||||
"""Test ServiceRequestor start method"""
|
||||
mock_pulsar_client = MagicMock()
|
||||
mock_sub_instance = AsyncMock()
|
||||
mock_subscriber.return_value = mock_sub_instance
|
||||
|
||||
requestor = ServiceRequestor(
|
||||
pulsar_client=mock_pulsar_client,
|
||||
request_queue="test-queue",
|
||||
request_schema=MagicMock(),
|
||||
response_queue="response-queue",
|
||||
response_schema=MagicMock()
|
||||
)
|
||||
|
||||
# Call start
|
||||
await requestor.start()
|
||||
|
||||
# Verify subscriber start was called
|
||||
mock_sub_instance.start.assert_called_once()
|
||||
assert requestor.running is True
|
||||
|
||||
@patch('trustgraph.gateway.dispatch.requestor.Publisher')
|
||||
@patch('trustgraph.gateway.dispatch.requestor.Subscriber')
|
||||
def test_service_requestor_attributes(self, mock_subscriber, mock_publisher):
|
||||
"""Test ServiceRequestor has correct attributes"""
|
||||
mock_pulsar_client = MagicMock()
|
||||
mock_pub_instance = MagicMock()
|
||||
mock_sub_instance = MagicMock()
|
||||
mock_publisher.return_value = mock_pub_instance
|
||||
mock_subscriber.return_value = mock_sub_instance
|
||||
|
||||
requestor = ServiceRequestor(
|
||||
pulsar_client=mock_pulsar_client,
|
||||
request_queue="test-queue",
|
||||
request_schema=MagicMock(),
|
||||
response_queue="response-queue",
|
||||
response_schema=MagicMock()
|
||||
)
|
||||
|
||||
# Verify attributes are set correctly
|
||||
assert requestor.pub == mock_pub_instance
|
||||
assert requestor.sub == mock_sub_instance
|
||||
assert requestor.running is True
|
||||
120
tests/unit/test_gateway/test_dispatch_sender.py
Normal file
120
tests/unit/test_gateway/test_dispatch_sender.py
Normal file
|
|
@ -0,0 +1,120 @@
|
|||
"""
|
||||
Tests for Gateway Service Sender
|
||||
"""
|
||||
|
||||
import pytest
|
||||
from unittest.mock import MagicMock, AsyncMock, patch
|
||||
|
||||
from trustgraph.gateway.dispatch.sender import ServiceSender
|
||||
|
||||
|
||||
class TestServiceSender:
|
||||
"""Test cases for ServiceSender class"""
|
||||
|
||||
@patch('trustgraph.gateway.dispatch.sender.Publisher')
|
||||
def test_service_sender_initialization(self, mock_publisher):
|
||||
"""Test ServiceSender initialization"""
|
||||
mock_pulsar_client = MagicMock()
|
||||
mock_schema = MagicMock()
|
||||
|
||||
sender = ServiceSender(
|
||||
pulsar_client=mock_pulsar_client,
|
||||
queue="test-queue",
|
||||
schema=mock_schema
|
||||
)
|
||||
|
||||
# Verify Publisher was created correctly
|
||||
mock_publisher.assert_called_once_with(
|
||||
mock_pulsar_client, "test-queue", schema=mock_schema
|
||||
)
|
||||
|
||||
@patch('trustgraph.gateway.dispatch.sender.Publisher')
|
||||
@pytest.mark.asyncio
|
||||
async def test_service_sender_start(self, mock_publisher):
|
||||
"""Test ServiceSender start method"""
|
||||
mock_pub_instance = AsyncMock()
|
||||
mock_publisher.return_value = mock_pub_instance
|
||||
|
||||
sender = ServiceSender(
|
||||
pulsar_client=MagicMock(),
|
||||
queue="test-queue",
|
||||
schema=MagicMock()
|
||||
)
|
||||
|
||||
# Call start
|
||||
await sender.start()
|
||||
|
||||
# Verify publisher start was called
|
||||
mock_pub_instance.start.assert_called_once()
|
||||
|
||||
@patch('trustgraph.gateway.dispatch.sender.Publisher')
|
||||
@pytest.mark.asyncio
|
||||
async def test_service_sender_stop(self, mock_publisher):
|
||||
"""Test ServiceSender stop method"""
|
||||
mock_pub_instance = AsyncMock()
|
||||
mock_publisher.return_value = mock_pub_instance
|
||||
|
||||
sender = ServiceSender(
|
||||
pulsar_client=MagicMock(),
|
||||
queue="test-queue",
|
||||
schema=MagicMock()
|
||||
)
|
||||
|
||||
# Call stop
|
||||
await sender.stop()
|
||||
|
||||
# Verify publisher stop was called
|
||||
mock_pub_instance.stop.assert_called_once()
|
||||
|
||||
@patch('trustgraph.gateway.dispatch.sender.Publisher')
|
||||
def test_service_sender_to_request_not_implemented(self, mock_publisher):
|
||||
"""Test ServiceSender to_request method raises RuntimeError"""
|
||||
sender = ServiceSender(
|
||||
pulsar_client=MagicMock(),
|
||||
queue="test-queue",
|
||||
schema=MagicMock()
|
||||
)
|
||||
|
||||
with pytest.raises(RuntimeError, match="Not defined"):
|
||||
sender.to_request({"test": "request"})
|
||||
|
||||
@patch('trustgraph.gateway.dispatch.sender.Publisher')
|
||||
@pytest.mark.asyncio
|
||||
async def test_service_sender_process(self, mock_publisher):
|
||||
"""Test ServiceSender process method"""
|
||||
mock_pub_instance = AsyncMock()
|
||||
mock_publisher.return_value = mock_pub_instance
|
||||
|
||||
# Create a concrete sender that implements to_request
|
||||
class ConcreteSender(ServiceSender):
|
||||
def to_request(self, request):
|
||||
return {"processed": request}
|
||||
|
||||
sender = ConcreteSender(
|
||||
pulsar_client=MagicMock(),
|
||||
queue="test-queue",
|
||||
schema=MagicMock()
|
||||
)
|
||||
|
||||
test_request = {"test": "data"}
|
||||
|
||||
# Call process
|
||||
await sender.process(test_request)
|
||||
|
||||
# Verify publisher send was called with processed request
|
||||
mock_pub_instance.send.assert_called_once_with(None, {"processed": test_request})
|
||||
|
||||
@patch('trustgraph.gateway.dispatch.sender.Publisher')
|
||||
def test_service_sender_attributes(self, mock_publisher):
|
||||
"""Test ServiceSender has correct attributes"""
|
||||
mock_pub_instance = MagicMock()
|
||||
mock_publisher.return_value = mock_pub_instance
|
||||
|
||||
sender = ServiceSender(
|
||||
pulsar_client=MagicMock(),
|
||||
queue="test-queue",
|
||||
schema=MagicMock()
|
||||
)
|
||||
|
||||
# Verify attributes are set correctly
|
||||
assert sender.pub == mock_pub_instance
|
||||
85
tests/unit/test_gateway/test_endpoint_manager.py
Normal file
85
tests/unit/test_gateway/test_endpoint_manager.py
Normal file
|
|
@ -0,0 +1,85 @@
|
|||
"""
|
||||
Tests for Gateway Endpoint Manager
|
||||
"""
|
||||
|
||||
import pytest
|
||||
from unittest.mock import MagicMock
|
||||
|
||||
from trustgraph.gateway.endpoint.manager import EndpointManager
|
||||
|
||||
|
||||
class TestEndpointManager:
|
||||
"""Test cases for EndpointManager class"""
|
||||
|
||||
def test_endpoint_manager_initialization(self):
|
||||
"""Test EndpointManager initialization creates all endpoints"""
|
||||
mock_dispatcher_manager = MagicMock()
|
||||
mock_auth = MagicMock()
|
||||
|
||||
# Mock dispatcher methods
|
||||
mock_dispatcher_manager.dispatch_global_service.return_value = MagicMock()
|
||||
mock_dispatcher_manager.dispatch_socket.return_value = MagicMock()
|
||||
mock_dispatcher_manager.dispatch_flow_service.return_value = MagicMock()
|
||||
mock_dispatcher_manager.dispatch_flow_import.return_value = MagicMock()
|
||||
mock_dispatcher_manager.dispatch_flow_export.return_value = MagicMock()
|
||||
mock_dispatcher_manager.dispatch_flow_stream.return_value = MagicMock()
|
||||
|
||||
manager = EndpointManager(
|
||||
dispatcher_manager=mock_dispatcher_manager,
|
||||
auth=mock_auth,
|
||||
prometheus_url="http://prometheus:9090",
|
||||
timeout=300
|
||||
)
|
||||
|
||||
assert manager.dispatcher_manager == mock_dispatcher_manager
|
||||
assert manager.timeout == 300
|
||||
assert manager.services == {}
|
||||
assert len(manager.endpoints) > 0 # Should have multiple endpoints
|
||||
|
||||
def test_endpoint_manager_with_default_timeout(self):
|
||||
"""Test EndpointManager with default timeout value"""
|
||||
mock_dispatcher_manager = MagicMock()
|
||||
mock_auth = MagicMock()
|
||||
|
||||
# Mock dispatcher methods
|
||||
mock_dispatcher_manager.dispatch_global_service.return_value = MagicMock()
|
||||
mock_dispatcher_manager.dispatch_socket.return_value = MagicMock()
|
||||
mock_dispatcher_manager.dispatch_flow_service.return_value = MagicMock()
|
||||
mock_dispatcher_manager.dispatch_flow_import.return_value = MagicMock()
|
||||
mock_dispatcher_manager.dispatch_flow_export.return_value = MagicMock()
|
||||
mock_dispatcher_manager.dispatch_flow_stream.return_value = MagicMock()
|
||||
|
||||
manager = EndpointManager(
|
||||
dispatcher_manager=mock_dispatcher_manager,
|
||||
auth=mock_auth,
|
||||
prometheus_url="http://prometheus:9090"
|
||||
)
|
||||
|
||||
assert manager.timeout == 600 # Default value
|
||||
|
||||
def test_endpoint_manager_dispatcher_calls(self):
|
||||
"""Test EndpointManager calls all required dispatcher methods"""
|
||||
mock_dispatcher_manager = MagicMock()
|
||||
mock_auth = MagicMock()
|
||||
|
||||
# Mock dispatcher methods
|
||||
mock_dispatcher_manager.dispatch_global_service.return_value = MagicMock()
|
||||
mock_dispatcher_manager.dispatch_socket.return_value = MagicMock()
|
||||
mock_dispatcher_manager.dispatch_flow_service.return_value = MagicMock()
|
||||
mock_dispatcher_manager.dispatch_flow_import.return_value = MagicMock()
|
||||
mock_dispatcher_manager.dispatch_flow_export.return_value = MagicMock()
|
||||
mock_dispatcher_manager.dispatch_flow_stream.return_value = MagicMock()
|
||||
|
||||
EndpointManager(
|
||||
dispatcher_manager=mock_dispatcher_manager,
|
||||
auth=mock_auth,
|
||||
prometheus_url="http://test:9090"
|
||||
)
|
||||
|
||||
# Verify all dispatcher methods were called during initialization
|
||||
mock_dispatcher_manager.dispatch_global_service.assert_called_once()
|
||||
mock_dispatcher_manager.dispatch_socket.assert_called()
|
||||
mock_dispatcher_manager.dispatch_flow_service.assert_called_once()
|
||||
mock_dispatcher_manager.dispatch_flow_import.assert_called()
|
||||
mock_dispatcher_manager.dispatch_flow_export.assert_called()
|
||||
mock_dispatcher_manager.dispatch_flow_stream.assert_called()
|
||||
124
tests/unit/test_gateway/test_endpoint_socket.py
Normal file
124
tests/unit/test_gateway/test_endpoint_socket.py
Normal file
|
|
@ -0,0 +1,124 @@
|
|||
"""
|
||||
Tests for Gateway Socket Endpoint
|
||||
"""
|
||||
|
||||
import pytest
|
||||
from unittest.mock import MagicMock, AsyncMock
|
||||
from aiohttp import WSMsgType
|
||||
|
||||
from trustgraph.gateway.endpoint.socket import SocketEndpoint
|
||||
|
||||
|
||||
class TestSocketEndpoint:
|
||||
"""Test cases for SocketEndpoint class"""
|
||||
|
||||
def test_socket_endpoint_initialization(self):
|
||||
"""Test SocketEndpoint initialization"""
|
||||
mock_auth = MagicMock()
|
||||
mock_dispatcher = MagicMock()
|
||||
|
||||
endpoint = SocketEndpoint(
|
||||
endpoint_path="/api/socket",
|
||||
auth=mock_auth,
|
||||
dispatcher=mock_dispatcher
|
||||
)
|
||||
|
||||
assert endpoint.path == "/api/socket"
|
||||
assert endpoint.auth == mock_auth
|
||||
assert endpoint.dispatcher == mock_dispatcher
|
||||
assert endpoint.operation == "socket"
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_worker_method(self):
|
||||
"""Test SocketEndpoint worker method"""
|
||||
mock_auth = MagicMock()
|
||||
mock_dispatcher = AsyncMock()
|
||||
|
||||
endpoint = SocketEndpoint("/api/socket", mock_auth, mock_dispatcher)
|
||||
|
||||
mock_ws = MagicMock()
|
||||
mock_running = MagicMock()
|
||||
|
||||
# Call worker method
|
||||
await endpoint.worker(mock_ws, mock_dispatcher, mock_running)
|
||||
|
||||
# Verify dispatcher.run was called
|
||||
mock_dispatcher.run.assert_called_once()
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_listener_method_with_text_message(self):
|
||||
"""Test SocketEndpoint listener method with text message"""
|
||||
mock_auth = MagicMock()
|
||||
mock_dispatcher = AsyncMock()
|
||||
|
||||
endpoint = SocketEndpoint("/api/socket", mock_auth, mock_dispatcher)
|
||||
|
||||
# Mock websocket with text message
|
||||
mock_msg = MagicMock()
|
||||
mock_msg.type = WSMsgType.TEXT
|
||||
|
||||
# Create async iterator for websocket
|
||||
async def async_iter():
|
||||
yield mock_msg
|
||||
|
||||
mock_ws = MagicMock()
|
||||
mock_ws.__aiter__ = lambda: async_iter()
|
||||
mock_running = MagicMock()
|
||||
|
||||
# Call listener method
|
||||
await endpoint.listener(mock_ws, mock_dispatcher, mock_running)
|
||||
|
||||
# Verify dispatcher.receive was called with the message
|
||||
mock_dispatcher.receive.assert_called_once_with(mock_msg)
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_listener_method_with_binary_message(self):
|
||||
"""Test SocketEndpoint listener method with binary message"""
|
||||
mock_auth = MagicMock()
|
||||
mock_dispatcher = AsyncMock()
|
||||
|
||||
endpoint = SocketEndpoint("/api/socket", mock_auth, mock_dispatcher)
|
||||
|
||||
# Mock websocket with binary message
|
||||
mock_msg = MagicMock()
|
||||
mock_msg.type = WSMsgType.BINARY
|
||||
|
||||
# Create async iterator for websocket
|
||||
async def async_iter():
|
||||
yield mock_msg
|
||||
|
||||
mock_ws = MagicMock()
|
||||
mock_ws.__aiter__ = lambda: async_iter()
|
||||
mock_running = MagicMock()
|
||||
|
||||
# Call listener method
|
||||
await endpoint.listener(mock_ws, mock_dispatcher, mock_running)
|
||||
|
||||
# Verify dispatcher.receive was called with the message
|
||||
mock_dispatcher.receive.assert_called_once_with(mock_msg)
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_listener_method_with_close_message(self):
|
||||
"""Test SocketEndpoint listener method with close message"""
|
||||
mock_auth = MagicMock()
|
||||
mock_dispatcher = AsyncMock()
|
||||
|
||||
endpoint = SocketEndpoint("/api/socket", mock_auth, mock_dispatcher)
|
||||
|
||||
# Mock websocket with close message
|
||||
mock_msg = MagicMock()
|
||||
mock_msg.type = WSMsgType.CLOSE
|
||||
|
||||
# Create async iterator for websocket
|
||||
async def async_iter():
|
||||
yield mock_msg
|
||||
|
||||
mock_ws = MagicMock()
|
||||
mock_ws.__aiter__ = lambda: async_iter()
|
||||
mock_running = MagicMock()
|
||||
|
||||
# Call listener method
|
||||
await endpoint.listener(mock_ws, mock_dispatcher, mock_running)
|
||||
|
||||
# Verify dispatcher.receive was NOT called for close message
|
||||
mock_dispatcher.receive.assert_not_called()
|
||||
124
tests/unit/test_gateway/test_endpoint_stream.py
Normal file
124
tests/unit/test_gateway/test_endpoint_stream.py
Normal file
|
|
@ -0,0 +1,124 @@
|
|||
"""
|
||||
Tests for Gateway Stream Endpoint
|
||||
"""
|
||||
|
||||
import pytest
|
||||
from unittest.mock import MagicMock
|
||||
|
||||
from trustgraph.gateway.endpoint.stream_endpoint import StreamEndpoint
|
||||
|
||||
|
||||
class TestStreamEndpoint:
|
||||
"""Test cases for StreamEndpoint class"""
|
||||
|
||||
def test_stream_endpoint_initialization_with_post(self):
|
||||
"""Test StreamEndpoint initialization with POST method"""
|
||||
mock_auth = MagicMock()
|
||||
mock_dispatcher = MagicMock()
|
||||
|
||||
endpoint = StreamEndpoint(
|
||||
endpoint_path="/api/stream",
|
||||
auth=mock_auth,
|
||||
dispatcher=mock_dispatcher,
|
||||
method="POST"
|
||||
)
|
||||
|
||||
assert endpoint.path == "/api/stream"
|
||||
assert endpoint.auth == mock_auth
|
||||
assert endpoint.dispatcher == mock_dispatcher
|
||||
assert endpoint.operation == "service"
|
||||
assert endpoint.method == "POST"
|
||||
|
||||
def test_stream_endpoint_initialization_with_get(self):
|
||||
"""Test StreamEndpoint initialization with GET method"""
|
||||
mock_auth = MagicMock()
|
||||
mock_dispatcher = MagicMock()
|
||||
|
||||
endpoint = StreamEndpoint(
|
||||
endpoint_path="/api/stream",
|
||||
auth=mock_auth,
|
||||
dispatcher=mock_dispatcher,
|
||||
method="GET"
|
||||
)
|
||||
|
||||
assert endpoint.method == "GET"
|
||||
|
||||
def test_stream_endpoint_initialization_default_method(self):
|
||||
"""Test StreamEndpoint initialization with default POST method"""
|
||||
mock_auth = MagicMock()
|
||||
mock_dispatcher = MagicMock()
|
||||
|
||||
endpoint = StreamEndpoint(
|
||||
endpoint_path="/api/stream",
|
||||
auth=mock_auth,
|
||||
dispatcher=mock_dispatcher
|
||||
)
|
||||
|
||||
assert endpoint.method == "POST" # Default value
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_stream_endpoint_start_method(self):
|
||||
"""Test StreamEndpoint start method (should be no-op)"""
|
||||
mock_auth = MagicMock()
|
||||
mock_dispatcher = MagicMock()
|
||||
|
||||
endpoint = StreamEndpoint("/api/stream", mock_auth, mock_dispatcher)
|
||||
|
||||
# start() should complete without error
|
||||
await endpoint.start()
|
||||
|
||||
def test_add_routes_with_post_method(self):
|
||||
"""Test add_routes method with POST method"""
|
||||
mock_auth = MagicMock()
|
||||
mock_dispatcher = MagicMock()
|
||||
mock_app = MagicMock()
|
||||
|
||||
endpoint = StreamEndpoint(
|
||||
endpoint_path="/api/stream",
|
||||
auth=mock_auth,
|
||||
dispatcher=mock_dispatcher,
|
||||
method="POST"
|
||||
)
|
||||
|
||||
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
|
||||
|
||||
def test_add_routes_with_get_method(self):
|
||||
"""Test add_routes method with GET method"""
|
||||
mock_auth = MagicMock()
|
||||
mock_dispatcher = MagicMock()
|
||||
mock_app = MagicMock()
|
||||
|
||||
endpoint = StreamEndpoint(
|
||||
endpoint_path="/api/stream",
|
||||
auth=mock_auth,
|
||||
dispatcher=mock_dispatcher,
|
||||
method="GET"
|
||||
)
|
||||
|
||||
endpoint.add_routes(mock_app)
|
||||
|
||||
# Verify add_routes was called with GET 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
|
||||
|
||||
def test_add_routes_with_invalid_method_raises_error(self):
|
||||
"""Test add_routes method with invalid method raises RuntimeError"""
|
||||
mock_auth = MagicMock()
|
||||
mock_dispatcher = MagicMock()
|
||||
mock_app = MagicMock()
|
||||
|
||||
endpoint = StreamEndpoint(
|
||||
endpoint_path="/api/stream",
|
||||
auth=mock_auth,
|
||||
dispatcher=mock_dispatcher,
|
||||
method="INVALID"
|
||||
)
|
||||
|
||||
with pytest.raises(RuntimeError, match="Bad method"):
|
||||
endpoint.add_routes(mock_app)
|
||||
Loading…
Add table
Add a link
Reference in a new issue