fix: Abruf sucht nach Datum statt nach "ungelesen"

Auf UNSEEN zu filtern klingt sparsam, ist aber eine Falle: Wer eine Mail in
seinem Mailprogramm ansieht, bevor Certain sie geholt hat, verliert sie
dauerhaft – sie ist dann fuer immer gelesen. Genau das ist passiert, als die
Mails vor dem ersten Abruf schon in Gmail geoeffnet waren: Ergebnis "0 neu",
ohne jeden Hinweis auf die Ursache.

Gesucht wird jetzt ab dem letzten Abruf mit einem Tag Ueberlappung; dass
nichts doppelt ankommt, sichert die Message-ID ab.

Die Meldung nennt ausserdem, wie viele Mails ueberhaupt geprueft wurden.
"0 neu" allein liess offen, ob nichts da war oder nichts passte.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
Guido
2026-08-22 20:25:47 +02:00
co-authored by Claude Opus 5
parent f3a08f2937
commit bfb6fa6b6d
5 changed files with 56 additions and 15 deletions
+27
View File
@@ -249,3 +249,30 @@ def test_uebergangene_mails_nennen_absender_und_betreff(admin, monkeypatch):
assert ergebnis["uebersprungen"] == 1
assert "raiffeisen.ch" in ergebnis["ohne_zuordnung"][0]["from"]
assert "Zahlungsstatus" in ergebnis["ohne_zuordnung"][0]["subject"]
def test_bereits_gelesene_mail_wird_trotzdem_geholt(admin, monkeypatch):
"""Wer die Mail vorher im Mailprogramm ansieht, darf sie nicht verlieren.
Frueher wurde auf UNSEEN gefiltert – eine einmal geoeffnete Mail war damit
fuer Certain unsichtbar, und das ohne jeden Hinweis.
"""
konto = _konto(admin)
quelle = _postfach(admin)
admin.post(f"/api/mail/sources/{quelle['id']}/senders", json={
"from_contains": "raiffeisen.ch", "account_id": konto["id"]})
class NurGelesene(FakeImap):
def search(self, charset, kriterium):
# Ein Server, der auf UNSEEN nichts liefert – wie bei einer Mail,
# die man schon angesehen hat.
assert "UNSEEN" not in kriterium, f"Es darf nicht auf UNSEEN gefiltert werden: {kriterium}"
return "OK", [b"1"]
roh = (MUSTER / "raiffeisen_zahlungsstatus.eml").read_bytes().replace(
b"<raiffeisen-muster-1@", b"<schon-gelesen-1@")
monkeypatch.setattr(mail_import, "_verbinden", lambda q: NurGelesene([roh]))
ergebnis = admin.post(f"/api/mail/sources/{quelle['id']}/fetch").json()
assert ergebnis["gefunden"] == 1
assert ergebnis["neu"] == 1