Files
odysseus/tests/test_imap_move_uid.py
T

57 lines
1.7 KiB
Python

"""_imap_move must address messages by UID, not sequence number.
The auto-spam poller passes a real IMAP UID (from conn.uid("SEARCH", ...))
to _imap_move, but the function used conn.copy()/conn.store(), which operate
on message SEQUENCE NUMBERS. So a UID like 90521 was interpreted as sequence
number 90521 — moving/deleting the wrong message or silently no-oping. It
must use the UID commands.
"""
import sys
import types
import pytest
@pytest.fixture
def email_helpers(monkeypatch, tmp_path):
# Keep _init_scheduled_db (run at import) off the real data dir.
monkeypatch.setenv("ODYSSEUS_DATA_DIR", str(tmp_path))
import routes.email_helpers as eh
return eh
class _FakeIMAP:
def __init__(self):
self.calls = []
def select(self, mbox):
self.calls.append(("select", mbox)); return ("OK", [b""])
def copy(self, *a):
self.calls.append(("copy",) + a); return ("OK", [b""])
def store(self, *a):
self.calls.append(("store",) + a); return ("OK", [b""])
def uid(self, *a):
self.calls.append(("uid",) + a); return ("OK", [b""])
def expunge(self):
self.calls.append(("expunge",)); return ("OK", [b""])
def logout(self):
pass
def test_move_uses_uid_commands_not_seqnum(email_helpers, monkeypatch):
fake = _FakeIMAP()
monkeypatch.setattr(email_helpers, "_imap_connect", lambda *a, **k: fake)
ok = email_helpers._imap_move(b"90521", "Spam", src="INBOX")
assert ok is True
verbs = [c[0] for c in fake.calls]
uid_ops = [c[1] for c in fake.calls if c[0] == "uid"]
assert "COPY" in uid_ops and "STORE" in uid_ops
# the sequence-number commands must NOT be used to address a UID
assert "copy" not in verbs
assert "store" not in verbs