#!/usr/bin/env python3 """MCP Edge-Case-Tests — ON-DEMAND (nicht naechtlich). Pro Connector: ungewoehnliche/boese Eingaben (Unicode/Emoji, Sonderzeichen, riesige Limits/Bodies, kaputte Datumsangaben, Path-Traversal). Ziel: der Server faengt das sauber ab (graceful) statt zu crashen oder Daten zu leaken. Lauf: /opt/mcp-servers/venv/bin/python -m pytest test_edge.py -q """ import time import pytest from test_all import SERVERS, get_token, mcp_call, tool_call pytestmark = pytest.mark.edge EMOJI = "Zürdäß 🚀😀 漢字 مرحبا" def _alive(port): """Server beantwortet nach einer boesen Eingabe noch normal.""" res = mcp_call(port, get_token(port), "tools/list") assert res and res.get("result", {}).get("tools"), f"Server {port} nach Edge-Call tot" # ============================================================ # Mail # ============================================================ class TestMailEdge: PORT = SERVERS["mail"] def test_huge_limit(self): tool_call(self.PORT, get_token(self.PORT), "search_mail", {"query": "mcptest", "limit": 100000, "account": "mcp-test-mail"}) _alive(self.PORT) def test_regex_special_chars_literal(self): for q in [".*", "[a-z]+", "%27 OR 1=1", "a\\b", "()|"]: tool_call(self.PORT, get_token(self.PORT), "search_mail", {"query": q, "limit": 3, "account": "mcp-test-mail"}) _alive(self.PORT) def test_very_long_query(self): tool_call(self.PORT, get_token(self.PORT), "search_mail", {"query": "x" * 2000, "limit": 3, "account": "mcp-test-mail"}) _alive(self.PORT) def test_nonexistent_account_filter(self): text = tool_call(self.PORT, get_token(self.PORT), "search_mail", {"query": "mcptest", "account": "does-not-exist-xyz"}) assert "No results" in text or text.strip() == "" or "Subject:" not in text _alive(self.PORT) # ============================================================ # Calendar # ============================================================ class TestCalendarEdge: PORT = SERVERS["calendar"] CAL = "calendar-test" def test_invalid_date_graceful(self): # kaputtes Datum darf den Server nicht killen mcp_call(self.PORT, get_token(self.PORT), "tools/call", { "name": "create_event", "arguments": {"calendar": self.CAL, "title": "BadDate", "start": "kein-datum", "end": "32.13.2026"}, }) _alive(self.PORT) def test_unicode_emoji_event(self): token = get_token(self.PORT) tag = f"edge-uni-{int(time.time())}" tool_call(self.PORT, token, "create_event", { "calendar": self.CAL, "title": f"{EMOJI} {tag}", "start": "2027-01-02T10:00", "end": "2027-01-02T11:00", }) found = tool_call(self.PORT, token, "search_events", {"query": tag}) assert tag in found def test_reversed_date_range(self): tool_call(self.PORT, get_token(self.PORT), "get_events", {"calendar": self.CAL, "date_from": "2027-12-31", "date_to": "2027-01-01"}) _alive(self.PORT) # ============================================================ # Contacts # ============================================================ class TestContactsEdge: PORT = SERVERS["contacts"] def test_unicode_emoji_contact(self): token = get_token(self.PORT) tag = f"EdgeUni{int(time.time())}" tool_call(self.PORT, token, "create_contact", {"name": f"{tag} {EMOJI}", "email": f"{tag.lower()}@example.com"}) found = tool_call(self.PORT, token, "search_contacts", {"query": tag}) assert tag in found def test_special_char_search(self): for q in ["O'Brien", "müller & söhne", "100% sicher", "