feat: Sonar + coverage + CI hardening (PR-A)#4
Conversation
- Install Vitest, React Testing Library, @vitest/coverage-v8 - Extract pure helpers: sanitizeRedirect, isValidEan, stripNonDigits, formatSlug - 56 unit tests across 4 test files (validation, rpc, query-keys, constants) - Wire coverage (lcov) into sonar-project.properties - Update CI workflow: npm ci → type-check → lint → build → test:coverage → Sonar - Fix PL/SQL warning: restrict file suffixes + exclude SQL from analysis - Add docs/SONAR.md documenting config, quality gate, exclusions - Add coverage/ to .gitignore
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
There was a problem hiding this comment.
Pull request overview
This PR introduces comprehensive unit testing infrastructure with SonarCloud integration for the frontend codebase. It establishes a foundation for test coverage reporting and quality gate enforcement by adding Vitest with React Testing Library, extracting pure helper functions for testability, and hardening the CI pipeline.
Changes:
- Added Vitest test framework with v8 coverage reporting configured to generate lcov reports for SonarCloud
- Extracted 4 pure helper functions (
sanitizeRedirect,isValidEan,stripNonDigits,formatSlug) tovalidation.tswith 56 comprehensive unit tests across 4 test files - Updated CI workflow to run full pipeline (type-check → lint → build → tests → coverage → SonarCloud scan) and configured SonarCloud quality gate for new-code-only enforcement
Reviewed changes
Copilot reviewed 14 out of 16 changed files in this pull request and generated no comments.
Show a summary per file
| File | Description |
|---|---|
sonar-project.properties |
Added coverage path, updated exclusions (coverage/, db/migrations/, vitest.config.ts), configured PL/SQL file suffixes, included frontend/src in test paths |
frontend/vitest.config.ts |
New Vitest configuration with jsdom environment, path aliases, v8 coverage provider targeting lcov+text output |
frontend/src/lib/validation.ts |
Extracted pure validation helpers (open-redirect prevention, EAN validation, digit stripping, slug formatting) |
frontend/src/lib/validation.test.ts |
25 unit tests covering all validation helper edge cases |
frontend/src/lib/rpc.test.ts |
10 unit tests for auth error detection logic |
frontend/src/lib/query-keys.test.ts |
13 unit tests verifying deterministic cache key generation and stale times |
frontend/src/lib/constants.test.ts |
8 structural assertion tests for constants (allergens, countries, score bands) |
frontend/src/__tests__/setup.ts |
Test setup file importing jest-dom matchers for Vitest |
frontend/src/app/auth/login/LoginForm.tsx |
Refactored to use extracted sanitizeRedirect helper |
frontend/src/app/app/scan/page.tsx |
Refactored to use extracted isValidEan and stripNonDigits helpers |
frontend/src/app/app/categories/[slug]/page.tsx |
Refactored to use extracted formatSlug helper |
frontend/package.json |
Added test scripts and 7 dev dependencies (vitest, @vitest/coverage-v8, @testing-library/*, jsdom, @vitejs/plugin-react) |
frontend/package-lock.json |
Lock file updates for all new dependencies |
docs/SONAR.md |
Comprehensive documentation of SonarCloud strategy, coverage reporting, SQL exclusions, CI integration |
.gitignore |
Added coverage/ directory exclusion |
.github/workflows/build.yml |
Renamed to "CI", added Node 20 setup with npm cache, full pipeline steps (install → type-check → lint → build → test:coverage → Sonar) |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
- Refactor rpc.ts: extract AUTH_CODES, AUTH_MESSAGES, normalizeRpcError, extractBusinessError as exported constants/helpers - Add 28 new tests for callRpc (success, supabase error, business error, exception, dev-logging branches), normalizeRpcError, extractBusinessError, AUTH_CODES, AUTH_MESSAGES - rpc.ts now at 100% coverage (statements, branches, functions, lines) - Total: 84 tests passing (was 56)
|
- Replace global idx_ps_ean_pending with idx_ps_ean_country_pending on (ean, suggested_country) WHERE status = 'pending' - Update api_submit_product: country-scoped duplicate check with global fallback for NULL country - Update api_record_scan: country-scoped has_pending_submission - Add 9 pgTAP tests (plan 92 -> 101) - Update QA check #4 for new index name
) - Replace global idx_ps_ean_pending with idx_ps_ean_country_pending on (ean, suggested_country) WHERE status = 'pending' - Update api_submit_product: country-scoped duplicate check with global fallback for NULL country - Update api_record_scan: country-scoped has_pending_submission - Add 9 pgTAP tests (plan 92 -> 101) - Update QA check #4 for new index name Co-authored-by: ericsocrat <ericsocrat@users.noreply.github.com>



Summary
Adds unit test infrastructure with coverage reporting, wires it into SonarCloud, and hardens CI — so Sonar's quality gate becomes actionable instead of always-failing at 0% coverage.
Changes
Test Framework
@vitest/coverage-v8installedvitest.config.tswith jsdom environment, path aliases, v8 coverage (lcov + text)validation.ts—sanitizeRedirect,isValidEan,stripNonDigits,formatSlug(25 tests)rpc.ts—isAuthErrorauth-code/message detection (10 tests)query-keys.ts— deterministic cache key factories + stale times (13 tests)constants.ts— structural assertions on allergens, countries, score bands, etc. (8 tests)Extracted Pure Helpers (
src/lib/validation.ts)sanitizeRedirect(raw, fallback)— open-redirect prevention (extracted fromLoginForm.tsx)isValidEan(code)— EAN-8/EAN-13 validation (extracted fromscan/page.tsx)stripNonDigits(value)— input sanitization (extracted fromscan/page.tsx)formatSlug(slug)—_→ space conversion (extracted fromcategories/[slug]/page.tsx)Sonar Configuration
sonar.javascript.lcov.reportPaths=frontend/coverage/lcov.infosonar.tests=frontend/src,frontend/e2e(includes unit + e2e test dirs)coverage/to exclusionssonar.plsql.file.suffixes=plsql,pkb,pks,pkg+db/migrations/**exclusionfrontend/vitest.config.tsto exclusionsCI Workflow (
.github/workflows/build.yml)npm ci→type-check→lint→build→test:coverage→ Sonar scan → Quality GateDocumentation
docs/SONAR.md— quality gate strategy, coverage howto, SQL exclusion rationale, known accepted issuesVerification
Acceptance Criteria