test: regression test suites for server and client#13
Merged
Conversation
Backend (jest, 87 new tests across 7 spec files): - games.service: move recording, game state transitions, result and rating handling, trimmed getGameCore selection shape - game-state.service: clock accounting, move application, draw offers - clock.service: timeout scheduling with grace period - matchmaking.service: queue join/leave, rating windows, expiry sweep - auth.service: credential validation, registration, refresh rotation - leaderboards.service: cache hit/miss and rank computation - game.gateway: move flow, resign, draw, spectate, queue handlers Frontend (vitest + testing-library + jsdom, 33 new tests): - Navbar: three-language rendering, ch-based width reservations, language switch persistence, auth vs anonymous variants, logout - i18n: locale key parity, meta title/description sync, html lang - auth and theme zustand stores: transitions and persistence keys - lib/utils: cn merging and clock formatting Also fixes the empty-suite vitest exit 1 that broke root pnpm test, and wires a Test job into the CI workflow.
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.
The MVP is feature-complete, so this PR adds a regression safety net over the behavior that works today. All tests are characterization tests: they lock in current semantics (mocked Prisma and Redis, no real database) so future iterations cannot silently break move handling, game endings, ratings, matchmaking, auth, or the trilingual UI.
Changes made
Backend (jest, mocked Prisma/Redis, 7 new spec files, 87 new tests):
games.service.spec.ts: game creation per time control, bot vs human rating snapshots, the trimmedgetGameCoreselection shape (scalars plus move count, never the move list), pagination,endGametransitions (active to ended, idempotent re-end, pgn rebuild, rating updates skipped for bot and abandoned games), move recording, abandongame-state.service.spec.ts: init state, clock charging with increment, zero clamp, promotion uci, draw offer lifecycle, move clears pending draw offer. Locks in that chess.js v1 throws on illegal moves instead of returning nullclock.service.spec.ts: 500ms grace period, cancel, reschedule replacement, per-game isolationmatchmaking.service.spec.ts: queue join/leave/re-join, 1200 default rating, base 100-point window, 50 points per 10s expansion capped at 400, cross-time-control isolation, coin-flip color assignment, expired entry sweep, bot game creationauth.service.spec.ts: credential validation (banned, wrong password), registration conflicts and the four rating rows, sha256-only refresh token storage, 7-day expiry, refresh rotation (old token revoked, new hash issued), expired token revocation, logout revoking all sessionsleaderboards.service.spec.ts: Redis cache hit skips the database, cache miss queries only 5+ game players and writes back with a 300s TTL, Redis read and write failures fall through safely, rank offsets by page, provisional players excluded from ranksgame.gateway.spec.ts: full move flow (inactive game, non-player, out of turn, illegal move, legal move broadcast plus clock scheduling), checkmate ends the game with rating deltas, resign awards the opponent, draw offer/accept/decline, spectate replays ended games and sends live clocks, queue matched notifications for both colorsFrontend (vitest + @testing-library/react + jsdom, 5 new test files, 33 new tests):
Navbar.test.tsx: renders in en/pt/es with translated labels, asserts the ch-based min-width classes that prevent layout shift on language switch, language buttons calli18n.changeLanguageand persist tochesskernel-lang, auth vs anonymous variants, logout calls the API and clears the sessioni18n.test.ts: pt and es have exactly the same key set as en,meta.title/meta.descriptionexist and are translated,document.titleand the meta description sync onlanguageChanged, pt maps to thept-BRhtml lang tagauth.store.test.tsandtheme.store.test.ts: zustand state transitions and localStorage persistence keysutils.test.ts:cntailwind conflict resolution andformatMsclock formattingInfrastructure:
client/vitest.config.ts(jsdom, reuses the vite aliases), fixing the empty-suite exit 1 that broke rootpnpm testjsdomand@testing-library/reactas client devDependencies.github/workflows/ci.yml(shared build, prisma generate,pnpm test), between Type Check and BuildTest plan
pnpm testat the root passes end to end: client 33/33 (5 files), server 95/95 (8 files, 87 new plus the pre-existing 8 glicko2 tests)pnpm -r buildclean (shared, client, server)pnpm typecheckclean for all three packagesIntentionally not covered: Stockfish analysis service and bots service (spawn external engine processes), presence service, controllers (thin passthroughs over the tested services), react-chessboard and Phaser internals, and socket reconnection flows (need a real socket server, better suited to an e2e suite). Client eslint was already failing on main because no eslint config file is committed; left untouched as out of scope.