fix: Die Meldung sagt jetzt, wenn die Gegenseite schon anderweitig verbunden ist

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
Scarriffle
2026-10-19 06:53:47 +02:00
co-authored by Claude Opus 5
parent b1f5eb9a51
commit 14254b483e
2 changed files with 72 additions and 0 deletions
+58
View File
@@ -455,3 +455,61 @@ def test_verknuepfte_buchungen_landen_nicht_in_uebersprungen(admin):
# Und sie bleibt unangetastet: kein Uebertrag, kein verschobenes Geld.
assert admin.get(f"/api/transactions/{raus['id']}").json()["type"] == "expense"
assert admin.get(f"/api/accounts/{pocket['id']}").json()["balance_cents"] == betrag
def _tx(admin, konto, typ, datum, cents, payee):
return admin.post("/api/transactions", json={
"type": typ, "date": datum, "account_id": konto["id"],
"amount_cents": cents, "payee": payee}).json()
def test_vergebene_gegenseite_wird_als_solche_benannt(admin):
"""Die Pruefung fragt „gibt es auf dem Zielkonto eine passende Buchung?",
nicht „ist sie noch frei?". Haengt die gefundene schon an einer anderen
Buchung, ist sie NICHT die Gegenseite dieser hier – und der Rat „verbinden"
geht ins Leere, denn die Vorschlagsliste laesst vergebene Buchungen aus.
Dann muss die Meldung sagen, was wirklich los ist."""
quelle = _kto(admin, name=f"Revolut {secrets.token_hex(3)}")
pocket = _kto(admin, name=f"Sparen Pocket {secrets.token_hex(3)}")
anderes = _kto(admin, name=f"Anderes {secrets.token_hex(3)}")
kennung = f"um chf sparen {secrets.token_hex(6)}"
betrag = 62 + secrets.randbelow(900)
# Der Zugang im Pocket gehoert schon zu einer Buchung vom dritten Konto.
zugang = _tx(admin, pocket, "income", "2026-05-20", betrag, "Pocket")
fremd = _tx(admin, anderes, "expense", "2026-05-20", betrag, "Fremd")
assert admin.post("/api/uebertraege/verbinden",
json={"a_id": fremd["id"], "b_id": zugang["id"]}).status_code == 200
# Und jetzt kommt die Revolut-Ausgabe, gleicher Tag, gleicher Betrag.
raus = _tx(admin, quelle, "expense", "2026-05-20", betrag, kennung.upper())
assert admin.post("/api/categories/transfer-keywords", json={
"word": kennung, "target_account_id": pocket["id"]}).status_code == 201
r = admin.post("/api/categories/keywords/anwenden", params={"vorschau": False}).json()
grund = next(z["grund"] for z in r["uebersprungen"] if z["text"] == kennung.upper())
assert "schon mit einer anderen Buchung verbunden" in grund
assert "Richtig ist hier, die beiden zu verbinden" not in grund, \
"zum Verbinden raten waere hier falsch – die Gegenseite ist vergeben"
# Geblockt wird weiter: kein Uebertrag, kein verschobenes Geld.
assert admin.get(f"/api/transactions/{raus['id']}").json()["type"] == "expense"
assert admin.get(f"/api/accounts/{pocket['id']}").json()["balance_cents"] == betrag
def test_freie_gegenseite_raet_weiter_zum_verbinden(admin):
"""Die Gegenprobe: Ist die Gegenseite noch frei, bleibt es beim alten Rat.
Sonst schluckte der neue Zweig alle Faelle."""
quelle = _kto(admin, name=f"Revolut {secrets.token_hex(3)}")
pocket = _kto(admin, name=f"Sparen Pocket {secrets.token_hex(3)}")
kennung = f"um chf sparen {secrets.token_hex(6)}"
betrag = 62 + secrets.randbelow(900)
_tx(admin, pocket, "income", "2026-05-20", betrag, "Pocket")
_tx(admin, quelle, "expense", "2026-05-20", betrag, kennung.upper())
assert admin.post("/api/categories/transfer-keywords", json={
"word": kennung, "target_account_id": pocket["id"]}).status_code == 201
r = admin.post("/api/categories/keywords/anwenden", params={"vorschau": False}).json()
grund = next(z["grund"] for z in r["uebersprungen"] if z["text"] == kennung.upper())
assert "Richtig ist hier, die beiden zu verbinden" in grund