Testing
Testing
Section titled “Testing”Last updated: 2026-07-25 — ADR-9: finstack-rs deleted. Everything below describes that deleted backend’s test setup — historical reference only. finstack’s test pattern is vitest run per Worker (via @cloudflare/vitest-pool-workers, isolated Miniflare runtimes) — e.g. cd finstack/workers/<name> && npx vitest run. No repo-wide test runner or coverage doc exists yet for finstack.
Stack (historical — finstack-rs, deleted)
Section titled “Stack (historical — finstack-rs, deleted)”- Unit: Rust
#[test]/#[tokio::test]inside crate source files - Integration:
finstack-rs/tests/integration/— real Postgres (Neon); two pools:finstack_app(RLS-enforced) andfinstack_worker(BYPASSRLS for seeds). Never mocked. - E2E: Playwright (planned)
Running integration tests
Section titled “Running integration tests”# Set both pool URLsexport DATABASE_URL_APP="postgres://finstack_app:<pw>@<host>/finstack"export DATABASE_URL_WORKER="postgres://finstack_worker:<pw>@<host>/finstack"
# All integration testscargo test --package finstack-integration-tests
# Specific suitecargo test --package finstack-integration-tests --test http_payment_lifecyclecargo test --package finstack-integration-tests --test admin_provisioncargo test --package finstack-integration-tests --test refund_ledgerCoverage (as of 2026-05-19)
Section titled “Coverage (as of 2026-05-19)”| Area | Unit | Integration |
|---|---|---|
| primitive-payment | ✓ (FSM, serde, service) | ✓ (create/capture/refund) |
| primitive-ledger | ✓ | ✓ (balance, reversing entry) |
| primitive-customer | ✓ | ✓ |
| primitive-fraud | ✓ | ✓ |
| primitive-receipt | ✓ | ✓ |
| primitive-tax | ✓ | ✓ |
| primitive-tip | ✓ | ✓ |
| primitive-split | ✓ | ✓ |
| api-rest HTTP (/v1/payments) | — | ✓ (7 tests, PR #343) |
| api-admin (provision, auth, keys) | ✓ (require_admin guard ×4, ProvisionOut serde ×1) | ✓ (admin.rs + admin_provision.rs) |
| finstack-auth | ✓ | — |
| finstack-observability | ✓ (PR #343) | — |
| finstack-events | ✓ | ✓ |
| svc-orchestration | ✓ (36 unit) | ✓ (orchestration.rs — service layer + executor E2E with wiremock, PR #346; orchestration_e2e.rs — 4-step multi-primitive DAG) |
| svc-payfac | ✓ (derive_status_changed_at ×5, serde round-trip ×1) | ✓ |
| svc-compliance | ✓ (derive_status_changed_at ×5, serde round-trip ×1) | ✓ |
| primitive-payout | ✓ (derive_status_changed_at ×6, serde round-trip ×1, 2026-07-01) | — (no local Postgres available this session; stale-list mirrors the payfac_stale_for_secs.rs pattern and should get an equivalent integration test next time a DB is reachable) |
| svc-workflow | ✓ | ✓ (workflow.rs — start/replay/step/RLS; workflow_subdag.rs — DAG; workflow_auto_executor.rs — 7 tests: claim/complete/depends_on/retry/terminal/delay/SKIP LOCKED, PR #390) |
| primitive-analytics | ✓ (fact_from_event, PR #344) | ✓ (analytics.rs) |
| primitive-inventory | ✓ (validate_create_item, validate_adjust_stock, PR #344) | ✓ (inventory.rs) |
| primitive-loyalty | ✓ (validate_earn, validate_redeem, PR #345) | ✓ (loyalty.rs) |
| svc-composer | ✓ (TenantConfig::empty, UpdateTenantConfig, PR #344) | ✓ (composer.rs) |
| svc-database | — | ✓ (database.rs — provision ×2, scope rejection ×3, path-validation ×3) |
| svc-routing | ✓ (credentials.rs — AES-256-GCM encrypt/decrypt round-trip, tamper/short-input/bad-key rejection ×11, PR #428) | ✓ (svc_routing_processor_router.rs — ADR-5 routing precedence: label pin, method/currency intersection, priority, created_at tiebreak; route_payout processor_type filter; disabled-config exclusion; tenant-scoped load() IDOR guard ×8, 2026-07-07) |
| svc-platform | ✓ (model.rs — FundingRequestStatus as_str/parse round-trip + serde drift check ×5, PR #428) | ✓ (svc_platform_account_service.rs — get_or_create idempotency, credit accumulation, debit_if_sufficient atomicity, pending-payout balance calc, funding-request CRUD + idempotency + tenant scoping, complete/fail webhook-path methods on the correct BYPASSRLS pool, settlement_report aggregation, + 1 regression test documenting the BUGS.md pool-wiring bug on the RLS pool ×10, 2026-07-07) |
Seed pattern (CLAUDE.md)
Section titled “Seed pattern (CLAUDE.md)”Seeds that bypass service methods MUST use pool_worker() (BYPASSRLS).
Production-path queries MUST use pool() (RLS-enforced).
See tests/integration/src/lib.rs for fresh_tenant, mint_api_key, app_router.