Overview
Vendor clients call live third-party APIs, so they aren’t part of the unit suite. You verify them two ways: thevendor debug CLI (exercises one client’s operations in isolation, no server) and the HTTP routes on a running server (the ownership-gated bind → verify → fetch path).
Metadata (
VendorInfo) needs no credentials; transport operations need real credentials against the vendor.The vendor debug CLI
The cli/vendor.cpp tool (built under cli/ when MIROBODY_BUILD_TOOLS is ON — the default) drives one vendor’s contract operations directly. Subcommands:
MIROBODY_VENDOR_<ID>_* env vars the server uses.
1
Metadata (no credentials)
Confirm your
VendorInfo is complete and the id is registered:2
Authorize URL
state.3
Fetch
With a real access token, fetch a domain over a window:Verify the returned JSON matches the vendor’s documented shape, and that unsupported domains throw with a clear message.
4
Webhook (signed vendors)
Feed a captured payload and confirm signature verification:Pass a tampered body and confirm it’s rejected.
5
Revoke
For stub operations, the CLI prints the vendor’s “not implemented” reason — that’s expected and is itself worth asserting (the message should name why it’s a stub).
Against a running server
Exercise the ownership-gated HTTP path (all routes need a bearer JWT; the server listens onHTTP_PORT, default 8080):
external_user_id (the UNIQUE(vendor_id, external_user_id) backstop).
For an EHR (SMART on FHIR), walk the browser flow: /health/ehr/providers → /health/ehr/authorize → /health/ehr/callback → /health/ehr/sync, then read the persisted Observations back from /fhir/Observation.
Local HTTPS for OAuth callbacks
Many vendors reject non-HTTPS redirect URIs, so a plainhttp://localhost:8080 callback won’t work for a real consent flow. Options for local development:
- A local reverse proxy on port 443 terminating TLS (nginx / Caddy) with a trusted cert from
mkcert, forwarding tolocalhost:8080, and a hosts-file entry mapping your production callback domain to127.0.0.1— so the same redirect URI works locally and in production. - A tunneling service such as ngrok (also handy for inbound webhooks and for
MCP_PUBLIC_URLduring local testing).
What to cover
Happy path
Happy path
Valid credentials →
auth-url builds, fetch returns documented JSON for each supported domain, signed webhook verifies, revoke succeeds.Missing / wrong config
Missing / wrong config
Empty
api_key / client_id → a clear VendorError naming the missing env var. Required base_url (self-hosted / EHR) empty → refusal, not a guessed host.Edge cases
Edge cases
Unsupported
DataDomain throws; empty date window uses the vendor default; tampered webhook signature is rejected; a stubbed op reports its reason.Next steps
Provider Integration
Build the vendor you’re testing
Testing Guide
The Catch2 unit suite
OAuth Implementation
Consent, webhooks, revocation
Using Providers
The bind / verify / data routes