fix(tests): Testsuite unabhängig von einer lokalen .env machen
Images bauen / build (backend) (push) Failing after 29s
Images bauen / build (frontend) (push) Failing after 30s
CI / backend (push) Successful in 2m6s
CI / frontend (push) Successful in 6m5s

Ohne backend/.env galt COOKIE_SECURE=true. Der Testclient spricht über http,
httpx verwarf die Secure-Cookies, und 106 Tests scheiterten mit 401. Lokal fiel
das nicht auf, weil dort eine nicht eingecheckte .env den Wert überschrieb – die
CI hat es aufgedeckt.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014e7t8UpmoVNMtWivY5LiSH
This commit is contained in:
Jonas Menzel
2026-09-09 17:25:34 +02:00
co-authored by Claude Opus 5
parent 55975338f9
commit bdf4097bd7
3 changed files with 606 additions and 0 deletions
+57
View File
@@ -0,0 +1,57 @@
"""CLI: Demodaten anlegen `python -m app.scripts.seed_demo [--reset]`.
Legt einen vollständigen deutschen Beispielhaushalt an: Konten, Firmen samt
Logos, wiederkehrende Posten, bestätigte Historie, Buchungen, Budgets und
Sparziele. Alle Termine liegen relativ zum heutigen Monat.
"""
import argparse
import asyncio
import sys
from app.db.session import SessionLocal, engine
from app.services.demo import has_data, seed_demo
async def main(reset: bool, resolve_logos: bool) -> int:
async with SessionLocal() as session:
if not reset and await has_data(session):
print(
"Es sind bereits Daten vorhanden. Mit --reset werden Konten, Firmen, "
"Posten, Buchungen, Budgets und Sparziele zuvor gelöscht.\n"
"Kategorien und Benutzer bleiben in jedem Fall erhalten.",
file=sys.stderr,
)
await engine.dispose()
return 1
ergebnis = await seed_demo(session, reset=reset, resolve_logos=resolve_logos)
await engine.dispose()
print(
"Demodaten angelegt:\n"
f" {ergebnis.accounts} Konten\n"
f" {ergebnis.merchants} Firmen ({ergebnis.logos} mit Logo)\n"
f" {ergebnis.recurrences} wiederkehrende Posten\n"
f" {ergebnis.occurrences} bestätigte Fälligkeiten\n"
f" {ergebnis.transactions} Buchungen\n"
f" {ergebnis.budgets} Budgets und Vorlagen\n"
f" {ergebnis.goals} Sparziele"
)
return 0
if __name__ == "__main__":
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument(
"--reset",
action="store_true",
help="Vorhandene Konten, Firmen, Posten, Buchungen, Budgets und Sparziele löschen.",
)
parser.add_argument(
"--no-logos",
action="store_true",
help="Logosuche überspringen schneller und ohne jeden Netzzugriff.",
)
args = parser.parse_args()
raise SystemExit(asyncio.run(main(args.reset, not args.no_logos)))