Antispam: online checks no longer switch off Bayes; replies teach ham
- The "online reputation checks" rspamd profile used groups_enabled, which means ONLY those groups: with the switch on, a message got the RBL lookups alone (1 rule instead of 19, score 0.00) and Bayes never ran, so every spam lesson was ignored. It now disables nothing. - A reply or reply-all teaches the answered message as ham (not forwards or new mail, not one's own Sent/Drafts, never over an explicit spam mark; once per message). message.sent now carries the draft's kind and reply_to_message_id. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -541,3 +541,50 @@ async def test_done_accounts_are_skipped_unless_forced(monkeypatch: pytest.Monke
|
||||
await jobs.bootstrap_account({}, user_id=str(uuid.uuid4()), account_id=account, force=True)
|
||||
assert ran == [True] # the button re-runs it
|
||||
assert kv.written == [] # already listed: not appended twice
|
||||
|
||||
|
||||
def _sent(kind: str = "reply", replied: str | None = "m") -> dict[str, Any]:
|
||||
return {
|
||||
"user_id": str(uuid.uuid4()),
|
||||
"kind": kind,
|
||||
"reply_to_message_id": str(uuid.uuid4()) if replied else None,
|
||||
}
|
||||
|
||||
|
||||
async def test_a_reply_teaches_ham(wired) -> None: # type: ignore[no-untyped-def]
|
||||
fake = wired()
|
||||
await hook.on_message_sent(_sent("reply_all"))
|
||||
assert fake.taught == [False]
|
||||
assert fake.recorded == [{"verdict": "ham", "action": "none"}]
|
||||
assert fake.published[0][1]["verdict"] == "ham"
|
||||
|
||||
|
||||
@pytest.mark.parametrize("kind", ["forward", "new"])
|
||||
async def test_forwards_and_new_mail_teach_nothing(wired, kind) -> None: # type: ignore[no-untyped-def]
|
||||
fake = wired()
|
||||
await hook.on_message_sent(_sent(kind))
|
||||
assert fake.taught == []
|
||||
|
||||
|
||||
@pytest.mark.parametrize("learned", ["ham", "spam"])
|
||||
async def test_a_reply_does_not_overrule_or_repeat_a_lesson(wired, learned) -> None: # type: ignore[no-untyped-def]
|
||||
fake = wired(learned=learned)
|
||||
await hook.on_message_sent(_sent())
|
||||
assert fake.taught == []
|
||||
|
||||
|
||||
async def test_a_reply_to_ones_own_message_teaches_nothing(wired) -> None: # type: ignore[no-untyped-def]
|
||||
fake = wired()
|
||||
|
||||
async def _own(*_a: object, **_k: object) -> dict[str, Any]:
|
||||
return {"account_id": "acc-1", "mailbox_special_use": "sent"}
|
||||
|
||||
fake.messages.envelope = _own
|
||||
await hook.on_message_sent(_sent())
|
||||
assert fake.taught == []
|
||||
|
||||
|
||||
async def test_a_reply_while_the_engine_is_down_records_nothing(wired) -> None: # type: ignore[no-untyped-def]
|
||||
fake = wired(engine_up=False)
|
||||
await hook.on_message_sent(_sent())
|
||||
assert fake.taught == [False] and fake.recorded == []
|
||||
|
||||
Reference in New Issue
Block a user