"""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