Commit Graph

609 Commits

Author SHA1 Message Date
Serreau Jovann
7869e4e7d9 Exclude editor.js from SonarQube analysis
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-02 14:52:26 +02:00
Serreau Jovann
f9aaa45d4b Add analytics test with real data to cover visitor/pageview chart loops
Creates AnalyticsUniqId and AnalyticsEvent records in DB so the
daily chart aggregation loops (visitorsPerDay, pageviewsPerDay,
allDays merge, DateTimeInterface check) are fully exercised.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-02 14:02:54 +02:00
Serreau Jovann
5f685d9d1f Cover setIsInvitation loop in createAccreditation test
Mock generateOrderTickets to create a real BilletOrder in DB so the
foreach loop setting isInvitation=true is exercised and verified.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-02 14:02:10 +02:00
Serreau Jovann
4f055af3f1 Add <th> headers to API doc tables, ignore css:S4662 for Tailwind @source directive
- Add <thead>/<th> to rate limiting and error codes tables in doc.html.twig
- Ignore SonarQube css:S4662 rule on SCSS files (Tailwind v4 @source)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-02 14:01:35 +02:00
Serreau Jovann
8eb7d74445 Add <thead>/<th> headers to all email and PDF template tables, fix infra test snapshot data
- Add proper <thead> with <th> headers to tables in email templates:
  order_cancelled_orga, order_notification_orga, order_refunded,
  organizer_invitation, payment_failed, scan_force_notification
- Add proper <thead> with <th> headers to tables in PDF templates:
  attestation_ventes, billet, export_recap, invoice
- Fix testInfraPageWithSnapshotData: provide complete server data
  (os, uptime, cpu, ram, disk, services, ssl) required by the template

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-02 13:40:48 +02:00
Serreau Jovann
7b618a700f Add istanbul ignore comments alongside c8 for analytics.js coverage
Ensures 100% coverage regardless of which provider (c8/istanbul/v8)
is used by the CI.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-02 13:13:26 +02:00
Serreau Jovann
83f2f40a91 Add missing test coverage for MeilisearchService, AnalyticsCryptoService, AccountController and AdminController
- MeilisearchServiceTest: add test for invalidateSearchCache()
- AnalyticsCryptoService: mark unreachable tryDecryptJsFormat guard
  with @codeCoverageIgnore (decrypt already checks strlen >= 28)
- AccountControllerTest: add test for tickets search query (tq param)
- AdminControllerTest: add test for infra page with snapshot data file

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-01 20:19:52 +02:00
Serreau Jovann
b1ec125bb9 Achieve 100% coverage on analytics.js
- Add test for navigator.language falsy branch
- Add test for retry getOrCreateVisitor failing on second attempt
- Mark unreachable defensive guards (encrypt/decrypt/send with null encKey)
  with c8 ignore since they cannot be triggered via public API

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-01 20:17:21 +02:00
Serreau Jovann
8b18617360 Fix AccountControllerTest: shorten order numbers to fit varchar(20) column
'2026-03-21-'.uniqid() was 24 chars, exceeding the 20-char limit.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-01 20:04:21 +02:00
Serreau Jovann
bf0171b352 Fix AccountControllerTest: use uniqid() for order numbers to avoid unique constraint violations
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-01 19:47:43 +02:00
Serreau Jovann
2ffb407323 Fix failing tests: AttestationController payload keys and StripeSyncCommand event mock
- AttestationControllerTest: add required template keys (ref, organizer,
  generatedAt, etc.) to test payloads so check_ventes.html.twig renders
- StripeSyncCommandTest: add getAccount() mock to event in
  testPendingOrderFailedWithoutEmail so order is not skipped

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-01 19:34:37 +02:00
Serreau Jovann
534f67dfbe Fix testPendingOrderFailedWithoutEmail: add missing audit mock expectation
The audit->log() call in handleFailed was not configured on the mock,
causing an exception caught by the try/catch which prevented setStatus
from being called.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-01 19:23:34 +02:00
Serreau Jovann
03342e8303 Fix StripeSyncCommandTest: use Stripe\PaymentIntent::constructFrom instead of stdClass
PHPUnit strict mock validation rejects stdClass as return value for
retrievePaymentIntent which declares Stripe\PaymentIntent return type.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-01 19:16:32 +02:00
Serreau Jovann
25354f9052 Fix decodeAndVerifyHash to have only 2 returns by merging base64 decode and pipe check guards
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-01 19:02:01 +02:00
Serreau Jovann
1b3371cb7f Add comprehensive test coverage for AttestationController, LegalController, AdminController, AccountController and AnalyticsEvent entity
- AttestationController: fix decodeAndVerifyHash to have max 3 returns, add 11 tests covering all routes (check, ventesRef, ventes) and all decodeAndVerifyHash branches (invalid base64, missing pipe, bad signature, bad JSON, valid hash with/without registered attestation), plus generateHash unit tests with unicode
- LegalController: add 6 tests for RGPD POST routes (rgpdAccess and rgpdDeletion) covering empty fields, data found, and no data found scenarios
- AdminController: add 10 tests for analytics page (all period filters + access denied) and orderTickets endpoint (single ticket PDF, multiple tickets ZIP, order not found, no tickets)
- AccountController: add 17 tests for downloadTicket (success/denied/404), resendTicket (success/denied/404), cancelTicket (success/denied/404), createAccreditation (staff/exposant/empty fields/no categories/invalid type), eventAttestation (with categories/billets/empty selection)
- AnalyticsEvent entity: new test file with 8 tests covering constructor defaults, all getters/setters, nullable fields, and fluent interface

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-01 18:41:18 +02:00
Serreau Jovann
a139feef07 init 2026-04-01 17:19:13 +02:00
Serreau Jovann
626510e692 Add force validate button in admin orders + fix Stripe Connect account in sync
- Add POST /admin/commandes/{id}/forcer-validation to force validate pending
  orders (generates tickets, sends emails, notifies organizer)
- Add "Forcer validation" button in orders template for pending orders
- Fix retrievePaymentIntent to query on organizer's Connect account
- Update stripe:sync to pass organizer stripeAccountId when checking payments
- Add 3 tests for force validation (pending, non-pending, not found)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-01 14:22:56 +02:00
Serreau Jovann
02519dcfa8 Add pending orders reconciliation to stripe:sync command
- Add retrievePaymentIntent() to StripeService
- StripeSyncCommand now checks pending orders against Stripe API:
  - succeeded: generates tickets, sends emails, notifies organizer
  - canceled: marks order as cancelled + audit log
  - requires_payment_method: marks as cancelled + audit + failure email
  - other statuses: logs as still pending
- Add 13 tests covering accounts sync + all pending order scenarios

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-01 14:14:29 +02:00
Serreau Jovann
381acd603e Split Stripe webhooks into 2 endpoints: insta (payments) and leger (Connect)
- /stripe/webhook → /webhooks/stripe/insta (paiements, payouts, disputes, subscriptions)
- /stripe/webhook/connect → /webhooks/stripe/leger (gestion comptes Connect)
- Rename env vars: STRIPE_WEBHOOK_SECRET → STRIPE_WEBHOOK_SECRET_INSTA,
  STRIPE_WEBHOOK_SECRET_CONNECT → STRIPE_WEBHOOK_SECRET_LEGER
- Update StripeService, CsrfProtectionSubscriber, vault, env files and all tests

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-01 14:07:49 +02:00
Serreau Jovann
1c559263a8 Add analytics.js test suite with 100% line/function coverage (16 tests)
Tests cover: init with missing config, importKey failure, visitor creation,
session reuse, sendBeacon usage, 403 retry flow, network errors, decrypt
failures, setAuth with/without session/key, and authenticated user tracking.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-01 13:54:43 +02:00
Serreau Jovann
97ef920514 Ignore CSP violations from browser userscripts (source-file: user-script)
Add 'user-script' to ignored source files in CspReportController to filter
out false positive CSP violations triggered by browser extensions/userscripts.
Add corresponding test case.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-01 11:33:09 +02:00
Serreau Jovann
622e1894ae aa 2026-03-30 13:43:06 +02:00
Serreau Jovann
918a52415d add new system for upgrade speed 2026-03-30 11:13:22 +02:00
Serreau Jovann
2f2da97f68 Fix code style: add blank line before constructor in AttestationController
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-30 08:58:07 +02:00
Serreau Jovann
fe91d26163 Add AnalyticsControllerTest with 100% coverage (19 tests, 70 assertions)
- Test token validation (invalid token returns 404)
- Test request validation (missing body, missing 'd' field, invalid JSON return 400)
- Test decryption validation (invalid encrypted data returns 403)
- Test new visitor creation with full fields, optional fields, mobile/tablet UA
- Test page view dispatch with valid hash, default values
- Test page view rejection with invalid/missing hash (403)
- Test setUser dispatch with valid hash
- Test visitor UID format (UUID v4), IP hash, UA truncation, language truncation
- Test response hash is verifiable by crypto service

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-30 08:48:03 +02:00
Serreau Jovann
3468b1288d Improve mobile/tablet responsive, fix structured data, update deploy schedule and fix HTML issues
- Add responsive breakpoints (sm/md) to event_detail.html.twig: adaptive titles, stacked ticket layout on mobile, reduced padding/spacing
- Add responsive breakpoints to order templates (guest, summary, public, payment, success): adaptive typography, padding, and layouts
- Fix BreadcrumbList JSON-LD: escape names with json_encode, remove item URL from last breadcrumb
- Update deploy.yml cron schedule from 3h/13h/19h/23h to 1h/22h
- Add <title> tags to rgpd_deletion.html.twig and rgpd_access.html.twig
- Add scope attributes to all <th> tags in rgpd_access.html.twig
- Replace deprecated width/cellpadding/cellspacing HTML attributes with CSS in scan_force_notification email

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-30 08:40:28 +02:00
Serreau Jovann
3a40de1ba0 Reduce return counts and fix code smells across controllers and services
- ApiAccountController::lookup: reduce from 4 to 3 returns via ternary
- AttestationController::ventes: reduce from 5 to 2 returns by extracting
  decodeAndVerifyHash() helper; add TPL_NOT_FOUND_VENTES constant for the
  template literal duplicated 5 times
- AnalyticsCryptoService::decrypt: reduce from 4 to 2 returns by extracting
  tryDecryptJsFormat() helper
- InfraService::fmtDuration: reduce from 4 to 1 return using match(true)
- InfraService: replace nested ternary with match(true) for SSL status

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-28 20:23:08 +01:00
Serreau Jovann
0df78f75ae Fix self-referencing constant NO_SNAPSHOT_MSG in AdminController
The constant was incorrectly defined as self::NO_SNAPSHOT_MSG = self::NO_SNAPSHOT_MSG
causing a PHP fatal error. Replace with the actual string value.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-28 19:06:51 +01:00
Serreau Jovann
ea50f8e740 Add POST /api/account/lookup route for account lookup by email
New API endpoint secured by X-App-Secret header (no JWT auth required).
Accepts an email in the request body and returns the user's id and
stripeAccountId if present. Includes 6 unit tests covering all cases
(success, missing secret, invalid secret, missing email, user not found).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-28 19:03:15 +01:00
Serreau Jovann
f2f8b31d6e Reduce method returns and cognitive complexity across controllers
- AnalyticsController::track: extract handleTrackData(), reduce from 7 to 3 returns
- ApiAuthController::ssoValidate: extract ssoError/ssoSuccess helpers, reduce from 6 to 3 returns
- ApiLiveController::scan: extract findTicketFromRequest(), reduce from 4 to 3 returns
- ApiLiveController::scanForce: flatten logic, reduce from 6 to 3 returns
- ApiLiveController::processScan: extract isAlwaysValidTicket, checkRefusal,
  markScannedAndRespond, reduce cognitive complexity from 16 to under 15

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-26 22:22:41 +01:00
Serreau Jovann
5062f356f1 Extract DQL_EXCLUDE_INVITATIONS and NO_SNAPSHOT_MSG constants in AdminController
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-26 22:20:36 +01:00
Serreau Jovann
b2c1cee51a Fix MeilisearchServiceTest: use ArrayAdapter instead of CacheInterface mock
ArrayAdapter implements both CacheInterface and CacheItemPoolInterface,
matching the intersection type on the constructor parameter.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-26 22:07:24 +01:00
Serreau Jovann
25564e4244 Fix all PHPStan errors: add missing iterable types and fix CacheInterface::clear()
- Add @param array<string, mixed> to AnalyticsController::createVisitor()
- Add @param/@return array<string, mixed> to AnalyticsCryptoService encrypt/decrypt
- Add @param array<string, mixed>|null to InfraService calcCpuPercent/calcMemory
- Merge duplicate docblocks on InfraService::calcMemory()
- Use intersection type CacheInterface&CacheItemPoolInterface for MeilisearchService cache

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-26 21:57:21 +01:00
Serreau Jovann
aeb4df8d92 Add Attestation, AnalyticsEvent, AnalyticsUniqId to PHPStan $id ignore list
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-26 21:54:41 +01:00
Serreau Jovann
af6cea00a8 Fix PHPStan errors and SonarQube warnings
- Remove redundant && $fix checks in MeilisearchConsistencyCommand (always true after early return)
- Add @param PHPDoc for Attestation::__construct $payload parameter
- Extract PDF_SUFFIX constant to avoid duplicated ".pdf"" literal

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-26 21:53:48 +01:00
Serreau Jovann
d77ee25bcf Apply PHP CS Fixer code style fixes
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-26 21:40:52 +01:00
Serreau Jovann
e0245afca5 Refactor AccountController: extract constants, reduce returns and cognitive complexity
- Add DQL_EXCLUDE_INVITATIONS, DQL_BB_EXCLUDE_INVITATIONS, CONTENT_TYPE_PDF constants
- Reduce createAccreditation from 4 to 3 returns by combining validations
- Extract collectAttestationBillets, buildAttestationStats, buildAttestationTicketDetails
  from eventAttestation to reduce cognitive complexity from 18 to under 15
- Remove unused $totalRevenue, duplicate $label, and securityKey from attestation details

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-26 21:39:20 +01:00
Serreau Jovann
02cce5608c Fix MeilisearchConsistencyCommand: remove unused variable, redundant array_values, always-true condition
- Remove unused $indexes variable (listIndexes() kept as health check)
- Make $fixMissing parameter required (always passed), remove && $fixMissing check
- Remove redundant array_values() on array_map result (already a list)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-26 21:36:14 +01:00
Serreau Jovann
59cf8dccde Fix linter warnings in analytics module: codePoint, const, optional chaining, Number.parseInt
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-26 21:34:22 +01:00
Serreau Jovann
20a6be0504 Destructure browser globals from globalThis in analytics module
Fixes linter warnings for sessionStorage, navigator, document, location, screen, fetch.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-26 21:11:15 +01:00
Serreau Jovann
73adc0a735 Use globalThis for TextEncoder, TextDecoder, and atob browser globals
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-26 21:08:37 +01:00
Serreau Jovann
a71493b87c Replace charCodeAt with codePointAt in analytics module
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-26 21:07:26 +01:00
Serreau Jovann
b062a5203b Use globalThis.atob/btoa in analytics module for linter compatibility
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-26 21:06:55 +01:00
Serreau Jovann
176b70650b Add SRI integrity hashes for CDN scripts and replace md5 with xxh128 for cache keys
- Add integrity/crossorigin attributes to chart.js and html5-qrcode CDN scripts
- Replace md5() with hash('xxh128') for Meilisearch cache key generation (non-sensitive context)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-26 21:06:00 +01:00
Serreau Jovann
1fe2c3a1d3 Fix scanner manifest test: update expected start_url to /scanner/
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-26 18:37:51 +01:00
Serreau Jovann
1796f2d022 Add e_ticket_test database to pgbouncer-dev config for test environment
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-26 18:31:17 +01:00
Serreau Jovann
2d14075d54 Fix infra page: add missing error key for redis/postgres/pgbouncer defaults
Template accesses redis_global.error, postgres.error and pgbouncer.error
in the else branch when connected=false, but the key was not provided.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-26 18:27:52 +01:00
Serreau Jovann
e8d2744333 Fix infra page crash when snapshot missing: provide default server values
Template accesses server.hostname etc. but server was passed as empty array
when infra.json does not exist. Now provides all expected keys with '?' defaults.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-26 18:13:26 +01:00
Serreau Jovann
21aa94c833 Fix cookie-consent tests: remove tests for analytics/cloudflare script loading
The script loading logic was removed from initCookieConsent() but tests
still expected it. Removed 5 obsolete tests, kept 7 core consent tests.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-26 16:21:55 +01:00
Serreau Jovann
58e139e261 Apply PHP CS Fixer code style fixes
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-26 16:19:15 +01:00