DEV-149 TESTING — Tests e2e del flujo crear/listar/ver personaje — test(e2e): add a black-box e2e for the character create/list/view flow#38
Open
LucianABC wants to merge 5 commits into
Conversation
DEV-149. Cover the MVP flow end-to-end against the real API: POST /characters -> GET list (character present) -> GET detail, plus the error paths (400 on values that don't match the Playbook template, 400 on a body that fails the request schema, 404 on a missing id). The scaffolded jest-e2e couldn't even start (it didn't map @db, so the Prisma client never resolved). Rework it into a self-contained black-box setup: globalSetup spins up an ephemeral Postgres via Testcontainers, runs prisma generate + migrate deploy, builds the app and boots node dist/src/main.js as a separate process; globalTeardown stops both. The app runs in real node rather than Test.createTestingModule because the Prisma 7 client (WASM engine) fails to initialize under ts-jest. The spec drives it over HTTP with supertest and seeds its own fixtures (System->Game->Playbook + User) with pg directly, so no Prisma is loaded in the jest process. Runs in CI after the build (Docker is available on ubuntu-latest); needs Docker locally too.
The e2e globalSetup failed in CI with 'webidl.util.markAsUncloneable is not a function': the undici bundled by Testcontainers 12 needs Node >=22, but the workflow pinned Node 20. Dev already runs on 22 and the project targets 20+, so bump the CI job to 22 (current LTS).
Address review findings on DEV-149: - Clean up on globalSetup failure: wrap the container/build/server steps in try/catch and stop the container + kill the server before rethrowing, so a failure mid-setup (where jest skips globalTeardown) doesn't leak them. - Formalize the Node requirement: Testcontainers' undici needs Node >=22.19. Add engines.node and .nvmrc, point CI at node-version-file, and update the CLAUDE.md/README claims (were 20+/18+). - Assert the full wire contract: check the exact key set of the created / listed / detail Character (so a dropped ownerId, timestamp, playbookVersion or the list enrichment fails the test) plus ISO date strings and the pagination meta, typed against the contract package. - Avoid fixed global resources: allocate a free port per run and name the bridge file per jest run (worker derives it from process.ppid), so two parallel runs or a busy port don't collide.
…EV-149/e2e-character-flow
Second review pass on DEV-149: - Fix start:prod: it pointed at 'node dist/main' but the build emits dist/src/main.js, so npm run start:prod failed with MODULE_NOT_FOUND. Point it at dist/src/main.js and boot the e2e server WITH that command (test/e2e/server.ts) so the deployable command is exercised — a future break of it now fails the e2e. - Build once: move prisma generate + build out of globalSetup into the test:e2e script; globalSetup only does what depends on the container (migrate + start server). CI reuses its Build step via test:e2e:run instead of rebuilding. - Exception-safe cleanup: on globalSetup failure and in globalTeardown, stop the server and the container via Promise.allSettled (a failing stop no longer masks the original error or skips the other cleanup), and wait for the server's exit event before resolving. - Align publish-contracts.yml with .nvmrc (was still Node 20). - expectIsoString: assert an exact ISO round-trip (new Date(v).toISOString() === v) instead of the laxer Date.parse.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
POST /characters→GET /characters(created one is in the list) →GET /characters/:id, plus error paths — 400 onvaluesthat don't match the Playbook template, 400 on a body that fails the request schema (emptyname), and 404 on a missing id. Runs withnpm run test:e2e.jest-e2e.jsondidn't map@db, so the Prisma client never resolved. Reworked it into a self-contained black-box setup instead:test/e2e/global-setup.tsspins up an ephemeral Postgres via Testcontainers, runsprisma generate+migrate deploy, builds the app and bootsnode dist/src/main.jsas a separate process;global-teardownstops both.Test.createTestingModule, on purpose: the Prisma 7 client (WASM engine) fails to initialize under ts-jest (deserializeParamGraphthrows). So the spec drives the API over HTTP withsupertestand seeds its own fixtures (System→Game→Playbook + User) withpgdirectly — no Prisma is loaded in the jest process.ubuntu-latest); document the setup and the Docker requirement inCLAUDE.md. Removed the boilerplateapp.e2e-spec.ts(its in-processAppModulebootstrap would load Prisma under jest).Test plan
npm run lintnpx tsc --noEmitnpm run test(unit — 50 tests, via pre-commit)npm run test:e2e— 4 tests, ran twice, all green, no leaked containers (needs Docker running)