AISE1_Project_Irina_Livio/tests/test_mcp_server_file_search.py
Irina Rueegg 015564d754 testts
2026-05-22 14:54:49 +02:00

278 lines
7.5 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import pytest
from pathlib import Path
from backend.agent.servers import mcp_server_file_search as server
# =========================================================
# FIXTURES
# =========================================================
@pytest.fixture()
def workspace(tmp_path, monkeypatch):
"""
Erstellt einen isolierten Workspace für jeden Test.
"""
ws = tmp_path / "workspace"
ws.mkdir()
monkeypatch.setattr(server, "ALLOWED_DIR", ws)
return ws
# =========================================================
# BASIC TESTS (1–10)
# =========================================================
# ---------------------------------------------------------
# 1. _safe_path erlaubt gültige Pfade
# ---------------------------------------------------------
def test_safe_path_valid(workspace):
result = server._safe_path("test.txt")
assert result == workspace / "test.txt"
# ---------------------------------------------------------
# 2. _safe_path blockiert Path Traversal
# ---------------------------------------------------------
def test_safe_path_blocks_traversal(workspace):
with pytest.raises(ValueError):
server._safe_path("../secret.txt")
# ---------------------------------------------------------
# 3. list_files liefert leeren Hinweis
# ---------------------------------------------------------
def test_list_files_empty(workspace):
result = server.list_files()
assert result == "No files found in the project directory."
# ---------------------------------------------------------
# 4. list_files findet Dateien rekursiv
# ---------------------------------------------------------
def test_list_files_recursive(workspace):
src = workspace / "src"
src.mkdir()
(src / "main.py").write_text("print('hello')")
result = server.list_files()
assert "src/main.py" in result
# ---------------------------------------------------------
# 5. read_file liest Datei korrekt
# ---------------------------------------------------------
def test_read_file_success(workspace):
file = workspace / "hello.txt"
file.write_text("Hello World")
result = server.read_file("hello.txt")
assert result == "Hello World"
# ---------------------------------------------------------
# 6. read_file erkennt fehlende Datei
# ---------------------------------------------------------
def test_read_file_missing(workspace):
result = server.read_file("missing.txt")
assert "does not exist" in result
# ---------------------------------------------------------
# 7. write_new_file erstellt Datei
# ---------------------------------------------------------
def test_write_new_file_success(workspace):
result = server.write_new_file("new.txt", "content")
assert "OK:" in result
assert (workspace / "new.txt").exists()
# ---------------------------------------------------------
# 8. write_new_file verhindert Überschreiben
# ---------------------------------------------------------
def test_write_new_file_existing(workspace):
file = workspace / "exists.txt"
file.write_text("old")
result = server.write_new_file("exists.txt", "new")
assert "already exists" in result
# ---------------------------------------------------------
# 9. create_new_directory erstellt Verzeichnis
# ---------------------------------------------------------
def test_create_new_directory_success(workspace):
result = server.create_new_directory("mydir")
assert "OK:" in result
assert (workspace / "mydir").is_dir()
# ---------------------------------------------------------
# 10. search_files findet Inhalte
# ---------------------------------------------------------
def test_search_files_content_match(workspace):
file = workspace / "notes.txt"
file.write_text("Python MCP Server")
result = server.search_files("mcp")
assert "[content]" in result
# =========================================================
# EDGE CASE TESTS (11–20)
# =========================================================
# ---------------------------------------------------------
# 11. Mehrfaches Traversal blockieren
# ---------------------------------------------------------
def test_safe_path_double_traversal(workspace):
with pytest.raises(ValueError):
server._safe_path("../../../../etc/passwd")
# ---------------------------------------------------------
# 12. Symlink Escape verhindern
# ---------------------------------------------------------
def test_safe_path_symlink_escape(workspace):
outside = workspace.parent / "outside"
outside.mkdir()
target = outside / "evil.txt"
target.write_text("bad")
link = workspace / "link"
link.symlink_to(outside)
with pytest.raises(ValueError):
server._safe_path("link/evil.txt")
# ---------------------------------------------------------
# 13. Dateien ohne Extension blockieren
# ---------------------------------------------------------
def test_write_file_without_extension(workspace):
result = server.write_new_file("README", "test")
assert "can only write" in result
# ---------------------------------------------------------
# 14. Hidden Files blockieren
# ---------------------------------------------------------
def test_write_hidden_file(workspace):
result = server.write_new_file(".env", "SECRET=123")
assert "can only write" in result
# ---------------------------------------------------------
# 15. Binary Files korrekt behandeln
# ---------------------------------------------------------
def test_read_binary_file(workspace):
binary = workspace / "data.bin"
binary.write_bytes(b"\xFF\xFE\xFD")
result = server.read_file("data.bin")
assert "not a text file" in result
# ---------------------------------------------------------
# 16. Sehr große Zeilen durchsuchen
# ---------------------------------------------------------
def test_search_huge_line(workspace):
huge_text = "A" * 1_000_000 + "needle"
file = workspace / "huge.txt"
file.write_text(huge_text)
result = server.search_files("needle")
assert "[content]" in result
# ---------------------------------------------------------
# 17. Leere Dateien lesen
# ---------------------------------------------------------
def test_read_empty_file(workspace):
file = workspace / "empty.txt"
file.write_text("")
result = server.read_file("empty.txt")
assert result == ""
# ---------------------------------------------------------
# 18. Sonderzeichen im Query
# ---------------------------------------------------------
def test_search_special_characters(workspace):
file = workspace / "test.txt"
file.write_text("hello [world] (test)")
result = server.search_files("[world]")
assert "[content]" in result
# ---------------------------------------------------------
# 19. Unicode-Dateinamen unterstützen
# ---------------------------------------------------------
def test_write_unicode_filename(workspace):
filename = "🔥_überraschung.txt"
result = server.write_new_file(filename, "unicode")
assert "OK:" in result
assert (workspace / filename).exists()
# ---------------------------------------------------------
# 20. Tiefe Verzeichnisstrukturen
# ---------------------------------------------------------
def test_list_files_deep_nesting(workspace):
current = workspace
for i in range(50):
current = current / f"dir_{i}"
current.mkdir()
file = current / "deep.txt"
file.write_text("deep")
result = server.list_files()
assert "deep.txt" in result