Merged
Size
M
Change Breakdown
Testing85%
CI/CD15%
#3438test: e2e auth baseline tests + webapp testcontainer infrastructure

End-to-end authentication test infrastructure added

A minimal end-to-end test harness using testcontainers now validates authentication behavior against throwaway Postgres and Redis databases. This baseline tracks regressions ahead of a planned RBAC migration.

An end-to-end test harness using testcontainers is being introduced to evaluate authentication behavior in the webapp. Instead of relying solely on unit tests, the compiled webapp is spawned as a child process alongside throwaway Postgres and Redis containers. This isolates the test environment, verifying API-key and JWT authorization flows from the network boundary down to the database level.

The infrastructure manages dynamic port allocation and overrides environment variables, ensuring that dependencies resolve correctly within forked processes. Eight baseline tests cover scenarios including missing headers, invalid keys, and empty-scope JWTs.

This suite establishes a regression check ahead of a planned RBAC migration. By freezing the current authentication logic, upcoming authorization changes can be merged without inadvertently altering existing token or key validation behavior.

View Original GitHub DescriptionFact Check
Fact Check Notice: The PR description mentions spawning against 'a throwaway Postgres container', but the final code also provisions and connects to a throwaway Redis container.

Adds a minimal end-to-end test harness that spawns the compiled webapp as a child process against a throwaway Postgres container, plus a baseline of 8 auth-behaviour tests. These tests will be used as a regression check before and after the upcoming apiBuilder RBAC migration to confirm auth behaviour is unchanged.

What's included

internal-packages/testcontainers/src/webapp.ts (new) Spawns build/server.js with a dynamically allocated port, polls /healthcheck, and exposes WebappInstance and startTestServer() (postgres container + webapp + PrismaClient in one call). Key details:

  • Uses process.execPath so the correct Node binary is found in forked test processes
  • Sets NODE_PATH to node_modules/.pnpm/node_modules so pnpm-hoisted transitive deps (e.g. eventsource-parser) resolve correctly inside the subprocess
  • Overrides both PORT and REMIX_APP_PORT so Vite's automatic .env loading doesn't override the dynamically allocated port

internal-packages/testcontainers/package.json Adds ./webapp sub-path export so tests can import from "@internal/testcontainers/webapp".

internal-packages/testcontainers/src/index.ts Exports createPostgresContainer (used internally by webapp.ts).

apps/webapp/test/helpers/seedTestEnvironment.ts (new) Creates a minimal org → project → environment row set with random suffixes.

apps/webapp/test/api-auth.e2e.test.ts (new) 8 tests across two suites:

  • API-key bearer: valid key (auth passes, 404), missing header (401), invalid key (401), error body shape
  • JWT bearer: valid JWT on JWT-enabled route (passes), valid JWT on non-JWT route (401), empty-scope JWT (403), wrong signing key (401)

How to run

# Build required first (one-time)
pnpm run build --filter webapp

cd apps/webapp && pnpm exec vitest run test/api-auth.e2e.test.ts

Test plan

  • All 8 tests pass against the current webapp build
  • Webapp healthcheck returns 200 on startup
  • CI passes
© 2026 · via Gitpulse