Adds the Mailpit HTTP client for BDD email assertions: MessagesTo/Get/AwaitMessageTo/PurgeMessagesTo. 3 build-tag-gated integration tests against live Mailpit (RoundTrip via real SMTP, AwaitTimeout, PurgeIsolation). Discovered Mailpit API quirk: /api/v1/messages?query= is for pagination, /api/v1/search?query=to:X is the actual filter endpoint — fix applied + documented in ADR-0030 + EMAIL.md. Run via 'docker compose up -d mailpit ; go test -tags integration -race ./pkg/bdd/mailpit/...'.
Adds the Mailpit HTTP client for BDD email assertions: MessagesTo/Get/AwaitMessageTo/PurgeMessagesTo. 3 build-tag-gated integration tests against live Mailpit (RoundTrip via real SMTP, AwaitTimeout, PurgeIsolation). Discovered Mailpit API quirk: /api/v1/messages?query= is for pagination, /api/v1/search?query=to:X is the actual filter endpoint — fix applied + documented in ADR-0030 + EMAIL.md. Run via 'docker compose up -d mailpit ; go test -tags integration -race ./pkg/bdd/mailpit/...'.
Adds the Mailpit HTTP API client used by BDD scenarios to assert on
emails sent during a test. Implements the per-recipient query/await/
purge pattern from ADR-0030.
Build-tag-gated integration tests run against the live Mailpit at
localhost:8025 (started via docker compose up -d mailpit).
Three operations on the client:
- MessagesTo(ctx, to) — list message IDs for a recipient
- Get(ctx, id) — fetch full message content (text, html,
headers, subject, etc.)
- AwaitMessageTo(ctx, to, — poll until a message arrives or timeout
timeout) (50ms polls, fail-fast on ctx cancel)
- PurgeMessagesTo(ctx, to) — delete all messages for a recipient
Tests in client_integration_test.go (build tag `integration`):
- RoundTrip: SMTP submit → list → get → assert subject/text — proves
the BDD-helper contract end-to-end via real SMTP
- AwaitTimeoutWhenNoMessage: bounded wait when no email arrives
- PurgeIsolation: per-recipient delete does NOT affect other recipients
Mailpit API quirk discovered + documented (Q-NNN candidate):
- /api/v1/messages?query=... is for PAGINATION, not filtering — the
`query` param there is silently ignored for filtering
- /api/v1/search?query=to:<addr> is the correct endpoint for filtering
AND the matching DELETE
- ADR-0030 + EMAIL.md updated with the correct endpoint
Run integration tests:
docker compose up -d mailpit
go test -tags integration -race ./pkg/bdd/mailpit/...
Out of scope for this PR (Phase A.3+):
- pkg/bdd/steps/email_steps.go BDD step definitions
- magic_link_tokens table + repository
- magic-link/request and magic-link/consume HTTP handlers
- BDD scenarios for the magic-link flow
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Adds the Mailpit HTTP client for BDD email assertions: MessagesTo/Get/AwaitMessageTo/PurgeMessagesTo. 3 build-tag-gated integration tests against live Mailpit (RoundTrip via real SMTP, AwaitTimeout, PurgeIsolation). Discovered Mailpit API quirk: /api/v1/messages?query= is for pagination, /api/v1/search?query=to:X is the actual filter endpoint — fix applied + documented in ADR-0030 + EMAIL.md. Run via 'docker compose up -d mailpit ; go test -tags integration -race ./pkg/bdd/mailpit/...'.
Adds the Mailpit HTTP API client used by BDD scenarios to assert on emails sent during a test. Implements the per-recipient query/await/ purge pattern from ADR-0030. Build-tag-gated integration tests run against the live Mailpit at localhost:8025 (started via docker compose up -d mailpit). Three operations on the client: - MessagesTo(ctx, to) — list message IDs for a recipient - Get(ctx, id) — fetch full message content (text, html, headers, subject, etc.) - AwaitMessageTo(ctx, to, — poll until a message arrives or timeout timeout) (50ms polls, fail-fast on ctx cancel) - PurgeMessagesTo(ctx, to) — delete all messages for a recipient Tests in client_integration_test.go (build tag `integration`): - RoundTrip: SMTP submit → list → get → assert subject/text — proves the BDD-helper contract end-to-end via real SMTP - AwaitTimeoutWhenNoMessage: bounded wait when no email arrives - PurgeIsolation: per-recipient delete does NOT affect other recipients Mailpit API quirk discovered + documented (Q-NNN candidate): - /api/v1/messages?query=... is for PAGINATION, not filtering — the `query` param there is silently ignored for filtering - /api/v1/search?query=to:<addr> is the correct endpoint for filtering AND the matching DELETE - ADR-0030 + EMAIL.md updated with the correct endpoint Run integration tests: docker compose up -d mailpit go test -tags integration -race ./pkg/bdd/mailpit/... Out of scope for this PR (Phase A.3+): - pkg/bdd/steps/email_steps.go BDD step definitions - magic_link_tokens table + repository - magic-link/request and magic-link/consume HTTP handlers - BDD scenarios for the magic-link flow