"""KI-Suche: Antwort des Modells lesen, Titel bei TMDB bestätigen.""" from app import ki, main def test_parsen_zieht_json_aus_geschwaetz(): text = ( "Der Nutzer mag ruhige Filme.\n" "Hier meine Vorschläge:\n" '{"filme": [{"titel": "The Witch", "jahr": 2015, "grund": "Langsam, düster."},' ' {"titel": "", "jahr": 1, "grund": "leer"},' ' {"titel": "Lamb", "jahr": "2021"}]}\nViel Spaß!' ) assert ki.parsen(text) == [ {"titel": "The Witch", "jahr": 2015, "grund": "Langsam, düster."}, {"titel": "Lamb", "jahr": 2021, "grund": ""}, ] def test_parsen_bei_muell_leer(): assert ki.parsen("Keine Ahnung.") == [] assert ki.parsen('{"filme": "nix"}') == [] assert ki.parsen("{kaputt") == [] def test_prompt_nennt_sammlung_und_gesehenes(): text = ki.prompt("blutig", ["Alien (1979)"], ["Nobody (2021)"]) assert "Gesucht: blutig" in text assert "- Alien (1979)" in text assert "- Nobody (2021)" in text # Ohne Beschreibung soll die Sammlung den Ton angeben assert "zu dieser Sammlung passt" in ki.prompt("", ["Alien (1979)"], []) def test_vorgaben_aus_der_leiste(): zeilen = ki.vorgaben( {"include": ["Horror", "Thriller"], "exclude": ["Komödie"], "jahr_min": 2010, "note_min": 6.5, "dauer_max": 120, "stimmen_min": None} ) assert zeilen == [ "Genre: Horror, Thriller", "Auf keinen Fall: Komödie", "Ab 2010", "Mindestens 6.5 von 10 auf TMDB", "Höchstens 120 Minuten", ] assert ki.vorgaben({"jahr_min": 1980, "jahr_max": 1989}) == ["Zwischen 1980 und 1989"] assert ki.vorgaben({}) == [] assert "unbedingt einhalten" in ki.prompt("x", [], [], {"include": ["Horror"]}) def test_route_fragt_und_loest_auf(client, film, monkeypatch): aufrufe = {} async def fragen(beschreibung, sammlung, gesehen, filter_): aufrufe.update( beschreibung=beschreibung, sammlung=sammlung, gesehen=gesehen, filter=filter_ ) return [{"titel": "The Witch", "jahr": 2015, "grund": "Passt."}] async def aufloesen(vorschlaege, filter_, ausser=()): aufrufe["ausser"] = set(ausser) return [{"id": 310131, "title": "The Witch", "grund": v["grund"]} for v in vorschlaege] monkeypatch.setattr(main.ki, "fragen", fragen) monkeypatch.setattr(main.ki, "aufloesen", aufloesen) # Ein Film in der Sammlung, einer gesehen client.post("/api/wishlist", json={"movie_id": film(1, "Alien")}) client.post("/api/watched", json={"movie_id": film(2)}) antwort = client.post( "/api/ki-suche", json={"beschreibung": " Folk-Horror ", "mit_sammlung": True, "include": "Horror,Mystery", "jahr_min": 2010}, ) assert antwort.status_code == 200, antwort.text assert antwort.json()[0]["grund"] == "Passt." assert aufrufe["beschreibung"] == "Folk-Horror" assert aufrufe["sammlung"] == ["Alien"] assert len(aufrufe["gesehen"]) == 1 assert aufrufe["ausser"] == {film(2)} assert aufrufe["filter"]["include"] == ["Horror", "Mystery"] assert aufrufe["filter"]["jahr_min"] == 2010 assert aufrufe["filter"]["note_max"] is None # Gesehene dürfen auch drinbleiben — dann zeigt die Karte es an client.post("/api/ki-suche", json={"beschreibung": "x", "ohne_gesehene": False}) assert aufrufe["ausser"] == set() def test_nur_filter_reichen_als_frage(client, monkeypatch): async def fragen(beschreibung, sammlung, gesehen, filter_): return [] async def aufloesen(vorschlaege, filter_, ausser=()): return [] monkeypatch.setattr(main.ki, "fragen", fragen) monkeypatch.setattr(main.ki, "aufloesen", aufloesen) assert client.post("/api/ki-suche", json={"include": "Horror"}).status_code == 200 def test_route_ohne_beschreibung_und_sammlung(client): assert client.post("/api/ki-suche", json={"beschreibung": " "}).status_code == 400 def test_route_wenn_die_ki_schweigt(client, monkeypatch): import httpx async def fragen(*_): raise httpx.ConnectError("weg") monkeypatch.setattr(main.ki, "fragen", fragen) assert client.post("/api/ki-suche", json={"beschreibung": "x"}).status_code == 502