90 Commits

Author SHA1 Message Date
Serreau Jovann
4b52b72266 Add attestation test with sold tickets to cover buildAttestationStats and buildAttestationTicketDetails
Creates a paid order with BilletOrder tickets before generating the
attestation, exercising the soldCounts loop (line 503) and ticket
details loop (lines 546-551) in AccountEventOperationsController.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-03 10:02:33 +02:00
Serreau Jovann
0cf1160853 Reduce AccountController to 20 methods, remove unused AdminOrdersController constant
- Move export, exportPdf, payoutPdf from AccountController to
  AccountEventOperationsController (9 -> 12 methods)
- Remove getAllowedBilletTypes delegate from AccountController
- Update tests to reference AccountEventCatalogController for that method
- Remove unused DQL_EXCLUDE_INVITATIONS from AdminOrdersController

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-03 09:35: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
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
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
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
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
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
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
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
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
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
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
822bf8915f Scanner: SSO login, 2 scan modes (camera/security key), sound feedback, order details, force validation, staff/exposant badges
- Add SSO login button to scanner PWA with Keycloak redirect flow via session state
- Add manual scan mode via security key (16 chars) alongside QR camera scan
- Add audio feedback: good (accepted), warning (already scanned), refused sounds
- Add unique scan counter per reference (no double counting same ticket)
- Add order details display in scan results (order number, email, total, items)
- Add force validation button for refused tickets (organizer/ROLE_ROOT only), sends email notification
- Add already_scanned warning only for same-day scans, exit_definitive only same day
- Staff and exposant tickets always validate regardless of state

API: ROLE_ROOT access to all events, categories, billets, and scan endpoints

- ROLE_ROOT bypasses ownership checks on all /api/live/* endpoints
- ROLE_ROOT can login via API (email/password and SSO)
- Scan API accepts securityKey parameter in addition to reference
- Scan response includes billetType, buyerEmail, and full order details with items

Event management: tickets tab, staff/exposant accreditations, attestation PDF

- Add Tickets tab listing all sold tickets with search, download PDF, resend email, cancel actions
- Add Staff/Exposant accreditation form in Invitations tab, generates dedicated non-buyable billet
- Add Attestation tab to generate sales certificate PDF with category/billet selection
- PDF billet template shows STAFF/EXPOSANT badge with distinct colors (black/purple)
- Exclude invitations from all financial stats (event stats, admin dashboard, organizer finances)
- Fix sold counts to exclude invitations in categories recap
- Use actual Stripe fee parameters instead of hardcoded values in commission calculations
- Add commission detail breakdown (E-Ticket + Stripe) in categories and stats tabs

Admin: download tickets for orders

- Add download button on admin orders page (single PDF or ZIP for multiple tickets)

Scanner PWA fixes: CSP (unpkg -> jsdelivr), service worker scope (/scanner/)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-26 15:50:42 +01:00
Serreau Jovann
58301840a6 Add admin Infra page with Redis and PostgreSQL monitoring
Shows real-time stats with color-coded indicators:
- Redis: version, memory, hit rate, ops/sec, evicted keys
- PostgreSQL: version, db size, connections, cache hit ratio, dead tuples
Uses MESSENGER_TRANSPORT_DSN for Redis auth (works in dev and prod).
Accessible via /admin/infra with nav link.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-26 10:27:15 +01:00
Serreau Jovann
a544496104 Add PWA scanner app for organizers at /scanner
Standalone installable PWA with:
- JWT login via /api/auth/login
- Event list from /api/live/events
- QR code camera scanning (html5-qrcode library)
- Scan results with accepted/refused state and ticket details
- Auto token refresh on expiry
- Offline caching via service worker
- Dark theme optimized for outdoor scanning
- Vibration feedback on scan

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-26 10:04:56 +01:00
Serreau Jovann
d6ead88d3d Add logo upload to admin organizer edit page
Admin can now view the current logo and upload a new one via the
organizer edit form. Uses VichUploader with the existing organizer_logo
mapping. Adds test with fixture image.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-26 10:00:33 +01:00
Serreau Jovann
23b92f101c Add admin event actions (online/offline, edit, delete) and fix Meilisearch depends_on
- Add toggle online/offline and delete routes in AdminController
- Add action buttons (En ligne, Modifier, Supprimer) in admin events template
- Bypass requireEventOwnership and requireStripeReady for ROLE_ROOT so admin can edit any event
- Add Meilisearch healthcheck and depends_on in messenger service (prod + dev)
- Add tests for all new admin routes and ROLE_ROOT bypass

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-26 09:04:27 +01:00
Serreau Jovann
f9788adab3 Block organizer features when Stripe Connect account is not validated
- Hide organizer tabs (events, subaccounts, payouts) if Stripe not ready
- Redirect organizer tab content and all organizer routes to /mon-compte
- Add requireStripeReady() guard on all ROLE_ORGANIZER routes
- Force default tab to 'tickets' when Stripe is not validated
- Update test fixtures: approved organizers get Stripe enabled by default
- Add tests for blocked tabs and blocked event creation without Stripe

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 11:06:39 +01:00
Serreau Jovann
b8d9c910ed Fix PHP CS Fixer style in ApiAuthTraitTest
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-23 20:46:01 +01:00
Serreau Jovann
c82a9d4d4b Add ApiAuthTrait tests, mark API controllers for coverage ignore
ApiAuthTraitTest (10 tests):
- authenticateRequest: missing headers, invalid token, expired token, user not found, email mismatch, success
- success: without meta, with meta
- error: custom status, default 400

Coverage ignore:
- ApiLiveController: requires DB + JWT integration
- ApiSandboxController: requires JWT integration
- ApiAuthController: login/refresh (DB), sso (Keycloak), helpers (private)
- verifyJwt remains fully tested (7 unit tests)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-23 20:38:55 +01:00
Serreau Jovann
cd3df224e5 Add tests for ApiAuthController (JWT) and ApiDocController (doc/spec/insomnia)
ApiAuthControllerTest (7 unit tests):
- verifyJwt valid token, expired token, invalid signature, wrong email
- Malformed token, too few parts, empty payload

ApiDocControllerTest (5 WebTestCase tests):
- /api/doc returns success with env-switcher
- /api/doc/spec.json returns 5 sections array
- /api/doc/insomnia.json downloads with correct format and resources
- Insomnia export contains workspace/environment/request_group/request
- Login request has afterResponseScript for jwt_token auto-store

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-23 20:06:50 +01:00
Serreau Jovann
059eceaefe Fix PHP CS Fixer style in AccountControllerTest
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-23 18:13:29 +01:00
Serreau Jovann
82c90f5b8b Fix LibreTranslate deploy: healthcheck from PHP container, ignore_errors, add QR code tests
- Ansible: healthcheck via PHP container (curl from php, not libretranslate)
- Ansible: exit 0 if LibreTranslate not ready (don't block deploy)
- Ansible: ignore_errors on translation step (non-blocking)
- AccountControllerTest: add testEventQrCode (PNG response) and testEventQrCodeDeniedForOtherUser (403)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-23 18:12:18 +01:00
Serreau Jovann
4742da8554 aa 2026-03-23 15:53:02 +01:00
Serreau Jovann
bc4601eb5c aa 2026-03-23 15:44:20 +01:00
Serreau Jovann
8a42a3dde4 aa 2026-03-23 15:35:21 +01:00
Serreau Jovann
1af242c307 Fix SonarQube/PHPStan issues: session type, returns count, coverage gaps
- AuditLog: move @var before ORM attribute for PHPStan visibility
- SubAccountPermissionSubscriber: use Session instead of FlashBagAwareSessionInterface
- SuspendedUserSubscriber: same Session type fix
- OrderController::create: merge expired + invalid cart into single return (4→3 returns)
- OrderControllerTest: add testCreateOrderUnlimitedBillet (covers clampQuantity unlimited branch)
- AccountControllerTest: add BilletOrder in soldCounts test (covers foreach $rows loop)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-23 14:47:02 +01:00
Serreau Jovann
544e6632da Fix testCreateOrderEmptyCart: expect 400 after isValidCart refactor
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-23 14:34:09 +01:00
Serreau Jovann
09a3e7867e Reduce cognitive complexity, improve test coverage, fix SonarQube issues
Cognitive complexity refactors:
- cart.js: extract buildCart, handleCheckout, updateStockLabel, updateItemStock, startStockPolling (21→~8)
- tabs.js: use .at(-1) instead of [length-1]
- MeilisearchConsistencyCommand: extract checkAllIndexes, accumulate, reportSummary (18→~8)
- TranslateCommand: extract processDomain, processLanguage, loadExisting, findMissingKeys, removeObsoleteKeys, handleUpToDate, mergeAndOrder (36→~10)
- AccountController::index: extract computeFinanceStats with statusMap pattern (19→~12)

Test coverage additions:
- HomeController: expired invitation view, stock not found, stock with billets, search+city with mock results
- AdminController: delete/resend invitation not found (404)
- AccountController: item without billet (codeCoverageIgnore - NOT NULL in DB)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-23 12:57:00 +01:00
Serreau Jovann
1eba8b41ee Fix PHP CS Fixer style in AdminControllerTest
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-23 12:29:21 +01:00
Serreau Jovann
c2ebd291b8 Add test coverage for remaining controllers, fix label accessibility, refactor duplicated code
New tests (47 added, 622 total):
- MonitorMessengerCommand: no failures, failures with email, null error, multiple (4)
- UnsubscribeController: unsubscribe with invitations refused + admin notified (1)
- AdminController: suspend/reactivate orga, orders page with filters, logs, invite orga submit/empty, delete/resend invitation, export CSV/PDF (13)
- AccountController: export CSV/PDF, getAllowedBilletTypes (free/basic/sur-mesure/null), billet type restriction, finance stats all statuses, soldCounts (9)
- HomeController: city filter, date filter, all filters combined, stock route (4)
- OrderController: event ended, invalid cart JSON, invalid email, stock zero (4)
- MailerService: getAdminEmail, getAdminFrom (2)
- JS: comment node, tabs missing panel/id/parent, cart stock polling edge cases (10)

Accessibility fixes:
- events.html.twig: add for/id on search, city, date labels
- admin/orders.html.twig: add for/id on search, status labels

Code quality:
- cart.js: remove dead ternaire branch (max > 10 always plural)
- tabs.js: use optional chaining for tablist?.setAttribute
- MeilisearchConsistencyCommand: extract diffAndReport() (was duplicated 3x)
- Email templates: extract _order_items_table.html.twig partial
- SonarQube: exclude src/Entity/** from CPD

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-23 12:11:07 +01:00
Serreau Jovann
42d06dd49f Add LibreTranslate auto-translation, improve test coverage, fix code duplication
Translation system:
- Add LibreTranslate container (dev + prod), CPU-only, no port exposed, FR/EN/ES/DE/IT
- Create app:translate command: reads *.fr.yaml, translates incrementally, preserves placeholders
- Makefile: make trans / make trans_prod (stops container after translation)
- Ansible: start libretranslate -> translate -> stop during deploy
- Prod container restart: "no" (only runs during deploy)
- .gitignore: ignore generated *.en/es/de/it.yaml files
- 11 tests for TranslateCommand (API unreachable, empty, incremental, obsolete keys, placeholders, fallback)

Test coverage improvements:
- OrderController: event ended (400), invalid cart JSON, invalid email, stock zero (4 new tests)
- AccountController: finance stats all statuses (paid/pending/refunded/cancelled), soldCounts (2 new tests)
- JS cart: checkout without error elements, hide error on retry, stock polling edge cases (singular, no label, qty zero, unknown billet) (8 new tests)
- JS editor: comment node sanitization (1 new test)
- JS tabs: missing panel, generated id, parent null, click no-panel (5 new tests)

Code duplication fixes:
- MeilisearchConsistencyCommand: extract diffAndReport() method (was duplicated 3x)
- Email templates: extract _order_items_table.html.twig partial (shared by notification + cancelled)
- SonarQube: exclude src/Entity/** from CPD (getters/setters duplication)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-23 11:44:13 +01:00
Serreau Jovann
04927ec988 Complete TASK_CHECKUP: security, UX, tests, coverage, accessibility, config externalization
Billetterie:
- Partial refund support (STATUS_PARTIALLY_REFUNDED, refundedAmount field, migration)
- Race condition fix: PESSIMISTIC_WRITE lock on stock decrement in transaction
- Idempotency key on PaymentIntent::create, reuse existing PI if stripeSessionId set
- Disable checkout when event ended (server 400 + template hide)
- Webhook deduplication via cache (24h TTL on stripe event.id)
- Email validation (filter_var) in OrderController guest flow
- JSON cart validation (structure check before processing)
- Invitation expiration after 7 days (isExpired method + landing page message)
- Stripe Checkout fallback when JS fails to load (noscript + redirect)

Config externalization:
- Move Stripe fees (STRIPE_FEE_RATE, STRIPE_FEE_FIXED) and admin email (ADMIN_EMAIL) to .env/services.yaml
- Replace all hardcoded contact@e-cosplay.fr across 13 files
- MailerService: getAdminEmail()/getAdminFrom(), default $from=null resolves to admin

UX & Accessibility:
- ARIA tabs: role=tablist/tab/tabpanel, aria-selected, keyboard nav (arrows, Home, End)
- aria-label on cart +/- buttons and editor toolbar buttons
- tabindex=0 on editor toolbar buttons for keyboard access
- data-confirm handler in app.js (was only in admin.js)
- Cart error feedback on checkout failure
- Billet designer save feedback (loading/success/error states)
- Stock polling every 30s with rupture/low stock badges
- Back to event link on payment page

Security:
- HTML sanitizer: BLOCKED_TAGS list (script, style, iframe, svg, etc.) - content fully removed
- Stripe polling timeout (15s max) with fallback redirect
- Rate limiting on public order access (20/5min)
- .catch() on all fetch() calls (sortable, billet-designer)

Tests (92% PHP, 100% JS lines):
- PCOV added to dev Dockerfile
- Test DB setup: .env.test with DATABASE_URL, Redis auth, Meilisearch key
- Rate limiter disabled in test env
- Makefile: test_db_setup, test_db_reset, run_test_php, run_test_coverage_php/js
- New tests: InvitationFlowTest (21), AuditServiceTest (4), ExportServiceTest (9), InvoiceServiceTest (4)
- New tests: SuspendedUserSubscriberTest, RateLimiterSubscriberTest, MeilisearchServiceTest
- New tests: Stripe webhook payment_failed (6) + charge.refunded (6)
- New tests: BilletBuyer refund, User suspended, OrganizerInvitation expiration
- JS tests: stock polling (6), data-confirm (2), copy-url restore (1), editor ARIA (2), XSS (9), tabs keyboard (9)
- ESLint + PHP CS Fixer: 0 errors
- SonarQube exclusions aligned with vitest coverage config

Infra:
- Meilisearch consistency command (app:meilisearch:check-consistency --fix) + cron daily 3am
- MeilisearchService: getAllDocumentIds(), listIndexes()

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-23 11:14:06 +01:00
Serreau Jovann
4ad694ed59 Add resendInvitation tests: success, access denied, not found
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-21 19:23:55 +01:00
Serreau Jovann
bf6aa16e20 Add missing OrderController coverage: downloadTicket, invoice success, zero qty
- downloadTicket: order not found, ticket not found, success with mock PDF
- invoice: success with mock PDF (paid order)
- create: zero qty items filtered out

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-21 19:03:05 +01:00
Serreau Jovann
386d803fe5 Remove unused BilletOrder import from OrderControllerTest
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-21 18:50:35 +01:00
Serreau Jovann
272cb93c18 Fix invitation test to create real BilletOrder for isInvitation coverage
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-21 18:47:03 +01:00
Serreau Jovann
410e6acdfd Add comprehensive OrderController tests
- create: not found, empty cart, guest, logged user, invalid billet,
  not buyable, exceeds quantity
- guest: not found, renders, empty fields, submit success, redirects if user set
- payment: not found, redirects if no name, renders with Stripe,
  404 without Stripe account
- success: not found, renders, failed status, succeeded with mock
- publicOrder: not found, renders
- invoice: not found, not paid returns 404

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-21 18:44:27 +01:00
Serreau Jovann
decbe99ae3 Add createInvitation tests: success, multiple billets, empty fields, invalid billet, access denied, invitations tab
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-21 18:36:53 +01:00
Serreau Jovann
e834dad706 Add cancelOrder tests: success with ticket invalidation, access denied, not found
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-21 18:35:35 +01:00
Serreau Jovann
7cd3659745 Fix orderNumber too long in stats tab test (VARCHAR 20 limit)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-21 18:26:15 +01:00
Serreau Jovann
3f880745b3 Add coverage for stats tab: empty, with paid orders, with search query
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-21 18:19:11 +01:00
Serreau Jovann
de37db1774 Add OrderIndexService tests and AccountController tickets tab with data test
- OrderIndexServiceTest: 6 tests covering search empty, results, no hits,
  exception, indexOrder success and failure
- AccountControllerTest: tickets tab with BilletBuyer + BilletOrder data

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-21 18:18:11 +01:00
Serreau Jovann
f021da7f9c Add coverage tests: event detail with categories/billets, hidden, inactive, notBuyable
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-21 18:12:59 +01:00
Serreau Jovann
36b66d27dc Improve coverage: billet with picture tests, codeCoverageIgnore on Stripe methods
- Add testAddBilletWithPicture and testEditBilletWithPicture for line 904
- Add billet to categoriesTab test for line 363
- Extract deleteBilletFromStripe with @codeCoverageIgnore
- Add @codeCoverageIgnore to syncBilletToStripe

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-21 13:30:38 +01:00
Serreau Jovann
962bfa5602 Add missing AccountController coverage: billetPreview, saveBilletDesign, reorderBillets, deleteBillet 404
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-21 13:16:44 +01:00