"""Fake-E2E: kompletter Generierungspfad in Sekunden. Thema (Web-Recherche) und Uni (Dateien), plus Resume-Idempotenz.""" import asyncio import itertools import db import guide import korpus import pipeline from conftest import topic_anlegen from fake_agents import FAKE_TEXT async def _lauf_komplett(topic): run_id = pipeline.lauf_starten(topic) await pipeline._laeufe[topic] return run_id def _pruefe_endzustand(topic, run_id): assert db.one("SELECT status FROM topics WHERE name=?", (topic,))["status"] == "fertig" run = db.one("SELECT * FROM runs WHERE id=?", (run_id,)) assert run["status"] == "done" offen = db.query("SELECT * FROM befunde WHERE run_id=? AND status='offen'", (run_id,)) assert offen == [], f"offene Befunde: {offen}" atome = db.query("SELECT * FROM atome WHERE topic=? AND status NOT IN" " ('gemerged','verworfen')", (topic,)) assert len(atome) == 3 # die Fake-Welt hat exakt drei Atome assert all(a["soll_id"] and a["ziel_id"] and a["baustein_id"] for a in atome) for a in atome: assert db.one("SELECT id FROM anker WHERE atom_id=?", (a["id"],)) karten = db.query("SELECT * FROM artefakte WHERE atom_id=? AND typ='flashcard'" " AND status='verifiziert'", (a["id"],)) assert karten md = guide.guide_markdown(topic) for a in atome: assert f"" not in md and "| M -->" not in md # Marker tragen kein Level mehr # Kapitel-Struktur: H2 = Kapitel (Struktur-Ebene, mit Intro), H3 = Baustein assert "\n## " in "\n" + md and "### " in md assert "**Kernpunkte:**" in md and "**Prüfe dich:**" in md kaps = db.query("SELECT * FROM kapitel WHERE topic=? ORDER BY ord", (topic,)) assert kaps, "keine Kapitel gebildet" for k in kaps: assert k["intro"], f"Kapitel-Intro fehlt: {k['titel']}" bausteine = db.query("SELECT * FROM bausteine WHERE topic=? ORDER BY ord", (topic,)) assert all(b["kapitel_id"] for b in bausteine) folge = [b["kapitel_id"] for b in bausteine] segmente = [k for k, _ in itertools.groupby(folge)] assert len(segmente) == len(set(segmente)) == len(kaps) # kontiguierlich, lückenlos # Stufen-Bausteine: jeder Baustein trägt genau ein Level, alle seine Atome # dieses Level; Kapitel-Level monoton E→M→S entlang der globalen ord rang = {"E": 0, "M": 1, "S": 2} kap_level = {k["id"]: k["level"] for k in kaps} for b in bausteine: assert kap_level[b["kapitel_id"]] == b["level"] for a in atome: if a["baustein_id"] == b["id"]: assert a["level"] == b["level"], (a["titel"], a["level"], b["level"]) level_folge = [rang[b["level"]] for b in bausteine] assert level_folge == sorted(level_folge), "Durchgänge nicht E