added test cases for multiple connected clients

This commit is contained in:
Jan Felix Wiebe 2025-07-09 22:28:39 +02:00
parent 87310d77f0
commit 5be71901bb

View file

@ -590,6 +590,385 @@ class TestWebSocket:
websocket_manager.disconnect(mock_ws)
class TestWebSocketMultiClient:
"""Test-Klasse für Multi-Client WebSocket-Funktionalität"""
@pytest.mark.asyncio
async def test_multiple_clients_receive_order_created(self):
"""Test dass alle verbundenen Clients order_created Nachrichten erhalten"""
from websocket_manager import websocket_manager
from database import db
from models import Drink, DrinkType, MateType
# Erstelle mehrere Test-WebSockets
class MockWebSocket:
def __init__(self, client_id):
self.client_id = client_id
self.messages = []
self.closed = False
async def accept(self):
pass
async def send_text(self, message):
self.messages.append(message)
async def receive_text(self):
return "ping"
async def close(self):
self.closed = True
# Verbinde mehrere Mock-WebSockets
mock_ws1 = MockWebSocket("client1")
mock_ws2 = MockWebSocket("client2")
mock_ws3 = MockWebSocket("client3")
await websocket_manager.connect(mock_ws1)
await websocket_manager.connect(mock_ws2)
await websocket_manager.connect(mock_ws3)
assert len(websocket_manager.active_connections) == 3
# Erstelle eine neue Bestellung (sollte an alle Clients broadcasten)
drinks = [
Drink(
drink_type=DrinkType.TSCHUNK,
mate_type=MateType.CLUB_MATE,
quantity=2,
notes="Multi-Client Test"
)
]
order = await db.create_order(drinks)
# Prüfe, dass alle Clients die order_created Nachricht erhalten haben
for mock_ws in [mock_ws1, mock_ws2, mock_ws3]:
assert len(mock_ws.messages) >= 1
# Finde die "order_created" Nachricht
order_created_found = False
for message in mock_ws.messages:
try:
data = json.loads(message)
if data.get("type") == "order_created":
order_created_found = True
assert data["order"]["id"] == order.id
assert "timestamp" in data
break
except json.JSONDecodeError:
continue
assert order_created_found, f"Client {mock_ws.client_id} hat keine order_created Nachricht erhalten"
# Cleanup
await db.delete_order(order.id)
websocket_manager.disconnect(mock_ws1)
websocket_manager.disconnect(mock_ws2)
websocket_manager.disconnect(mock_ws3)
@pytest.mark.asyncio
async def test_multiple_clients_receive_order_deleted(self):
"""Test dass alle verbundenen Clients order_deleted Nachrichten erhalten"""
from websocket_manager import websocket_manager
from database import db
from models import Drink, DrinkType, MateType
# Erstelle mehrere Test-WebSockets
class MockWebSocket:
def __init__(self, client_id):
self.client_id = client_id
self.messages = []
self.closed = False
async def accept(self):
pass
async def send_text(self, message):
self.messages.append(message)
async def receive_text(self):
return "ping"
async def close(self):
self.closed = True
# Verbinde mehrere Mock-WebSockets
mock_ws1 = MockWebSocket("client1")
mock_ws2 = MockWebSocket("client2")
await websocket_manager.connect(mock_ws1)
await websocket_manager.connect(mock_ws2)
# Erstelle zuerst eine Bestellung
drinks = [
Drink(
drink_type=DrinkType.VIRGIN_TSCHUNK,
mate_type=MateType.FLORA_MATE,
quantity=1,
notes="Delete Test"
)
]
order = await db.create_order(drinks)
order_id = order.id
# Lösche die Bestellung (sollte an alle Clients broadcasten)
success = await db.delete_order(order_id)
assert success is True
# Prüfe, dass alle Clients die order_deleted Nachricht erhalten haben
for mock_ws in [mock_ws1, mock_ws2]:
assert len(mock_ws.messages) >= 2 # Mindestens create + delete
# Finde die "order_deleted" Nachricht
order_deleted_found = False
for message in mock_ws.messages:
try:
data = json.loads(message)
if data.get("type") == "order_deleted":
order_deleted_found = True
assert data["order_id"] == order_id
assert "timestamp" in data
break
except json.JSONDecodeError:
continue
assert order_deleted_found, f"Client {mock_ws.client_id} hat keine order_deleted Nachricht erhalten"
# Cleanup
websocket_manager.disconnect(mock_ws1)
websocket_manager.disconnect(mock_ws2)
@pytest.mark.asyncio
async def test_client_disconnection_handling(self):
"""Test dass getrennte Clients keine weiteren Nachrichten erhalten"""
from websocket_manager import websocket_manager
from database import db
from models import Drink, DrinkType, MateType
# Erstelle Test-WebSockets
class MockWebSocket:
def __init__(self, client_id):
self.client_id = client_id
self.messages = []
self.closed = False
async def accept(self):
pass
async def send_text(self, message):
if not self.closed:
self.messages.append(message)
async def receive_text(self):
return "ping"
async def close(self):
self.closed = True
# Verbinde WebSockets
mock_ws1 = MockWebSocket("client1")
mock_ws2 = MockWebSocket("client2")
await websocket_manager.connect(mock_ws1)
await websocket_manager.connect(mock_ws2)
# Trenne ersten Client
websocket_manager.disconnect(mock_ws1)
assert len(websocket_manager.active_connections) == 1
# Erstelle eine Bestellung (sollte nur an client2 gehen)
drinks = [
Drink(
drink_type=DrinkType.TSCHUNK_HANNOVER_MISCHE,
mate_type=MateType.CLUB_MATE,
quantity=1
)
]
order = await db.create_order(drinks)
# Prüfe, dass nur client2 die Nachricht erhalten hat
assert len(mock_ws1.messages) == 0 # Getrennter Client sollte keine Nachrichten erhalten
assert len(mock_ws2.messages) >= 1 # Verbundener Client sollte Nachricht erhalten
# Prüfe, dass client2 die order_created Nachricht erhalten hat
order_created_found = False
for message in mock_ws2.messages:
try:
data = json.loads(message)
if data.get("type") == "order_created":
order_created_found = True
assert data["order"]["id"] == order.id
break
except json.JSONDecodeError:
continue
assert order_created_found, "Verbundener Client hat keine order_created Nachricht erhalten"
# Cleanup
await db.delete_order(order.id)
websocket_manager.disconnect(mock_ws2)
@pytest.mark.asyncio
async def test_concurrent_client_operations(self):
"""Test gleichzeitige Operationen mit mehreren Clients"""
from websocket_manager import websocket_manager
from database import db
from models import Drink, DrinkType, MateType
import asyncio
# Erstelle Test-WebSockets
class MockWebSocket:
def __init__(self, client_id):
self.client_id = client_id
self.messages = []
self.closed = False
async def accept(self):
pass
async def send_text(self, message):
self.messages.append(message)
async def receive_text(self):
return "ping"
async def close(self):
self.closed = True
# Verbinde mehrere WebSockets
clients = []
for i in range(5):
client = MockWebSocket(f"client{i}")
await websocket_manager.connect(client)
clients.append(client)
assert len(websocket_manager.active_connections) == 5
# Erstelle mehrere Bestellungen schnell hintereinander
orders = []
for i in range(3):
drinks = [
Drink(
drink_type=DrinkType.TSCHUNK,
mate_type=MateType.CLUB_MATE,
quantity=i + 1,
notes=f"Concurrent Test {i + 1}"
)
]
order = await db.create_order(drinks)
orders.append(order)
await asyncio.sleep(0.05) # Kurze Pause
# Prüfe, dass alle Clients alle Nachrichten erhalten haben
for client in clients:
# Jeder Client sollte mindestens 3 order_created Nachrichten erhalten haben
order_created_count = 0
for message in client.messages:
try:
data = json.loads(message)
if data.get("type") == "order_created":
order_created_count += 1
except json.JSONDecodeError:
continue
assert order_created_count >= 3, f"Client {client.client_id} hat nicht alle Nachrichten erhalten: {order_created_count}/3"
# Lösche alle Bestellungen
for order in orders:
await db.delete_order(order.id)
# Prüfe, dass alle Clients die delete-Nachrichten erhalten haben
for client in clients:
order_deleted_count = 0
for message in client.messages:
try:
data = json.loads(message)
if data.get("type") == "order_deleted":
order_deleted_count += 1
except json.JSONDecodeError:
continue
assert order_deleted_count >= 3, f"Client {client.client_id} hat nicht alle delete-Nachrichten erhalten: {order_deleted_count}/3"
# Cleanup
for client in clients:
websocket_manager.disconnect(client)
@pytest.mark.asyncio
async def test_websocket_message_format_consistency(self):
"""Test dass alle WebSocket-Nachrichten konsistentes Format haben"""
from websocket_manager import websocket_manager
from database import db
from models import Drink, DrinkType, MateType
# Erstelle Test-WebSocket
class MockWebSocket:
def __init__(self):
self.messages = []
self.closed = False
async def accept(self):
pass
async def send_text(self, message):
self.messages.append(message)
async def receive_text(self):
return "ping"
async def close(self):
self.closed = True
mock_ws = MockWebSocket()
await websocket_manager.connect(mock_ws)
# Erstelle und lösche eine Bestellung
drinks = [
Drink(
drink_type=DrinkType.TSCHUNK,
mate_type=MateType.CLUB_MATE,
quantity=1
)
]
order = await db.create_order(drinks)
order_id = order.id
await db.delete_order(order_id)
# Prüfe Nachrichtenformat
for message in mock_ws.messages:
try:
data = json.loads(message)
# Alle Nachrichten sollten diese Felder haben
assert "type" in data
assert "timestamp" in data
# Prüfe spezifische Nachrichtentypen
if data["type"] == "order_created":
assert "order" in data
assert "id" in data["order"]
assert "order_date" in data["order"]
assert "drinks" in data["order"]
elif data["type"] == "order_deleted":
assert "order_id" in data
elif data["type"] == "all_orders":
assert "orders" in data
assert isinstance(data["orders"], list)
except json.JSONDecodeError:
assert False, f"Ungültiges JSON-Format: {message}"
# Cleanup
websocket_manager.disconnect(mock_ws)
class TestDatabase:
"""Test-Klasse für Datenbankfunktionalität"""