Skip to content

Testes: instalar Vitest + primeiro suite na fronteira anti-cheat (sanitizeResults) e rodar no CI #31

Closed

Description

@caioross

Contexto

O projeto tem zero testes automatizados e nenhum test runner: package.json só expõe dev/build/start/typecheck/lint/db:migrate — não há test, nem Vitest/Jest nas devDependencies. A única "cobertura" hoje são scripts .mjs ad-hoc (scripts/validate-persistence.mjs, .claude/skills/*/scripts/validate-metrics.mjs) que a CI não roda (.github/workflows/ci.yml = typecheck + build). Isso é a dívida nº1 do backlog.

O melhor primeiro alvo já existe puro e pronto para teste: a fronteira anti-cheat do leaderboard em src/lib/room.ts:123 (sanitizeResults) + clampInt (room.ts:107). É código security-critical — a API roda com service_role e sanitizeResults é o único guardião das tabelas públicas matches/scores (ver comentário room.ts:93-104). Uma regressão aqui corrompe silenciosamente o ranking global (foi exatamente a classe de bug de #7 e #28), e nada na CI hoje pegaria.

O próprio docstring de sanitizeResults (room.ts:121) já afirma "coberto por scripts/validate-persistence.mjs" — mas isso é um script solto, não um teste versionado que roda no CI. Esta issue transforma essa promessa em rede de segurança real.

Escopo

  1. Adicionar Vitest como devDependency (runner leve, dev-only — não entra no bundle de runtime, respeita HANDBOOK §7.1 sobre deps pesadas de runtime). Config mínima (vitest.config.ts) com environment: 'node' (as funções-alvo são puras, sem DOM).
  2. Script "test": "vitest run" (e opcionalmente "test:watch": "vitest") em package.json.
  3. Primeiro suite src/lib/room.test.ts cobrindo sanitizeResults e clampInt.
  4. A CI (.github/workflows/ci.yml) passa a rodar pnpm test como etapa do gate.

Acceptance criteria (verificáveis)

  • pnpm test existe e roda; sai verde com o novo suite.
  • Vitest está em devDependencies (não em dependencies); pnpm build continua verde e o bundle de produção não muda.
  • src/lib/room.test.ts cobre, no mínimo, para sanitizeResults:
    • input não-array → [];
    • linha com wpm > MAX_PLAUSIBLE_WPM (350) → descartada (não clampada) — caso do recorde 3596 WPM de Anti-cheat/Leaderboard: recorde impossível (3596 WPM) no Ranking Global — sem teto de plausibilidade #28;
    • linha com wpm negativo / NaN / não-finito → descartada;
    • name vazio após trim → descartada (score anônimo); name > MAX_NAME_LEN → truncado em 20;
    • accuracy fora de 0..100 → clampada para o intervalo;
    • array maior que room.max_players → cortado no cap; max_players inválido → cap absoluto 12 (ABSOLUTE_MAX_PLAYERS);
    • campos cosméticos (id/color/progress/finishedAt) preservados/normalizados como no código atual.
  • clampInt: NaN/não-finito → min; arredonda; respeita [min,max].
  • CI roda a suíte de testes (passo novo em ci.yml) e falha o build se um teste quebrar.

Dica de abordagem

  • Vitest integra com o tsconfig do Next sem transpiler extra; import { sanitizeResults, clampInt, MAX_PLAUSIBLE_WPM } from './room'. clampInt hoje não é exportado (room.ts:107) — exportá-lo é uma mudança segura de 1 linha, ou testá-lo indiretamente via sanitizeResults (accuracy/errors).
  • Reaproveite os casos que já existem em scripts/validate-persistence.mjs como fonte de casos-verdade — a ideia é migrar aquele conhecimento ad-hoc para um teste versionado que a CI executa (o script pode continuar existindo ou ser aposentado numa fatia futura; não é escopo desta issue removê-lo).
  • Gate (HANDBOOK §6): pnpm typecheck && pnpm build && pnpm test. Como adiciona dep nova leve + mexe na CI, o PR cai na área de quórum (§7.2) — abra non-draft com a linha Solicito quórum (HANDBOOK §7).

Activity

  1. added
    P1Alto valor — próximo da fila
    area:infraCI/CD, build, tooling, deploy, deps
    area:securityRLS, service_role, validação de entrada, segredos
    em-resolucaoClaim: um Resolvedor está trabalhando nisto
    and removed
    em-resolucaoClaim: um Resolvedor está trabalhando nisto
    on Jul 14, 2026
  2. caioross commented on Jul 14, 2026

    @caioross
    OwnerAuthor

    Resolvida em PR #33 — instala Vitest (dev-only) + src/lib/room.test.ts com 21 casos cobrindo sanitizeResults (incl. o recorde impossível de 3596 WPM de #28) e clampInt, e adiciona pnpm test ao gate do CI.

    Gate: typecheck ✅ · test 21/21 ✅ · build ✅ (bundle inalterado) · validate-persistence 33/33 ✅. PR non-draft com pedido de quórum (§7.2, mexe em CI + dep nova leve).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    P1Alto valor — próximo da filaarea:infraCI/CD, build, tooling, deploy, depsarea:securityRLS, service_role, validação de entrada, segredos

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions