gotta store my records
README.md

at-record e2e #

Real end-to-end tests against a fully local, deterministic atproto network (a PDS, jetstream, Constellation, Slingshot, Caddy for TLS on the test handles) — not the public network, so no indexing lag and no dependency on real accounts.

These exist for what the unit tests structurally can't cover: the real OAuth wire flow (PAR/PKCE/DPoP against a real PDS), and cross-account behavior that depends on real Constellation indexing (adoption, the edit-inbox). Business logic itself is already covered fast and in isolation by server/test/promotion_test.gleam and friends via injected Deps stubs — don't duplicate that here.

One-time setup #

make e2e-setup   # clones jetstream + microcosm-rs at pinned commits, generates devnet secrets

Running #

Three things need to be running:

  1. The devnet: make e2e-up (wipes any previous devnet state for a clean slate, boots fresh, waits for the PDS to be healthy, seeds the fixed alice.test/bob.test accounts).
  2. at-record's own dev server, pointed at the devnet:
    SLINGSHOT_URL=http://localhost:6790 CONSTELLATION_URL=http://localhost:6789 ./scripts/dev.sh
    
  3. The test suite: make e2e (this also does step 1 for you — running it standalone is only useful if you want to poke at the devnet by hand first).

make e2e-down tears the devnet down and wipes its volumes when you're done.

Why fixed test handles, not generated per run #

Caddy's TLS termination and the PDS's network alias are declared per-handle in devnet/docker-compose.yml and devnet/Caddyfile (atproto's bidirectional handle verification needs a real, if locally-CA-signed, TLS endpoint for each handle — see the devnet's own README for why). Adding a handle means declaring it in both places, not just calling create-test-accounts.sh with a new name. make e2e-up wipes and reseeds the same two accounts fresh each run instead, which is enough isolation for now — revisit if tests start needing more than two accounts at once.

Pinned dependencies #

devnet/setup.sh clones bluesky-social/jetstream and microcosm.blue/microcosm-rs at specific commits, not main. Both are under active, fast-moving development with no published container image matching their current main — pinning is what keeps this reproducible. Re-pin deliberately (edit the SHAs in setup.sh, rm -rf the old clones, re-run make e2e-setup) when there's a reason to, not by accident.