c56497d88a
- KommandoTyp.SPIEL_NEUHEITEN (+ /neu, /neuheiten, Neu-Keywords) - extrahiere_spielname: sucht + bewertet mit Prefix-Unterstützung - extrahiere_bewertung: float-Extraktion mit clamp (1-10) - WhatsApp-Webhook: Vollständige Parse-Pipeline + Queue-Integration - Fakeredis-Mock in Tests, _next_id für IDs statt global SEED_ID - refaktor: verarbeite_submission in _handle_*-Subfunktions - ruff clean: S105/PLR0911 ignores, Umlaut-fix, pyproject.toml - 39 Tests green
194 lines
7.3 KiB
Python
194 lines
7.3 KiB
Python
"""Tests für Message-Intake-Service."""
|
|
|
|
from unittest.mock import MagicMock
|
|
|
|
from src.services.intake import (
|
|
KommandoTyp,
|
|
erkenne_kommando,
|
|
extrahiere_bewertung,
|
|
extrahiere_spielname,
|
|
verarbeite_submission,
|
|
)
|
|
|
|
|
|
class TestErkenneKommando:
|
|
"""Tests für erkenne_kommando."""
|
|
|
|
def test_suche_catanspielen_ergibt_spiel_suchen(self) -> None:
|
|
"""'suche Catan' → KommandoTyp.SPIEL_SUCHEN."""
|
|
assert erkenne_kommando("suche Catan") == KommandoTyp.SPIEL_SUCHEN
|
|
|
|
def test_suche_ohne_begriff_ergibt_spiel_suchen(self) -> None:
|
|
"""'suche' ohne space → KommandoTyp.SPIEL_SUCHEN falls prefix match."""
|
|
assert erkenne_kommando("suche") == KommandoTyp.SPIEL_SUCHEN
|
|
|
|
def test_finde_catan_ergibt_spiel_suchen(self) -> None:
|
|
"""'finde Catan' → KommandoTyp.SPIEL_SUCHEN."""
|
|
assert erkenne_kommando("finde Catan") == KommandoTyp.SPIEL_SUCHEN
|
|
|
|
def test_suche_prefix_mit_slash(self) -> None:
|
|
"""/suche Catan → KommandoTyp.SPIEL_SUCHEN."""
|
|
assert erkenne_kommando("/suche Catan") == KommandoTyp.SPIEL_SUCHEN
|
|
|
|
def test_finde_prefix_mit_slash(self) -> None:
|
|
"""/finde Monopoly → KommandoTyp.SPIEL_SUCHEN."""
|
|
assert erkenne_kommando("/finde Monopoly") == KommandoTyp.SPIEL_SUCHEN
|
|
|
|
def test_bewerte_carcassonne_ergibt_spiel_bewerten(self) -> None:
|
|
"""'bewerte Carcassonne' → KommandoTyp.SPIEL_BEWERTEN."""
|
|
assert erkenne_kommando("bewerte Carcassonne") == KommandoTyp.SPIEL_BEWERTEN
|
|
|
|
def test_bewertung_prefix(self) -> None:
|
|
"""'bewertung Catan' → KommandoTyp.SPIEL_BEWERTEN."""
|
|
assert erkenne_kommando("bewertung Catan") == KommandoTyp.SPIEL_BEWERTEN
|
|
|
|
def test_hilfe_ergibt_hilfe(self) -> None:
|
|
"""'hilfe' → KommandoTyp.HILFE."""
|
|
assert erkenne_kommando("hilfe") == KommandoTyp.HILFE
|
|
|
|
def test_kommandos_ergibt_hilfe(self) -> None:
|
|
"""'commands' → KommandoTyp.HILFE."""
|
|
assert erkenne_kommando("commands") == KommandoTyp.HILFE
|
|
|
|
def test_unknown_ertext_ergibt_unbekannt(self) -> None:
|
|
"""'blabla' → KommandoTyp.UNBEKANNT."""
|
|
assert erkenne_kommando("blabla") == KommandoTyp.UNBEKANNT
|
|
|
|
def test_neuheiten_patterns(self) -> None:
|
|
"""Neu-Help-Patterns: 'neu' → KommandoTyp.SPIEL_NEUHEITEN."""
|
|
assert erkenne_kommando("neu") == KommandoTyp.SPIEL_NEUHEITEN
|
|
assert erkenne_kommando("was ist neu") == KommandoTyp.SPIEL_NEUHEITEN
|
|
assert erkenne_kommando("/neu") == KommandoTyp.SPIEL_NEUHEITEN
|
|
|
|
def test_case_insensitive(self) -> None:
|
|
"""Case-insensitive Prüfung."""
|
|
assert erkenne_kommando("SUCHE Catan") == KommandoTyp.SPIEL_SUCHEN
|
|
assert erkenne_kommando("Suche Catan") == KommandoTyp.SPIEL_SUCHEN
|
|
assert erkenne_kommando("BEWERTE x mit 9") == KommandoTyp.SPIEL_BEWERTEN
|
|
|
|
|
|
class TestExtrahiereSpielName:
|
|
"""Tests für extrahiere_spielname."""
|
|
|
|
def test_suche_catans_gibt_spielname(self) -> None:
|
|
"""'suche Catan' → 'Catan'."""
|
|
assert extrahiere_spielname("suche Catan") == "Catan"
|
|
|
|
def test_suche_ohne_begriff_gibt_none(self) -> None:
|
|
"""'suche' → None."""
|
|
assert extrahiere_spielname("suche") is None
|
|
|
|
def test_finde_monopoly_gibt_spielname(self) -> None:
|
|
"""'finde Monopoly' → 'Monopoly'."""
|
|
assert extrahiere_spielname("finde Monopoly") == "Monopoly"
|
|
|
|
def test_slash_suche_gibt_spielname(self) -> None:
|
|
"""/suche Die Siedler von Catan → 'Die Siedler von Catan'."""
|
|
assert extrahiere_spielname("/suche Die Siedler von Catan") == "Die Siedler von Catan"
|
|
|
|
def test_bewerte_gibt_spielname(self) -> None:
|
|
"""'bewert Catan' → 'Catan'."""
|
|
assert extrahiere_spielname("bewert Catan") == "Catan"
|
|
|
|
def test_bewertung_gibt_spielname(self) -> None:
|
|
"""'bewertung Catan' → 'Catan'."""
|
|
assert extrahiere_spielname("bewertung Catan") == "Catan"
|
|
|
|
def test_bewerte_mit_score_gibt_spielname(self) -> None:
|
|
"""'bewert Catan mit 9' → 'Catan'."""
|
|
assert extrahiere_spielname("bewert Catan mit 9") == "Catan"
|
|
|
|
def test_slash_bewertung_gibt_spielname(self) -> None:
|
|
"""/bewertung Catan → 'Catan'."""
|
|
assert extrahiere_spielname("/bewertung Catan") == "Catan"
|
|
|
|
|
|
class TestExtrahiereBewertung:
|
|
"""Tests für extrahiere_bewertung."""
|
|
|
|
def test_ganze_zahl(self) -> None:
|
|
"""'bewert x mit 9' → 9.0."""
|
|
assert extrahiere_bewertung("bewert x mit 9") == 9.0
|
|
|
|
def test_dezimal_zahl(self) -> None:
|
|
"""'bewert x mit 8.5' → 8.5."""
|
|
assert extrahiere_bewertung("bewert x mit 8.5") == 8.5
|
|
|
|
def test_kein_mit(self) -> None:
|
|
"""'bewert x ohne Zahl' → None."""
|
|
assert extrahiere_bewertung("bewert x ohne Zahl") is None
|
|
|
|
def test_clamp_unten(self) -> None:
|
|
"""Negative Werte → min 1.0."""
|
|
assert extrahiere_bewertung("bewert x mit 0") <= 1.0
|
|
|
|
def test_clamp_oben(self) -> None:
|
|
"""Werte > 10 → max 10.0."""
|
|
assert extrahiere_bewertung("bewert x mit 15") == 10.0
|
|
|
|
|
|
class TestVerarbeiteSubmission:
|
|
"""Tests für verarbeite_submission."""
|
|
|
|
def test_verarbeite_submission_mit_hilfe(self) -> None:
|
|
"""verarbeite_submission mit 'hilfe' → Antwort enthält Hilfe-Text."""
|
|
mock_submission = MagicMock()
|
|
mock_submission.text = "hilfe"
|
|
|
|
result = verarbeite_submission(mock_submission)
|
|
|
|
assert result["kommando"] == "hilfe"
|
|
assert "Verfügbare Kommandos" in result["antwort"]
|
|
assert "suche" in result["antwort"]
|
|
|
|
def test_verarbeite_submission_mit_suche(self) -> None:
|
|
"""verarbeite_submission mit 'suche Catan' → Antowrt enthält Suchbegriff."""
|
|
mock_submission = MagicMock()
|
|
mock_submission.text = "suche Catan"
|
|
|
|
result = verarbeite_submission(mock_submission)
|
|
|
|
assert result["kommando"] == "spiel_suchen"
|
|
assert result["suchbegriff"] == "Catan"
|
|
assert "Catan" in result["antwort"]
|
|
|
|
def test_verarbeite_submission_mit_unbekanntem_text(self) -> None:
|
|
"""verarbeite_submission mit unbekanntem Text → UNBEKANNT."""
|
|
mock_submission = MagicMock()
|
|
mock_submission.text = "hallo wie gehts"
|
|
|
|
result = verarbeite_submission(mock_submission)
|
|
|
|
assert result["kommando"] == "unbekannt"
|
|
|
|
def test_verarbeite_submission_mit_neuheiten(self) -> None:
|
|
"""'neu' → SPIEL_NEUHEITEN."""
|
|
mock_submission = MagicMock()
|
|
mock_submission.text = "neu"
|
|
|
|
result = verarbeite_submission(mock_submission)
|
|
|
|
assert result["kommando"] == "spiel_neuheiten"
|
|
assert "Neu" in result["antwort"]
|
|
|
|
def test_verarbeite_submission_mit_bewertung(self) -> None:
|
|
"""'bewert x mit 9' → SPIEL_BEWERTEN mit Score."""
|
|
mock_submission = MagicMock()
|
|
mock_submission.text = "bewert x mit 9"
|
|
|
|
result = verarbeite_submission(mock_submission)
|
|
|
|
assert result["kommando"] == "spiel_bewerten"
|
|
assert result["bewertung"] == 9.0
|
|
assert result["spiel_name"] == "x"
|
|
|
|
def test_verarbeite_submission_bewerte_ohne_bewertung(self) -> None:
|
|
"""'bewert x' ohne Score → noch Bewertung gefragt."""
|
|
mock_submission = MagicMock()
|
|
mock_submission.text = "bewert x"
|
|
|
|
result = verarbeite_submission(mock_submission)
|
|
|
|
assert result["kommando"] == "spiel_bewerten"
|
|
assert "bewertest du es" in result["antwort"]
|