gwoe-antragspruefer/tests/test_thread_splitter.py
Dotty Dotter ba1f104c8e feat(#178 Folge): Thread-Auto-Splitter + Quality-Audit-Skript
- _split_into_thread_posts() splittet zu lange Bodies an Satzgrenzen
  in mehrere Posts ≤ max_chars (Default 280). Greedy: möglichst viele
  Sätze pro Post. Hashtags am Ende bleiben erhalten.
- generate_draft(style='thread') ruft den Splitter auf, wenn das LLM
  weniger als 3 Posts oder Posts > 290 chars liefert.
- 7 Unit-Tests fuer den Splitter (test_thread_splitter.py).
- scripts/pm-quality-audit.sh: prueft alle PM-Drafts gegen Verbotsliste
  (GWÖ-Score, Matrix-Codes, Floskeln) + Wortzahl + Absatzzahl + Post-Laengen.
  Markdown-Report-Output. Audit von 23 Drafts: 4/23 ohne Auffaelligkeit;
  Hauptbefund: PMs haeufig zu kurz, Threads splittten ohne Auto-Splitter
  nicht zuverlaessig — Splitter behebt das.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-06 17:08:57 +02:00

65 lines
2.4 KiB
Python

"""Tests fuer _split_into_thread_posts (#178 Folge)."""
import pytest
try:
from app.presse_generator import _split_into_thread_posts
_HAS_FN = True
except ImportError:
_HAS_FN = False
pytestmark = pytest.mark.skipif(not _HAS_FN, reason="presse_generator nicht importierbar")
class TestSplitIntoThreadPosts:
def test_short_text_one_post(self):
text = "Kurzer Satz. Noch einer."
out = _split_into_thread_posts(text)
assert out.split("\n\n") == ["Kurzer Satz. Noch einer."]
def test_long_text_splits_at_sentences(self):
# 4 lange Sätze, jeder ~80 chars → 2-3 Posts
text = (
"Mieter haben ein Recht auf sichere Versorgung. "
"Der Antrag will das durch Strafrecht schützen. "
"Versorgungssicherheit ist lebenswichtig für Familien. "
"Wenn Vermieter Geld zurückhalten droht Wärme- und Wassersperre. "
"Aktuelle Krisen verschärfen das Problem für Mieter:innen. "
"Wir fordern eine klare Regelung. #GWO"
)
out = _split_into_thread_posts(text, max_chars=200)
posts = out.split("\n\n")
assert len(posts) >= 2
for p in posts:
assert len(p) <= 220 # mit etwas Toleranz für letzten Satz
def test_each_post_under_280(self):
# Realistischer Sample: 4-5 Sätze
text = " ".join(["Ein Satz mit etwa 60 Zeichen Länge zur Prüfung."] * 8)
out = _split_into_thread_posts(text)
for p in out.split("\n\n"):
assert len(p) <= 290
def test_handles_newlines(self):
text = "Erster Satz.\nZweiter.\n\nDritter Satz."
out = _split_into_thread_posts(text)
# die Original-Newlines wurden zu Spaces zusammengeführt
assert "\nZweiter" not in out
assert "Erster Satz." in out
assert "Dritter Satz." in out
def test_hashtags_preserved(self):
text = "Erster Satz mit Inhalt. Zweiter Satz mit Substanz. #GWO #Wohnrecht"
out = _split_into_thread_posts(text)
assert "#GWO" in out
assert "#Wohnrecht" in out
def test_empty_input(self):
assert _split_into_thread_posts("") == ""
def test_single_long_sentence_kept(self):
"""Wenn ein einzelner Satz > max_chars ist, wird er trotzdem nicht zerlegt."""
text = "A" * 350
out = _split_into_thread_posts(text, max_chars=280)
# Sollte NUR einen Post liefern, weil keine Satzgrenze
assert "\n\n" not in out