email-connect/tests/test_harness_users.py

125 lines
3.6 KiB
Python
Raw Normal View History

"""Test-user addressing and reset contract for the local mail harness.
The slug and config cases run offline. The cases that talk to the harness are
skipped unless it is up, so the default suite stays container-free.
"""
from __future__ import annotations
import imaplib
import tempfile
from pathlib import Path
import pytest
import harness
requires_harness = pytest.mark.skipif(
not harness.available(),
reason="mail harness not running: docker compose -f tests/harness/docker-compose.yml up -d",
)
def mailbox_count(user_address: str) -> int:
connection = imaplib.IMAP4(harness.HOST, harness.IMAP_PORT)
try:
connection.login(user_address, harness.PASSWORD)
_status, data = connection.select("INBOX", readonly=True)
return int(data[0])
finally:
connection.logout()
@pytest.mark.parametrize(
("name", "expected"),
[
("alpha", "alpha"),
("invitation resend", "invitation-resend"),
("Invitation Resend", "invitation-resend"),
("test_user_01", "test-user-01"),
(" spaced ", "spaced"),
("weird!!name??", "weird-name"),
],
)
def test_address_is_a_deterministic_slug(name, expected):
assert harness.address(name) == f"{expected}@{harness.DOMAIN}"
assert harness.address(name) == harness.address(name)
def test_address_rejects_names_with_no_slug():
with pytest.raises(ValueError):
harness.address("!!!")
def test_addresses_use_the_reserved_test_tld():
assert harness.DOMAIN.endswith(".test")
def test_mailbox_config_sets_credential_environment(monkeypatch):
monkeypatch.delenv(harness.IMAP_USER_ENV, raising=False)
monkeypatch.delenv(harness.IMAP_PASSWORD_ENV, raising=False)
user_address = harness.address("config probe")
config = harness.mailbox_config(user_address, storage_path="state.sqlite", reports_dir="reports")
import os
assert os.environ[harness.IMAP_USER_ENV] == user_address
assert os.environ[harness.IMAP_PASSWORD_ENV] == harness.PASSWORD
assert config.mailbox.protocol == "imap"
assert config.mailbox.host == harness.HOST
assert config.mailbox.port == harness.IMAP_PORT
assert config.mailbox.tls is False
assert config.scan.mark_seen is False
@requires_harness
def test_reset_clears_users_and_mail():
harness.reset()
recipient = harness.address("reset probe")
harness.smtp_provider().send(recipient, "Probe", "body")
assert mailbox_count(recipient) == 1
assert any(user["email"] == recipient for user in harness.users())
harness.reset()
assert harness.users() == []
assert mailbox_count(recipient) == 0
@requires_harness
def test_named_test_users_get_isolated_mailboxes():
harness.reset()
first = harness.address("isolation one")
second = harness.address("isolation two")
provider = harness.smtp_provider()
provider.send(first, "For first", "body")
provider.send(first, "For first again", "body")
provider.send(second, "For second", "body")
assert mailbox_count(first) == 2
assert mailbox_count(second) == 1
@requires_harness
def test_scanner_reads_a_harness_mailbox():
harness.reset()
recipient = harness.address("scanner probe")
harness.smtp_provider().send(recipient, "Scanner probe", "body text")
from email_connect.scanner import scan_mailbox
with tempfile.TemporaryDirectory() as tmp:
root = Path(tmp)
config = harness.mailbox_config(
recipient,
storage_path=str(root / "state.sqlite"),
reports_dir=str(root / "reports"),
)
result = scan_mailbox(config)
assert result.scan.messages_seen == 1
assert result.scan.messages_new == 1