Skip to main content

Overview

Vendor clients call live third-party APIs, so they aren’t part of the unit suite. You verify them two ways: the vendor 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:
Credentials come from the same 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

Check the URL is well-formed and carries your scopes / 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 on HTTP_PORT, default 8080):
Confirm that fetching before verifying is refused, and that a second user can’t bind the same 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 plain http://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 to localhost:8080, and a hosts-file entry mapping your production callback domain to 127.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_URL during local testing).
The point is to present the vendor with the exact HTTPS callback URL it expects without deploying for every change.

What to cover

Valid credentials → auth-url builds, fetch returns documented JSON for each supported domain, signed webhook verifies, revoke succeeds.
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.
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