Files
aza/AzA march 2026 - Kopie (17)/_test_audit_log.py
2026-04-19 20:41:37 +02:00

102 lines
3.6 KiB
Python

# -*- coding: utf-8 -*-
"""Test-Skript fuer aza_audit_log.py"""
import os, sys, json
sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
os.chdir(os.path.dirname(os.path.abspath(__file__)))
from pathlib import Path
from aza_audit_log import (
log_event, export_audit_log, get_log_stats, _LOG_FILE,
)
if _LOG_FILE.exists():
_LOG_FILE.unlink()
passed = 0
failed = 0
def check(name, condition):
global passed, failed
if condition:
print(f" PASS: {name}")
passed += 1
else:
print(f" FAIL: {name}")
failed += 1
print("=== TEST 1: Events schreiben ===")
log_event("APP_START", "test_user", detail="test")
log_event("LOGIN_OK", "test_user")
log_event("LOGIN_FAIL", "test_user", success=False, detail="wrong password")
log_event("CONSENT_GRANT", "test_user")
log_event("AI_TRANSCRIBE", "test_user")
log_event("AI_CHAT", "test_user", detail="model=gpt-5.2")
log_event("AI_BLOCKED", "test_user", success=False, detail="kein Consent")
log_event("CONSENT_REVOKE", "test_user")
log_event("2FA_OK", "test_user")
log_event("2FA_FAIL", "test_user", success=False)
log_event("PASSWORD_CHANGE", "test_user")
log_event("APP_STOP", "test_user")
check("Logdatei existiert", _LOG_FILE.exists())
print("\n=== TEST 2: Log-Inhalt pruefen ===")
with open(_LOG_FILE, "r", encoding="utf-8") as f:
lines = [l.strip() for l in f if l.strip()]
check(f"12 Zeilen (gefunden: {len(lines)})", len(lines) == 12)
line1 = lines[0]
parts = [p.strip() for p in line1.split("|")]
check("6 Felder pro Zeile", len(parts) == 6)
check("Timestamp endet mit +00:00", "+00:00" in parts[0])
check("Event = APP_START", parts[1] == "APP_START")
check("User = test_user", parts[2] == "test_user")
check("Status = OK", parts[3] == "OK")
check("Source = desktop", parts[4] == "desktop")
line3 = lines[2]
parts3 = [p.strip() for p in line3.split("|")]
check("LOGIN_FAIL Status = FAIL", parts3[3] == "FAIL")
print("\n=== TEST 3: Statistiken ===")
stats = get_log_stats()
check("Datei existiert", stats["exists"])
check(f"12 Zeilen (stats: {stats['total_lines']})", stats["total_lines"] == 12)
check("APP_START in events", stats["events"].get("APP_START", 0) == 1)
check("LOGIN_FAIL in events", stats["events"].get("LOGIN_FAIL", 0) == 1)
check("AI_CHAT in events", stats["events"].get("AI_CHAT", 0) == 1)
print("\n=== TEST 4: Export ===")
path = export_audit_log()
check("Export-Datei existiert", os.path.exists(path))
with open(path, "r", encoding="utf-8") as f:
data = json.load(f)
check(f"12 Eintraege (export: {data['total_entries']})", data["total_entries"] == 12)
check("Erster Eintrag APP_START", data["entries"][0]["event"] == "APP_START")
check("Letzter Eintrag APP_STOP", data["entries"][-1]["event"] == "APP_STOP")
os.remove(path)
print("\n=== TEST 5: Data Minimization ===")
all_text = open(_LOG_FILE, "r", encoding="utf-8").read()
check("Kein Passwort im Log", "password" not in all_text.lower() or "wrong password" in all_text.lower())
check("Kein API-Key im Log", "sk-" not in all_text)
check("Kein Prompt im Log", "TRANSKRIPT:" not in all_text)
check("Detail < 200 Zeichen", all(len(p.strip()) < 200 for line in lines for p in [line.split("|")[-1]]))
print("\n=== TEST 6: Pipe-Sanitierung ===")
log_event("TEST", "user", detail="detail|mit|pipes")
with open(_LOG_FILE, "r", encoding="utf-8") as f:
last = [l.strip() for l in f if l.strip()][-1]
pipe_count = last.count("|")
check(f"Pipes ersetzt (nur 5 Trennzeichen, gefunden: {pipe_count})", pipe_count == 5)
# Cleanup
if _LOG_FILE.exists():
_LOG_FILE.unlink()
print(f"\n{'='*50}")
print(f"ERGEBNIS: {passed} PASS, {failed} FAIL")
if failed == 0:
print("ALLE TESTS BESTANDEN")
else:
sys.exit(1)