Skip to content
This repository was archived by the owner on Oct 25, 2026. It is now read-only.

Testing

Syed Ahmer Shah edited this page Oct 25, 2026 · 1 revision

Automated tests

php artisan test

46 PHPUnit feature tests (331 assertions) run against a real MySQL/MariaDB database (bookmymovie_test). They cover the booking flow, seat holds, the unique live-seat key, idempotent checkout, cancellations and refunds, snacks with gift cards and points, payments and signed URLs, bans, commerce rules, group bookings, waitlists, admin roles, SEO limits, error-page noindex, the Usher assistant and the Vite build manifest.

Production-style load test (October 2026)

The Docker stack (Apache + PHP 8.3, MySQL 8.4, Redis, queue worker, scheduler) was run with APP_ENV=production and 15 simulated people, each in its own container with its own IP address:

Group What they did
4 browsers Home, films, film pages, seat maps, cinemas, offers, FAQ, search and Usher for 90 seconds
8 buyers All pressed "hold" on the same seat in the same instant, then held their own seats, checked out with a double-tapped Confirm, opened their bookings and some cancelled
3 staff Owner, manager and box office opened every admin page in a loop

Results of the final run:

  • About 1,900 requests with no 5xx responses and no logged exceptions. Median response 100 to 160 ms, 95th percentile under 0.55 s.
  • One of the eight buyers got the contested seat; the other seven were told straight away that it had just been taken.
  • Every double-tapped Confirm produced exactly one booking, and both taps landed on it.
  • Each staff role saw exactly its own pages and got 403 for the rest.

Admin feature sweep

61 checks, all passing: every admin page for each role; creating, editing, pausing and deleting coupons; snack stock; pausing film sales; member, IP and device bans and unbans; review moderation; issuing gift cards; verifying, rejecting forged and admitting tickets at the door; refunds (and refusing a second refund); broadcasts; refusing unknown actions; and the audit log.

Security probe

Nonce-based CSP with a fresh nonce per response and no unsafe-inline; X-Frame-Options, nosniff, Referrer-Policy, Permissions-Policy; HSTS on HTTPS; no X-Powered-By or server version; HttpOnly SameSite session cookie. CSRF-less and forged-token POSTs are rejected without side effects. No XSS reflection, no SQL injection through search, route parameters or admin search. Guessed booking numbers return 404, and staff roles are enforced. .env, .git, logs and vendor are not served, and no stack traces leak. Logins need the image code, admin login is rate limited, a 150-request burst from one IP is throttled by the abuse shield, and oversized bodies are refused. All stored passwords are Argon2id.

Bugs the load test found (all fixed in v1.0.2)

  • A database CHECK constraint rejected every booking that used snacks, a gift card or loyalty points, and the customer saw "one of your seats was just booked".
  • Opening a booking with snacks failed because the snacks pivot inherited the bookings table's booked_at timestamp name.
  • Cancelling without a reason, or issuing a gift card without a recipient, raised an error instead of using the default.
  • The second tap of a double-tapped Confirm showed "your hold expired" instead of the booking it had just made.
  • Banning a member could also block the admin's own browser if it appeared in the member's device list.

Clone this wiki locally