Skip to main content

Testing the Inbound Email System

Running Tests

# All inbound email integration tests
TEST_TYPE=integration:http jest --testPathPattern="inbound-emails"

# A specific test by name
TEST_TYPE=integration:http NODE_OPTIONS="--experimental-vm-modules" \
jest --testNamePattern="should extract order data"

Test File

integration-tests/http/inbound-emails-api.spec.ts

Uses the shared test setup (setupSharedTestSuite, createAdminUser, getAuthHeaders).

Test Helper

Tests seed data directly via the module service:

const createTestEmail = async (overrides = {}) => {
const service = container.resolve("inbound_emails")
return service.createInboundEmails({
imap_uid: `uid_${Date.now()}_${Math.random().toString(36).slice(2)}`,
from_address: "[email protected]",
to_addresses: ["[email protected]"],
subject: "Order Confirmation #12345",
html_body: "<html>...<table>..items..</table>...</html>",
folder: "INBOX",
received_at: new Date(),
status: "received",
...overrides,
})
}

Test Coverage

Service-Level CRUD (6 tests)

TestWhat's Verified
Create recordID has inb_email_ prefix, fields stored correctly
Retrieve by IDReturns matching record
List + count with filtersStatus filter works, count is accurate
Update recordStatus and action_type update correctly
Delete recordRecord no longer retrievable
JSON and nullable fieldsmetadata, to_addresses stored/returned as JSON; nullable fields accept null

GET /admin/inbound-emails (10 tests)

TestWhat's Verified
Empty listReturns { inbound_emails: [], count: 0, offset: 0, limit: 20 }
Paginationlimit and count work correctly
Offset paginationDifferent records on different pages
Status filterOnly matching status returned
from_address filterExact match works
folder filterExact match works
Search by subject (q)Partial match on subject
Search by from_address (q)Partial match on sender
Excluded heavy fieldshtml_body, text_body, extracted_data, action_result not in list
Invalid statusReturns 400
UnauthenticatedReturns 401

GET /admin/inbound-emails/:id (3 tests)

TestWhat's Verified
Full detailAll fields including html_body and to_addresses returned
Non-existent IDReturns 404
UnauthenticatedReturns 401

POST /admin/inbound-emails/:id/extract (7 tests)

TestWhat's Verified
Extract order dataorder_number, currency, items extracted from HTML
Status updateChanges to action_pending, stores extracted_data
Unknown action typeReturns 400
Missing action_typeReturns 400
Non-existent emailReturns 404
Table-based item extractionItems parsed from <table> rows
IdempotencyExtracting twice returns same data

POST /admin/inbound-emails/:id/ignore (5 tests)

TestWhat's Verified
Set statusReturns { status: "ignored" }
PersistenceDetail endpoint confirms status change
IdempotentIgnoring already-ignored email works
Non-existent emailReturns 404
From any statusWorks on action_pending emails too

GET /admin/inbound-emails/actions (3 tests)

TestWhat's Verified
Lists actionsArray with at least 1 action
Action metadatacreate_inventory_order has type, label, description
No internal functionsResponse doesn't include extract or execute methods

POST /admin/inbound-emails/:id/execute (4 tests)

TestWhat's Verified
Missing action_typeReturns 400
Missing paramsReturns 400
Unknown action typeReturns 400
Non-existent emailReturns 404

POST /admin/inbound-emails/sync (2 tests)

TestWhat's Verified
IMAP not configuredReturns error (test env has no IMAP vars)
Count parameterPasses validation

Lifecycle (1 test)

TestWhat's Verified
Full flowreceived → extract → action_pending → filter works → ignore → ignored

Edge Cases (5 tests)

TestWhat's Verified
Minimal HTMLEmpty items array, no crash
Empty HTML bodyHandles gracefully
Concurrent requestsExtract + detail in parallel don't conflict
Special characters in email[email protected] stored correctly
Long subjects500-char subject stored and returned

Adding Tests for New Actions

When adding a new action, add tests for:

  1. Extract — verify extracted data shape for the new action type
  2. Execute — verify the action creates the expected records (mock or real)
  3. Validation — verify required params are enforced
  4. Error handling — verify errors are stored on the email record