IEE Edu’s test suite is powered by Pest v3 (Documentation Index
Fetch the complete documentation index at: https://mintlify.com/RigbySawGame/ieeEdu_Wen/llms.txt
Use this file to discover all available pages before exploring further.
pestphp/pest ^3.8) with the pestphp/pest-plugin-laravel ^3.2 adapter. Tests run against an in-memory SQLite database with the queue set to sync, mail set to array, and cache set to array — so the full application can be exercised without any external services. All test environment overrides are declared in phpunit.xml.
Running Tests
Full suite
--compact flag produces a condensed single-line output per test, making it easier to spot failures at a glance in CI logs.
Filter to a specific test class or method
Test Structure
Tests are organized into two suites as defined inphpunit.xml:
| Suite | Directory | Purpose |
|---|---|---|
| Unit | tests/Unit/ | Isolated tests for individual classes, services, and helpers with no HTTP or database interaction. |
| Feature | tests/Feature/ | Full HTTP request-cycle tests that boot the application, hit routes, and assert against the database and response. |
app/ directory is included as the source for code coverage analysis. To generate a coverage report, add --coverage to any test command (requires Xdebug or PCOV).
Test Environment (phpunit.xml)
The following environment variables are automatically applied during every test run, overriding whatever is in your.env file:
| Variable | Test Value | Reason |
|---|---|---|
APP_ENV | testing | Disables production-only guards and enables test helpers. |
APP_MAINTENANCE_DRIVER | file | Forces file-based maintenance mode state during tests. |
DB_CONNECTION | sqlite | Lightweight driver for fast test execution. |
DB_DATABASE | :memory: | Fresh in-memory database per test run — no leftovers between runs. |
CACHE_STORE | array | Prevents test cache pollution; resets automatically each run. |
QUEUE_CONNECTION | sync | Jobs execute immediately inline rather than being queued. |
MAIL_MAILER | array | Captures outgoing emails in memory for assertion without sending. |
SESSION_DRIVER | array | In-memory session storage; no database writes needed. |
BCRYPT_ROUNDS | 4 | Reduces password hashing cost so user factories run fast. |
TELESCOPE_ENABLED | false | Prevents Telescope from recording during tests. |
PULSE_ENABLED | false | Prevents Pulse from recording metrics during tests. |
Key Test Scenarios
The following twelve scenarios cover the most critical fixes and performance improvements in the platform. Each scenario includes the affected file, the exact manual verification steps, and what a passing result looks like.1. WhatsApp Lead API Route — POST /api/leads/whatsapp
1. WhatsApp Lead API Route — POST /api/leads/whatsapp
routes/web.phpVerifies that the POST /api/leads/whatsapp route exists and correctly persists a lead record to the whatsapp_leads table when called by an authenticated user.Manual steps:- Log in as a regular student.
- Add a course to the cart.
- Open DevTools → Network.
- Click “Enviar por WhatsApp”.
- Confirm the Network tab shows
POST /api/leads/whatsappwith HTTP 200. - Check the
whatsapp_leadstable to confirm the record was saved.
200, no 500 error appears, and a new row exists in whatsapp_leads.2. Consultancy Rate Limiting — 5 req/min
2. Consultancy Rate Limiting — 5 req/min
routes/web.phpVerifies that the consultancy form is rate-limited to 5 requests per minute per IP. The 6th submission within the same minute must be rejected.Manual steps:- Visit
/consultoriawithout logging in. - Submit the form 6 times as fast as possible.
- Confirm the 6th submission returns HTTP 429 Too Many Requests.
3. Comment Authorization — Enrollment Check
3. Comment Authorization — Enrollment Check
4. Nullable User in WhatsApp Leads
4. Nullable User in WhatsApp Leads
app/Http/Controllers/WhatsappLeadController.phpVerifies that the WhatsApp lead endpoint does not crash when called by an unauthenticated visitor. The user_id column is nullable and must be stored as null rather than causing a 500 error.Manual steps:- Log out completely.
- Send
POST /api/leads/whatsappwith a valid JSON payload (course name, plan, etc.). - Confirm the response is not HTTP 500.
- Check
whatsapp_leads— the new row should haveuser_id = null.
user_id = null.5. Admin Dashboard — N+1 Query Fix
5. Admin Dashboard — N+1 Query Fix
app/Http/Controllers/Admin/DashboardController.phpVerifies that the admin dashboard executes approximately 4 grouped queries instead of ~30 individual SUM queries for its chart data.Manual steps:- Log in as an admin.
- Navigate to
/admin/dashboard. - Open Laravel Telescope (or check
storage/logs/laravel.log). - Confirm there is 1 query per chart (weekly, monthly, quarterly) using
GROUP BYrather than multiple separateSUMstatements. - Verify the dashboard loads noticeably faster with a large payments dataset.
6. Course Editor Eager Loading Fix
6. Course Editor Eager Loading Fix
app/Http/Controllers/Admin/CourseController.phpVerifies that the 'quizzes.attempts.user' relation is no longer eager-loaded on the course edit page, preventing memory exhaustion and timeouts on courses with many students.Manual steps:- Log in as an admin.
- Navigate to the edit page for a course with 500+ enrolled students.
- Confirm the page loads without timeout.
- In Telescope, verify that the
quiz_attemptstable is not queried on this page load.
quiz_attempts query appears in the log.7. Explore Pagination — Books & Articles
7. Explore Pagination — Books & Articles
app/Http/Controllers/Student/DashboardController.phpVerifies that the publications explore page uses paginate(12) instead of all(), returning only 12 items per page regardless of the total number of records.Manual steps:- Log in as a student.
- Navigate to
/student/explore/publications. - Confirm pagination controls appear and only 12 items are shown on the first page.
- Verify fast load time even if there are 1,000+ books in the database.
LIMIT 12 OFFSET 0.8. Classroom setInterval Memory Leak Fix
8. Classroom setInterval Memory Leak Fix
resources/js/pages/student/Classroom.vueVerifies that the setInterval used to update the current time display in the classroom is properly cleared when the component is unmounted, preventing a memory leak during navigation.Manual steps:- Open the classroom for any course.
- Navigate away to a different page (e.g., the student dashboard).
- In DevTools → Performance → Memory, take a heap snapshot before and after navigation.
- Confirm there are no lingering
Classroom.vuecomponent instances in the heap after unmounting.
onUnmounted hook clears the interval; no Classroom.vue instances appear in the post-navigation heap snapshot.9. Centralized TypeScript Types
9. Centralized TypeScript Types
resources/js/types/course.tsVerifies that the centralized TypeScript interface file compiles without errors and that the frontend build succeeds end-to-end.Manual steps:npm run build exits with code 0 and no type errors are reported in the Vite output.10. CourseController Str Import Fix
10. CourseController Str Import Fix
app/Http/Controllers/Admin/CourseController.phpVerifies that use Illuminate\Support\Str; is explicitly imported in CourseController, fixing course duplication which uses Str::slug() to generate a unique slug.Manual steps:- Log in as an admin.
- Navigate to any course and click Duplicar (Duplicate).
- Confirm the duplicate course is created with a unique slug.
- Confirm no
Class "Str" not foundPHP error appears.
11. Dashboard Caching — Admin & Student
11. Dashboard Caching — Admin & Student
Admin/DashboardController.php, Student/DashboardController.phpVerifies that dashboard statistics are cached (5 minutes for admin, 1 minute for student) and that repeated page loads do not re-execute the stats queries.Manual steps:- Navigate to the admin dashboard.
- Reload the page 3–4 times.
- In Telescope, confirm that only the first load executes the stats queries; subsequent reloads serve the cached result with no new queries.
- Wait 5 minutes and reload — queries should execute again to refresh the cache.
12. PublicCourseController SELECT Optimization
12. PublicCourseController SELECT Optimization
app/Http/Controllers/PublicCourseController.phpVerifies that the public course listing queries only the columns actually needed (explicit SELECT) rather than fetching all columns with SELECT *, reducing both query execution time and Inertia payload size.Manual steps:- Visit the homepage
/. - In Telescope, open the query for
coursesand confirm it has an explicitSELECTcolumn list rather thanSELECT *. - In DevTools → Network, inspect the Inertia JSON payload and confirm the course objects contain only the expected subset of fields.
SELECT; the Inertia JSON payload is visibly smaller than before the optimization.Frontend Build Verification
After any change to Vue components, TypeScript types, or Tailwind configuration, verify the frontend compiles cleanly:Route Verification
After adding or modifying routes, confirm the full route list is consistent and no conflicts exist:grep to narrow down:
Post-Deploy Smoke Test
After every production deployment, run through the following checklist to verify the application is functioning end-to-end. This checklist is drawn directly fromDEPLOY.md.
Authentication
Plans page
/planes and confirm subscription plan pricing cards are rendered with the correct prices from IIE_PLAN_TRIMESTRAL_PRICE, IIE_PLAN_SEMESTRAL_PRICE, and IIE_PLAN_ANUAL_PRICE.Payment → classroom access flow
Automated test suite