from types import SimpleNamespace from pneumatube.smol_to_email import SmolToEmailBridge class _StubSmol: SmolError = RuntimeError def cmd_fetch(self, args, store): pass class _StubStore: def __init__(self, rows): self._rows = rows self.requested_box = None def mail(self, box): self.requested_box = box return self._rows def _config(**overrides): defaults = {"smolmail_key": "k", "smolmail_db": "d", "require_accepted_sender": True} return SimpleNamespace(**{**defaults, **overrides}) def test_poll_once_does_not_stop_after_one_message_fails(): """A message that keeps raising out of _relay() (e.g. a value smtp_client.send() rejects that _relay()'s own except clause doesn't cover) must not block every message behind it -- it always sorts first on the next poll, since only a successful _relay() deletes it.""" rows = [(b"poison", b"", 0, None), (b"ok", b"", 1, None)] bridge = SmolToEmailBridge(_StubSmol(), _StubStore(rows), account=None, config=_config()) relayed = [] def fake_relay(mid, envelope): if mid == b"poison": raise ValueError("simulated failure unrelated to InvalidAddress/OSError") relayed.append(mid) bridge._relay = fake_relay bridge.poll_once() assert relayed == [b"ok"] def test_poll_once_uses_main_tier_only_by_default(): """require_accepted_sender=True (the default) must poll "inbox" (main tier), not "all" -- "all" would include requests-tier mail from first-contact senders with no accept token (SPEC.md S5.8), which is exactly what this setting exists to keep the gateway from relaying.""" store = _StubStore([]) bridge = SmolToEmailBridge(_StubSmol(), store, account=None, config=_config()) bridge.poll_once() assert store.requested_box == "inbox" def test_poll_once_uses_all_tiers_when_open_bridge_enabled(): store = _StubStore([]) bridge = SmolToEmailBridge(_StubSmol(), store, account=None, config=_config(require_accepted_sender=False)) bridge.poll_once() assert store.requested_box == "all"