This repository has been archived on 2026-02-15. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
BreakPilot Dev 19855efacc
Some checks failed
Tests / Go Tests (push) Has been cancelled
Tests / Python Tests (push) Has been cancelled
Tests / Integration Tests (push) Has been cancelled
Tests / Go Lint (push) Has been cancelled
Tests / Python Lint (push) Has been cancelled
Tests / Security Scan (push) Has been cancelled
Tests / All Checks Passed (push) Has been cancelled
Security Scanning / Secret Scanning (push) Has been cancelled
Security Scanning / Dependency Vulnerability Scan (push) Has been cancelled
Security Scanning / Go Security Scan (push) Has been cancelled
Security Scanning / Python Security Scan (push) Has been cancelled
Security Scanning / Node.js Security Scan (push) Has been cancelled
Security Scanning / Docker Image Security (push) Has been cancelled
Security Scanning / Security Summary (push) Has been cancelled
CI/CD Pipeline / Go Tests (push) Has been cancelled
CI/CD Pipeline / Python Tests (push) Has been cancelled
CI/CD Pipeline / Website Tests (push) Has been cancelled
CI/CD Pipeline / Linting (push) Has been cancelled
CI/CD Pipeline / Security Scan (push) Has been cancelled
CI/CD Pipeline / Docker Build & Push (push) Has been cancelled
CI/CD Pipeline / Integration Tests (push) Has been cancelled
CI/CD Pipeline / Deploy to Staging (push) Has been cancelled
CI/CD Pipeline / Deploy to Production (push) Has been cancelled
CI/CD Pipeline / CI Summary (push) Has been cancelled
ci/woodpecker/manual/build-ci-image Pipeline was successful
ci/woodpecker/manual/main Pipeline failed
feat: BreakPilot PWA - Full codebase (clean push without large binaries)
All services: admin-v2, studio-v2, website, ai-compliance-sdk,
consent-service, klausur-service, voice-service, and infrastructure.
Large PDFs and compiled binaries excluded via .gitignore.
2026-02-11 13:25:58 +01:00

184 lines
6.0 KiB
Python

"""
Tests für AlertItem Model.
"""
import pytest
from datetime import datetime
from alerts_agent.models.alert_item import AlertItem, AlertSource, AlertStatus
class TestAlertItemCreation:
"""Tests für AlertItem Erstellung."""
def test_create_minimal_alert(self):
"""Test minimale Alert-Erstellung."""
alert = AlertItem(title="Test Alert", url="https://example.com/article")
assert alert.title == "Test Alert"
assert alert.url == "https://example.com/article"
assert alert.id is not None
assert len(alert.id) == 36 # UUID format
assert alert.status == AlertStatus.NEW
assert alert.source == AlertSource.GOOGLE_ALERTS_RSS
def test_create_full_alert(self):
"""Test vollständige Alert-Erstellung."""
alert = AlertItem(
source=AlertSource.GOOGLE_ALERTS_EMAIL,
topic_label="Inklusion Bayern",
title="Neue Inklusions-Richtlinie",
url="https://example.com/inklusion",
snippet="Die neue Richtlinie für inklusive Bildung...",
lang="de",
published_at=datetime(2024, 1, 15, 10, 30),
)
assert alert.source == AlertSource.GOOGLE_ALERTS_EMAIL
assert alert.topic_label == "Inklusion Bayern"
assert alert.lang == "de"
assert alert.published_at.year == 2024
def test_url_hash_generated(self):
"""Test dass URL Hash automatisch generiert wird."""
alert = AlertItem(
title="Test",
url="https://example.com/test"
)
assert alert.url_hash is not None
assert len(alert.url_hash) == 16 # 16 hex chars
def test_canonical_url_generated(self):
"""Test dass kanonische URL generiert wird."""
alert = AlertItem(
title="Test",
url="https://EXAMPLE.com/path/"
)
# Sollte lowercase und ohne trailing slash sein
assert alert.canonical_url == "https://example.com/path"
class TestURLNormalization:
"""Tests für URL Normalisierung."""
def test_remove_tracking_params(self):
"""Test Entfernung von Tracking-Parametern."""
alert = AlertItem(
title="Test",
url="https://example.com/article?utm_source=google&utm_medium=email&id=123"
)
# utm_source und utm_medium sollten entfernt werden, id bleibt
assert "utm_source" not in alert.canonical_url
assert "utm_medium" not in alert.canonical_url
assert "id=123" in alert.canonical_url
def test_lowercase_domain(self):
"""Test Domain wird lowercase."""
alert = AlertItem(
title="Test",
url="https://WWW.EXAMPLE.COM/Article"
)
assert "www.example.com" in alert.canonical_url
def test_remove_fragment(self):
"""Test Fragment wird entfernt."""
alert = AlertItem(
title="Test",
url="https://example.com/article#section1"
)
assert "#" not in alert.canonical_url
def test_same_url_same_hash(self):
"""Test gleiche URL produziert gleichen Hash."""
alert1 = AlertItem(title="Test", url="https://example.com/test")
alert2 = AlertItem(title="Test", url="https://example.com/test")
assert alert1.url_hash == alert2.url_hash
def test_different_url_different_hash(self):
"""Test verschiedene URLs produzieren verschiedene Hashes."""
alert1 = AlertItem(title="Test", url="https://example.com/test1")
alert2 = AlertItem(title="Test", url="https://example.com/test2")
assert alert1.url_hash != alert2.url_hash
class TestAlertSerialization:
"""Tests für Serialisierung."""
def test_to_dict(self):
"""Test Konvertierung zu Dictionary."""
alert = AlertItem(
title="Test Alert",
url="https://example.com",
topic_label="Test Topic",
)
data = alert.to_dict()
assert data["title"] == "Test Alert"
assert data["url"] == "https://example.com"
assert data["topic_label"] == "Test Topic"
assert data["source"] == "google_alerts_rss"
assert data["status"] == "new"
def test_from_dict(self):
"""Test Erstellung aus Dictionary."""
data = {
"id": "test-id-123",
"title": "Test Alert",
"url": "https://example.com",
"source": "google_alerts_email",
"status": "scored",
"relevance_score": 0.85,
}
alert = AlertItem.from_dict(data)
assert alert.id == "test-id-123"
assert alert.title == "Test Alert"
assert alert.source == AlertSource.GOOGLE_ALERTS_EMAIL
assert alert.status == AlertStatus.SCORED
assert alert.relevance_score == 0.85
def test_round_trip(self):
"""Test Serialisierung und Deserialisierung."""
original = AlertItem(
title="Round Trip Test",
url="https://example.com/roundtrip",
topic_label="Testing",
relevance_score=0.75,
relevance_decision="KEEP",
)
data = original.to_dict()
restored = AlertItem.from_dict(data)
assert restored.title == original.title
assert restored.url == original.url
assert restored.relevance_score == original.relevance_score
class TestAlertStatus:
"""Tests für Alert Status."""
def test_status_enum_values(self):
"""Test Status Enum Werte."""
assert AlertStatus.NEW.value == "new"
assert AlertStatus.PROCESSED.value == "processed"
assert AlertStatus.DUPLICATE.value == "duplicate"
assert AlertStatus.SCORED.value == "scored"
assert AlertStatus.REVIEWED.value == "reviewed"
assert AlertStatus.ARCHIVED.value == "archived"
def test_source_enum_values(self):
"""Test Source Enum Werte."""
assert AlertSource.GOOGLE_ALERTS_RSS.value == "google_alerts_rss"
assert AlertSource.GOOGLE_ALERTS_EMAIL.value == "google_alerts_email"
assert AlertSource.MANUAL.value == "manual"