Skip to content

feat(stability): Phase 5 — test coverage hardening - #3

Open
dariusvorster wants to merge 18 commits into
mainfrom
stability/phase5-test-coverage
Open

feat(stability): Phase 5 — test coverage hardening#3
dariusvorster wants to merge 18 commits into
mainfrom
stability/phase5-test-coverage

Conversation

@dariusvorster

Copy link
Copy Markdown
Owner

Summary

  • Added property-based tests for buildCaddyRoute and applyDockerDns using fast-check (P1–P6)
  • Added migration integrity tests for Phase 4 schema columns using in-memory SQLite (5E)
  • Added Caddy round-trip integration tests with CADDY_ADMIN_URL skip guard (5A)
  • Added tRPC route mutation tests with in-memory DB, RBAC mocks, and conflict detection (5C)
  • Added Playwright E2E test for full route management flow (5B)
  • Added CI workflow gating all test suites, typecheck, and shadow guard on every PR (5F)
  • Fixed RT2 doubled route ID prefix (roundtrip-test not proxyos-roundtrip-test)
  • Fixed P6 to be genuinely property-based using routeArb arbitrary

Test Plan

  • pnpm --filter @proxyos/caddy test — 65 passed, 3 skipped
  • pnpm --filter @proxyos/db test — 7 passed
  • pnpm --filter @proxyos/api test — 5 passed
  • CI workflow triggers on push/PR to main

🤖 Generated with Claude Code

Darius Vorster and others added 18 commits April 22, 2026 11:55
…oxy transports (4A)

Adds applyDockerDns() wrapper that injects resolvers: ['127.0.0.11'] and
dial_timeout: '3s' into every reverse_proxy handler's transport block,
ensuring Caddy re-resolves container names on each dial instead of caching
the IP at config load time. Applied in bootstrap and all three buildCaddyRoute
call sites in routes.ts (syncRouteToCaddy, create, expose).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…yDockerDns

- apply-docker-dns.ts: use (route.handle ?? []).map(...) to prevent throw when handle is undefined
- bootstrap.ts: always wrap opts.buildRoute with applyDockerDns so Docker DNS resolvers are never skipped when a caller provides a custom build function

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…ty check (4D)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Extends the existing Cloudflare tunnel deployment doc with a new section
covering how to survive ProxyOS container rebuilds: user-defined Docker
network, container-name upstreams in cloudflared config, removal of
healthcheck (distroless incompatibility), sidecar alternative, and a note
on how Task 4A's 127.0.0.11 resolver makes ProxyOS's own upstreams
rebuild-resilient when using container names.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
… is lost (4C)

Replace the generic enrollment error with a structured message that names
the missing identity file path and provides two concrete recovery paths
(volume restore or re-enrollment via PROXYOS_AGENT_TOKEN). Update the
instrumentation.node.ts catch block to surface the identity-lost message
directly rather than wrapping it in a generic failure log.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Replace :latest tags with ghcr.io/proxyos/proxyos:1.0.0 and
cloudflare/cloudflared:2025.4.1 in all three docs files, and add an
upgrade-path note in each file.
Verifies ProxyOS survives ProxyOS container recreation and upstream
container recreation, including DNS re-resolution detection.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Single-container architecture uses s6-overlay for intra-container
ordering: caddy starts first, proxyos polls the admin API before
exec-ing node, and bootstrapProxyOs() runs migrations then
waitForCaddyReady() before pushing routes. docker-compose depends_on
is not applicable — one service, no inter-container ordering needed.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
… smoke test (4G)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…ckerDns (5D)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
… tests (5D)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Replace hardcoded routeWithHeaders fixture with fc.assert(fc.property(routeArb, ...))
that verifies built-in request header names match /^[\w-]+$/ and all values are
non-empty strings across all generated routes.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…ntainer (5A)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
5 tests for routes.create: happy path, validation error (empty domain),
unauthorized (no session), forbidden (viewer role), and duplicate domain
conflict. Uses getDb() singleton over :memory: with per-test table reset,
vi.mock for rbac/caddy/federation, and vitest forks pool for native addon
compatibility.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Adds playwright.config.ts, tests/e2e/routes.spec.ts covering login →
expose route → verify in list → edit name → save → delete flow. CI job
scaffolded in ci.yml with if:false pending full container setup.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…refix

- Change TEST_ROUTE_ID from 'proxyos-roundtrip-test' to 'roundtrip-test'
  so buildCaddyRoute/caddyRouteId produces 'proxyos-route-roundtrip-test'
  instead of the doubled 'proxyos-route-proxyos-roundtrip-test'
- Import caddyRouteId from '../config' and use it in the RT2 assertion
- Add 'Run API unit tests' step to CI test job after DB migration tests

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant