lupin.Open console
Email

Test an email agent with fixtures instead of live recipients

Build a focused offline suite for parsing, permissions, retries and review boundaries.

Choose behaviors with real failure consequences

An email-agent test suite should prove that a received message becomes the correct bounded work item and that uncertain or unauthorized actions do not become real sends. Start with a normal incoming request, a quoted reply, a quarantined message and a duplicate webhook. Add a draft that changes after review and a provider timeout after acceptance. These cases exercise the boundaries where a superficially successful model response can hide a serious application error. Avoid tests that merely assert a helper returned the same hardcoded text it was given.

Use realistic synthetic message structure

Include sender and recipient fields, timestamps, stable message and thread IDs, labels, extracted_text, attachment metadata and a raw-source fixture where MIME behavior matters. Use example.test or example.com addresses and harmless bytes instead of copying a customer’s correspondence into the repository. Preserve structural oddities such as folded headers, repeated subjects or quoted replies without retaining personal information. A useful fixture describes the condition it represents and the expected result. Record parser warnings explicitly so a malformed attachment does not disappear behind a generic processed status.

Exercise authorization at the transport boundary

Run requests against an isolated local Hono and SQLite/D1-compatible setup where available, with fixture keys for workspace, project, inbox and restricted bootstrap access. Check actual status and structured error codes for missing permissions and cross-scope resource IDs. Mock provider adapters so no mail provider, phone service or payment endpoint can be contacted. A fake model response alone cannot prove server-side ownership enforcement. Test the same routes and dispatch path the real client uses, while keeping every external provider disabled or replaced by a deterministic local stub.

Inject failures around durable state

Simulate a lost response after provider acceptance and verify a retry preserves the same idempotency key. Deliver the same verified webhook twice and assert one queue record. Crash the worker after recording a page’s partial progress, then resume without repeating completed local classifications or external effects. Test invalid signatures before JSON parsing and a stale approval after a recipient change. These cases should assert provider call count, stored operation state and the user-facing outcome together; a 200 response alone does not establish that duplicate prevention worked.

Keep verification claims proportional

Label examples source-reviewed when they were checked against code but not executed. Label them tested only when the stated behavior was actually exercised in a safe fixture and retain enough detail to reproduce it. Offline coverage does not prove DNS propagation, production provider configuration or recipient delivery. Reserve any live integration smoke for a separately authorized controlled environment. Your next step is a small fixture manifest with the input, failure injection and expected evidence for each boundary, then run only those checks needed to validate the workflow you are implementing.

Assert the final user-facing statement

A fixture should inspect the completion message as well as database state. After an attachment parser fails, the response must not say that the document was reviewed. After a draft is created, it must not say the email was sent. These assertions catch a practical class of errors where infrastructure behaves correctly but the agent misleads the user.

Sources & verification

Reviewed against checked-in Lupin API handlers and documentation. Example requests were not executed against live providers.

Prepared with AI assistance by Lupin editorial. How we research and maintain these guides.

Put it into practice

Give your agent the right tools.

Review the API, workspace requirements and permissions before enabling a workflow.

Explore email Register an agent