teqo/docs/TESTING.md
Francisco Ignácio Fontoura Solla adc0f31f5b Sync all project docs with the deployed remodel and hardening; compile roadmap
- Compile docs/roadmap.md into a next-steps document (277→206 lines): R0–R5/M1–M5
  tables and the delivered map/list item paragraphs compressed into 'Já entregue';
  janelas, grafo and cortes list only open IDs; C10/C11/C8 fill-ins keep their
  original triggers; C5 moved under 'A validar'.
- Record the production deploy of the destructive remodel chain (2026-07-23 Vercel
  builds) across roadmap, AGENTS.md, the project notebook and plans — supersedes
  every 'deploy pendente'; smoke pós-deploy + onboarding remain the open blockers.
- Fix AGENTS.md internal contradictions: Município locked-decisions bullet (435,
  Camaçari whole, candidate role), campaignUser role enum, deploy-checklist item 7
  as historical, access/* structure note, election-aggregates artifact +
  election-tse revalidate runbook.
- Sync open plans to real identifiers (plaza*/nucleus* → municipality*): the
  intelligence program (master + E8–E15/B13/C12 with artifact/caching context and
  satisfied deps), B8 rescoped to Salvador ZE 1–19 only, WhatsApp D3–D5, D2, A6
  (now the insight layer over stateDeputy), RS+, onda-0 smoke step.
- Close items verified done in code: C8 F4 (DRY de forms) complete, filtros-auto
  shared pending shell, petition generateStaticParams select/depth; ledger the
  surviving user-visible 'Praça' copy in src as new P2 debt.
- Banner delivered praça-era plans (production note + rename pointer); mark
  remodelagem-pracas.md superseded and remodelagem-municipios.md delivered.
- TECH-DEBT smell statuses, TESTING RBAC row, README quality gates, campanha
  UI rules updated to current component names.
2026-07-24 02:04:45 -03:00

5.7 KiB

Testing

Test Strategy

Three layers, all local-database-only (see local-database skill; tests refuse any database not ending in _test):

  • Unit (tests/unit/**/*.unit.spec.ts, 33+ specs): pure logic; runs with a deliberately invalid DATABASE_URL so nothing can touch a database.
  • Integration (tests/int/**/*.int.spec.ts, 42+ specs): real Payload + Postgres (teqo_test); campaign fixtures allocate seeded municipalities via a Postgres sequence so parallel spec files never share one, and purge residue on claim. Shared consent rows with stable keys are leased (tests/helpers/testDatabaseLease.ts), never owned.
  • E2E (tests/e2e, Playwright, 5 specs): smoke-level; most campaign behavior is pinned at the int layer.

CI (.github/workflows/ci.yml) runs lint (zero warnings), typecheck, knip, unit, migrate, int against a Postgres 17 service.

Safety Net Map

Modules the 2026-07 hardening phases touch, and where their behavior is pinned:

Module Pinned behaviors Test files Gaps
RBAC — src/utilities/access/* (split 2026-07-23; campaignAccess.ts is the re-export surface) per-role municipality/leadership/pledge/supporter/demand/plan scoping; leader lockdown; staff field asymmetry campaignMunicipalityAccess, campaignVotePledge, campaignSupporter, campaignUserPhone, campaignActionPlan, campaignDemandWorkflow, collectionAccessLockdown (int) no dedicated per-export suite; covered through collection behavior
Collection access lockdown campaign JWT denied on users/PII/CMS writes; anonymous read of public content; admin unaffected collectionAccessLockdown.int.spec.ts REST-transport variant untested (Local API with overrideAccess: false is equivalent)
municipalityMapData.ts bundle scoping by URL filters + advisor access; validVotesByYear incl. 2026 reuse of 2022; null on empty scope municipalityMapData.int.spec.ts zone breakdown shape
votePledgeData.ts estimated[scenario] ?? declared aggregation; role scoping; leader denial campaignVotePledge.int.spec.ts
Supporter import (token/bulk) preview→confirm flow, dedup by phone, consent fail-closed campaignSupporter.int.spec.ts supporterImportBulk/supporterImportToken internals only via flow
Leader supporter create linked-municipality scope; out-of-scope rejection; staff rejection collectionAccessLockdown.int.spec.ts
Posts visibility/caching isPostVisible fail-closed; cached listing (indirect via routes) no dedicated posts spec — backlog

Characterization Backlog

  • src/utilities/posts.ts — dedicated spec for isPostVisible fail-closed matrix and cache wrappers.
  • actionPlanViewModels.ts + other actionPlan* utilities (~1k lines) — currently untested directly.
  • campaignDemandData.ts / leadershipData.ts / organizationData.ts / stateDeputyData.ts list loaders.
  • Election aggregate artifact (Phase 2): snapshot test pinning artifact ↔ municipalityCatalog key consistency.