Nyt modul erindringer.py: emner (projekter) med baggrund og startspørgsmål, personer (indloggede + gæstelinks), Claude stiller opfølgende spørgsmål, ElevenLabs læser op (cachet) og transskriberer, ffmpeg laver mp3, admin med klip, favoritter og zip-eksport. Forsidekort og admin-modul. Røgtest i tests/. Claude-Session: https://claude.ai/code/session_01JmhJG6JnhXfzNiKv8f2vHu
57 lines
4.2 KiB
Python
57 lines
4.2 KiB
Python
# Røgtest af erindringer-modulet med FastAPI TestClient, uden OIDC: sessionen sættes direkte.
|
|
# Kør i CT151: PORTAL_DATA=/tmp/ef-test/data + env fra /etc/portal.env. Rører ikke prod-data.
|
|
import io, json, os, sys
|
|
from fastapi.testclient import TestClient
|
|
import main, erindringer
|
|
|
|
c = TestClient(main.app, base_url="https://weircon.dk")
|
|
adm = {"username": "agw", "name": "Asger", "groups": [main.config.ADMIN_GROUP, "Familie"]}
|
|
|
|
|
|
def login(client, user):
|
|
# Starlette-session: skriv via en lille rute er omstændeligt; monkeypatch current_user i stedet.
|
|
main.current_user = lambda request: user
|
|
|
|
|
|
login(c, adm)
|
|
r = c.get("/admin/erindringer"); assert r.status_code == 200 and "Erindringer" in r.text, r.status_code
|
|
r = c.post("/admin/erindringer/projekt", data={"slug": "test-ep", "titel": "Testemne", "beskrivelse": "b", "kontekst": "Personen er Asger. Vi ved at han bor i Sønderlund.", "start": "Hvad husker du fra Rørbæk?\nHvem var din morfar?"}, follow_redirects=False)
|
|
assert r.status_code == 303, r.text
|
|
assert erindringer.projekt("test-ep")["start"][0].startswith("Hvad husker")
|
|
r = c.post("/admin/erindringer/gaest", data={"navn": "Tina Test", "projekter": ["test-ep"]}, follow_redirects=False)
|
|
assert r.status_code == 303
|
|
pid = [p for p in erindringer.alle_personer() if p["navn"] == "Tina Test"][0]["pid"]; noegle = erindringer.person(pid)["noegle"]
|
|
print("gæst", pid)
|
|
|
|
# API som gæst (uden session)
|
|
login(c, None)
|
|
r = c.post("/erindringer/api/naeste", json={"projekt": "test-ep", "samtale": None, "noegle": noegle}); assert r.status_code == 200, r.text
|
|
q1 = r.json(); print("Q1", q1["spoergsmaal"], "| lyd:", bool(q1["lyd_url"]))
|
|
if q1["lyd_url"]:
|
|
assert c.get(q1["lyd_url"]).status_code == 200
|
|
r = c.post("/erindringer/api/svar", data={"projekt": "test-ep", "samtale": q1["samtale"], "spoergsmaal": q1["spoergsmaal"], "noegle": noegle, "tekst": "Jeg husker min morfar Gustav i Villa Monika i Hannerup. Han havde en stor have og en motorcykel, som han aldrig kørte på."})
|
|
assert r.status_code == 200, r.text; s1 = r.json(); print("svar1", s1["id"])
|
|
r = c.post("/erindringer/api/naeste", json={"projekt": "test-ep", "samtale": q1["samtale"], "noegle": noegle}); assert r.status_code == 200, r.text
|
|
q2 = r.json(); print("Q2 (Claude)", q2["spoergsmaal"], "| afslut:", q2["afslut"])
|
|
# lydsvar: 2 s tone som mp3 lavet med ffmpeg
|
|
os.system("ffmpeg -y -v error -f lavfi -i 'sine=frequency=440:duration=2' -c:a libmp3lame /tmp/ef-test/tone.mp3")
|
|
r = c.post("/erindringer/api/svar", data={"projekt": "test-ep", "samtale": q1["samtale"], "spoergsmaal": q2["spoergsmaal"], "noegle": noegle}, files={"lyd": ("svar.mp3", open("/tmp/ef-test/tone.mp3", "rb"), "audio/mpeg")})
|
|
assert r.status_code == 200, r.text; s2 = r.json(); print("svar2 lyd", s2["id"], "varighed", s2["varighed"], "tekst:", repr(s2["tekst"])[:60])
|
|
r = c.get(f"/erindringer/g/{noegle}/klip/{s2['id']}.mp3"); assert r.status_code == 200 and r.headers["content-type"].startswith("audio")
|
|
r = c.post("/erindringer/api/ret", json={"id": s1["id"], "tekst": "Rettet tekst.", "noegle": noegle}); assert r.status_code == 200
|
|
assert erindringer.klip(pid, s1["id"])["tekst"] == "Rettet tekst."
|
|
# forkert nøgle -> 404
|
|
r = c.post("/erindringer/api/naeste", json={"projekt": "test-ep", "samtale": None, "noegle": "x" * 40}); assert r.status_code == 404
|
|
# indlogget familie: dagbog findes, admin-person-side, eksport
|
|
login(c, adm)
|
|
r = c.post("/erindringer/api/naeste", json={"projekt": "dagbog", "samtale": None, "noegle": ""}); assert r.status_code == 200, r.text
|
|
print("dagbog Q", r.json()["spoergsmaal"])
|
|
r = c.get(f"/admin/erindringer/p/{pid}"); assert r.status_code == 200 and "Rettet tekst." in r.text
|
|
r = c.get(f"/admin/erindringer/p/{pid}/eksport.zip"); assert r.status_code == 200 and r.headers["content-type"] == "application/zip" and len(r.content) > 1000
|
|
r = c.post(f"/admin/erindringer/p/{pid}/klip/{s1['id']}", data={"handling": "favorit", "favorit": "1"}, follow_redirects=False); assert r.status_code == 303
|
|
assert erindringer.klip(pid, s1["id"])["favorit"] is True
|
|
r = c.post(f"/admin/erindringer/person/{pid}", data={"handling": "luk"}, follow_redirects=False); assert r.status_code == 303
|
|
login(c, None)
|
|
r = c.post("/erindringer/api/naeste", json={"projekt": "test-ep", "samtale": None, "noegle": noegle}); assert r.status_code == 404
|
|
print("ALT OK")
|