Backend Test Suite // Social discovery platform · under NDA
A backend test suite built where the runtime did not allow one
The client (covered under NDA) operates a social discovery platform for real-time, location-aware interaction — users discover nearby events, check in at venues, connect with attendees, and manage social profiles through a mobile app. The server side is a collection of Supabase Edge Functions: individually deployed, serverless TypeScript handlers behind a shared Hono routing layer, covering auth, events, profiles, venues, photo uploads, Stripe payments, and admin operations.
When Coralsoft joined the project, the backend had no test coverage. The challenge was not simply writing tests — it was building the testing infrastructure that made meaningful tests possible in a non-standard runtime. Edge Functions run on Deno; the natural test runner for TypeScript projects runs on Node. Bridging the two module systems without a transpilation step, mocking the Supabase query builder's fluent API faithfully, and doing all of this without ever touching a live database required deliberate infrastructure work before a single assertion could be written.
The product surface
The suite is structured around three testing levels. Every piece of behaviour that can be exercised without a live database or external network call is — the pyramid is deliberately weighted toward fast, isolated tests. The 50 test files span 13 feature modules including auth (OTP + magic link), event join and RSVP, event check-in, nearby discovery, photo uploads, Stripe webhooks, OAuth callbacks, and the admin panel.
Unit tests
Pure utility logic — phone normalisation, Haversine geofence, age calculation, SMS templates, magic link tokens, env config. Fast, isolated, no external dependencies.
Schema tests
Zod contracts tested independently — required fields, conditional rules, format patterns, character limits, date ordering. Validation logic exercised before it ever hits a handler.
Integration tests
Full HTTP handler path — real Hono context, real Zod validation, mocked Supabase and external services. Status codes and response bodies are asserted exactly as the client sees them.
Deno-to-Node bridge
Vitest module aliases map Deno-style ESM import URLs to Node package names at resolution time — allowing Deno TypeScript to run through Vitest in Node mode without a transpilation step.
Mock Supabase client
createMockSupabaseClient — a full reproduction of the Supabase JS query builder API as a tree of vi.fn() stubs. Per-table response queues, per-RPC overrides, storage path overrides, arbitrary chain length.
Stripe webhook coverage
Signature verification with timestamp tolerance, idempotent processing via event ID deduplication, four supported event types writing to different Supabase tables, structured error responses on both signature and schema failures.
Decisions, not just dependencies.
Three pieces of custom infrastructure make the entire suite possible. First, a Vitest module alias layer maps Deno-style ESM import URLs to their Node equivalents at resolution time — allowing Deno TypeScript to run through Vitest in Node environment mode without a transpilation step. Second, a Deno environment shim installs a Deno global that proxies env.get and env.set to a plain object reset between tests — no real credentials anywhere in the suite.
Third, and most significantly, createMockSupabaseClient — a full reproduction of the Supabase JS query builder API as a tree of vi.fn() stubs. It supports default responses, per-table overrides, per-RPC overrides, storage path overrides, and response queues for tests where the same table is queried multiple times in one request with different expected results. Fixture factories validate their output against the real Zod production schemas before returning — broken fixtures fail at creation time, not buried in assertion failures.
What was hard, and how we shipped it.
- 01
Deno-to-Node bridge without transpilation
Vitest module aliases map Deno ESM import URLs to Node package names at resolution time — making it possible to test Deno-authored TypeScript through Vitest in Node environment mode. No build step, no source transformation, no separate test runtime to maintain.
- 02
Full Supabase query builder mock
createMockSupabaseClient reproduces the fluent query builder API — including per-table response queues for fetch-then-update patterns — as configurable vi.fn() stubs. Zero live database calls in the entire suite.
- 03
Geofence unit coverage with 26 edge cases
Haversine formula tests cover equator and prime meridian crossing, antimeridian spanning, polar coordinates, boundary inclusivity, and distance symmetry — verifying geographic correctness for the nearby event and venue discovery flows.
- 04
Stripe webhook handler integration tests
Covers signature verification with frozen-time timestamp tolerance, idempotent processing via Stripe event ID deduplication, four event types writing to distinct Supabase tables, and structured error responses on both signature and schema failures.
- 05
CI/CD quality gates with coverage reporting
Every PR runs lint, Deno typecheck, build validation, and Vitest with coverage thresholds enforced. Coverage summaries are written to the GitHub Step Summary as a formatted markdown table; the full HTML report is uploaded as a workflow artifact.
Looking at a project that sits at this kind of seam?
Bring us the architecture, the constraints, and the ship date. We will bring the rest.