From 39228168c8f73ad5f58932ee66232190fd704d87 Mon Sep 17 00:00:00 2001 From: root Date: Mon, 6 Jul 2026 00:55:01 -0400 Subject: [PATCH] add school year and security fix --- app/.DS_Store | Bin 6148 -> 10244 bytes app/Http/Controllers/Api/.DS_Store | Bin 6148 -> 6148 bytes app/Http/Middleware/EnsureAccountActive.php | 34 + .../SchoolYears/ArchiveSchoolYearRequest.php | 23 + .../SchoolYears/ReopenSchoolYearRequest.php | 23 + app/Services/.DS_Store | Bin 6148 -> 8196 bytes .../SchoolYears/SchoolYearClosureService.php | 91 +- bootstrap/app.php | 5 + bootstrap/cache/packages.php | 12 + bootstrap/cache/services.php | 14 +- composer.json | 3 +- composer.lock | 303 +- database/.DS_Store | Bin 0 -> 6148 bytes ...001_add_school_year_closure_foundation.php | 162 + ...2_seed_school_year_closure_permissions.php | 151 + .../alrahma_sunday_school_api.code-workspace | 0 .../car_management_system.code-workspace | 0 .../car_rental_app.code-workspace | 0 .../command_to_run_dev.txt | 0 deploy_dev.txt => docs/deploy_dev.txt | 0 envfile.txt => docs/envfile.txt | 0 failed-tests.txt => docs/failed-tests.txt | Bin test.sql => docs/test.sql | 0 routes/api.php | 27 +- storage/.DS_Store | Bin 0 -> 8196 bytes storage/test-logs/test-results-after-jwt.log | 17444 ++++++++++++++++ storage/test-logs/test-results.log | 1861 ++ .../drafts/exam_6a4abcff285845.51919952.docx | 0 .../drafts/exam_6a4ac0eb362bc6.28143006.docx | 0 .../drafts/exam_6a4ac116b2e363.41805786.docx | 0 .../drafts/exam_6a4ac23fcf7fb1.82462443.docx | 0 .../drafts/exam_6a4ac27bf2fa37.62621938.docx | 0 .../drafts/exam_6a4ac288490c23.94142736.docx | 0 .../drafts/exam_6a4ad610776194.16519083.docx | 0 .../drafts/exam_6a4ad61cd5aed9.45472025.docx | 0 test-output.txt | Bin 117880 -> 0 bytes tests/.DS_Store | Bin 6148 -> 6148 bytes tests/Concerns/CreatesApiTestUsers.php | 78 + tests/Feature/Api/V1/.DS_Store | Bin 0 -> 6148 bytes .../SchoolYears/SchoolYearControllerTest.php | 209 +- 40 files changed, 20370 insertions(+), 70 deletions(-) create mode 100644 app/Http/Middleware/EnsureAccountActive.php create mode 100644 app/Http/Requests/SchoolYears/ArchiveSchoolYearRequest.php create mode 100644 app/Http/Requests/SchoolYears/ReopenSchoolYearRequest.php create mode 100644 database/.DS_Store create mode 100644 database/migrations/2026_07_05_000001_add_school_year_closure_foundation.php create mode 100644 database/migrations/2026_07_05_000002_seed_school_year_closure_permissions.php rename alrahma_sunday_school_api.code-workspace => docs/alrahma_sunday_school_api.code-workspace (100%) rename car_management_system.code-workspace => docs/car_management_system.code-workspace (100%) rename car_rental_app.code-workspace => docs/car_rental_app.code-workspace (100%) rename command_to_run_dev.txt => docs/command_to_run_dev.txt (100%) rename deploy_dev.txt => docs/deploy_dev.txt (100%) rename envfile.txt => docs/envfile.txt (100%) rename failed-tests.txt => docs/failed-tests.txt (100%) rename test.sql => docs/test.sql (100%) create mode 100644 storage/.DS_Store create mode 100644 storage/test-logs/test-results-after-jwt.log create mode 100644 storage/test-logs/test-results.log create mode 100644 storage/uploads/exams/drafts/exam_6a4abcff285845.51919952.docx create mode 100644 storage/uploads/exams/drafts/exam_6a4ac0eb362bc6.28143006.docx create mode 100644 storage/uploads/exams/drafts/exam_6a4ac116b2e363.41805786.docx create mode 100644 storage/uploads/exams/drafts/exam_6a4ac23fcf7fb1.82462443.docx create mode 100644 storage/uploads/exams/drafts/exam_6a4ac27bf2fa37.62621938.docx create mode 100644 storage/uploads/exams/drafts/exam_6a4ac288490c23.94142736.docx create mode 100644 storage/uploads/exams/drafts/exam_6a4ad610776194.16519083.docx create mode 100644 storage/uploads/exams/drafts/exam_6a4ad61cd5aed9.45472025.docx delete mode 100644 test-output.txt create mode 100644 tests/Feature/Api/V1/.DS_Store diff --git a/app/.DS_Store b/app/.DS_Store index 958caa952f4b11bd2e750de6add920847572acea..f418bedae4690782287f5ca843eb0887d5233734 100644 GIT binary patch literal 10244 zcmeHMU2GLa6rOKe=w7B4rm+}(Q% zmYT*yA3!wvqVX^KNeUzpq9A>i9&!iMmXjv_+=Skt zAoM`!fzSh?2SN{o9=H)aKzlY%a;czU8G0b}K($qP4ymYk+Vm2+L@t&0#rvJ1xR>&B zZc8e=mvfztW2FoARC$^Irfp<>1yeVuOJBEX>&{S%le2Z#*Nuw?IU+}r zYUS{7L;b4S=-O3{Bel`tbq)2k(KV~@7#WGk6*Vh2>`orG25jeqFag19fXy6d(#f&* z=x)YJ)B1Ryt43OGzExaO6vYcheo-(oGNV+PsdXoMdX>JUIww!obPRf?W4n8dtV=Yh zmbqm0mW*TX${M`AJL6cn0ozTgvok3xle1Eu(QH|9^In5wWo{boZeanu! zFP5pZ=gd_qlwNYL?V0zOMz$yAW(-?5?SoxIrtbB3=S|m4TSljy8ZaWWQ5(5fRylvc ztyP*PI$TpIbWP;a=8>G~9aC#$*`Fh-RV#fuEpCUS^I3FRJxk-z>`Sz2Z7*+W%^Fnd zfxa|3}nqLbyq( z&=MJEV1P_?BSO}!wQBqMwA)jz*D+|=d`TBX+nv-MLzM#m80GFZ`8lKPL7HL-djr`=9t4XllAX9rl84YO1133i&j&d#&<*=Ou4_C5QB{RUti?w18c@jM#1Jbir2Dt&k}&Rmo?Ss)p4O3O}_dVCx!*gIvH|*o>V%y5s1=ek5@KY3LY$4F^XE z=f^RE`!I_83FQwF&L6>}coI+HX~Oyoco8q*G+rU3zln2r3-97RoW}?D%J2W%|N8s?6wDM35qco> zz>Vqw6t~6OT4;5JL;d)L^1JpZR_|(Z delta 135 zcmZn(XfcprU|?W$DortDU=RQ@Ie-{MGqg=C6q~50D98k4GlIlYij#Aa^7C^h7HUs6 zP+^&TUqEznl(^tzKXIOorEctt**Q1_nL#>%in)P=D-gGBEd0(qnO{Yh6KDj(0U&0W VY{MfxIYEV;6=X5P=6IeN%mBcj8N2`h diff --git a/app/Http/Controllers/Api/.DS_Store b/app/Http/Controllers/Api/.DS_Store index bf2b2d0ae4db4a0c2be239f090d604a4639fcefd..f95540af8229fec24b2aaac541cce947a07ed54e 100644 GIT binary patch delta 88 zcmZoMXfc=|&e%S&P;8=}A|unp0PD#HA}ka8YLd)1UMMmHeUSBJeglamz9x$ Mf#JYrTam-e01H?Vl>h($ diff --git a/app/Http/Middleware/EnsureAccountActive.php b/app/Http/Middleware/EnsureAccountActive.php new file mode 100644 index 00000000..a97c940f --- /dev/null +++ b/app/Http/Middleware/EnsureAccountActive.php @@ -0,0 +1,34 @@ +user(); + + if (! $user) { + return response()->json(['message' => 'Unauthorized.'], 401); + } + + $status = strtolower(trim((string) ($user->status ?? ''))); + $isVerified = filter_var($user->is_verified ?? false, FILTER_VALIDATE_BOOLEAN); + $isSuspended = filter_var($user->is_suspended ?? false, FILTER_VALIDATE_BOOLEAN); + + if (! $isVerified || $status !== 'active' || $isSuspended) { + return response()->json([ + 'message' => 'Account unavailable.', + ], 403); + } + + return $next($request); + } +} diff --git a/app/Http/Requests/SchoolYears/ArchiveSchoolYearRequest.php b/app/Http/Requests/SchoolYears/ArchiveSchoolYearRequest.php new file mode 100644 index 00000000..042ac745 --- /dev/null +++ b/app/Http/Requests/SchoolYears/ArchiveSchoolYearRequest.php @@ -0,0 +1,23 @@ +user()?->id ?? 0); + + return app(PermissionCheckService::class)->hasPermission($userId, 'school_year.archive'); + } + + public function rules(): array + { + return [ + 'reason' => ['nullable', 'string', 'max:1000'], + ]; + } +} diff --git a/app/Http/Requests/SchoolYears/ReopenSchoolYearRequest.php b/app/Http/Requests/SchoolYears/ReopenSchoolYearRequest.php new file mode 100644 index 00000000..d0502a7e --- /dev/null +++ b/app/Http/Requests/SchoolYears/ReopenSchoolYearRequest.php @@ -0,0 +1,23 @@ +user()?->id ?? 0); + + return app(PermissionCheckService::class)->hasPermission($userId, 'school_year.reopen'); + } + + public function rules(): array + { + return [ + 'reason' => ['nullable', 'string', 'max:1000'], + ]; + } +} diff --git a/app/Services/.DS_Store b/app/Services/.DS_Store index abf0a397132558a8ba9abadd0d3ecab55e41a29c..a2716819a4c1ae81275ab2ace701c0987f181f72 100644 GIT binary patch literal 8196 zcmeHMTWl0n7(U;$v@>*|1GKVW2R2=ZfGw1AX}Klan{qF*E!~#FGP^UA`dD`e9=Tv^ik0SV|>79ygX>4FDeiIGiSD3N)tnj!7!(p^Pm6x z|9{SzZ~kx2o+)Dt?RkAAV-d!fNS7y-DynW$JiB*IDnigxNfH##n894#%~)y2u_k$k z9U%fC0wDq+0wDq+0=EMKv}b!ooMPYS*02r{2obm=5%As*QMx=C4`h)`|J6a2e*_>| zPThW?Hk||fm}ns5fh=LN zMSXXMIG14^A`l`l83FI?UcuU##&mY@#`C*$jUmA@Q5*G&e-otX@0b z5FK0B+|&?Vy=v|FxFpubR&3avI&2Nw&It|#f|m)K!S#vyB(sZz<$2GlS`ja{1XwI`uG9?FGC!6c=2TLhR-Zgd` zG?rN~I%z~VY0{KlV9f*$yaDOV%()8}Eop3S*%2qU(PL}FhBONe(#7h?y!m(6sVaB48c=dg=F{epyqPo(y~VPDCKOhqOH{HKT_)Vg1U4w=lDiKV`sgp_Ity%>AHUp z^CR=B)r8tBDxZn;h)la+5>M!{a=M7I(xZvRm+@xo{Z!F!aiC-IrocsHDr;t)Y&$zZ ztQ=#f*wgGZdyAcCAF(gkH|$6D8~X!51u8KeRj9#yEJ6d;pard1hjw&h7j`3oK@7pf zA-Fh-V;IA6Jc<)IiBotSPvLpIfEV!+Uc(!B6KC-@-opiaf=}@|F5_E#hwt$V{={Fn zB1{wJ3K3zRP%ktHjly!FMQ9b)3mb%;Lbs3l&AfL{mlZ zRk^Ntl|*Dz$^x~qg;a1w-mp<3S}Ns%x*$#}^Od@~&Mq3}f+GG~Ie&>=WWF^-2(#3PjRk5Se?fhX|{p2c&N z`7h%Yyo%F!o$~%2oWr~L03YH!J`Nc0HRbi}I|@%)Nh`XN;L w$8nPWah&ADKMbiIC08#d9>^k>)I;Sz{}2%F|JVL{<(qA||9ii6@2LI%Z#ucYasU7T delta 120 zcmZp1XfcprU|?W$DortDU=RQ@Ie-{MGqg=C6q~50$jCG?zwhere('school_year', $fromSchoolYear) - ->whereNotIn(DB::raw('LOWER(COALESCE(status, ""))'), ['void', 'voided', 'cancelled', 'canceled']) + ->whereNotIn(DB::raw("LOWER(COALESCE(status, ''))"), ['void', 'voided', 'cancelled', 'canceled']) + ->select('parent_id') + ->selectRaw('ROUND(SUM(COALESCE(balance, 0)), 2) as net_balance') + ->selectRaw('COUNT(CASE WHEN COALESCE(balance, 0) > 0.01 THEN 1 END) as unpaid_invoice_count') + ->groupBy('parent_id') + ->havingRaw('ABS(SUM(COALESCE(balance, 0))) > 0.01') ->get(); - $byParent = []; - foreach ($invoices as $invoice) { - $parentId = (int) ($invoice->parent_id ?? 0); - if ($parentId <= 0) { - continue; - } - - $balance = $invoice->balance !== null - ? (float) $invoice->balance - : (float) ($invoice->total_amount ?? 0) - (float) ($invoice->paid_amount ?? 0); - - if (! isset($byParent[$parentId])) { - $existing = ParentBalanceTransfer::query() - ->where('parent_id', $parentId) - ->where('from_school_year', $fromSchoolYear) - ->where('to_school_year', $toSchoolYear) - ->first(); - - $byParent[$parentId] = [ - 'parent_id' => $parentId, - 'parent_name' => $this->resolveParentName($parentId), - 'student_names' => $this->resolveStudentNames($parentId, $fromSchoolYear), - 'unpaid_invoice_count' => 0, - 'old_unpaid_balance' => 0.0, - 'credit_balance' => 0.0, - 'net_balance' => 0.0, - 'amount_to_transfer' => 0.0, - 'transfer_status' => $existing?->status, - 'existing_transfer_id' => $existing?->id, - 'source_invoice_ids' => [], - ]; - } - - $byParent[$parentId]['source_invoice_ids'][] = (int) $invoice->id; - $byParent[$parentId]['net_balance'] += $balance; - if ($balance > 0) { - $byParent[$parentId]['unpaid_invoice_count']++; - } - } - $rows = []; $summary = [ 'parents_with_non_zero_balance' => 0, @@ -683,16 +648,46 @@ class SchoolYearClosureService 'net_balance_to_transfer' => 0.0, ]; - foreach ($byParent as $row) { - $net = round((float) $row['net_balance'], 2); + foreach ($invoiceBalances as $balanceRow) { + $parentId = (int) ($balanceRow->parent_id ?? 0); + if ($parentId <= 0) { + continue; + } + + $net = round((float) ($balanceRow->net_balance ?? 0), 2); if (abs($net) < 0.01) { continue; } - $row['old_unpaid_balance'] = $net > 0 ? $net : 0.0; - $row['credit_balance'] = $net < 0 ? abs($net) : 0.0; - $row['amount_to_transfer'] = $net; - $row['transfer_status'] = $row['transfer_status'] ?? ($net > 0 ? 'pending' : 'credit_pending'); + $existing = ParentBalanceTransfer::query() + ->where('parent_id', $parentId) + ->where('from_school_year', $fromSchoolYear) + ->where('to_school_year', $toSchoolYear) + ->first(); + + $sourceInvoiceIds = DB::table('invoices') + ->where('parent_id', $parentId) + ->where('school_year', $fromSchoolYear) + ->whereRaw('ABS(COALESCE(balance, 0)) > 0.01') + ->whereNotIn(DB::raw("LOWER(COALESCE(status, ''))"), ['void', 'voided', 'cancelled', 'canceled']) + ->pluck('id') + ->map(fn ($id) => (int) $id) + ->all(); + + $row = [ + 'parent_id' => $parentId, + 'parent_name' => $this->resolveParentName($parentId), + 'student_names' => $this->resolveStudentNames($parentId, $fromSchoolYear), + 'unpaid_invoice_count' => (int) ($balanceRow->unpaid_invoice_count ?? 0), + 'old_unpaid_balance' => $net > 0 ? $net : 0.0, + 'credit_balance' => $net < 0 ? abs($net) : 0.0, + 'net_balance' => $net, + 'amount_to_transfer' => $net, + 'transfer_status' => $existing?->status ?? ($net > 0 ? 'pending' : 'credit_pending'), + 'existing_transfer_id' => $existing?->id, + 'source_invoice_ids' => $sourceInvoiceIds, + ]; + $rows[] = $row; $summary['parents_with_non_zero_balance']++; diff --git a/bootstrap/app.php b/bootstrap/app.php index c98b82f1..898c8100 100644 --- a/bootstrap/app.php +++ b/bootstrap/app.php @@ -3,6 +3,7 @@ use App\Http\Middleware\ApiDocsAuth; use App\Http\Middleware\ApiJwtAuth; use App\Http\Middleware\CleanupScheduler; +use App\Http\Middleware\EnsureAccountActive; use App\Http\Middleware\EnsureBadgeScanLogsAccess; use App\Http\Middleware\EnsureClassProgressTeacherPortalAccess; use App\Http\Middleware\EnsureParentProgressAccess; @@ -32,6 +33,7 @@ return Application::configure(basePath: dirname(__DIR__)) ) ->withMiddleware(function (Middleware $middleware): void { $middleware->append(SecurityHeaders::class); + $middleware->alias([ // JWT auth @@ -43,6 +45,9 @@ return Application::configure(basePath: dirname(__DIR__)) 'auth.multi' => MultiAuth::class, 'multi.auth' => MultiAuth::class, + // Account status + 'account.active' => EnsureAccountActive::class, + // Permission / role gates 'perm' => RequirePermission::class, 'require.permission' => RequirePermission::class, diff --git a/bootstrap/cache/packages.php b/bootstrap/cache/packages.php index d09ac981..9fe4c742 100755 --- a/bootstrap/cache/packages.php +++ b/bootstrap/cache/packages.php @@ -41,4 +41,16 @@ 0 => 'Termwind\\Laravel\\TermwindServiceProvider', ), ), + 'php-open-source-saver/jwt-auth' => + array ( + 'aliases' => + array ( + 'JWTAuth' => 'PHPOpenSourceSaver\\JWTAuth\\Facades\\JWTAuth', + 'JWTFactory' => 'PHPOpenSourceSaver\\JWTAuth\\Facades\\JWTFactory', + ), + 'providers' => + array ( + 0 => 'PHPOpenSourceSaver\\JWTAuth\\Providers\\LaravelServiceProvider', + ), + ), ); \ No newline at end of file diff --git a/bootstrap/cache/services.php b/bootstrap/cache/services.php index 91260b7b..ea5fd7ff 100755 --- a/bootstrap/cache/services.php +++ b/bootstrap/cache/services.php @@ -30,9 +30,10 @@ 26 => 'Carbon\\Laravel\\ServiceProvider', 27 => 'NunoMaduro\\Collision\\Adapters\\Laravel\\CollisionServiceProvider', 28 => 'Termwind\\Laravel\\TermwindServiceProvider', - 29 => 'App\\Providers\\AppServiceProvider', - 30 => 'App\\Providers\\EventServiceProvider', - 31 => 'Laravel\\Sanctum\\SanctumServiceProvider', + 29 => 'PHPOpenSourceSaver\\JWTAuth\\Providers\\LaravelServiceProvider', + 30 => 'App\\Providers\\AppServiceProvider', + 31 => 'App\\Providers\\EventServiceProvider', + 32 => 'Laravel\\Sanctum\\SanctumServiceProvider', ), 'eager' => array ( @@ -51,9 +52,10 @@ 12 => 'Carbon\\Laravel\\ServiceProvider', 13 => 'NunoMaduro\\Collision\\Adapters\\Laravel\\CollisionServiceProvider', 14 => 'Termwind\\Laravel\\TermwindServiceProvider', - 15 => 'App\\Providers\\AppServiceProvider', - 16 => 'App\\Providers\\EventServiceProvider', - 17 => 'Laravel\\Sanctum\\SanctumServiceProvider', + 15 => 'PHPOpenSourceSaver\\JWTAuth\\Providers\\LaravelServiceProvider', + 16 => 'App\\Providers\\AppServiceProvider', + 17 => 'App\\Providers\\EventServiceProvider', + 18 => 'Laravel\\Sanctum\\SanctumServiceProvider', ), 'deferred' => array ( diff --git a/composer.json b/composer.json index c1f8abd1..401b48dc 100644 --- a/composer.json +++ b/composer.json @@ -10,7 +10,8 @@ "chillerlan/php-qrcode": "^5.0", "dompdf/dompdf": "^3.1", "laravel/framework": "^12.0", - "laravel/sanctum": "^4.3" + "laravel/sanctum": "^4.3", + "php-open-source-saver/jwt-auth": "^2.9" }, "require-dev": { "fakerphp/faker": "^1.23", diff --git a/composer.lock b/composer.lock index a4a8f33a..77b590a1 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "bdb0090286bd5459f0600321c75dfaf7", + "content-hash": "030fdeff24a9b7f70514420d59d17283", "packages": [ { "name": "brick/math", @@ -1780,6 +1780,79 @@ }, "time": "2026-04-16T14:03:50+00:00" }, + { + "name": "lcobucci/jwt", + "version": "5.6.0", + "source": { + "type": "git", + "url": "https://github.com/lcobucci/jwt.git", + "reference": "bb3e9f21e4196e8afc41def81ef649c164bca25e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/lcobucci/jwt/zipball/bb3e9f21e4196e8afc41def81ef649c164bca25e", + "reference": "bb3e9f21e4196e8afc41def81ef649c164bca25e", + "shasum": "" + }, + "require": { + "ext-openssl": "*", + "ext-sodium": "*", + "php": "~8.2.0 || ~8.3.0 || ~8.4.0 || ~8.5.0", + "psr/clock": "^1.0" + }, + "require-dev": { + "infection/infection": "^0.29", + "lcobucci/clock": "^3.2", + "lcobucci/coding-standard": "^11.0", + "phpbench/phpbench": "^1.2", + "phpstan/extension-installer": "^1.2", + "phpstan/phpstan": "^1.10.7", + "phpstan/phpstan-deprecation-rules": "^1.1.3", + "phpstan/phpstan-phpunit": "^1.3.10", + "phpstan/phpstan-strict-rules": "^1.5.0", + "phpunit/phpunit": "^11.1" + }, + "suggest": { + "lcobucci/clock": ">= 3.2" + }, + "type": "library", + "autoload": { + "psr-4": { + "Lcobucci\\JWT\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Luís Cobucci", + "email": "lcobucci@gmail.com", + "role": "Developer" + } + ], + "description": "A simple library to work with JSON Web Token and JSON Web Signature", + "keywords": [ + "JWS", + "jwt" + ], + "support": { + "issues": "https://github.com/lcobucci/jwt/issues", + "source": "https://github.com/lcobucci/jwt/tree/5.6.0" + }, + "funding": [ + { + "url": "https://github.com/lcobucci", + "type": "github" + }, + { + "url": "https://www.patreon.com/lcobucci", + "type": "patreon" + } + ], + "time": "2025-10-17T11:30:53+00:00" + }, { "name": "league/commonmark", "version": "2.8.2", @@ -2509,6 +2582,73 @@ ], "time": "2026-01-02T08:56:05+00:00" }, + { + "name": "namshi/jose", + "version": "7.2.3", + "source": { + "type": "git", + "url": "https://github.com/namshi/jose.git", + "reference": "89a24d7eb3040e285dd5925fcad992378b82bcff" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/namshi/jose/zipball/89a24d7eb3040e285dd5925fcad992378b82bcff", + "reference": "89a24d7eb3040e285dd5925fcad992378b82bcff", + "shasum": "" + }, + "require": { + "ext-date": "*", + "ext-hash": "*", + "ext-json": "*", + "ext-pcre": "*", + "ext-spl": "*", + "php": ">=5.5", + "symfony/polyfill-php56": "^1.0" + }, + "require-dev": { + "phpseclib/phpseclib": "^2.0", + "phpunit/phpunit": "^4.5|^5.0", + "satooshi/php-coveralls": "^1.0" + }, + "suggest": { + "ext-openssl": "Allows to use OpenSSL as crypto engine.", + "phpseclib/phpseclib": "Allows to use Phpseclib as crypto engine, use version ^2.0." + }, + "type": "library", + "autoload": { + "psr-4": { + "Namshi\\JOSE\\": "src/Namshi/JOSE/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Alessandro Nadalin", + "email": "alessandro.nadalin@gmail.com" + }, + { + "name": "Alessandro Cinelli (cirpo)", + "email": "alessandro.cinelli@gmail.com" + } + ], + "description": "JSON Object Signing and Encryption library for PHP.", + "keywords": [ + "JSON Web Signature", + "JSON Web Token", + "JWS", + "json", + "jwt", + "token" + ], + "support": { + "issues": "https://github.com/namshi/jose/issues", + "source": "https://github.com/namshi/jose/tree/master" + }, + "time": "2016-12-05T07:27:31+00:00" + }, { "name": "nesbot/carbon", "version": "3.13.0", @@ -2859,6 +2999,99 @@ ], "time": "2026-02-16T23:10:27+00:00" }, + { + "name": "php-open-source-saver/jwt-auth", + "version": "2.9.2", + "source": { + "type": "git", + "url": "https://github.com/PHP-Open-Source-Saver/jwt-auth.git", + "reference": "ce08363a9986e5253efd3663ed4f75c976bec89a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/PHP-Open-Source-Saver/jwt-auth/zipball/ce08363a9986e5253efd3663ed4f75c976bec89a", + "reference": "ce08363a9986e5253efd3663ed4f75c976bec89a", + "shasum": "" + }, + "require": { + "ext-json": "*", + "illuminate/auth": "^12|^13", + "illuminate/contracts": "^12|^13", + "illuminate/http": "^12|^13", + "illuminate/support": "^12|^13", + "lcobucci/jwt": "^5.4", + "namshi/jose": "^7.0", + "nesbot/carbon": "^2.0|^3.0", + "php": "^8.3" + }, + "require-dev": { + "friendsofphp/php-cs-fixer": "^3", + "illuminate/console": "^12|^13", + "illuminate/routing": "^12|^13", + "mockery/mockery": "^1.6", + "orchestra/testbench": "^10|^11", + "phpstan/phpstan": "^2", + "phpunit/phpunit": "^10.5|^11" + }, + "type": "library", + "extra": { + "laravel": { + "aliases": { + "JWTAuth": "PHPOpenSourceSaver\\JWTAuth\\Facades\\JWTAuth", + "JWTFactory": "PHPOpenSourceSaver\\JWTAuth\\Facades\\JWTFactory" + }, + "providers": [ + "PHPOpenSourceSaver\\JWTAuth\\Providers\\LaravelServiceProvider" + ] + } + }, + "autoload": { + "psr-4": { + "PHPOpenSourceSaver\\JWTAuth\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Sean Tymon", + "email": "tymon148@gmail.com", + "homepage": "https://tymon.xyz", + "role": "Forked package creator | Developer" + }, + { + "name": "Eric Schricker", + "email": "eric.schricker@adiutabyte.de", + "role": "Developer" + }, + { + "name": "Fabio William Conceição", + "email": "messhias@gmail.com", + "role": "Developer" + }, + { + "name": "Max Snow", + "email": "contact@maxsnow.me", + "role": "Developer" + } + ], + "description": "JSON Web Token Authentication for Laravel and Lumen", + "homepage": "https://github.com/PHP-Open-Source-Saver/jwt-auth", + "keywords": [ + "Authentication", + "JSON Web Token", + "auth", + "jwt", + "laravel" + ], + "support": { + "issues": "https://github.com/PHP-Open-Source-Saver/jwt-auth/issues", + "source": "https://github.com/PHP-Open-Source-Saver/jwt-auth" + }, + "time": "2026-05-07T16:44:01+00:00" + }, { "name": "phpoption/phpoption", "version": "1.9.5", @@ -5051,6 +5284,74 @@ ], "time": "2026-05-27T06:59:30+00:00" }, + { + "name": "symfony/polyfill-php56", + "version": "v1.20.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-php56.git", + "reference": "54b8cd7e6c1643d78d011f3be89f3ef1f9f4c675" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-php56/zipball/54b8cd7e6c1643d78d011f3be89f3ef1f9f4c675", + "reference": "54b8cd7e6c1643d78d011f3be89f3ef1f9f4c675", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "type": "metapackage", + "extra": { + "thanks": { + "url": "https://github.com/symfony/polyfill", + "name": "symfony/polyfill" + }, + "branch-alias": { + "dev-main": "1.20-dev" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill backporting some PHP 5.6+ features to lower PHP versions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-php56/tree/v1.20.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2020-10-23T14:02:19+00:00" + }, { "name": "symfony/polyfill-php80", "version": "v1.37.0", diff --git a/database/.DS_Store b/database/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..780579599a8d83aa7068b7c2f1386b758910a918 GIT binary patch literal 6148 zcmeHK%Sr=55Ukc5f?jgWael!+7()C4f51mTgy@3N`=0V$`82B^h+&h9;6?0&UZZE11}ixhTWw4bi%n;cqQu@??3sQ z-P87Q7`CTr%1Qw#AO)m=6p#YHRKR;LZGN4oC*bB$R_;fJD2tb@M z9maLc62#^SVlNyMnW0%yiAl8@F)ZoKx2o%fV`9=_HGEi|Y&D@+oX+>RD2Me#MJXT! zjup7f?ZW&2E&a^=e@xO&3P^!}rGU-Wck30eRK0a_Iq$WNeoyzB1Ko}5pfE%`CPq8v g#@q2Sin6Zxn$LUTm>6{CgHF`Xfa@ZY0)MT*7aTqnwEzGB literal 0 HcmV?d00001 diff --git a/database/migrations/2026_07_05_000001_add_school_year_closure_foundation.php b/database/migrations/2026_07_05_000001_add_school_year_closure_foundation.php new file mode 100644 index 00000000..31e78c11 --- /dev/null +++ b/database/migrations/2026_07_05_000001_add_school_year_closure_foundation.php @@ -0,0 +1,162 @@ +id(); + $table->string('name', 50)->unique(); + $table->date('start_date'); + $table->date('end_date'); + $table->string('status', 20)->default('draft')->index(); + $table->boolean('is_current')->default(false)->index(); + $table->timestamp('closed_at')->nullable(); + $table->unsignedBigInteger('closed_by')->nullable(); + $table->timestamp('reopened_at')->nullable(); + $table->unsignedBigInteger('reopened_by')->nullable(); + $table->timestamp('archived_at')->nullable(); + $table->unsignedBigInteger('archived_by')->nullable(); + $table->timestamps(); + }); + } else { + Schema::table('school_years', function (Blueprint $table): void { + if (! Schema::hasColumn('school_years', 'reopened_at')) { + $table->timestamp('reopened_at')->nullable()->after('closed_by'); + } + if (! Schema::hasColumn('school_years', 'reopened_by')) { + $table->unsignedBigInteger('reopened_by')->nullable()->after('reopened_at'); + } + if (! Schema::hasColumn('school_years', 'archived_at')) { + $table->timestamp('archived_at')->nullable()->after('reopened_by'); + } + if (! Schema::hasColumn('school_years', 'archived_by')) { + $table->unsignedBigInteger('archived_by')->nullable()->after('archived_at'); + } + }); + } + + if (! Schema::hasTable('student_enrollments')) { + Schema::create('student_enrollments', function (Blueprint $table): void { + $table->id(); + $table->unsignedBigInteger('student_id'); + $table->unsignedBigInteger('school_year_id'); + $table->unsignedBigInteger('grade_id'); + $table->unsignedBigInteger('class_id')->nullable(); + $table->string('status', 30)->default('enrolled')->index(); + $table->unsignedBigInteger('promoted_from_enrollment_id')->nullable(); + $table->timestamps(); + $table->unique(['student_id', 'school_year_id'], 'uniq_student_year'); + $table->index('school_year_id', 'idx_enrollment_school_year'); + $table->index('student_id', 'idx_enrollment_student'); + }); + } + + if (! Schema::hasTable('parent_accounts')) { + Schema::create('parent_accounts', function (Blueprint $table): void { + $table->id(); + $table->unsignedBigInteger('parent_id'); + $table->string('school_year', 50)->nullable(); + $table->unsignedBigInteger('school_year_id')->nullable(); + $table->decimal('opening_balance', 12, 2)->default(0); + $table->decimal('current_balance', 12, 2)->default(0); + $table->timestamps(); + $table->unique(['parent_id', 'school_year'], 'uniq_parent_school_year_name'); + $table->index('parent_id', 'idx_parent_account_parent'); + $table->index('school_year_id', 'idx_parent_account_school_year_id'); + }); + } else { + Schema::table('parent_accounts', function (Blueprint $table): void { + if (! Schema::hasColumn('parent_accounts', 'school_year_id')) { + $table->unsignedBigInteger('school_year_id')->nullable()->after('school_year'); + } + }); + } + + if (! Schema::hasTable('parent_balance_transfers')) { + Schema::create('parent_balance_transfers', function (Blueprint $table): void { + $table->id(); + $table->unsignedBigInteger('parent_id'); + $table->string('from_school_year', 50)->nullable(); + $table->string('to_school_year', 50)->nullable(); + $table->unsignedBigInteger('from_school_year_id')->nullable(); + $table->unsignedBigInteger('to_school_year_id')->nullable(); + $table->decimal('amount', 12, 2); + $table->string('status', 30)->default('transferred'); + $table->json('source_summary_json')->nullable(); + $table->json('source_summary')->nullable(); + $table->unsignedBigInteger('new_invoice_id')->nullable(); + $table->unsignedBigInteger('old_balance_invoice_id')->nullable(); + $table->timestamp('reversed_at')->nullable(); + $table->unsignedBigInteger('reversed_by')->nullable(); + $table->text('reversal_reason')->nullable(); + $table->unsignedBigInteger('created_by')->nullable(); + $table->timestamps(); + $table->unique(['parent_id', 'from_school_year', 'to_school_year'], 'uniq_parent_year_transfer_name'); + $table->index('parent_id', 'idx_balance_transfer_parent'); + $table->index('from_school_year_id', 'idx_balance_transfer_from_year_id'); + $table->index('to_school_year_id', 'idx_balance_transfer_to_year_id'); + }); + } else { + Schema::table('parent_balance_transfers', function (Blueprint $table): void { + if (! Schema::hasColumn('parent_balance_transfers', 'from_school_year_id')) { + $table->unsignedBigInteger('from_school_year_id')->nullable()->after('to_school_year'); + } + if (! Schema::hasColumn('parent_balance_transfers', 'to_school_year_id')) { + $table->unsignedBigInteger('to_school_year_id')->nullable()->after('from_school_year_id'); + } + if (! Schema::hasColumn('parent_balance_transfers', 'source_summary')) { + $table->json('source_summary')->nullable()->after('source_summary_json'); + } + if (! Schema::hasColumn('parent_balance_transfers', 'old_balance_invoice_id')) { + $table->unsignedBigInteger('old_balance_invoice_id')->nullable()->after('new_invoice_id'); + } + if (! Schema::hasColumn('parent_balance_transfers', 'reversed_at')) { + $table->timestamp('reversed_at')->nullable(); + } + if (! Schema::hasColumn('parent_balance_transfers', 'reversed_by')) { + $table->unsignedBigInteger('reversed_by')->nullable(); + } + if (! Schema::hasColumn('parent_balance_transfers', 'reversal_reason')) { + $table->text('reversal_reason')->nullable(); + } + }); + } + + if (Schema::hasTable('invoices')) { + Schema::table('invoices', function (Blueprint $table): void { + if (! Schema::hasColumn('invoices', 'school_year_id')) { + $table->unsignedBigInteger('school_year_id')->nullable()->after('school_year'); + } + if (! Schema::hasColumn('invoices', 'parent_id')) { + $table->unsignedBigInteger('parent_id')->nullable(); + } + if (! Schema::hasColumn('invoices', 'student_id')) { + $table->unsignedBigInteger('student_id')->nullable()->after('parent_id'); + } + if (! Schema::hasColumn('invoices', 'invoice_type')) { + $table->string('invoice_type', 50)->nullable()->after('invoice_number'); + } + if (! Schema::hasColumn('invoices', 'balance_transfer_id')) { + $table->unsignedBigInteger('balance_transfer_id')->nullable()->after('invoice_type'); + } + if (! Schema::hasColumn('invoices', 'locked_at')) { + $table->timestamp('locked_at')->nullable(); + } + if (! Schema::hasColumn('invoices', 'locked_by')) { + $table->unsignedBigInteger('locked_by')->nullable(); + } + }); + } + } + + public function down(): void + { + Schema::dropIfExists('student_enrollments'); + } +}; diff --git a/database/migrations/2026_07_05_000002_seed_school_year_closure_permissions.php b/database/migrations/2026_07_05_000002_seed_school_year_closure_permissions.php new file mode 100644 index 00000000..ed47106e --- /dev/null +++ b/database/migrations/2026_07_05_000002_seed_school_year_closure_permissions.php @@ -0,0 +1,151 @@ + */ + private array $permissions = [ + 'school_year.view', + 'school_year.view_closed', + 'school_year.create', + 'school_year.close', + 'school_year.reopen', + 'school_year.archive', + 'school_year.manage', + 'school_year.select', + 'student_enrollment.view', + 'student_enrollment.manage', + 'student_enrollment.promote', + 'student_enrollment.transition', + 'finance.view', + 'finance.manage', + 'finance.invoice.manage', + 'finance.payment.manage', + 'finance.balance_transfer.view', + 'finance.balance_transfer.run', + 'finance.balance_transfer.reverse', + 'finance.report.view', + 'reports.view', + 'reports.export', + 'audit.view', + ]; + + public function up(): void + { + if (! Schema::hasTable('permissions')) { + return; + } + + foreach ($this->permissions as $permission) { + DB::table('permissions')->updateOrInsert( + ['name' => $permission], + $this->filterColumns('permissions', [ + 'description' => $this->describe($permission), + 'created_at' => now(), + 'updated_at' => now(), + ]) + ); + } + + $this->grantByRoleNames(['super admin', 'super_admin', 'administrator', 'admin'], $this->permissions); + $this->grantByRoleNames(['director', 'principal'], [ + 'school_year.view', + 'school_year.view_closed', + 'school_year.select', + 'school_year.close', + 'student_enrollment.view', + 'student_enrollment.promote', + 'finance.balance_transfer.view', + 'reports.view', + ]); + $this->grantByRoleNames(['finance admin', 'finance_admin', 'finance'], [ + 'school_year.view', + 'school_year.select', + 'finance.view', + 'finance.manage', + 'finance.invoice.manage', + 'finance.payment.manage', + 'finance.balance_transfer.view', + 'finance.balance_transfer.run', + 'finance.balance_transfer.reverse', + 'finance.report.view', + 'reports.view', + 'reports.export', + ]); + $this->grantByRoleNames(['teacher'], [ + 'school_year.view', + 'school_year.view_closed', + 'school_year.select', + 'student_enrollment.view', + ]); + $this->grantByRoleNames(['parent'], [ + 'school_year.view', + 'school_year.select', + 'finance.view', + ]); + } + + public function down(): void + { + if (! Schema::hasTable('permissions')) { + return; + } + + DB::table('permissions')->whereIn('name', $this->permissions)->delete(); + } + + private function grantByRoleNames(array $roleNames, array $permissions): void + { + if (! Schema::hasTable('roles') || ! Schema::hasTable('role_permissions')) { + return; + } + + $roleIds = DB::table('roles') + ->whereIn(DB::raw('LOWER(name)'), array_map('strtolower', $roleNames)) + ->pluck('id') + ->map(fn ($id) => (int) $id) + ->all(); + + if ($roleIds === []) { + return; + } + + $permissionRows = DB::table('permissions') + ->whereIn('name', $permissions) + ->pluck('id', 'name'); + + foreach ($roleIds as $roleId) { + foreach ($permissionRows as $permissionId) { + DB::table('role_permissions')->updateOrInsert( + ['role_id' => $roleId, 'permission_id' => (int) $permissionId], + $this->filterColumns('role_permissions', [ + 'can_create' => true, + 'can_read' => true, + 'can_update' => true, + 'can_delete' => true, + 'can_manage' => true, + 'created_at' => now(), + 'updated_at' => now(), + ]) + ); + } + } + } + + private function describe(string $permission): string + { + return 'Allows '.$permission.' for the school-year closure workflow.'; + } + + private function filterColumns(string $table, array $values): array + { + return array_filter( + $values, + static fn (string $column): bool => Schema::hasColumn($table, $column), + ARRAY_FILTER_USE_KEY + ); + } +}; diff --git a/alrahma_sunday_school_api.code-workspace b/docs/alrahma_sunday_school_api.code-workspace similarity index 100% rename from alrahma_sunday_school_api.code-workspace rename to docs/alrahma_sunday_school_api.code-workspace diff --git a/car_management_system.code-workspace b/docs/car_management_system.code-workspace similarity index 100% rename from car_management_system.code-workspace rename to docs/car_management_system.code-workspace diff --git a/car_rental_app.code-workspace b/docs/car_rental_app.code-workspace similarity index 100% rename from car_rental_app.code-workspace rename to docs/car_rental_app.code-workspace diff --git a/command_to_run_dev.txt b/docs/command_to_run_dev.txt similarity index 100% rename from command_to_run_dev.txt rename to docs/command_to_run_dev.txt diff --git a/deploy_dev.txt b/docs/deploy_dev.txt similarity index 100% rename from deploy_dev.txt rename to docs/deploy_dev.txt diff --git a/envfile.txt b/docs/envfile.txt similarity index 100% rename from envfile.txt rename to docs/envfile.txt diff --git a/failed-tests.txt b/docs/failed-tests.txt similarity index 100% rename from failed-tests.txt rename to docs/failed-tests.txt diff --git a/test.sql b/docs/test.sql similarity index 100% rename from test.sql rename to docs/test.sql diff --git a/routes/api.php b/routes/api.php index 9ecf7e6b..12a36554 100644 --- a/routes/api.php +++ b/routes/api.php @@ -480,19 +480,20 @@ Route::prefix('v1')->group(function () { }); }); - Route::middleware(['multi.auth', 'admin.access'])->prefix('school-years')->group(function () { - Route::get('/', [SchoolYearController::class, 'index']); - Route::get('current', [SchoolYearController::class, 'current']); - Route::get('options', [SchoolYearController::class, 'options']); - Route::post('/', [SchoolYearController::class, 'store']); - Route::patch('{schoolYear}', [SchoolYearController::class, 'update'])->whereNumber('schoolYear'); - Route::get('{schoolYear}/summary', [SchoolYearController::class, 'summary'])->whereNumber('schoolYear'); - Route::post('{schoolYear}/validate-close', [SchoolYearController::class, 'validateClose'])->whereNumber('schoolYear'); - Route::post('{schoolYear}/preview-close', [SchoolYearController::class, 'previewClose'])->whereNumber('schoolYear'); - Route::post('{schoolYear}/close', [SchoolYearController::class, 'close'])->whereNumber('schoolYear'); - Route::post('{schoolYear}/reopen', [SchoolYearController::class, 'reopen'])->whereNumber('schoolYear'); - Route::get('{schoolYear}/parent-balances', [SchoolYearController::class, 'parentBalances'])->whereNumber('schoolYear'); - Route::get('{schoolYear}/promotion-preview', [SchoolYearController::class, 'promotionPreview'])->whereNumber('schoolYear'); + Route::middleware(['multi.auth', 'account.active'])->prefix('school-years')->group(function () { + Route::get('/', [SchoolYearController::class, 'index'])->middleware('perm:school_year.view'); + Route::get('current', [SchoolYearController::class, 'current'])->middleware('perm:school_year.select'); + Route::get('options', [SchoolYearController::class, 'options'])->middleware('perm:school_year.select'); + Route::post('/', [SchoolYearController::class, 'store'])->middleware('perm:school_year.create'); + Route::patch('{schoolYear}', [SchoolYearController::class, 'update'])->middleware('perm:school_year.manage')->whereNumber('schoolYear'); + Route::get('{schoolYear}/summary', [SchoolYearController::class, 'summary'])->middleware('perm:school_year.view')->whereNumber('schoolYear'); + Route::post('{schoolYear}/validate-close', [SchoolYearController::class, 'validateClose'])->middleware('perm:school_year.close')->whereNumber('schoolYear'); + Route::post('{schoolYear}/preview-close', [SchoolYearController::class, 'previewClose'])->middleware('perm:school_year.close')->whereNumber('schoolYear'); + Route::post('{schoolYear}/close', [SchoolYearController::class, 'close'])->middleware('perm:school_year.close')->whereNumber('schoolYear'); + Route::post('{schoolYear}/reopen', [SchoolYearController::class, 'reopen'])->middleware('perm:school_year.reopen')->whereNumber('schoolYear'); + Route::post('{schoolYear}/archive', [SchoolYearController::class, 'archive'])->middleware('perm:school_year.archive')->whereNumber('schoolYear'); + Route::get('{schoolYear}/parent-balances', [SchoolYearController::class, 'parentBalances'])->middleware('perm:finance.balance_transfer.view')->whereNumber('schoolYear'); + Route::get('{schoolYear}/promotion-preview', [SchoolYearController::class, 'promotionPreview'])->middleware('perm:student_enrollment.promote')->whereNumber('schoolYear'); }); Route::middleware(['multi.auth', 'school_year.editable'])->prefix('attendance')->group(function () { diff --git a/storage/.DS_Store b/storage/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..b7111e7b26c02e650d15802ed1a10c29fe122d4b GIT binary patch literal 8196 zcmeHMU2GIp6u#fI&>1?=0a{tG1Dh^Hz!pmRY57aGf69N6ZRxfYw!1qc9hlCPo!Ko| zYBnamfM|Tu_!oWhhscA95??e?6n#`Q!5AMf8h;)%(HE5m&&-|Wr!6nU7#rs%bI(2Z zoOACzXTEc1Ps?K z*+qSIhB&8TA4VXIz~l&c=_4_h>CB=2ruy9($(VMAq!%(Hrs24ajbB12E1xm5LaY!g z#e<0Z$Zre69rExm5-_S=>N_D$!xoN}FbH0J0>7+8yYgn2++Ggi1 z&GBs$Tp&uKlu{yNV{4k5>Z9w|Z5XeQj%{petdFi+yJ37>5^G|sH}6XwHHR(x6n6%} zg}`P{aPIWfo|#UeoqJZ6D0%i($untIr94~hP4@N611V)*fn4YsaShvY_Uk!^XiBMa z$kpvx+uEDcJ$Y}|HuJ-llTzkp(`Ghrrd_?&G!w={I?Yu%*_>^fdu_+?mg!5n`f=Bj zO%f&h9Xsc?`-`O%CGY6_bXvyscF?TeLL^ z_JtIUJ$0(u=PlQ&X}%AOA`7e3gxVu2pNaH}469&J0?=#ac_7A0uO=2>$%nD`Q$>Ho z109Pu1}Y*`SrhAEyVxMhu`zarJV$fsL0Ba;3oXJXVY9GD=n|4bS~w!u!U#XV zP)fRkfjx7anxK4y~Qzu>R{oA(hkata+q`NZ5PqXTpyB0*3tz5mXWozqo zICA`!AbWEn_~^eSXMFVg=$L@q%YHt}i_9_*Dc5JCgX`{>t z*ySsT-KosvY;D6Tky2C1fNA(698+d53rQYPGLI4!s`e#(ef|99U0@Bh=nm++8b1i}d1Sp-ntk?3e6+uPk` zUacLaXOJGRd3r@oeG}^Za-67NjuXB94?`M9N!7E72eim3%~1Q-{}6EV@9{hT(H(yO L!|(sJ{{H_Bi79^0 literal 0 HcmV?d00001 diff --git a/storage/test-logs/test-results-after-jwt.log b/storage/test-logs/test-results-after-jwt.log new file mode 100644 index 00000000..e077e309 --- /dev/null +++ b/storage/test-logs/test-results-after-jwt.log @@ -0,0 +1,17444 @@ + + FAIL Tests\Unit\ApiDocsServiceTest + ⨯ public bootstrap matches ci public flags 0.01s + ⨯ full bootstrap enables try and welcome 0.01s + + FAIL Tests\Unit\ApiLoginSecurityServiceTest + ✓ roles object map preserves role names 0.02s + ⨯ build login response includes teacher class context 0.01s + ⨯ build login response includes teacher assistant class context + + PASS Tests\Unit\AuthSessionServiceTest + ✓ sanitize redirect relative 0.01s + ✓ sanitize redirect empty + ✓ sanitize rejects protocol relative + + PASS Tests\Unit\Http\Controllers\Api\AttendanceCommentTemplateControllerTest + ✓ index returns success json 0.10s + ✓ index passes active only true 0.01s + ✓ show returns template 0.01s + ✓ store returns created response 0.02s + ✓ update returns success response 0.01s + ✓ destroy returns success response 0.02s + ✓ list data returns templates key 0.01s + + PASS Tests\Unit\Grading\ScoreValueValidatorTest + ✓ blank score remains null 0.04s + ✓ score must be inside range + ✓ status inference preserves legacy pending behavior + + PASS Tests\Unit\Listeners\DeleteUnverifiedUserListenerTest + ✓ listener invokes service 0.02s + + PASS Tests\Unit\Models\AdditionalChargeTest + ✓ scope by parent term filters status and orders desc 0.04s + ✓ mark applied updates status and invoice 0.01s + ✓ list all for term falls back to year 0.01s + ✓ list all for term filters by search query 0.01s + + PASS Tests\Unit\Models\AdminNotificationSubjectModelTest + ✓ admin relationship returns user 0.04s + ✓ timestamps are set on create 0.01s + + PASS Tests\Unit\Models\AttendanceCommentTemplateModelTest + ✓ get active templates filters and orders 0.03s + + PASS Tests\Unit\Models\AttendanceDataTest + ✓ get attendance by class and get attendance 0.03s + ✓ unreported term rows filters unreported 0.01s + ✓ get unreported absences and lates groups rows 0.01s + ✓ mark reported and notified updates flags 0.01s + + PASS Tests\Unit\Models\AttendanceDayTest + ✓ get or create draft creates once and reuses 0.30s + ✓ find by section date returns model or null 0.01s + ✓ submit sets submitted fields 0.01s + ✓ finalize is alias to submit 0.01s + ✓ publish sets published fields 0.01s + ✓ reopen sets reopen fields and status 0.01s + ✓ reopen rejects invalid status 0.01s + ✓ is finalized true for published or legacy finalized 0.01s + + FAIL Tests\Unit\Models\AttendanceEmailTemplateTest + ⨯ get template returns exact active variant when available 0.02s + ⨯ get template falls back to default when requested variant missing 0.02s + ⨯ get template ignores inactive exact variant and uses active default 0.01s + ⨯ get template returns null when no active template exists 0.01s + + PASS Tests\Unit\Models\AttendanceRecordTest + ✓ model metadata is converted + ✓ model class loads + + PASS Tests\Unit\Models\AttendanceTrackingTest + ✓ model metadata is converted + ✓ model class loads + + PASS Tests\Unit\Models\AuthorizedUserTest + ✓ model metadata is converted + ✓ model class loads + + PASS Tests\Unit\Models\BadgePrintLogTest + ✓ model metadata is converted + ✓ model class loads + + PASS Tests\Unit\Models\CalendarTest + ✓ model metadata is converted + ✓ model class loads + + FAIL Tests\Unit\Models\ClassPrepAdjustmentTest + ⨯ model metadata is converted + ✓ model class loads + + FAIL Tests\Unit\Models\ClassPreparationLogTest + ⨯ model metadata is converted + ✓ model class loads + + PASS Tests\Unit\Models\ClassProgressAttachmentTest + ✓ model metadata is converted + ✓ model class loads + + PASS Tests\Unit\Models\ClassProgressReportTest + ✓ model metadata is converted + ✓ model class loads + + PASS Tests\Unit\Models\ClassSectionTest + ✓ model metadata is converted + ✓ model class loads + + PASS Tests\Unit\Models\ClassTest + ✓ model metadata is converted + ✓ model class loads + + FAIL Tests\Unit\Models\CommunicationLogTest + ⨯ model metadata is converted + ✓ model class loads + + PASS Tests\Unit\Models\CompetitionClassWinnerTest + ✓ model metadata is converted + ✓ model class loads + + PASS Tests\Unit\Models\CompetitionScoreTest + ✓ model metadata is converted + ✓ model class loads + + PASS Tests\Unit\Models\CompetitionTest + ✓ model metadata is converted + ✓ model class loads + + PASS Tests\Unit\Models\CompetitionWinnerTest + ✓ model metadata is converted + ✓ model class loads + + PASS Tests\Unit\Models\ConfigurationTest + ✓ model metadata is converted + ✓ model class loads + + PASS Tests\Unit\Models\ContactUsTest + ✓ model metadata is converted + ✓ model class loads + + PASS Tests\Unit\Models\CurrentFlagTest + ✓ model metadata is converted + ✓ model class loads + + PASS Tests\Unit\Models\DiscountUsageTest + ✓ model metadata is converted + ✓ model class loads + + PASS Tests\Unit\Models\DiscountVoucherTest + ✓ model metadata is converted + ✓ model class loads + + PASS Tests\Unit\Models\EarlyDismissalSignatureTest + ✓ model metadata is converted + ✓ model class loads + + FAIL Tests\Unit\EmailTemplateTest + ⨯ get template returns exact variant when active 0.02s + ⨯ get template falls back to default variant 0.01s + ⨯ get template ignores inactive templates and can return null 0.01s + ⨯ get template prefers exact variant over default 0.01s + + PASS Tests\Unit\Models\EmergencyContactTest + ✓ model metadata is converted + ✓ model class loads + + PASS Tests\Unit\Models\EnrollmentTest + ✓ model metadata is converted + ✓ model class loads + + FAIL Tests\Unit\Models\EventChargesTest + ⨯ model metadata is converted + ✓ model class loads + + PASS Tests\Unit\Models\EventTest + ✓ model metadata is converted + ✓ model class loads + + PASS Tests\Unit\Models\ExamDraftTest + ✓ model metadata is converted + ✓ model class loads + + FAIL Tests\Unit\Models\ExamTest + ⨯ model metadata is converted + ✓ model class loads + + PASS Tests\Unit\Models\ExpenseTest + ✓ model metadata is converted + ✓ model class loads + + PASS Tests\Unit\Models\FamilyCommPrefTest + ✓ model metadata is converted + ✓ model class loads + + PASS Tests\Unit\Models\FamilyGuardianTest + ✓ model metadata is converted + ✓ model class loads + + PASS Tests\Unit\Models\FamilyStudentTest + ✓ model metadata is converted + ✓ model class loads + + PASS Tests\Unit\Models\FamilyTest + ✓ model metadata is converted + ✓ model class loads + + FAIL Tests\Unit\Models\FinalExamTest + ⨯ model metadata is converted + ✓ model class loads + + PASS Tests\Unit\Models\FinalScoreTest + ✓ model metadata is converted + ✓ model class loads + + PASS Tests\Unit\Models\GradingLockTest + ✓ model metadata is converted + ✓ model class loads + + FAIL Tests\Unit\Models\HomeworkTest + ⨯ model metadata is converted + ✓ model class loads + + PASS Tests\Unit\Models\IncidentTest + ✓ model metadata is converted + ✓ model class loads + + PASS Tests\Unit\Models\InventoryCategoryTest + ✓ model metadata is converted + ✓ model class loads + + PASS Tests\Unit\Models\InventoryItemTest + ✓ model metadata is converted + ✓ model class loads + + PASS Tests\Unit\Models\InventoryMovementTest + ✓ model metadata is converted + ✓ model class loads + + PASS Tests\Unit\Models\InvoiceEventTest + ✓ model metadata is converted + ✓ model class loads + + PASS Tests\Unit\Models\InvoiceStudentListTest + ✓ model metadata is converted + ✓ model class loads + + FAIL Tests\Unit\Models\InvoiceTest + ⨯ model metadata is converted + ✓ model class loads + + PASS Tests\Unit\Models\IpAttemptTest + ✓ model metadata is converted + ✓ model class loads + + PASS Tests\Unit\Models\LateSlipLogTest + ✓ model metadata is converted + ✓ model class loads + + PASS Tests\Unit\Models\LoginActivityTest + ✓ model metadata is converted + ✓ model class loads + + PASS Tests\Unit\Models\ManualPaymentTest + ✓ model metadata is converted + ✓ model class loads + + PASS Tests\Unit\Models\MessageTest + ✓ model metadata is converted + ✓ model class loads + + FAIL Tests\Unit\Models\MidtermExamTest + ⨯ model metadata is converted + ✓ model class loads + + PASS Tests\Unit\Models\MissingScoreOverrideTest + ✓ model metadata is converted + ✓ model class loads + + PASS Tests\Unit\Models\NavItemTest + ✓ model metadata is converted + ✓ model class loads + + PASS Tests\Unit\Models\NotificationTest + ✓ model metadata is converted + ✓ model class loads + + PASS Tests\Unit\Models\ParentAttendanceReportTest + ✓ model metadata is converted + ✓ model class loads + + PASS Tests\Unit\Models\ParentMeetingScheduleTest + ✓ model metadata is converted + ✓ model class loads + + PASS Tests\Unit\Models\ParentNotificationTest + ✓ model metadata is converted + ✓ model class loads + + PASS Tests\Unit\Models\ParentTest + ✓ model metadata is converted + ✓ model class loads + + FAIL Tests\Unit\Models\ParticipationTest + ⨯ model metadata is converted + ✓ model class loads + + FAIL Tests\Unit\Models\PasswordResetRequestTest + ⨯ model metadata is converted + ✓ model class loads + + FAIL Tests\Unit\Models\PasswordResetTest + ⨯ model metadata is converted + ✓ model class loads + + FAIL Tests\Unit\Models\PayPalPaymentTest + ⨯ model metadata is converted + ✓ model class loads + + PASS Tests\Unit\Models\PaymentErrorTest + ✓ model metadata is converted + ✓ model class loads + + PASS Tests\Unit\Models\PaymentNotificationLogTest + ✓ model metadata is converted + ✓ model class loads + + FAIL Tests\Unit\Models\PaymentTest + ⨯ model metadata is converted + ✓ model class loads + + PASS Tests\Unit\Models\PaymentTransactionTest + ✓ model metadata is converted + ✓ model class loads + + PASS Tests\Unit\Models\PaypalTransactionTest + ✓ model metadata is converted + ✓ model class loads + + PASS Tests\Unit\Models\PermissionTest + ✓ model metadata is converted + ✓ model class loads + + PASS Tests\Unit\Models\PlacementBatchTest + ✓ model metadata is converted + ✓ model class loads + + PASS Tests\Unit\Models\PlacementLevelTest + ✓ model metadata is converted + ✓ model class loads + + PASS Tests\Unit\Models\PlacementScoreTest + ✓ model metadata is converted + ✓ model class loads + + PASS Tests\Unit\Models\PreferencesTest + ✓ model metadata is converted + ✓ model class loads + + PASS Tests\Unit\Models\PrintRequestTest + ✓ model metadata is converted + ✓ model class loads + + PASS Tests\Unit\Models\ProjectTest + ✓ model metadata is converted + ✓ model class loads + + PASS Tests\Unit\Models\PromotionQueueTest + ✓ model metadata is converted + ✓ model class loads + + FAIL Tests\Unit\Models\PurchaseOrderItemTest + ⨯ model metadata is converted + ✓ model class loads + + PASS Tests\Unit\Models\PurchaseOrderTest + ✓ model metadata is converted + ✓ model class loads + + FAIL Tests\Unit\Models\QuizTest + ⨯ model metadata is converted + ✓ model class loads + + PASS Tests\Unit\Models\RefundTest + ✓ model metadata is converted + ✓ model class loads + + PASS Tests\Unit\Models\ReimbursementBatchAdminFileTest + ✓ model metadata is converted + ✓ model class loads + + PASS Tests\Unit\Models\ReimbursementBatchItemTest + ✓ model metadata is converted + ✓ model class loads + + PASS Tests\Unit\Models\ReimbursementBatchTest + ✓ model metadata is converted + ✓ model class loads + + PASS Tests\Unit\Models\ReimbursementTest + ✓ model metadata is converted + ✓ model class loads + + PASS Tests\Unit\Models\RoleNavItemTest + ✓ model metadata is converted + ✓ model class loads + + PASS Tests\Unit\Models\RolePermissionTest + ✓ model metadata is converted + ✓ model class loads + + PASS Tests\Unit\Models\RoleTest + ✓ model metadata is converted + ✓ model class loads + + FAIL Tests\Unit\Models\ScoreCommentTest + ⨯ model metadata is converted + ✓ model class loads + + FAIL Tests\Unit\Models\SectionTest + ⨯ model metadata is converted + ✓ model class loads + + PASS Tests\Unit\Models\SemesterScoreTest + ✓ model metadata is converted + ✓ model class loads + + PASS Tests\Unit\Models\SettingsTest + ✓ model metadata is converted + ✓ model class loads + + PASS Tests\Unit\Models\StaffAttendanceTest + ✓ model metadata is converted + ✓ model class loads + + FAIL Tests\Unit\Models\StaffTest + ⨯ model metadata is converted + ✓ model class loads + + PASS Tests\Unit\Models\StatsTest + ✓ model metadata is converted + ✓ model class loads + + PASS Tests\Unit\Models\StudentAllergyTest + ✓ model metadata is converted + ✓ model class loads + + PASS Tests\Unit\Models\StudentClassTest + ✓ model metadata is converted + ✓ model class loads + + PASS Tests\Unit\Models\StudentMedicalConditionTest + ✓ model metadata is converted + ✓ model class loads + + PASS Tests\Unit\Models\StudentTest + ✓ model metadata is converted + ✓ model class loads + + PASS Tests\Unit\Models\SubjectCurriculumTest + ✓ model metadata is converted + ✓ model class loads + + PASS Tests\Unit\Models\TeacherClassTest + ✓ model metadata is converted + ✓ model class loads + + PASS Tests\Unit\Models\TeacherSubmissionNotificationHistoryTest + ✓ model metadata is converted + ✓ model class loads + + FAIL Tests\Unit\Models\TeacherTest + ⨯ model metadata is converted + ✓ model class loads + + PASS Tests\Unit\Models\UserNotificationTest + ✓ model metadata is converted + ✓ model class loads + + PASS Tests\Unit\Models\UserRoleTest + ✓ model metadata is converted + ✓ model class loads + + FAIL Tests\Unit\Models\UserTest + ⨯ model metadata is converted + ✓ model class loads + ✓ password mutator preserves pbkdf2 hashes 0.62s + + PASS Tests\Unit\Models\WhatsappGroupLinkTest + ✓ model metadata is converted + ✓ model class loads + + PASS Tests\Unit\Models\WhatsappGroupMembershipTest + ✓ model metadata is converted + ✓ model class loads + + PASS Tests\Unit\Models\WhatsappInviteLogTest + ✓ model metadata is converted + ✓ model class loads + + PASS Tests\Unit\Http\Requests\AttendanceCommentTemplate\StoreAttendanceCommentTemplateRequestTest + ✓ rules pass with valid data 0.01s + ✓ rules fail when required fields missing 0.01s + ✓ rules fail when max score less than min score 0.01s + ✓ rules fail when score out of range 0.01s + + PASS Tests\Unit\Http\Requests\AttendanceCommentTemplate\UpdateAttendanceCommentTemplateRequestTest + ✓ rules pass with partial valid data 0.01s + ✓ rules pass when both scores valid 0.01s + ✓ rules fail when both scores invalid relation 0.01s + ✓ rules fail on invalid boolean 0.01s + + PASS Tests\Unit\Resources\ClassProgress\ClassProgressReportResourceTest + ✓ resource has expected keys 0.03s + + PASS Tests\Unit\Resources\Frontend\FrontendPageResourceTest + ✓ resource returns page 0.01s + + PASS Tests\Unit\Resources\Frontend\PageContentResourceTest + ✓ resource returns content 0.01s + + FAIL Tests\Unit\Resources\Messaging\MessageResourceTest + ⨯ resource returns expected shape 0.02s + + PASS Tests\Unit\Resources\Messaging\RecipientResourceTest + ✓ resource returns expected shape 0.02s + + PASS Tests\Unit\Resources\Notifications\NotificationResourceTest + ✓ resource returns expected shape 0.01s + + PASS Tests\Unit\Resources\Notifications\UserNotificationResourceTest + ✓ resource returns expected shape 0.01s + + PASS Tests\Unit\Resources\Roles\PermissionResourceTest + ✓ resource shape 0.01s + + PASS Tests\Unit\Resources\Roles\RolePermissionResourceTest + ✓ resource shape 0.01s + + PASS Tests\Unit\Resources\Roles\RoleResourceTest + ✓ resource shape 0.01s + + PASS Tests\Unit\Resources\Roles\UserWithRolesResourceTest + ✓ resource shape 0.02s + + PASS Tests\Unit\Resources\Settings\SchoolCalendarEventResourceTest + ✓ resource returns expected shape 0.02s + + PASS Tests\Unit\Resources\Settings\SettingsResourceTest + ✓ resource returns expected shape 0.01s + + FAIL Tests\Unit\Resources\Staff\StaffResourceTest + ⨯ resource returns expected shape 0.02s + + PASS Tests\Unit\Resources\Support\ContactMessageResourceTest + ✓ resource returns expected shape 0.01s + + FAIL Tests\Unit\Resources\Support\SupportRequestResourceTest + ⨯ resource returns expected shape 0.01s + + PASS Tests\Unit\Resources\Ui\UiStyleResourceTest + ✓ resource returns expected shape 0.02s + + PASS Tests\Unit\Services\Administrator\AdminNotificationSubjectServiceTest + ✓ alerts data includes admins 0.02s + + PASS Tests\Unit\Services\Administrator\AdminNotificationUserServiceTest + ✓ fetch admin notification users excludes parents 0.02s + + PASS Tests\Unit\Services\Administrator\AdminPrintRecipientServiceTest + ✓ data returns admins and assigned 0.02s + + FAIL Tests\Unit\Services\Administrator\AdministratorAbsenceServiceTest + ⨯ submit requires reason 0.02s + + PASS Tests\Unit\Services\Administrator\AdministratorDashboardServiceTest + ✓ delegates to metrics and search 0.01s + + FAIL Tests\Unit\Services\Administrator\AdministratorEnrollmentEventServiceTest + ⨯ dispatch grouped events with empty groups 0.02s + + PASS Tests\Unit\Services\Administrator\AdministratorEnrollmentQueryServiceTest + ✓ enrollment withdrawal data returns structure 0.01s + + PASS Tests\Unit\Services\Administrator\AdministratorEnrollmentRefundServiceTest + ✓ process refunds reports missing invoice 0.01s + + PASS Tests\Unit\Services\Administrator\AdministratorEnrollmentServiceTest + ✓ delegates to query and status services 0.02s + + PASS Tests\Unit\Services\Administrator\AdministratorEnrollmentStatusServiceTest + ✓ update statuses requires payload 0.01s + + PASS Tests\Unit\Services\Administrator\AdministratorMetricsServiceTest + ✓ metrics returns counts 0.01s + + PASS Tests\Unit\Services\Administrator\AdministratorNotificationServiceTest + ✓ delegates to subject and print services 0.02s + + PASS Tests\Unit\Services\Administrator\AdministratorSharedServiceTest + ✓ get previous school year 0.01s + + PASS Tests\Unit\Services\Administrator\AdministratorTeacherSubmissionServiceTest + ✓ delegates to report and notification 0.01s + + PASS Tests\Unit\Services\Administrator\AdministratorUserSearchServiceTest + ✓ empty query returns no results 0.02s + + FAIL Tests\Unit\Services\Administrator\TeacherSubmissionNotificationServiceTest + ⨯ send requires targets 0.01s + + FAIL Tests\Unit\Services\Administrator\TeacherSubmissionReportServiceTest + ⨯ report returns summary 0.01s + + PASS Tests\Unit\Services\Administrator\TeacherSubmissionSupportServiceTest + ✓ submission status labels 0.02s + ✓ build missing items 0.01s + + PASS Tests\Unit\Services\Assignment\AssignmentContextServiceTest + ✓ get current term values 0.01s + + PASS Tests\Unit\Services\Assignment\AssignmentDataLoaderServiceTest + ✓ load teacher classes includes teacher name 0.02s + ✓ load student classes filters inactive 0.01s + + PASS Tests\Unit\Services\Assignment\AssignmentMetaServiceTest + ✓ get school years uses fallback 0.01s + ✓ get school years returns distinct sorted 0.01s + ✓ first non empty returns first value 0.01s + + FAIL Tests\Unit\Services\Assignment\AssignmentSectionServiceTest + ⨯ get section names map 0.01s + + FAIL Tests\Unit\Services\AssignmentServiceTest + ✓ get current semester returns config value 0.02s + ✓ get current school year returns config value 0.02s + ⨯ get assignments overview returns grouped sections 0.02s + ✓ get assignments overview uses fallback config values when metadata… 0.01s + ✓ get assignments overview excludes inactive students 0.02s + ⨯ get assignments overview sorts sections by name 0.01s + ✓ get assignments overview collects school years descending 0.01s + ✓ store assignment creates new row 0.02s + ✓ store assignment updates existing row 0.01s + ⨯ get class assignment data returns all sections 0.02s + ✓ get class assignment data deduplicates teacher names 0.01s + + PASS Tests\Feature\Api\Attendance\AdminAttendanceApiControllerTest + ✓ daily data returns success 0.05s + + PASS Tests\Unit\Services\Attendance\AttendanceAutoPublishJobServiceTest + ✓ run publishes due records 0.01s + + PASS Tests\Unit\Services\Attendance\AttendanceAutoPublishServiceTest + ✓ second sunday after end of day 0.02s + ✓ second sunday backward date 0.01s + + PASS Tests\Unit\Services\Attendance\AttendanceCommentServiceTest + ✓ comment from score uses template and name 0.01s + ✓ comment from score falls back to this student 0.02s + + PASS Tests\Unit\Services\Attendance\AttendanceConsequenceServiceTest + ✓ send follow up requires parent email 0.03s + ✓ send follow up marks tracking and notifies 0.01s + + FAIL Tests\Unit\Services\Attendance\AttendanceDailySummaryServiceTest + ⨯ send absentees summary notifies parent 0.02s + + PASS Tests\Unit\Services\Attendance\AttendancePolicyServiceTest + ✓ teacher can edit draft 0.01s + ✓ teacher cannot edit finalized 0.01s + ✓ admin like by permission 0.01s + ✓ can manage early dismissals for teacher 0.01s + + PASS Tests\Unit\Services\Attendance\AttendanceQueryServiceTest + ✓ teacher grid returns section labels and grid 0.02s + + PASS Tests\Unit\Services\Attendance\AttendanceRecordSyncServiceTest + ✓ update attendance record adjusts totals 0.02s + ✓ add new attendance record creates row 0.01s + + FAIL Tests\Unit\Services\Attendance\AttendanceSemesterRangeServiceTest + ⨯ get semester range 0.01s + ✓ build sunday list returns sundays 0.02s + + PASS Tests\Unit\Services\Attendance\AttendanceServiceTest + ✓ update attendance management throws when locked 0.02s + ✓ update attendance management saves row 0.02s + + PASS Tests\Unit\Services\Attendance\AttendanceSummaryRebuildServiceTest + ✓ rebuild inserts summary rows 0.02s + + FAIL Tests\Unit\Services\Attendance\LateSlipLogCommandServiceTest + ⨯ delete removes log 0.01s + + FAIL Tests\Unit\Services\Attendance\LateSlipLogQueryServiceTest + ⨯ paginate filters by date 0.01s + + FAIL Tests\Unit\Services\Attendance\SemesterRangeServiceTest + ✓ normalize semester + ⨯ get school year range + ✓ build sunday list + + PASS Tests\Feature\Api\Attendance\StaffAttendanceApiControllerTest + ✓ month data returns success 0.02s + ✓ admins data returns success 0.02s + + PASS Tests\Unit\Services\Attendance\StaffAttendanceServiceTest + ✓ month data returns sections and days 0.02s + + PASS Tests\Unit\Services\Attendance\StudentAttendanceWriterServiceTest + ✓ resolve student school id from student 0.02s + ✓ save or update updates existing and syncs record 0.01s + + PASS Tests\Feature\Api\Attendance\TeacherAttendanceApiControllerTest + ✓ teacher grid endpoint returns success 0.02s + ✓ teacher form endpoint returns success or validation message 0.02s + + PASS Tests\Unit\Services\Attendance\TeacherAttendanceSubmissionServiceTest + ✓ submit requires attendance data 0.02s + + PASS Tests\Unit\Services\AttendanceManagement\AttendanceManagementServiceTest + ✓ badge scan persists school year and semester for the event date 0.02s + ✓ dashboard derives academic context for legacy rows and applies filt… 0.02s + + PASS Tests\Unit\Services\AttendanceTracking\AttendanceCaseQueryServiceTest + ✓ returns not found when student missing 0.02s + + PASS Tests\Unit\Services\AttendanceTracking\AttendanceCommunicationSupportServiceTest + ✓ compose requires student id 0.02s + ✓ get violation dates for student 0.02s + + PASS Tests\Unit\Services\AttendanceTracking\AttendanceEmailComposerServiceTest + ✓ render template replaces tokens 0.01s + ✓ pick variant fallback 0.01s + + PASS Tests\Unit\Services\AttendanceTracking\AttendanceNotificationLogServiceTest + ✓ log notification creates and updates 0.02s + + PASS Tests\Unit\Services\AttendanceTracking\AttendanceNotificationWorkflowServiceTest + ✓ record requires parent email 0.02s + + PASS Tests\Unit\Services\AttendanceTracking\AttendanceParentLookupServiceTest + ✓ get primary parent for student 0.01s + ✓ get secondary parent falls back to parent row 0.02s + + PASS Tests\Unit\Services\AttendanceTracking\AttendancePendingViolationServiceTest + ✓ returns error when no students 0.01s + + FAIL Tests\Unit\Services\AttendanceTracking\AttendanceTrackingServiceTest + ⨯ service instantiates 0.01s + + PASS Tests\Unit\Services\AttendanceTracking\AttendanceViolationStudentResolverServiceTest + ✓ resolve for school year returns students 0.02s + + PASS Tests\Unit\Services\AttendanceTracking\ViolationRuleEngineServiceTest + ✓ school year helpers 0.01s + ✓ window weeks for violation code 0.01s + + PASS Tests\Unit\Services\Auth\PasswordResetCleanupServiceTest + ✓ cleanup removes old requests 0.02s + + PASS Tests\Unit\Services\Auth\PermissionCheckServiceTest + ✓ has permission returns true when assigned 0.01s + + PASS Tests\Unit\Services\Auth\RegistrationCaptchaServiceTest + ✓ generate sets cache value 0.01s + ✓ verify and clear 0.02s + + PASS Tests\Unit\Services\Auth\RegistrationFormatterServiceTest + ✓ format normalizes parent fields 0.01s + ✓ format includes second parent when present 0.01s + + FAIL Tests\Unit\Services\Auth\RegistrationServiceTest + ⨯ register creates parent user 0.02s + ⨯ register rejects pending activation 0.32s + + PASS Tests\Unit\Services\Auth\UserRoleServiceTest + ✓ has permission for crud checks roles 0.01s + + PASS Tests\Unit\Services\Badges\BadgeFormDataServiceTest + ✓ build formats users and assigns latest class for teacherish roles 0.02s + ✓ build defaults invalid active role to teacher 0.01s + + PASS Tests\Unit\Services\Badges\BadgePdfServiceTest + ✓ generate returns pdf response and logs prints 0.10s + ✓ generate returns empty state pdf when no valid users found 0.09s + ✓ generate deduplicates same badge content 0.08s + + PASS Tests\Unit\Services\Badges\BadgePrintLogServiceTest + ✓ get status normalizes ids before calling model 0.02s + ✓ log normalizes ids and returns inserted count 0.01s + ✓ log safely swallows exceptions and logs error 0.01s + + PASS Tests\Unit\Services\Badges\BadgeTextFormatterTest + ✓ normalize ids filters and deduplicates 0.02s + ✓ norm removes extra spaces and control chars 0.01s + ✓ format role handles special words and acronyms 0.01s + ✓ format roles csv formats each role 0.01s + ✓ format class normalizes known values 0.01s + ✓ resolve role prefers first available candidate 0.01s + ✓ to pdf returns string 0.01s + ✓ fit text returns size within bounds 0.01s + + FAIL Tests\Unit\Services\Billing\BalanceCalculationServiceTest + ⨯ calculate family account applies balance formula 0.02s + ✓ overpayment records account credit 0.01s + ✓ student rows include event charges 0.01s + + FAIL Tests\Unit\Services\Billing\BillingTotalsServiceTest + ⨯ event and additional subtotals 0.02s + ⨯ additional subtotal by parent sums applied charges 0.02s + ✓ event subtotals by student groups amounts 0.01s + + FAIL Tests\Unit\Services\Billing\ChargeServiceTest + ✓ create extra charge blocks duplicate 0.02s + ✓ create event charge blocks duplicate 0.01s + ✓ create event charge succeeds 0.01s + ⨯ cancel event charge zeros charge and creates credit 0.01s + ✓ apply extra charge marks applied 0.02s + ✓ list for parent returns both charge types 0.01s + + PASS Tests\Unit\Services\BroadcastEmail\BroadcastEmailComposerServiceTest + ✓ sanitize removes script and events 0.01s + ✓ compose replaces name when personalized 0.01s + + PASS Tests\Unit\Services\BroadcastEmail\BroadcastEmailRecipientServiceTest + ✓ parents with emails filters missing email 0.02s + ✓ recipients by ids returns names 0.02s + + PASS Tests\Unit\Services\BroadcastEmail\BroadcastEmailSenderOptionsServiceTest + ✓ list options from env 0.02s + + PASS Tests\Unit\Services\CertificateAdminServiceTest + ✓ dashboard groups students and uses saved decisions as source of tru… 0.02s + ✓ issue certificates reuses existing record and creates new one for u… 0.02s + ✓ audit log returns year summary and filtered records 0.02s + + PASS Tests\Unit\Services\ClassPrep\ClassRosterServiceTest + ✓ list students by class 0.01s + + PASS Tests\Unit\Services\ClassPrep\StickerCountServiceTest + ✓ list all returns totals excluding youth 0.01s + ✓ list for class limits results 0.02s + + PASS Tests\Unit\Services\ClassPreparation\ClassPreparationAdjustmentServiceTest + ✓ apply adjustments updates counts 0.01s + + FAIL Tests\Unit\Services\ClassPreparation\ClassPreparationAdjustmentWriterServiceTest + ⨯ save adjustments persists allowed items 0.02s + + PASS Tests\Unit\Services\ClassPreparation\ClassPreparationCalculatorServiceTest + ✓ get class level by section 0.02s + ✓ calculate prep items for lower grades 0.01s + + PASS Tests\Unit\Services\ClassPreparation\ClassPreparationContextServiceTest + ✓ has roster for semester 0.01s + + PASS Tests\Unit\Services\ClassPreparation\ClassPreparationInventoryServiceTest + ✓ build availability uses max value 0.02s + + FAIL Tests\Unit\Services\ClassPreparation\ClassPreparationLogServiceTest + ✓ has prep changed detects diff 0.01s + ⨯ create log and get latest 0.01s + + FAIL Tests\Unit\Services\ClassPreparation\ClassPreparationPrintServiceTest + ⨯ print prep creates log 0.02s + ✓ print prep handles log failure 0.02s + + PASS Tests\Unit\Services\ClassPreparation\ClassPreparationRosterServiceTest + ✓ get class section student counts 0.01s + ✓ get student count for section 0.02s + + FAIL Tests\Unit\Services\ClassPreparation\ClassPreparationServiceTest + ✓ list prep returns sections and totals 0.01s + ⨯ mark printed creates logs 0.01s + + PASS Tests\Unit\Services\ClassProgress\ClassProgressAttachmentServiceTest + ✓ store attachments persists records 0.03s + + PASS Tests\Unit\Services\ClassProgress\ClassProgressMetaServiceTest + ✓ subject sections return configured values 0.01s + + FAIL Tests\Unit\Services\ClassProgress\ClassProgressMutationServiceTest + ⨯ create reports persists multiple subjects 0.02s + ⨯ update report changes status 0.02s + ⨯ delete report removes record 0.01s + + PASS Tests\Unit\Services\ClassProgress\ClassProgressQueryServiceTest + ✓ list reports filters by class section 0.02s + + PASS Tests\Unit\Services\ClassProgress\ClassProgressRuleServiceTest + ✓ build unit chapter summary limits length + ✓ ensure week end defaults to six days + + PASS Tests\Unit\Services\ClassSections\ClassAttendanceServiceTest + ✓ get attendance payload includes students 0.02s + + PASS Tests\Unit\Services\ClassSections\ClassSectionCommandServiceTest + ✓ create update delete 0.01s + + PASS Tests\Unit\Services\ClassSections\ClassSectionQueryServiceTest + ✓ list filters by search 0.01s + + PASS Tests\Unit\Services\ClassSections\ClassSectionSeedServiceTest + ✓ seed defaults creates rows 0.02s + + PASS Tests\Unit\Services\Communication\CommunicationTemplateServiceTest + ✓ list active templates maps columns 0.01s + + PASS Tests\Unit\Services\CompetitionScores\CompetitionScoresSaveServiceTest + ✓ filter scores rejects non integers 0.01s + ✓ save scores upserts 0.02s + + PASS Tests\Unit\Services\Dashboard\DashboardRouteServiceTest + ✓ resolve returns fallback when no roles 0.02s + ✓ resolve returns dashboard route for role 0.01s + + FAIL Tests\Unit\Services\Discounts\DiscountApplyServiceTest + ⨯ apply voucher returns error when no remaining uses 0.02s + + PASS Tests\Unit\Services\Email\EmailExtractorServiceTest + ✓ list and compare emails 0.01s + + PASS Tests\Unit\Services\Email\EmailProfileServiceTest + ✓ resolve profile maps aliases 0.01s + ✓ env key from profile 0.01s + ✓ sanitize reply to name 0.01s + + PASS Tests\Unit\Services\EmergencyContacts\EmergencyContactDirectoryServiceTest + ✓ groups include parent students contacts and phones 0.02s + + PASS Tests\Unit\Services\Events\EventCategoryServiceTest + ✓ categories returns list 0.02s + + PASS Tests\Unit\Services\Events\EventChargeQueryServiceTest + ✓ list returns paginated charges 0.01s + + PASS Tests\Unit\Services\Events\EventChargeServiceTest + ✓ seed charges creates event charges 0.01s + + PASS Tests\Unit\Services\Events\EventListServiceTest + ✓ list filters active events 0.02s + + PASS Tests\Unit\Services\Events\EventManagementServiceTest + ✓ update returns not found 0.01s + + FAIL Tests\Unit\Services\Events\EventStudentChargeServiceTest + ⨯ list students with charges 0.01s + + PASS Tests\Unit\Services\Exams\ExamDraftTeacherServiceTest + ✓ store creates draft 0.02s + + FAIL Tests\Unit\Services\Expenses\ExpenseReceiptServiceTest + ⨯ store receipt returns filename and url 0.01s + + PASS Tests\Unit\Services\Expenses\ExpenseStaffServiceTest + ✓ list staff users excludes parents 0.02s + + PASS Tests\Unit\Services\ExtraCharges\ExtraChargesMetaServiceTest + ✓ get school years uses fallback 0.01s + ✓ get school years merges sources 0.01s + + PASS Tests\Unit\Services\Families\FamilyFinanceServiceTest + ✓ load financials for parents returns summary 0.01s + + PASS Tests\Unit\Services\Families\FamilyMutationServiceTest + ✓ bootstrap creates family 0.02s + ✓ attach second by email creates guardian 0.02s + ✓ set primary home updates flag 0.01s + + PASS Tests\Unit\Services\Families\FamilyNotificationServiceTest + ✓ send compose email delegates to dispatcher 0.02s + + PASS Tests\Unit\Services\Families\FamilyQueryServiceTest + ✓ admin index returns families 0.01s + ✓ search suggestions returns items 0.01s + ✓ family card returns payload 0.02s + + PASS Tests\Unit\Services\FeeCalculationServiceTest + ✓ calculate refund returns calculator amount 0.01s + + PASS Tests\Unit\Services\Fees\FeeGradeServiceTest + ✓ grade level parsing 0.01s + ✓ compare grades orders numeric then suffix 0.02s + + PASS Tests\Unit\Services\Fees\FeeRefundCalculatorServiceTest + ✓ calculate refund caps at total paid 0.01s + ✓ returns zero when parent has no payments 0.01s + ✓ returns zero when no withdrawn students 0.02s + ✓ withdrawn student breakdown carries assigned tuition fee 0.01s + ✓ multi student family only refunds withdrawn students 0.01s + ✓ withdrawal after deadline is not eligible 0.01s + ✓ missing withdrawal date is skipped with reason 0.02s + + FAIL Tests\Unit\Services\Fees\FeeRefundDetailServiceTest + ⨯ calculate refund details returns amount 0.01s + + PASS Tests\Unit\Services\Fees\FeeStudentFeeServiceTest + ✓ total tuition fee applies tiers and youth fee 0.01s + ✓ assign fees stores tuition fee and fee category on each student 0.02s + ✓ calculate breakdown includes billable and non billable students 0.01s + ✓ is billable and is withdrawn classifiers 0.01s + + PASS Tests\Unit\Services\Fees\TuitionCalculationServiceTest + ✓ calculate returns family total and per student breakdown 0.02s + ✓ calculate excludes non billable students from family total 0.01s + ✓ calculate applies per student discount 0.01s + ✓ family total helper 0.01s + + PASS Tests\Unit\Services\Files\ExamDraftDownloadNameServiceTest + ✓ build returns slugified name 0.02s + + PASS Tests\Unit\Services\Files\FileServeServiceTest + ✓ meta returns file metadata 0.01s + ✓ serve inline returns 304 when etag matches 0.01s + ✓ serve inline rejects invalid extension 0.02s + + PASS Tests\Unit\Services\Finance\FinancialChartServiceTest + ✓ generate charts returns null in tests 0.01s + + PASS Tests\Unit\Services\Finance\FinancialPaymentServiceTest + ✓ payment aggregates exclude void statuses 0.02s + + PASS Tests\Unit\Services\Finance\FinancialPdfReportServiceTest + ✓ build pdf returns bytes 0.02s + + PASS Tests\Unit\Services\Finance\FinancialReportServiceTest + ✓ report returns grouped data 0.02s + + PASS Tests\Unit\Services\Finance\FinancialSchoolYearServiceTest + ✓ list years returns distinct sorted years 0.01s + + PASS Tests\Unit\Services\Finance\FinancialSummaryServiceTest + ✓ summary calculates totals 0.02s + + PASS Tests\Unit\Services\Finance\FinancialUnpaidParentsServiceTest + ✓ unpaid parents returns installment data 0.02s + + PASS Tests\Unit\Services\Frontend\ContactSubmissionServiceTest + ✓ submit creates contact record 0.02s + + PASS Tests\Unit\Services\Frontend\FrontendPageServiceTest + ✓ page returns payload 0.02s + + PASS Tests\Unit\Services\Frontend\LandingPageContextServiceTest + ✓ context returns config values 0.01s + + PASS Tests\Unit\Services\Frontend\LandingPageParentDashboardServiceTest + ✓ summary returns parent payload 0.01s + + PASS Tests\Unit\Services\Frontend\LandingPageRoleServiceTest + ✓ resolve role returns guest when missing 0.02s + ✓ resolve role returns first role 0.01s + + PASS Tests\Unit\Services\Frontend\LandingPageServiceTest + ✓ dashboard for user returns guest 0.01s + ✓ dashboard for user returns admin 0.02s + + PASS Tests\Unit\Services\Frontend\LandingPageTeacherSummaryServiceTest + ✓ summary returns dashboard payload 0.02s + + PASS Tests\Unit\Services\Frontend\ProfileIconServiceTest + ✓ build for user returns initials 0.02s + + PASS Tests\Unit\Services\Frontend\StaticPageServiceTest + ✓ load returns content 0.02s + ✓ load missing returns error 0.01s + + PASS Tests\Unit\Services\Grading\BelowSixtyEmailServiceTest + ✓ send requires student id 0.01s + ✓ send delivers to guardians 0.02s + + PASS Tests\Unit\Services\Grading\GradingBelowSixtyServiceTest + ✓ list rows returns students below sixty 0.02s + + PASS Tests\Unit\Services\Grading\GradingLockServiceTest + ✓ toggle creates lock 0.01s + ✓ lock all locks sections 0.02s + + PASS Tests\Unit\Services\Grading\HomeworkTrackingServiceTest + ✓ report returns teacher rows 0.02s + + PASS Tests\Unit\Services\Incidents\IncidentAnalysisServiceTest + ✓ analyze groups incidents by student 0.01s + + PASS Tests\Unit\Services\Incidents\IncidentHistoryServiceTest + ✓ processed enriches grade and updater names 0.02s + + PASS Tests\Unit\Services\Incidents\IncidentLookupServiceTest + ✓ grade options with active students 0.01s + ✓ updater name map 0.01s + + PASS Tests\Unit\Services\Inventory\InventoryCategoryServiceTest + ✓ create category 0.02s + ✓ update category 0.01s + + PASS Tests\Unit\Services\Inventory\InventoryItemServiceTest + ✓ create creates item and movement 0.02s + ✓ update updates item 0.02s + + PASS Tests\Unit\Services\Inventory\InventoryMovementServiceTest + ✓ create movement 0.01s + + PASS Tests\Unit\Services\Inventory\InventorySummaryServiceTest + ✓ summary returns items 0.01s + + PASS Tests\Unit\Services\Inventory\InventoryTeacherDistributionServiceTest + ✓ form data requires teacher role 0.02s + ✓ distribute success 0.02s + + PASS Tests\Unit\Services\Inventory\SupplierServiceTest + ✓ create supplier 0.01s + ✓ update supplier 0.02s + + PASS Tests\Unit\Services\Inventory\SupplyCategoryServiceTest + ✓ create category 0.01s + ✓ update category 0.01s + + PASS Tests\Unit\Services\Invoices\InvoiceConfigServiceTest + ✓ config service reads values 0.02s + + PASS Tests\Unit\Services\Invoices\InvoiceGenerationServiceTest + ✓ generate invoice creates new invoice 0.02s + + PASS Tests\Unit\Services\Invoices\InvoiceGradeServiceTest + ✓ grade parsing handles common cases 0.01s + ✓ compare grades orders numeric then suffix 0.02s + + PASS Tests\Unit\Services\Invoices\InvoiceManagementServiceTest + ✓ management data returns parent invoice summary 0.02s + + PASS Tests\Unit\Services\Invoices\InvoicePaymentServiceTest + ✓ parent invoice summary includes refunds and last payment 0.01s + + PASS Tests\Unit\Services\Invoices\InvoicePdfServiceTest + ✓ build pdf returns bytes 0.02s + + PASS Tests\Unit\Services\Invoices\InvoiceServiceTest + ✓ has class assignment returns true 0.02s + + PASS Tests\Unit\Services\Invoices\InvoiceTuitionServiceTest + ✓ calculate tuition fee counts regular and youth 0.01s + ✓ refund deadline includes withdrawn when passed 0.02s + + PASS Tests\Unit\Services\Messaging\MessageCommandServiceTest + ✓ create sends message 0.02s + ✓ create rejects invalid role 0.01s + + PASS Tests\Unit\Services\Messaging\MessageQueryServiceTest + ✓ inbox filters messages 0.02s + + PASS Tests\Unit\Services\Messaging\MessageRecipientServiceTest + ✓ teachers returns list 0.01s + ✓ parents returns list 0.02s + + FAIL Tests\Unit\Services\Navigation\NavBuilderServiceTest + ✓ save creates nav item and roles 0.02s + ⨯ reorder updates sort order 0.01s + + PASS Tests\Unit\Services\Navigation\NavbarServiceTest + ✓ get menu for roles builds tree 0.01s + + PASS Tests\Unit\Services\Notifications\NotificationActiveServiceTest + ✓ list filters by target group 0.02s + + PASS Tests\Unit\Services\Notifications\NotificationCleanupServiceTest + ✓ cleanup expired soft deletes rows 0.01s + + PASS Tests\Unit\Services\Notifications\NotificationDeletedServiceTest + ✓ list returns deleted notifications 0.01s + + PASS Tests\Unit\Services\Notifications\NotificationDispatchServiceTest + ✓ dispatch logs email and sms 0.02s + + PASS Tests\Unit\Services\Notifications\NotificationManagementServiceTest + ✓ update modifies notification 0.01s + ✓ update returns false when missing 0.01s + ✓ delete and restore notification 0.02s + + PASS Tests\Unit\Services\Notifications\NotificationReadServiceTest + ✓ mark read updates row 0.01s + ✓ mark read returns false when missing 0.01s + + PASS Tests\Unit\Services\Notifications\NotificationRecipientServiceTest + ✓ get recipients by role 0.02s + + FAIL Tests\Unit\Services\Notifications\NotificationSendServiceTest + ⨯ send creates notification and user notifications 0.02s + + PASS Tests\Unit\Services\Notifications\NotificationShowServiceTest + ✓ get for user returns notification 0.01s + ✓ get for user returns null when missing 0.02s + + PASS Tests\Unit\Services\Notifications\NotificationTriggerServiceTest + ✓ trigger dispatches event 0.01s + ✓ to user dispatches event 0.01s + + PASS Tests\Unit\Services\Notifications\NotificationUserListServiceTest + ✓ list filters by read status 0.02s + + PASS Tests\Unit\Services\Notifications\UserNotificationDispatchServiceTest + ✓ notify user creates notification 0.02s + ✓ notify user rejects invalid user 0.01s + + PASS Tests\Unit\Services\Parents\ParentAttendanceReportServiceTest + ✓ form data returns students 0.02s + + PASS Tests\Unit\Services\Parents\ParentAttendanceServiceTest + ✓ list attendance returns rows 0.02s + + PASS Tests\Unit\Services\Parents\ParentConfigServiceTest + ✓ context returns config values 0.01s + + PASS Tests\Unit\Services\Parents\ParentEmergencyContactServiceTest + ✓ store creates contact 0.02s + + PASS Tests\Unit\Services\Parents\ParentEnrollmentServiceTest + ✓ overview returns students 0.02s + + PASS Tests\Unit\Services\Parents\ParentInvoiceServiceTest + ✓ list invoices filters by parent 0.02s + + PASS Tests\Unit\Services\Parents\ParentRegistrationServiceTest + ✓ register creates student and contact 0.02s + + PASS Tests\Unit\Services\Payments\PaymentBalanceServiceTest + ✓ update balance adjusts payment totals 0.01s + + PASS Tests\Unit\Services\Payments\PaymentEnrollmentEventServiceTest + ✓ build event data requires parent 0.02s + ✓ build event data returns parent payload when no students 0.02s + + PASS Tests\Unit\Services\Payments\PaymentEventChargesServiceTest + ✓ get enrolled students returns grade 0.01s + + PASS Tests\Unit\Services\Payments\PaymentLookupServiceTest + ✓ get by parent filters school year 0.01s + + PASS Tests\Unit\Services\Payments\PaymentManualServiceTest + ✓ record payment rejects invalid method 0.02s + ✓ suggest returns matches 0.01s + + PASS Tests\Unit\Services\Payments\PaymentMissedCheckServiceTest + ✓ find users with missed payments 0.01s + ✓ send reminders sends email and notification 0.02s + + PASS Tests\Unit\Services\Payments\PaymentNotificationDispatchServiceTest + ✓ notify user creates notification records 0.01s + + PASS Tests\Unit\Services\Payments\PaymentNotificationServiceTest + ✓ send records log and returns sent count 0.02s + ✓ list logs filters by type 0.02s + + PASS Tests\Unit\Services\Payments\PaymentPlanServiceTest + ✓ create plan uses defaults when missing 0.02s + + PASS Tests\Unit\Services\Payments\PaymentTestNotificationServiceTest + ✓ send logs and sends email 0.02s + + PASS Tests\Unit\Services\Payments\PaymentTransactionServiceTest + ✓ create and update transaction 0.02s + + PASS Tests\Unit\Services\Payments\PaypalPaymentServiceTest + ✓ create payment falls back to hosted when sdk missing 0.01s + ✓ execute payment throws when sdk missing 0.01s + + PASS Tests\Unit\Services\Payments\PaypalPaymentSyncServiceTest + ✓ sync applies payment and marks synced 0.02s + + PASS Tests\Unit\Services\Payments\PaypalTransactionsServiceTest + ✓ list all filters by keyword 0.01s + + PASS Tests\Unit\Services\Phone\PhoneFormatterServiceTest + ✓ format returns null for invalid 0.01s + ✓ format formats digits 0.02s + + PASS Tests\Unit\Services\Policy\PolicyContentServiceTest + ✓ get policy returns content 0.01s + + PASS Tests\Unit\Services\Preferences\PreferencesCommandServiceTest + ✓ upsert creates record 0.01s + + PASS Tests\Unit\Services\Preferences\PreferencesOptionsServiceTest + ✓ defaults include expected keys 0.02s + + PASS Tests\Unit\Services\Preferences\PreferencesQueryServiceTest + ✓ get for user returns defaults when missing 0.01s + ✓ paginate filters by user id 0.01s + + PASS Tests\Unit\Services\Promotions\LevelProgressionServiceTest + ✓ seed defaults creates baseline levels 0.02s + ✓ resolve by class id uses mapping when present 0.02s + ✓ resolve falls back to class id plus one when no mapping 0.01s + ✓ upsert mapping updates existing row 0.01s + + FAIL Tests\Unit\Services\Promotions\PromotionEligibilityServiceTest + ✓ passing student becomes awaiting parent enrollment 0.02s + ✓ failing student becomes repeated 0.02s + ✓ missing scores marks on hold 0.01s + ⨯ terminal level is graduated 0.02s + ✓ audit log records status changes 0.02s + + PASS Tests\Unit\Services\Promotions\PromotionEnrollmentServiceTest + ✓ completing checklist finalises promotion and creates enrollment 0.02s + ✓ partial checklist keeps status in progress 0.02s + ✓ submit requires complete checklist 0.01s + ✓ other parent cannot act on record 0.01s + ✓ expired records become not enrolled 0.01s + + PASS Tests\Unit\Services\Promotions\PromotionStatusServiceTest + ✓ allowed transition updates status and audit log 0.02s + ✓ disallowed transition throws 0.01s + ✓ force status bypasses transition map 0.01s + ✓ no op transition returns record unchanged 0.01s + + PASS Tests\Unit\Services\PurchaseOrders\PurchaseOrderCreateServiceTest + ✓ create persists purchase order and items 0.01s + + FAIL Tests\Unit\Services\PurchaseOrders\PurchaseOrderReceiveServiceTest + ⨯ receive updates items and inventory 0.01s + + PASS Tests\Unit\Services\PurchaseOrders\PurchaseOrderStatusServiceTest + ✓ cancel marks purchase order canceled 0.02s + + PASS Tests\Unit\Services\Refunds\RefundDecisionServiceTest + ✓ approve updates refund status 0.01s + + PASS Tests\Unit\Services\Refunds\RefundInvoiceAdjustmentServiceTest + ✓ apply book charge inserts additional charge 0.01s + + PASS Tests\Unit\Services\Refunds\RefundNotificationServiceTest + ✓ notify pending logs event 0.02s + + FAIL Tests\Unit\Services\Refunds\RefundOverpaymentServiceTest + ⨯ recalculate creates overpayment refund 0.01s + + PASS Tests\Unit\Services\Refunds\RefundPayoutServiceTest + ✓ record payment marks partial 0.01s + + FAIL Tests\Unit\Services\Refunds\RefundPolicyServiceTest + ⨯ process withdrawal refund creates refund 0.02s + + PASS Tests\Unit\Services\Refunds\RefundQueryServiceTest + ✓ list filters by status 0.01s + + FAIL Tests\Unit\Services\Refunds\RefundRequestServiceTest + ⨯ request overpayment creates refund 0.01s + + FAIL Tests\Unit\Services\Refunds\RefundSummaryServiceTest + ⨯ summary calculates unapplied balance 0.02s + + PASS Tests\Unit\Services\Reimbursements\ReimbursementBatchAssignmentServiceTest + ✓ assign and unassign batch item 0.02s + + PASS Tests\Unit\Services\Reimbursements\ReimbursementBatchServiceTest + ✓ create batch assigns sequence and title 0.01s + + PASS Tests\Unit\Services\Reimbursements\ReimbursementDonationServiceTest + ✓ mark donation updates expense and unassigns 0.02s + + PASS Tests\Unit\Services\Reimbursements\ReimbursementRecipientServiceTest + ✓ recipient options include staff and specials 0.02s + + PASS Tests\Unit\Services\Reports\ReportCards\ReportCardServiceTest + ✓ meta returns data sets 0.02s + ✓ completeness returns summary 0.02s + ✓ acknowledgement returns signed data 0.01s + ✓ generate single report returns pdf 0.02s + ✓ generate single report handles missing scores 0.01s + + PASS Tests\Unit\Services\Reports\SlipPrinterFormatterServiceTest + ✓ to db date parses us format 0.02s + ✓ to db time parses string 0.01s + + PASS Tests\Unit\Services\Reports\Stickers\StickerPresetServiceTest + ✓ presets include alias fields 0.01s + + PASS Tests\Unit\Services\Reports\Stickers\StickerPrintServiceTest + ✓ generate returns pdf content 0.02s + ✓ generate returns error when no students 0.02s + + PASS Tests\Unit\Services\Reports\Stickers\StickerQueryServiceTest + ✓ list students by class returns rows 0.01s + ✓ list students for print all excludes youth and kg 0.02s + + PASS Tests\Unit\Services\Roles\PermissionCrudServiceTest + ✓ create and update permission 0.01s + + FAIL Tests\Unit\Services\Roles\RoleAssignmentServiceTest + ⨯ assign roles creates user roles and staff 0.02s + + PASS Tests\Unit\Services\Roles\RoleCrudServiceTest + ✓ create and update role 0.02s + + PASS Tests\Unit\Services\Roles\RoleDashboardServiceTest + ✓ best dashboard route for returns route 0.01s + + PASS Tests\Unit\Services\Roles\RolePermissionServiceTest + ✓ save role permissions persists rows 0.02s + + PASS Tests\Unit\Services\Roles\RoleQueryServiceTest + ✓ list roles returns paginator 0.02s + ✓ list users with roles returns roles 0.01s + + PASS Tests\Unit\Services\Roles\RoleSwitchServiceTest + ✓ get user role names returns roles 0.01s + + PASS Tests\Unit\Services\School\AccountEventServiceTest + ✓ new account added creates family links 0.02s + ✓ delete unverified user handles missing admin emails 0.01s + + FAIL Tests\Unit\Services\School\EnrollmentEventServiceTest + ⨯ admission under review sends email 0.01s + ⨯ admission under review requires email 0.02s + + FAIL Tests\Unit\Services\School\PaymentEventServiceTest + ⨯ payment received sends email 0.01s + ⨯ extra charge requires email 0.01s + + PASS Tests\Unit\Services\School\SemesterSelectionServiceTest + ✓ selected teacher semester prefers session value 0.02s + ✓ selected teacher semester falls back to config 0.01s + + FAIL Tests\Unit\Services\SchoolIds\SchoolIdAssignmentServiceTest + ⨯ assigns school id when missing 0.01s + ✓ assign returns existing school id 0.02s + + PASS Tests\Unit\Services\SchoolIds\SchoolIdGenerationServiceTest + ✓ generates student school id with prefix 0.01s + ✓ generates user school id with prefix 0.01s + + PASS Tests\Unit\Services\Scores\AttendanceCalculatorTest + ✓ calculate uses configured days 0.02s + + PASS Tests\Unit\Services\Scores\ExamScoreServiceTest + ✓ list returns latest exam score 0.01s + ✓ update creates exam score and missing override 0.01s + + PASS Tests\Unit\Services\Scores\HomeworkCalculatorTest + ✓ calculate returns average score 0.02s + + PASS Tests\Unit\Services\Scores\HomeworkScoreServiceTest + ✓ list includes semester variants 0.02s + ✓ add column inserts next index 0.01s + + PASS Tests\Unit\Services\Scores\ParticipationScoreServiceTest + ✓ list returns participation scores 0.02s + ✓ update updates existing scores 0.01s + + FAIL Tests\Unit\Services\Scores\ProjectCalculatorTest + ⨯ calculate returns average score 0.01s + + PASS Tests\Unit\Services\Scores\ProjectScoreServiceTest + ✓ list returns headers and scores 0.02s + ✓ update creates scores and missing overrides 0.01s + ✓ add column inserts next index 0.01s + + PASS Tests\Unit\Services\Scores\QuizCalculatorTest + ✓ calculate returns average score 0.02s + + PASS Tests\Unit\Services\Scores\QuizScoreServiceTest + ✓ list returns headers and scores 0.01s + ✓ update creates scores and missing overrides 0.01s + ✓ add column inserts next index 0.02s + + PASS Tests\Unit\Services\Scores\ScoreCommentServiceTest + ✓ list returns comments for students 0.01s + ✓ save returns validation errors for short comment 0.01s + + PASS Tests\Unit\Services\Scores\ScoreDashboardServiceTest + ✓ overview returns students and scores 0.02s + ✓ view student scores groups by year and semester 0.01s + + PASS Tests\Unit\Services\Scores\ScorePredictorServiceTest + ✓ report builds predictions 0.01s + + PASS Tests\Unit\Services\Scores\ScoreTermServiceTest + ✓ semester and school year fallback to configuration 0.02s + ✓ normalize and variants 0.01s + + PASS Tests\Unit\Services\Scores\SemesterScoreServiceTest + ✓ update student scores upserts semester scores 0.02s + + FAIL Tests\Unit\Services\Security\IpBanCommandServiceTest + ⨯ ban now updates blocked until 0.02s + ⨯ unban all resets active 0.01s + + FAIL Tests\Unit\Services\Security\IpBanQueryServiceTest + ⨯ paginate filters active 0.01s + + PASS Tests\Unit\Services\Security\Pbkdf2HasherTest + ✓ hash and verify 0.94s + + PASS Tests\Unit\Services\Semesters\SemesterConfigServiceTest + ✓ reads dates from configuration 0.01s + + PASS Tests\Unit\Services\Semesters\SemesterRangeServiceTest + ✓ get school year range falls back when config missing 0.01s + ✓ get semester for date uses config dates 0.02s + ✓ normalize semester 0.01s + + PASS Tests\Unit\Services\Settings\ConfigurationServiceTest + ✓ store creates config 0.01s + + PASS Tests\Unit\Services\Settings\SchoolCalendar\SchoolCalendarContextServiceTest + ✓ event types returns list 0.02s + + PASS Tests\Unit\Services\Settings\SchoolCalendar\SchoolCalendarFormatterServiceTest + ✓ format event sets background for no school 0.01s + ✓ format event normalizes iso dates to plain calendar date 0.01s + + PASS Tests\Unit\Services\Settings\SchoolCalendar\SchoolCalendarMeetingServiceTest + ✓ list meetings filters for parent 0.02s + + FAIL Tests\Unit\Services\Settings\SchoolCalendar\SchoolCalendarMutationServiceTest + ✓ create persists event 0.01s + ⨯ update persists changes 0.01s + + FAIL Tests\Unit\Services\Settings\SchoolCalendar\SchoolCalendarNotificationServiceTest + ⨯ notify returns empty when no targets 0.02s + + PASS Tests\Unit\Services\Settings\SchoolCalendar\SchoolCalendarQueryServiceTest + ✓ list events filters by school year 0.01s + ✓ filter events for audience limits visibility 0.01s + + PASS Tests\Unit\Services\Settings\SettingsServiceTest + ✓ update persists settings 0.02s + + PASS Tests\Unit\Services\Staff\StaffCommandServiceTest + ✓ create requires user 0.01s + ✓ create with user id 0.01s + + PASS Tests\Unit\Services\Staff\StaffQueryServiceTest + ✓ paginate returns staff 0.02s + + PASS Tests\Unit\Services\Staff\StaffTimeOffLinkServiceTest + ✓ token round trip 0.02s + ✓ token invalid on expiry 2.02s + + PASS Tests\Unit\Services\Students\StudentAssignmentServiceTest + ✓ assign creates student class rows 0.03s + ✓ remove deletes assignment 0.01s + + FAIL Tests\Unit\Services\Students\StudentProfileServiceTest + ⨯ update student saves allergies 0.01s + + FAIL Tests\Unit\Services\Students\StudentScoreCardServiceTest + ⨯ score card returns rows and comments 0.02s + + PASS Tests\Unit\Services\Subjects\SubjectCurriculumServiceTest + ✓ store creates entry 0.01s + ✓ update changes title 0.01s + + PASS Tests\Unit\Services\Support\ContactMessageServiceTest + ✓ send returns payload 0.02s + + PASS Tests\Unit\Services\Support\SupportRequestServiceTest + ✓ create persists request 0.02s + + PASS Tests\Unit\Services\System\CleanupSchedulerServiceTest + ✓ should run when no cache 0.01s + ✓ mark run sets cache 0.02s + ✓ run unverified cleanup calls artisan 0.01s + + PASS Tests\Unit\Services\System\ConfigUpdateServiceTest + ✓ run task rejects unknown task 0.01s + ✓ run task sets config when forced 0.02s + + PASS Tests\Unit\Services\System\GlobalConfigServiceTest + ✓ get semester and school year 0.01s + + PASS Tests\Unit\Services\System\HealthCheckServiceTest + ✓ check returns payload 0.01s + + PASS Tests\Unit\Services\System\TimeServiceTest + ✓ to utc and to local round trip 0.02s + + FAIL Tests\Unit\Services\Teachers\TeacherAbsenceServiceTest + ⨯ form data returns available dates 0.02s + ⨯ submit creates staff attendance 0.01s + + PASS Tests\Unit\Services\Teachers\TeacherAssignmentServiceTest + ✓ assign creates teacher class row 0.02s + ✓ delete removes assignment 0.02s + + PASS Tests\Unit\Services\Teachers\TeacherDashboardServiceTest + ✓ class view returns students 0.02s + + PASS Tests\Unit\Services\TrophyReportServiceTest + ✓ calculate threshold enforces minimum of three winners 0.02s + ✓ projection marks students without fall scores as not projected 0.02s + ✓ final report classifies confirmed surprise and missed winners 0.02s + + PASS Tests\Unit\Services\Ui\UiStyleServiceTest + ✓ update creates preferences 0.02s + + PASS Tests\Unit\Services\Users\DeleteUnverifiedUserServiceTest + ✓ delete after timeout deletes user 0.01s + ✓ delete after timeout skips recent user 0.01s + + PASS Tests\Unit\Services\Users\InactiveUserCleanupServiceTest + ✓ cleanup removes inactive users and roles 0.02s + + PASS Tests\Unit\Services\Users\LoginActivityServiceTest + ✓ list returns paginated payload 0.01s + + PASS Tests\Unit\Services\Users\UserEventServiceTest + ✓ handle new account sends email 0.01s + ✓ handle new account requires email 0.02s + + PASS Tests\Unit\Services\Users\UserListServiceTest + ✓ list includes roles and second parent flag 0.02s + + PASS Tests\Unit\Services\Users\UserManagementServiceTest + ✓ create persists user and role and sends welcome 0.02s + ✓ update changes user fields 0.02s + ✓ delete removes user and roles 0.01s + + PASS Tests\Unit\Services\Whatsapp\WhatsappContactServiceTest + ✓ list parent contacts returns primary and second 0.02s + + PASS Tests\Unit\Services\Whatsapp\WhatsappContextServiceTest + ✓ school year aliases generate expected values 0.02s + ✓ has roster for year 0.01s + + PASS Tests\Unit\Services\Whatsapp\WhatsappInviteBundleServiceTest + ✓ bundle for parent returns links and emails 0.02s + ✓ consolidate bundles merges by parent 0.02s + + PASS Tests\Unit\Services\Whatsapp\WhatsappInviteEmailServiceTest + ✓ send requires recipients 0.01s + ✓ send dispatches email 0.01s + + FAIL Tests\Unit\Services\Whatsapp\WhatsappInviteNotificationServiceTest + ⨯ dispatch returns error when no listeners 0.02s + ✓ dispatch triggers event when listener registered 0.03s + + PASS Tests\Unit\Services\Whatsapp\WhatsappInviteServiceTest + ✓ send returns success for parent mode 0.02s + + PASS Tests\Unit\Services\Whatsapp\WhatsappLinkServiceTest + ✓ upsert creates link 0.02s + ✓ paginate filters by active 0.01s + + PASS Tests\Unit\Services\Whatsapp\WhatsappMembershipServiceTest + ✓ update membership saves primary 0.01s + ✓ update membership returns error when table missing 0.02s + + PASS Tests\Feature\Api\ApiAttendanceTemplateFeatureTest + ✓ attendance comment templates can be managed through current api 0.03s + ✓ attendance comment template validation blocks bad ranges 0.02s + ✓ legacy attendance template aliases still work 0.03s + + FAIL Tests\Feature\Api\ApiAuthenticationAndAuthorizationTest + ✓ api login returns token and user object 0.03s + ✓ session login also returns token and user object for spa clients 0.03s + ✓ auth me requires authentication 0.02s + ✓ auth me returns the current authenticated user 0.02s + ⨯ admin only routes reject non admin users 0.03s + ✓ protected api routes reject anonymous requests before business logi… 0.14s + + PASS Tests\Feature\Api\ApiPreferencesFeatureTest + ✓ authenticated user can create read update and delete preferences 0.03s + ✓ non admin cannot list or manage another users preferences 0.03s + ✓ admin can list and delete any users preferences 0.03s + ✓ preferences validation rejects invalid options 0.02s + + PASS Tests\Feature\Api\ApiPublicEndpointsTest + ✓ health endpoint is available 0.01s + ✓ public policy endpoints are available 0.02s + ✓ public static pages are available 0.01s + ✓ public frontend content endpoints do not server error 0.01s + ✓ registration captcha endpoint returns captcha payload 0.02s + ✓ invalid login payload is rejected cleanly 0.01s + + PASS Tests\Feature\Api\ApiRolePermissionFeatureTest + ✓ admin can manage roles permissions and assign roles 0.04s + ✓ role permission validation rejects bad payloads 0.02s + + FAIL Tests\Feature\Api\ApiRouteContractTest + ⨯ every api route points to an existing controller method 0.01s + ✓ api routes do not duplicate method and uri pairs 0.02s + ✓ mutating api routes are protected unless explicitly public 0.06s + + PASS Tests\Feature\Api\ApiUseCaseCoverageMatrixTest + ✓ every api route is mapped to an explicit use case domain 0.01s + ✓ required use case domains have route coverage 0.01s + ✓ every protected api route rejects anonymous requests 0.20s + + PASS Tests\Feature\Api\ApiUserManagementFeatureTest + ✓ admin can create list update and delete a user through api 0.04s + ✓ user creation validates required payload and unique email 0.02s + ✓ user creation rejects nonexistent role id 0.02s + + PASS Tests\Feature\Api\V1\Admin\AdministratorAbsenceControllerTest + ✓ guest cannot access absence index 0.01s + ✓ authenticated user can get absence index 0.02s + ✓ absence store requires reason 0.01s + ✓ absence store requires valid date format 0.01s + ✓ absence store calls service and returns success 0.02s + + PASS Tests\Feature\Api\V1\Administrator\AdministratorDashboardControllerTest + ✓ metrics require authentication 0.01s + ✓ metrics are forbidden for non admin users 0.02s + ✓ metrics return payload for admin 0.02s + ✓ user search passes query to service 0.02s + + PASS Tests\Feature\Api\Administrator\AdministratorEnrollmentControllerTest + ✓ guest cannot update enrollment statuses 0.02s + ✓ can fetch enrollment withdrawal data 0.02s + ✓ can fetch new students 0.01s + ✓ update statuses requires valid status values 0.01s + ✓ update statuses calls service 0.02s + + PASS Tests\Feature\Api\V1\Admin\AdministratorEnrollmentQueryApiTest + ✓ enrollment withdrawal endpoint returns students classes and years 0.02s + ✓ new students endpoint returns transformed rows 0.02s + + PASS Tests\Feature\Api\Administrator\AdministratorEnrollmentUpdateStatusesApiTest + ✓ update statuses requires enrollment status payload 0.02s + ✓ update statuses rejects invalid status value 0.02s + ✓ update statuses creates new enrollment row 0.02s + ✓ update statuses updates existing enrollment row 0.03s + ✓ update statuses creates or updates refund when status is refund pen… 0.02s + ✓ update statuses returns partial success when some students are inva… 0.02s + + PASS Tests\Feature\Api\Administrator\AdministratorNotificationControllerTest + ✓ can get alerts data 0.02s + ✓ save alerts requires subjects payload 0.01s + ✓ save alerts calls subject service 0.01s + ✓ can get print recipients data 0.02s + ✓ save print recipients requires notify payload 0.01s + ✓ save print recipients calls service 0.01s + + PASS Tests\Feature\Api\Administrator\AdministratorTeacherSubmissionControllerTest + ✓ can get teacher submission report 0.02s + ✓ notify requires notify payload 0.02s + ✓ notify calls service 0.01s + + PASS Tests\Feature\Api\Administrator\AdministratorTeacherSubmissionNotifyApiTest + ✓ notify endpoint requires notify payload 0.02s + ✓ notify endpoint sends email and creates history row 0.02s + ✓ notify endpoint marks failed when teacher email is invalid 0.02s + ✓ notify endpoint accepts flat teacher ids from spa payload 0.02s + ✓ notify endpoint accepts flat teacher ids when teacher class has no… 0.02s + + PASS Tests\Feature\Api\Administrator\AdministratorTeacherSubmissionReportApiTest + ✓ teacher submission report endpoint returns rows summary and history 0.03s + ✓ teacher submission report returns no students status for empty sect… 0.02s + ✓ teacher submission report handles teacher class without semester co… 0.02s + ✓ teacher submission report limits history to three entries 0.02s + ✓ teacher submission report honors school year and semester query fil… 0.02s + + PASS Tests\Feature\Api\V1\Administrator\EmergencyContactControllerTest + ✓ index returns grouped contacts 0.02s + ✓ update changes emergency contact 0.02s + ✓ destroy deletes emergency contact 0.02s + ✓ show returns single contact for parent 0.02s + ✓ update requires matching parent id 0.02s + ✓ destroy requires matching parent id 0.02s + + PASS Tests\Feature\Api\V1\Administrator\TeacherClassAssignmentControllerTest + ✓ index returns teachers and classes 0.02s + ✓ store and delete assignment 0.02s + + PASS Tests\Feature\Api\V1\Administrator\TrophyControllerTest + ✓ index requires authentication 0.02s + ✓ index is forbidden for non admin users 0.02s + ✓ index returns projection for admin 0.02s + ✓ winners returns data for admin 0.03s + ✓ final returns data for admin 0.02s + ✓ index validates percentile range 0.02s + + PASS Tests\Feature\Api\AssignmentApiControllerTest + ✓ index returns assignment overview 0.02s + ✓ index filters by school year 0.02s + ✓ index sorts sections by name 0.02s + ✓ index excludes inactive students 0.02s + ✓ store creates new assignment 0.02s + ✓ store updates existing assignment for same unique keys 0.02s + ✓ store validates required fields 0.02s + ✓ store validates foreign keys 0.02s + ✓ class assignment data returns expected structure 0.02s + ✓ class assignment data deduplicates teacher names 0.02s + + PASS Tests\Feature\Api\AssignmentApiTest + ✓ it returns assignment sections json 0.02s + ✓ it filters assignments by school year 0.02s + ✓ it creates or updates student assignment 0.02s + ✓ it validates required fields when storing assignment 0.01s + ✓ store is idempotent for same student semester and year 0.02s + ✓ guest cannot access assignment api when auth is required 0.01s + + PASS Tests\Feature\Api\V1\Attendance\LateSlipLogsControllerTest + ✓ index requires admin 0.02s + ✓ index returns logs 0.02s + ✓ show returns log 0.02s + ✓ destroy deletes log 0.02s + ✓ index validation rejects bad dates 0.02s + + PASS Tests\Feature\Api\AttendanceCommentTemplateApiTest + ✓ can list templates 0.01s + ✓ can list templates active only 0.02s + ✓ can create template 0.01s + ✓ store validation fails when max less than min 0.01s + ✓ can show template 0.02s + ✓ can update template 0.01s + ✓ update validation fails if both scores invalid relation 0.01s + ✓ can delete template 0.02s + ✓ legacy list data endpoint returns templates key 0.01s + + PASS Tests\Feature\Api\V1\AttendanceTracking\AttendanceTrackingControllerTest + ✓ pending violations returns json response 0.02s + ✓ notified violations returns json response 0.02s + ✓ student case returns service payload 0.01s + ✓ student case returns service status code when not found 0.01s + ✓ record validates and returns service response 0.02s + ✓ record returns validation errors for bad payload 0.01s + ✓ send auto emails returns service response 0.01s + ✓ compose returns service response 0.02s + ✓ send manual email returns service response 0.01s + ✓ send manual email validates payload 0.02s + ✓ parents info returns service response 0.02s + ✓ save notification note returns service response 0.01s + ✓ save notification note validates payload 0.01s + + PASS Tests\Feature\Api\V1\Auth\IpBanControllerTest + ✓ index requires admin 0.02s + ✓ index returns bans 0.02s + ✓ show returns ban 0.02s + ✓ ban creates block 0.02s + ✓ unban single 0.02s + ✓ unban all 0.02s + ✓ ban validation requires ip or id 0.02s + + PASS Tests\Feature\Api\V1\Auth\RegisterControllerTest + ✓ captcha endpoint returns value 0.02s + ✓ register creates user 0.33s + + PASS Tests\Feature\Api\V1\Auth\RegisterPayloadDebugTest + ✓ debug payload shows json body 0.01s + + PASS Tests\Feature\Api\BadgeControllerTest + ✓ form data returns success response 0.02s + ✓ print status returns success response 0.02s + ✓ print status returns 500 when service throws 0.02s + ✓ log print returns success response 0.02s + ✓ log print returns 500 when service throws 0.01s + ✓ generate pdf returns pdf response 0.02s + ✓ generate pdf validates required user ids 0.01s + ✓ log print validates required user ids 0.02s + ✓ endpoints require authentication 0.02s + + PASS Tests\Feature\Api\V1\BadgeScan\BadgeScanControllerTest + ✓ scan is public but validates badge value 0.02s + ✓ scan returns 404 for unrecognized badge 0.02s + ✓ logs require authentication 0.01s + ✓ logs are forbidden for non staff roles 0.02s + ✓ logs return data for staff 0.02s + + PASS Tests\Feature\Api\V1\BroadcastEmail\BroadcastEmailControllerTest + ✓ options returns parents and senders 0.02s + ✓ send test only dispatches email 0.02s + + PASS Tests\Feature\Api\V1\ClassPreparation\ClassPreparationControllerTest + ✓ sticker counts returns payload 0.02s + ✓ students by class returns roster 0.02s + + PASS Tests\Feature\Api\V1\ClassProgress\ClassProgressControllerTest + ✓ meta returns sections 0.02s + ✓ index returns paginated reports 0.03s + ✓ store creates reports 0.02s + ✓ show returns weekly reports 0.02s + ✓ update modifies report 0.02s + ✓ destroy deletes report 0.02s + ✓ authorization blocks other teachers 0.02s + ✓ validation rejects invalid payload 0.02s + ✓ attachment download returns file 0.02s + + PASS Tests\Feature\Api\V1\Classes\ClassSectionControllerTest + ✓ index returns sections 0.02s + ✓ store requires admin 0.02s + ✓ store creates class section 0.02s + ✓ update requires admin 0.02s + ✓ show returns section 0.02s + ✓ update modifies class section 0.02s + ✓ destroy deletes class section 0.01s + ✓ attendance returns students 0.02s + ✓ seed defaults creates classes 0.02s + ✓ validation rejects invalid payload 0.01s + + PASS Tests\Feature\Api\V1\Communication\CommunicationControllerTest + ✓ options returns students and templates 0.03s + ✓ preview returns rendered subject and body 0.02s + ✓ send dispatches email 0.02s + + PASS Tests\Feature\Api\V1\CompetitionScores\CompetitionScoresControllerTest + ✓ index returns competitions and counts 0.02s + ✓ edit returns students and scores 0.02s + ✓ save updates scores 0.02s + + PASS Tests\Feature\Api\V1\CompetitionWinners\CompetitionWinnersControllerTest + ✓ index returns admin competitions with ids 0.02s + ✓ lock and unlock toggle competition 0.02s + ✓ export quiz creates quiz rows 0.02s + + PASS Tests\Feature\Api\V1\Discounts\DiscountControllerTest + ✓ options returns vouchers and parents 0.03s + ✓ apply voucher applies discount 0.02s + ✓ store voucher creates row 0.02s + ✓ show voucher returns resource 0.02s + ✓ delete voucher removes row 0.02s + + PASS Tests\Feature\Api\V1\Email\EmailControllerTest + ✓ senders endpoint returns options 0.02s + ✓ send endpoint uses dispatch service 0.02s + + PASS Tests\Feature\Api\V1\Email\EmailExtractorControllerTest + ✓ emails endpoint returns users and parents 0.02s + ✓ legacy emails endpoint returns top level arrays 0.02s + ✓ compare endpoint returns comparison 0.02s + + PASS Tests\Feature\Api\V1\Exams\ExamDraftControllerTest + ✓ teacher store creates draft 0.03s + ✓ admin review updates status 0.02s + + PASS Tests\Feature\Api\V1\Expenses\ExpenseControllerTest + ✓ options returns staff and retailors 0.02s + ✓ store creates expense 0.02s + ✓ index lists expenses 0.02s + ✓ show returns expense 0.02s + ✓ update status changes status 0.02s + + PASS Tests\Feature\Api\V1\ExtraCharges\ExtraChargesControllerTest + ✓ list returns rows 0.03s + ✓ options returns parent options 0.02s + ✓ parent options returns results 0.02s + ✓ invoices for parent returns results 0.02s + ✓ store creates charge and updates invoice 0.03s + ✓ update adjusts charge 0.02s + ✓ void changes status 0.02s + ✓ reverse changes status 0.02s + + PASS Tests\Feature\Api\V1\Family\FamilyAdminControllerTest + ✓ index returns family admin payload 0.02s + ✓ search returns items 0.02s + ✓ card returns family details 0.02s + ✓ compose email returns error on failure 0.02s + ✓ requires authentication 0.01s + ✓ compose email validation fails 0.02s + + PASS Tests\Feature\Api\V1\Family\FamilyControllerTest + ✓ families by student returns families 0.02s + ✓ guardians by family returns guardians 0.02s + ✓ bootstrap creates family and links 0.02s + ✓ attach second by user links guardian 0.02s + ✓ attach second by email creates user and links 0.02s + ✓ set primary home updates record 0.02s + ✓ set guardian flags updates record 0.02s + ✓ set guardian flags requires payload 0.02s + ✓ unlink guardian removes record 0.02s + ✓ unlink student removes record 0.02s + ✓ import legacy second parents links guardian 0.02s + ✓ requires authentication 0.02s + ✓ attach second by user validation fails 0.02s + + PASS Tests\Feature\Api\V1\Finance\ChargeControllerTest + ✓ list charges for parent 0.02s + ✓ store extra charge returns 409 on duplicate 0.02s + ✓ store event charge creates row 0.02s + ✓ cancel extra charge voids row 0.02s + ✓ charges endpoints require authentication 0.01s + + PASS Tests\Feature\Api\V1\Finance\EventChargeControllerTest + ✓ show requires authentication 0.02s + ✓ show returns event charge 0.03s + ✓ show returns 404 for unknown charge 0.02s + ✓ update modifies event charge 0.03s + ✓ approve marks charge as charged 0.02s + ✓ void clears charged flag 0.02s + ✓ destroy voids the charge 0.03s + + PASS Tests\Feature\Api\V1\Finance\FeeCalculationControllerTest + ✓ refund endpoint returns amount 0.02s + ✓ tuition breakdown endpoint returns per student detail 0.02s + ✓ tuition breakdown endpoint requires authentication 0.01s + ✓ tuition breakdown endpoint validates payload 0.02s + ✓ family balance endpoint returns account summary 0.02s + ✓ family balance endpoint requires authentication 0.01s + ✓ tuition total endpoint returns total 0.02s + ✓ refund endpoint requires authentication 0.01s + ✓ tuition total endpoint requires authentication 0.02s + ✓ refund endpoint validates payload 0.02s + ✓ tuition total endpoint validates payload 0.02s + ✓ refund endpoint handles service failure 0.02s + ✓ tuition total endpoint handles service failure 0.02s + + PASS Tests\Feature\Api\V1\Finance\FinancialControllerTest + ✓ report returns financial report 0.03s + ✓ summary returns totals 0.02s + ✓ unpaid parents lists balances 0.02s + + PASS Tests\Feature\Api\V1\Finance\InvoiceControllerTest + ✓ management returns parent invoice data 0.02s + ✓ generate creates invoice 0.03s + ✓ by parent returns invoices 0.02s + + PASS Tests\Feature\Api\V1\Finance\PaymentControllerTest + ✓ store creates payment plan 0.02s + ✓ by parent returns payments 0.02s + ✓ update balance updates payment 0.02s + + PASS Tests\Feature\Api\V1\Finance\PaymentEventChargesControllerTest + ✓ store creates event charges 0.02s + + PASS Tests\Feature\Api\V1\Finance\PaymentManualControllerTest + ✓ search returns parent data 0.02s + ✓ suggest returns items 0.02s + + PASS Tests\Feature\Api\V1\Finance\PaymentNotificationControllerTest + ✓ send creates log 0.02s + ✓ index lists logs 0.02s + + PASS Tests\Feature\Api\V1\Finance\PaymentTransactionControllerTest + ✓ store creates transaction 0.02s + ✓ by payment returns transactions 0.02s + ✓ update status updates transaction 0.02s + + PASS Tests\Feature\Api\V1\Finance\PaypalTransactionsControllerTest + ✓ index returns transactions 0.02s + ✓ csv download 0.02s + + PASS Tests\Feature\Api\V1\Finance\PurchaseOrderControllerTest + ✓ index returns orders 0.02s + ✓ options returns suppliers and supplies 0.02s + ✓ store creates purchase order and items 0.02s + ✓ receive updates inventory 0.02s + ✓ cancel marks purchase order 0.02s + + PASS Tests\Feature\Api\V1\Finance\RefundControllerTest + ✓ index requires authentication 0.02s + ✓ index returns paginated refunds 0.02s + ✓ show returns refund 0.02s + ✓ store overpayment creates refund 0.02s + ✓ store validates payload 0.02s + ✓ update approves refund 0.02s + ✓ reject requires reason 0.02s + ✓ record payment updates refund 0.02s + ✓ recalculate overpayments creates refund 0.02s + ✓ destroy cancels refund 0.02s + + PASS Tests\Feature\Api\V1\Finance\ReimbursementControllerTest + ✓ create batch creates open batch 0.02s + ✓ mark donation updates expense 0.02s + ✓ store reimbursement creates record and updates expense 0.02s + ✓ update reimbursement updates fields 0.02s + + PASS Tests\Feature\Api\V1\Frontend\FrontendControllerTest + ✓ index returns page 0.02s + ✓ fetch user requires auth 0.01s + ✓ fetch user returns profile 0.01s + + PASS Tests\Feature\Api\V1\Frontend\InfoIconControllerTest + ✓ profile icon returns initials 0.02s + + PASS Tests\Feature\Api\V1\Frontend\LandingPageControllerTest + ✓ index returns admin dashboard 0.02s + ✓ teacher dashboard returns summary 0.02s + ✓ parent dashboard returns summary 0.02s + + PASS Tests\Feature\Api\V1\Frontend\PageControllerTest + ✓ privacy returns content 0.01s + ✓ help missing returns error 0.01s + ✓ submit contact persists 0.02s + + PASS Tests\Feature\Api\V1\FullSurface\ApiAcademicAttendanceFullSurfaceContractTest + ✓ academic attendance and grading surfaces have controlled contracts 0.18s + + PASS Tests\Feature\Api\V1\FullSurface\ApiAccountStatusLifecycleContractTest + ✓ suspended disabled and pending status values do not gain access thr… 0.15s + + PASS Tests\Feature\Api\V1\FullSurface\ApiAdminOperationsFullSurfaceContractTest + ✓ administrator operational surface responds with controlled contract… 0.16s + + PASS Tests\Feature\Api\V1\FullSurface\ApiAttachmentUploadContentSafetyContractTest + ✓ upload endpoints reject executable or misleading files cleanly 0.08s + ✓ download and file response routes do not allow path traversal param… 0.07s + + PASS Tests\Feature\Api\V1\FullSurface\ApiAuditLogAndAdministrativeTraceabilityContractTest + ✓ admin mutations return traceable status without exposing internal l… 0.18s + ✓ audit and log routes are not mutable by public or low privilege use… 0.26s + + PASS Tests\Feature\Api\V1\FullSurface\ApiAuthenticationLifecycleDepthContractTest + ✓ authentication lifecycle handles login me refresh logout and invali… 0.08s + ✓ password reset and registration like routes do not leak account exi… 0.05s + + FAIL Tests\Feature\Api\V1\FullSurface\ApiAuthorizationCacheInvalidationContractTest + ⨯ role and permission mutations do not make low privilege actor admin… 0.06s + + PASS Tests\Feature\Api\V1\FullSurface\ApiBatch11RouteRegressionNetTest + ✓ every api family has at least one negative contract probe in batch… 0.05s + ✓ batch 11 high risk routes return controlled responses under combine… 0.21s + + PASS Tests\Feature\Api\V1\FullSurface\ApiBatch12AcademicGradeBoundaryContractTest + ✓ grade and score routes reject out of range and wrong student contex… 0.20s + ✓ locked or finalized grade routes do not accept low privilege overri… 0.06s + + PASS Tests\Feature\Api\V1\FullSurface\ApiBatch12AttachmentLifecycleContractTest + ✓ attachment upload routes handle multiple file shapes cleanly 0.06s + ✓ file download routes reject path and storage driver probing 0.08s + + PASS Tests\Feature\Api\V1\FullSurface\ApiBatch12AttendanceCorrectionAuditContractTest + ✓ attendance corrections require valid actor date status and reason 0.20s + ✓ parent and student cannot correct attendance records 0.10s + + FAIL Tests\Feature\Api\V1\FullSurface\ApiBatch12BulkMutationBoundaryContractTest + ⨯ bulk mutation routes reject empty and cross domain targets cleanly 0.08s + ✓ bulk routes do not accept unbounded target lists 0.12s + + PASS Tests\Feature\Api\V1\FullSurface\ApiBatch12CombinedRegressionSweepTest + ✓ batch 12 combined security business rule and contract probe 0.26s + + PASS Tests\Feature\Api\V1\FullSurface\ApiBatch12ConsistencyUnderPartialPayloadContractTest + ✓ patch routes do not null identity or ownership when optional fields… 0.06s + ✓ post routes handle sparse payloads as validation not crashes 0.13s + + PASS Tests\Feature\Api\V1\FullSurface\ApiBatch12CrossActorDataLeakageContractTest + ✓ parent teacher and student scoped reads do not leak admin only fiel… 0.32s + ✓ actor cannot select a different owner scope with query parameters 0.12s + + PASS Tests\Feature\Api\V1\FullSurface\ApiBatch12FinancialLedgerIntegrityContractTest + ✓ financial mutations reject ledger breaking amounts and cross invoic… 0.44s + ✓ parent cannot force finance scope to all families 0.34s + + PASS Tests\Feature\Api\V1\FullSurface\ApiBatch12GuardianDelegationExpirationContractTest + ✓ guardian and authorized user routes validate expiration relationshi… 0.10s + ✓ student cannot manage guardians or authorized users 0.05s + + PASS Tests\Feature\Api\V1\FullSurface\ApiBatch12LongRunningExportJobContractTest + ✓ export report and generation routes handle async parameters without… 0.14s + ✓ low privilege users cannot request full school exports 0.09s + + PASS Tests\Feature\Api\V1\FullSurface\ApiBatch12MaintenanceModeAndOperationalControlContractTest + ✓ operational control routes are admin only and controlled 0.07s + ✓ public requests cannot toggle system state 0.05s + + PASS Tests\Feature\Api\V1\FullSurface\ApiBatch12RouteMetadataRiskRegisterTest + ✓ high risk route families exist in the contract risk register 0.05s + ✓ mutating high risk routes have specific route names when available 0.04s + + PASS Tests\Feature\Api\V1\FullSurface\ApiBatch12SearchEnumerationResistanceContractTest + ✓ search autocomplete and lookup routes resist identifier enumeration 0.37s + + PASS Tests\Feature\Api\V1\FullSurface\ApiBatch12SensitiveConfigurationExposureContractTest + ✓ configuration and bootstrap responses do not expose secrets 0.07s + ✓ low privilege users cannot read sensitive configuration domains 0.08s + + PASS Tests\Feature\Api\V1\FullSurface\ApiBatch12WebhookProviderMatrixContractTest + ✓ provider callbacks reject missing mismatched and replayed signature… 0.08s + + PASS Tests\Feature\Api\V1\FullSurface\ApiBatch13AccountRecoveryCredentialChangeContractTest + ✓ password reset and credential routes do not leak user existence or… 0.05s + ✓ low privilege users cannot change other users credentials 0.06s + + PASS Tests\Feature\Api\V1\FullSurface\ApiBatch13ApiPaginationPerformanceGuardContractTest + ✓ list routes cap unbounded pagination and include requests 0.12s + ✓ search routes handle unicode and extreme terms without leaking sql 0.10s + + PASS Tests\Feature\Api\V1\FullSurface\ApiBatch13ContactMessagingAbuseModerationContractTest + ✓ message and contact routes handle spam headers and html payloads 0.11s + ✓ broadcast routes remain admin only under channel spoofing 0.08s + + PASS Tests\Feature\Api\V1\FullSurface\ApiBatch13DiscountVoucherScholarshipAbuseContractTest + ✓ discount and voucher routes reject abusive amounts and scope overri… 0.06s + ✓ parent cannot self grant discounts or scholarships 0.05s + + PASS Tests\Feature\Api\V1\FullSurface\ApiBatch13FullSurfaceRegressionSuperSweepTest + ✓ batch13 super sweep keeps major route families under controlled fai… 0.23s + ✓ batch13 major mutation families are represented 0.05s + + PASS Tests\Feature\Api\V1\FullSurface\ApiBatch13InventoryProcurementReceivingIntegrityContractTest + ✓ inventory receiving routes reject negative or impossible stock move… 0.07s + ✓ non admins cannot adjust inventory or procurement state 0.11s + + FAIL Tests\Feature\Api\V1\FullSurface\ApiBatch13LocaleCalendarReligiousDateContractTest + ⨯ calendar and event routes handle locale specific dates cleanly 0.07s + ✓ attendance and academic routes reject out of term religious calenda… 0.10s + + PASS Tests\Feature\Api\V1\FullSurface\ApiBatch13MobileOfflineSyncConflictContractTest + ✓ offline sync headers do not override authorization or state 0.13s + ✓ duplicate offline submissions have controlled outcome 0.26s + + PASS Tests\Feature\Api\V1\FullSurface\ApiBatch13ObservableErrorCorrelationContractTest + ✓ malformed requests preserve safe error correlation without reflecti… 0.07s + ✓ error responses do not disclose controller or model stack details 0.11s + + PASS Tests\Feature\Api\V1\FullSurface\ApiBatch13ParentPortalInvoicePrivacyContractTest + ✓ parent finance queries cannot request all families or other parent… 0.21s + ✓ parent cannot mark invoice paid or refunded directly 0.26s + + PASS Tests\Feature\Api\V1\FullSurface\ApiBatch13PaymentProviderLedgerReconciliationContractTest + ✓ payment provider payloads do not bypass ledger validation 0.27s + ✓ duplicate provider reference is controlled across payment routes 0.29s + + PASS Tests\Feature\Api\V1\FullSurface\ApiBatch13ReportCardTranscriptCertificateForgeryContractTest + ✓ document generation rejects forged finalization and signer payloads 0.26s + ✓ students and parents cannot generate admin documents for other stud… 0.11s + + PASS Tests\Feature\Api\V1\FullSurface\ApiBatch13RolePermissionMutationRaceContractTest + ✓ permission mutations reject wildcards and recursive assignments 0.06s + ✓ non admin cannot gain permission by replaying role payload 0.09s + + PASS Tests\Feature\Api\V1\FullSurface\ApiBatch13StaffHrPayrollBoundaryContractTest + ✓ staff and payroll routes redact sensitive personnel fields 0.11s + ✓ low privilege users cannot mutate staff or payroll routes 0.06s + + PASS Tests\Feature\Api\V1\FullSurface\ApiBatch13StudentEnrollmentLifecycleIntegrityContractTest + ✓ enrollment routes reject cross family and cross class payloads clea… 0.08s + ✓ parent cannot self enroll or move student into arbitrary class 0.07s + + PASS Tests\Feature\Api\V1\FullSurface\ApiBatch13TeacherRosterAndAssignmentBoundaryContractTest + ✓ teacher roster routes ignore forced teacher and class scope overrid… 0.25s + ✓ unassigned teacher mutations are denied or validated 0.11s + + FAIL Tests\Feature\Api\V1\FullSurface\ApiBatch14AcademicPromotionRollbackIntegrityContractTest + ⨯ promotion and school year routes reject unsafe rollback payloads 0.10s + ✓ low privilege actors cannot close reopen or promote school years 0.07s + + PASS Tests\Feature\Api\V1\FullSurface\ApiBatch14AccountEnumerationAndIdentityPrivacyContractTest + ✓ identity recovery routes do not reveal whether user exists 0.05s + ✓ identity payloads do not leak internal auth fields 0.08s + + PASS Tests\Feature\Api\V1\FullSurface\ApiBatch14AdminDelegationApprovalWorkflowContractTest + ✓ approval and delegation routes reject forged approval metadata 0.08s + ✓ low privilege users cannot self approve or delegate privileges 0.09s + + PASS Tests\Feature\Api\V1\FullSurface\ApiBatch14ApiConsumerContractCompatibilityTest + ✓ core identity contracts remain compatible for web mobile and api cl… 0.13s + ✓ successful login like responses keep token and user contract when p… 0.05s + + PASS Tests\Feature\Api\V1\FullSurface\ApiBatch14AttendanceDeviceAndKioskAbuseContractTest + ✓ kiosk scanner and attendance routes reject forged device identity 0.11s + ✓ student and parent cannot self mark attendance through device paylo… 0.06s + + PASS Tests\Feature\Api\V1\FullSurface\ApiBatch14AuditTrailTamperResistanceContractTest + ✓ audit and log routes reject client supplied actor and timestamp fie… 0.09s + ✓ non admin users cannot clear or rewrite audit history 0.05s + + PASS Tests\Feature\Api\V1\FullSurface\ApiBatch14BulkAssignmentCollisionContractTest + ✓ bulk assignment routes handle duplicate and conflicting ids cleanly 0.07s + ✓ parent and student cannot force bulk assignment scope 0.07s + + PASS Tests\Feature\Api\V1\FullSurface\ApiBatch14CrossModuleInvariantRiskRegisterTest + ✓ batch14 route families have cross module risk coverage 0.05s + ✓ batch14 high risk mutation families exist 0.04s + + FAIL Tests\Feature\Api\V1\FullSurface\ApiBatch14DataLifecycleArchivePurgeContractTest + ⨯ archive purge and retention routes require safe controlled requests 0.05s + ✓ non admin users cannot purge or restore global records 0.06s + + PASS Tests\Feature\Api\V1\FullSurface\ApiBatch14FinanceReconciliationAndRefundAbuseContractTest + ✓ finance reconciliation routes reject mismatched invoice parent and… 0.13s + ✓ parent cannot self refund or self reconcile 0.07s + + PASS Tests\Feature\Api\V1\FullSurface\ApiBatch14NotificationTemplateInjectionContractTest + ✓ notification and template routes reject template injection payloads 0.08s + ✓ non admin users cannot broadcast by template override 0.09s + + PASS Tests\Feature\Api\V1\FullSurface\ApiBatch14PrintExportTamperingContractTest + ✓ print export and document generation routes reject tampered scope f… 0.10s + ✓ low privilege users cannot generate full school exports 0.12s + + PASS Tests\Feature\Api\V1\FullSurface\ApiBatch14RegressionMegaSweepTest + ✓ batch14 mega sweep keeps new risk payloads under controlled failure 0.23s + + PASS Tests\Feature\Api\V1\FullSurface\ApiBatch14RelationshipOwnershipMatrixExpansionTest + ✓ relationship owner override fields are not trusted across route fam… 0.09s + ✓ student user cannot read or write other relationship graphs 0.09s + + PASS Tests\Feature\Api\V1\FullSurface\ApiBatch14SessionCookieCsrfBoundaryContractTest + ✓ api auth routes do not depend on browser session cookies 0.09s + ✓ browser only session headers do not grant api privileges 0.06s + + PASS Tests\Feature\Api\V1\FullSurface\ApiBatch14StoragePathAndSignedUrlContractTest + ✓ file and signed url routes reject path and disk overrides 0.08s + ✓ public file routes do not honor expired or forged signature paramet… 0.05s + + WARN Tests\Feature\Api\V1\FullSurface\ApiBatch15AdminImpersonationSessionBoundaryContractTest + ! batch15 impersonation and acting as routes require real admin conte… 0.05s + + PASS Tests\Feature\Api\V1\FullSurface\ApiBatch15AuthTokenRotationAndRevocationContractTest + ✓ batch15 token rotation revocation and identity routes do not accept… 0.10s + ✓ batch15 repeat logout and refresh replay are controlled 0.05s + + PASS Tests\Feature\Api\V1\FullSurface\ApiBatch15BackgroundCommandAndSchedulerContractTest + ✓ batch15 command scheduler and job trigger routes are admin only and… 0.08s + + PASS Tests\Feature\Api\V1\FullSurface\ApiBatch15ConsentPrivacyAndDataSubjectRightsContractTest + ✓ batch15 privacy consent erasure and export routes are admin or owne… 0.05s + ✓ batch15 student actor cannot request family wide or school wide pri… 0.08s + + PASS Tests\Feature\Api\V1\FullSurface\ApiBatch15CrossSchoolIdentityCollisionContractTest + ✓ batch15 duplicate external identifiers and cross school aliases fai… 0.06s + + PASS Tests\Feature\Api\V1\FullSurface\ApiBatch15DataResidencyBackupAndRestoreContractTest + ✓ batch15 backup restore residency and snapshot routes do not expose… 0.05s + + PASS Tests\Feature\Api\V1\FullSurface\ApiBatch15DomainEventOutboxAndNotificationConsistencyContractTest + ✓ batch15 event outbox and notification trigger routes reject forged… 0.10s + + PASS Tests\Feature\Api\V1\FullSurface\ApiBatch15FeatureFlagExperimentAndRolloutContractTest + ✓ batch15 feature flag and rollout routes reject low privilege overri… 0.09s + + PASS Tests\Feature\Api\V1\FullSurface\ApiBatch15FormRequestAuthorizationCoverageContractTest + ✓ batch15 mutating routes do not allow public or low privilege form r… 0.09s + + PASS Tests\Feature\Api\V1\FullSurface\ApiBatch15GlobalSearchAndDirectoryEnumerationContractTest + ✓ batch15 global search directory and lookup routes resist enumeratio… 0.19s + + PASS Tests\Feature\Api\V1\FullSurface\ApiBatch15LocalizationContentDirectionAndEncodingContractTest + ✓ batch15 rtl unicode and encoding payloads remain controlled across… 0.06s + + PASS Tests\Feature\Api\V1\FullSurface\ApiBatch15MetadataFilteringAndSparseFieldsetSecurityContractTest + ✓ batch15 sparse fieldsets metadata and embeds do not reveal sensitiv… 0.09s + + PASS Tests\Feature\Api\V1\FullSurface\ApiBatch15RateLimitAndAbusePatternContractTest + ✓ batch15 repeated sensitive requests return controlled responses wit… 0.13s + + PASS Tests\Feature\Api\V1\FullSurface\ApiBatch15RegressionUltraSweepTest + ✓ batch15 ultra sweep keeps cross domain hostile payloads under contr… 0.24s + + PASS Tests\Feature\Api\V1\FullSurface\ApiBatch15ReportDrilldownAndAggregatePrivacyContractTest + ✓ batch15 report drilldown filters do not allow scope escape or sensi… 0.14s + + PASS Tests\Feature\Api\V1\FullSurface\ApiBatch15RouteParameterPoisoningExpansionTest + ✓ batch15 route parameters reject encoded path script and type confus… 0.09s + + PASS Tests\Feature\Api\V1\FullSurface\ApiBatch15StudentSafetyIncidentEscalationContractTest + ✓ batch15 safety incident escalation routes are not mutable by parent… 0.14s + + PASS Tests\Feature\Api\V1\FullSurface\ApiBatch16AccessibilityAndClientHintsContractTest + ✓ batch16 client hints accessibility headers and locale variants do n… 0.12s + + PASS Tests\Feature\Api\V1\FullSurface\ApiBatch16AdaptivePublicEndpointAbuseContractTest + ✓ batch16 public endpoints ignore identity spoofing and privileged qu… 0.08s + + PASS Tests\Feature\Api\V1\FullSurface\ApiBatch16DeviceTrustAndScannerReplayContractTest + ✓ batch16 kiosk scanner and device routes do not trust client asserte… 0.13s + + PASS Tests\Feature\Api\V1\FullSurface\ApiBatch16EmergencyContactAndPickupSafetyContractTest + ✓ batch16 pickup guardian and emergency contact routes reject wrong f… 0.08s + + PASS Tests\Feature\Api\V1\FullSurface\ApiBatch16EventualConsistencyAndRetryContractTest + ✓ batch16 retry headers and client operation ids are scoped per actor… 0.11s + + PASS Tests\Feature\Api\V1\FullSurface\ApiBatch16ImportPreviewCommitSeparationContractTest + ✓ batch16 import preview payloads cannot force commit or skip validat… 0.10s + + PASS Tests\Feature\Api\V1\FullSurface\ApiBatch16MoneyPrecisionCurrencyContractTest + ✓ batch16 money routes reject precision currency and rounding abuse c… 0.35s + + PASS Tests\Feature\Api\V1\FullSurface\ApiBatch16MultiStepWorkflowCompensationContractTest + ✓ batch16 multi step school operations fail safely when later steps a… 0.10s + ✓ batch16 compensation flags cannot be user supplied by low privilege… 0.08s + + PASS Tests\Feature\Api\V1\FullSurface\ApiBatch16NotificationDeliverySuppressionContractTest + ✓ batch16 notification suppression and delivery flags cannot be overr… 0.09s + + PASS Tests\Feature\Api\V1\FullSurface\ApiBatch16OptimisticLockingAndVersionFieldContractTest + ✓ batch16 version and lock fields cannot be forged to override newer… 0.07s + + PASS Tests\Feature\Api\V1\FullSurface\ApiBatch16PermissionDriftDetectionContractTest + ✓ batch16 permission names and route families do not drift into ungua… 0.07s + + PASS Tests\Feature\Api\V1\FullSurface\ApiBatch16ReadModelProjectionConsistencyContractTest + ✓ batch16 summary dashboard and projection routes resist privileged i… 0.10s + + PASS Tests\Feature\Api\V1\FullSurface\ApiBatch16RegressionHyperSweepTest + ✓ batch16 hyper sweep applies cross cutting hostile payloads to high… 0.19s + + PASS Tests\Feature\Api\V1\FullSurface\ApiBatch16RouteGraphInvariantRegisterTest + ✓ batch16 route graph has contract pressure for new risk families 0.05s + + PASS Tests\Feature\Api\V1\FullSurface\ApiBatch16SchemaEvolutionDeprecationContractTest + ✓ batch16 deprecated aliases remain controlled and do not return inco… 0.09s + ✓ batch16 removed or deprecated fields are not required for current c… 0.07s + + FAIL Tests\Feature\Api\V1\FullSurface\ApiBatch16TemporalConsistencyAndClockSkewContractTest + ⨯ batch16 clock skew and temporal boundaries do not bypass business r… 0.29s + + PASS Tests\Feature\Api\V1\FullSurface\ApiBatch17AcademicPrerequisiteAndDependencyContractTest + ✓ academic actions do not skip required prerequisites or locks 0.09s + + PASS Tests\Feature\Api\V1\FullSurface\ApiBatch17ApiContractDiffAndCriticalKeyRegisterTest + ✓ critical identity finance attendance and academic payloads keep con… 0.11s + + PASS Tests\Feature\Api\V1\FullSurface\ApiBatch17AttendanceTamperWindowContractTest + ✓ attendance cutoff backdate future and reason requirements are contr… 0.15s + + PASS Tests\Feature\Api\V1\FullSurface\ApiBatch17CommunicationRecipientExpansionContractTest + ✓ message broadcast and notification recipient scope cannot be expand… 0.09s + + PASS Tests\Feature\Api\V1\FullSurface\ApiBatch17DataLineageAndSourceAttributionContractTest + ✓ client supplied lineage and audit source fields are not authoritati… 0.08s + + PASS Tests\Feature\Api\V1\FullSurface\ApiBatch17ExportColumnLevelSecurityContractTest + ✓ export field selection cannot request secrets or cross scope column… 0.11s + + PASS Tests\Feature\Api\V1\FullSurface\ApiBatch17ExternalIdAndNaturalKeyCollisionContractTest + ✓ external ids student numbers and emails are not cross domain author… 0.10s + + PASS Tests\Feature\Api\V1\FullSurface\ApiBatch17FinancialPeriodCloseAndAdjustmentContractTest + ✓ closed period adjustments writeoffs and credit transfers are guarde… 0.12s + + PASS Tests\Feature\Api\V1\FullSurface\ApiBatch17InventoryAssetCustodyContractTest + ✓ inventory asset custody transfers and disposal are not client autho… 0.07s + + PASS Tests\Feature\Api\V1\FullSurface\ApiBatch17MultiGuardBoundaryContractTest + ✓ api guard boundaries are not crossed by session or web identity 0.11s + + PASS Tests\Feature\Api\V1\FullSurface\ApiBatch17PartialFailureErrorDetailRedactionContractTest + ✓ bulk partial failure details are actionable without leaking databas… 0.08s + + PASS Tests\Feature\Api\V1\FullSurface\ApiBatch17PerResourceRateLimitIdentityContractTest + ✓ repeated sensitive actions are scoped by actor resource and operati… 0.16s + + PASS Tests\Feature\Api\V1\FullSurface\ApiBatch17RegressionOmegaSweepTest + ✓ batch17 omega sweep combines headers payloads queries and route par… 0.08s + + PASS Tests\Feature\Api\V1\FullSurface\ApiBatch17SearchRankingAndPermissionFilterContractTest + ✓ search autocomplete and lookup do not bypass permission filters 0.19s + + PASS Tests\Feature\Api\V1\FullSurface\ApiBatch17StudentIdentityMergeSplitContractTest + ✓ merge split and duplicate student identity routes reject unsafe pay… 0.07s + + PASS Tests\Feature\Api\V1\FullSurface\ApiBatch17ZeroTrustInternalHeaderContractTest + ✓ internal proxy and service headers do not grant privilege 0.10s + + PASS Tests\Feature\Api\V1\FullSurface\ApiBatch18ApiKeyServiceAccountAndMachineIdentityContractTest + ✓ batch18 apikeyserviceaccountandmachineidentity stays controlled 0.12s + + PASS Tests\Feature\Api\V1\FullSurface\ApiBatch18CanonicalIdentifierImmutabilityContractTest + ✓ batch18 canonicalidentifierimmutability stays controlled 0.17s + + PASS Tests\Feature\Api\V1\FullSurface\ApiBatch18ClassCapacityWaitlistAndScheduleConflictContractTest + ✓ batch18 classcapacitywaitlistandscheduleconflict stays controlled 0.18s + + PASS Tests\Feature\Api\V1\FullSurface\ApiBatch18ConsentRevocationAndCommunicationComplianceContractTest + ✓ batch18 consentrevocationandcommunicationcompliance stays controlle… 0.14s + + PASS Tests\Feature\Api\V1\FullSurface\ApiBatch18CrossModuleBusinessInvariantRegisterTest + ✓ batch18 business invariant route families remain present 0.05s + + PASS Tests\Feature\Api\V1\FullSurface\ApiBatch18ExportWatermarkAndAuditabilityContractTest + ✓ batch18 exportwatermarkandauditability stays controlled 0.12s + + PASS Tests\Feature\Api\V1\FullSurface\ApiBatch18FeatureEntitlementAndLicenseBoundaryContractTest + ✓ batch18 featureentitlementandlicenseboundary stays controlled 0.18s + + PASS Tests\Feature\Api\V1\FullSurface\ApiBatch18FileVirusScanAndQuarantineContractTest + ✓ batch18 filevirusscanandquarantine stays controlled 0.09s + + PASS Tests\Feature\Api\V1\FullSurface\ApiBatch18FinanceChargebackDisputeContractTest + ✓ batch18 financechargebackdispute stays controlled 0.09s + + FAIL Tests\Feature\Api\V1\FullSurface\ApiBatch18OrphanedRecordAndCascadeBoundaryContractTest + ⨯ batch18 orphanedrecordandcascadeboundary stays controlled 0.24s + + PASS Tests\Feature\Api\V1\FullSurface\ApiBatch18PrivilegeBoundaryAfterRoleMutationContractTest + ✓ batch18 privilegeboundaryafterrolemutation stays controlled 0.12s + + PASS Tests\Feature\Api\V1\FullSurface\ApiBatch18RegressionFinalitySweepTest + ✓ batch18 combined hostile payload sweep stays controlled 0.20s + + PASS Tests\Feature\Api\V1\FullSurface\ApiBatch18ReportDrillthroughAndRowLevelSecurityContractTest + ✓ batch18 reportdrillthroughandrowlevelsecurity stays controlled 0.10s + + PASS Tests\Feature\Api\V1\FullSurface\ApiBatch18StudentMedicalAndSafetyDataMinimizationContractTest + ✓ batch18 studentmedicalandsafetydataminimization stays controlled 0.15s + + FAIL Tests\Feature\Api\V1\FullSurface\ApiBatch18TemporalAuditAndTimezoneForgeryContractTest + ⨯ batch18 temporalauditandtimezoneforgery stays controlled 0.10s + + PASS Tests\Feature\Api\V1\FullSurface\ApiBatch18TwoPersonApprovalAndSegregationContractTest + ✓ batch18 twopersonapprovalandsegregation stays controlled 0.14s + + PASS Tests\Feature\Api\V1\FullSurface\ApiBatch18WebhookOrderingAndOutOfSequenceContractTest + ✓ batch18 webhookorderingandoutofsequence stays controlled 0.06s + + PASS Tests\Feature\Api\V1\FullSurface\ApiBatch19AggregateDashboardScopeContractTest + ✓ batch19 aggregate dashboard scope stays controlled 0.18s + + PASS Tests\Feature\Api\V1\FullSurface\ApiBatch19AppendOnlyAuditLedgerContractTest + ✓ batch19 append only audit ledger stays controlled 0.19s + + PASS Tests\Feature\Api\V1\FullSurface\ApiBatch19AttendanceExcuseDocumentLifecycleContractTest + ✓ batch19 attendance excuse document lifecycle stays controlled 0.34s + + PASS Tests\Feature\Api\V1\FullSurface\ApiBatch19AttributeBasedAccessConditionContractTest + ✓ batch19 attribute based access condition stays controlled 0.13s + + PASS Tests\Feature\Api\V1\FullSurface\ApiBatch19BackupRestoreIsolationContractTest + ✓ batch19 backup restore isolation stays controlled 0.08s + + PASS Tests\Feature\Api\V1\FullSurface\ApiBatch19ClassTransferTranscriptContinuityContractTest + ✓ batch19 class transfer transcript continuity stays controlled 0.18s + + PASS Tests\Feature\Api\V1\FullSurface\ApiBatch19CommunicationBounceAndSuppressionWebhookContractTest + ✓ batch19 communication bounce and suppression webhook stays controll… 0.16s + + PASS Tests\Feature\Api\V1\FullSurface\ApiBatch19CustodyRestrictionPickupAuthorizationContractTest + ✓ batch19 custody restriction pickup authorization stays controlled 0.18s + + PASS Tests\Feature\Api\V1\FullSurface\ApiBatch19NestedRelationshipRedactionContractTest + ✓ batch19 nested relationship redaction stays controlled 0.17s + + PASS Tests\Feature\Api\V1\FullSurface\ApiBatch19OperationalAndPrivacyInvariantRegisterTest + ✓ batch19 operational and privacy route families remain present 0.05s + + PASS Tests\Feature\Api\V1\FullSurface\ApiBatch19PaymentAllocationAndBalanceContractTest + ✓ batch19 payment allocation and balance stays controlled 0.18s + + PASS Tests\Feature\Api\V1\FullSurface\ApiBatch19RefundMethodAndSettlementBoundaryContractTest + ✓ batch19 refund method and settlement boundary stays controlled 0.30s + + PASS Tests\Feature\Api\V1\FullSurface\ApiBatch19RegressionContinuitySweepTest + ✓ batch19 continuity and privacy sweep stays controlled 0.42s + + PASS Tests\Feature\Api\V1\FullSurface\ApiBatch19ReportCacheInvalidationContractTest + ✓ batch19 report cache invalidation stays controlled 0.18s + + PASS Tests\Feature\Api\V1\FullSurface\ApiBatch19RevokedDeletedUserTokenBoundaryContractTest + ✓ batch19 revoked deleted user token boundary stays controlled 0.17s + + PASS Tests\Feature\Api\V1\FullSurface\ApiBatch19TeacherSubstitutionCoverageContractTest + ✓ batch19 teacher substitution coverage stays controlled 0.21s + + PASS Tests\Feature\Api\V1\FullSurface\ApiBatch19TemporaryUrlExpirationRevocationContractTest + ✓ batch19 temporary url expiration revocation stays controlled 0.09s + + PASS Tests\Feature\Api\V1\FullSurface\ApiBatch19ThirdPartySyncCanonicalizationContractTest + ✓ batch19 third party sync canonicalization stays controlled 0.17s + + PASS Tests\Feature\Api\V1\FullSurface\ApiBatch20AdminAuditExportRedactionContractTest + ✓ batch20 admin audit export redaction stays controlled 0.14s + + PASS Tests\Feature\Api\V1\FullSurface\ApiBatch20ApiSunsetDeprecationAndCompatibilityContractTest + ✓ batch20 api sunset deprecation and compatibility stays controlled 0.14s + + PASS Tests\Feature\Api\V1\FullSurface\ApiBatch20AttendanceGeofenceAndDeviceTrustContractTest + ✓ batch20 attendance geofence and device trust stays controlled 0.13s + + PASS Tests\Feature\Api\V1\FullSurface\ApiBatch20CashDrawerManualPaymentIntegrityContractTest + ✓ batch20 cash drawer manual payment integrity stays controlled 0.20s + + PASS Tests\Feature\Api\V1\FullSurface\ApiBatch20ClassCapacityLotteryAndWaitlistContractTest + ✓ batch20 class capacity lottery and waitlist stays controlled 0.37s + + PASS Tests\Feature\Api\V1\FullSurface\ApiBatch20ContinuityComplianceRiskRegisterTest + ✓ batch20 continuity and compliance route families remain visible 0.05s + + PASS Tests\Feature\Api\V1\FullSurface\ApiBatch20DataWarehouseAnalyticsExportContractTest + ✓ batch20 data warehouse analytics export stays controlled 0.20s + + PASS Tests\Feature\Api\V1\FullSurface\ApiBatch20EmergencyClosureBroadcastContractTest + ✓ batch20 emergency closure broadcast stays controlled 0.14s + + PASS Tests\Feature\Api\V1\FullSurface\ApiBatch20GradebookLockAndAmendmentContractTest + ✓ batch20 gradebook lock and amendment stays controlled 0.21s + + FAIL Tests\Feature\Api\V1\FullSurface\ApiBatch20LegalHoldRetentionAndPurgeConflictContractTest + ⨯ batch20 legal hold retention and purge conflict stays controlled 0.05s + + PASS Tests\Feature\Api\V1\FullSurface\ApiBatch20MultilingualContentAndTranslationContractTest + ✓ batch20 multilingual content and translation stays controlled 0.11s + + PASS Tests\Feature\Api\V1\FullSurface\ApiBatch20NotificationDeadLetterAndRetryContractTest + ✓ batch20 notification dead letter and retry stays controlled 0.11s + + PASS Tests\Feature\Api\V1\FullSurface\ApiBatch20ParentDisputeAndCustodyReviewContractTest + ✓ batch20 parent dispute and custody review stays controlled 0.17s + + PASS Tests\Feature\Api\V1\FullSurface\ApiBatch20ReceiptNumberingAndTaxDocumentIntegrityContractTest + ✓ batch20 receipt numbering and tax document integrity stays controll… 0.18s + + FAIL Tests\Feature\Api\V1\FullSurface\ApiBatch20RegressionContinuityComplianceSweepTest + ⨯ batch20 continuity compliance and export sweep stays controlled 0.28s + + PASS Tests\Feature\Api\V1\FullSurface\ApiBatch20ScholarshipRenewalAndEligibilityContractTest + ✓ batch20 scholarship renewal and eligibility stays controlled 0.21s + + PASS Tests\Feature\Api\V1\FullSurface\ApiBatch20SiblingFamilyDiscountAbuseContractTest + ✓ batch20 sibling family discount abuse stays controlled 0.20s + + PASS Tests\Feature\Api\V1\FullSurface\ApiBatch20SyntheticMonitoringAndHealthProbeContractTest + ✓ batch20 synthetic monitoring and health probe stays controlled 0.07s + + PASS Tests\Feature\Api\V1\FullSurface\ApiBatch20TransportationPickupRouteSafetyContractTest + ✓ batch20 transportation pickup route safety stays controlled 0.12s + + PASS Tests\Feature\Api\V1\FullSurface\ApiBatch20WebhookSecretRotationContractTest + ✓ batch20 webhook secret rotation stays controlled 0.09s + + PASS Tests\Feature\Api\V1\FullSurface\ApiBulkImportExportAndPartialFailureExpansionTest + ✓ bulk routes handle mixed valid and invalid ids cleanly 0.08s + ✓ import routes reject wrong file types with validation not crashes 0.05s + ✓ export download routes do not return mutating statuses 0.09s + + PASS Tests\Feature\Api\V1\FullSurface\ApiBusinessRuleEdgeCaseContractTest + ✓ school year semester and class mismatch payloads fail without crash… 0.16s + ✓ financial amount rules reject zero negative and precision abuse cle… 0.35s + ✓ attendance status and time edge cases are controlled 0.41s + + PASS Tests\Feature\Api\V1\FullSurface\ApiCacheFreshnessAndConditionalRequestContractTest + ✓ private authenticated resources are not publicly cacheable 0.17s + ✓ conditional headers do not bypass authorization or return wrong use… 0.07s + + PASS Tests\Feature\Api\V1\FullSurface\ApiCalendarScheduleConflictContractTest + ✓ calendar event and school schedule routes handle conflicts and inva… 0.07s + ✓ calendar list routes tolerate window queries and do not leak unscop… 0.09s + + PASS Tests\Feature\Api\V1\FullSurface\ApiClientCompatibilityVersioningContractTest + ✓ publicly registered api routes remain versioned or explicitly legac… 0.04s + ✓ route names are unique enough for client generation 0.05s + ✓ legacy and current auth contracts return compatible failure shapes 0.05s + + FAIL Tests\Feature\Api\V1\FullSurface\ApiConcurrencyAndStaleWriteContractTest + ⨯ duplicate update payloads remain controlled and do not throw server… 0.07s + ✓ stale if match headers do not force successful mutations 0.08s + + PASS Tests\Feature\Api\V1\FullSurface\ApiContentNegotiationAndMediaTypeContractTest + ✓ json accept header receives controlled api responses across major d… 0.14s + ✓ unsupported accept headers do not trigger server errors 0.09s + ✓ malformed content type for mutations fails cleanly 0.11s + + PASS Tests\Feature\Api\V1\FullSurface\ApiContractCoverageHeatmapExpansionTest + ✓ every major route family has a meaningful contract probe bucket 0.05s + ✓ mutating route surface is not accidentally unowned by contract suit… 0.04s + + PASS Tests\Feature\Api\V1\FullSurface\ApiContractSnapshotSeedTest + ✓ core success payloads keep contract keys when available 0.07s + ✓ auth identity payload never drops user identity when successful 0.04s + + PASS Tests\Feature\Api\V1\FullSurface\ApiCrossModuleReferentialWorkflowExpansionTest + ✓ wrong but existing ids across modules do not silently cross link re… 0.18s + + PASS Tests\Feature\Api\V1\FullSurface\ApiCrossVersionRouteCompatibilityMatrixTest + ✓ v1 and unversioned auth routes keep failure contract compatible 0.06s + ✓ legacy routes do not expand beyond documented aliases silently 0.04s + + PASS Tests\Feature\Api\V1\FullSurface\ApiCsvExcelFormulaInjectionContractTest + ✓ exportable and importable text fields handle excel formula payloads 0.67s + + PASS Tests\Feature\Api\V1\FullSurface\ApiDataExportLeastPrivilegeContractTest + ✓ export and download routes do not grant low privilege bulk access 0.12s + ✓ export filters respect actor scope parameters 0.10s + + PASS Tests\Feature\Api\V1\FullSurface\ApiDataMinimizationByRoleContractTest + ✓ parent and student responses do not expose back office finance or a… 0.19s + + PASS Tests\Feature\Api\V1\FullSurface\ApiDataShapeBackwardCompatibilityContractTest + ✓ collection endpoints keep backward compatible envelope keys 0.19s + ✓ successful detail endpoints keep identifier or data keys 0.13s + + FAIL Tests\Feature\Api\V1\FullSurface\ApiDatabaseTransactionRollbackContractTest + ✓ multi step mutations do not leave obvious partial records after val… 0.17s + ⨯ delete failures do not remove parent or student fixtures 0.25s + + FAIL Tests\Feature\Api\V1\FullSurface\ApiDateMoneyAndTimezoneBoundaryContractTest + ⨯ date accepting endpoints reject impossible or ambiguous dates clean… 0.25s + ✓ money accepting endpoints reject negative nan and overflow amounts… 0.50s + + PASS Tests\Feature\Api\V1\FullSurface\ApiDeepAuthorizationIsolationMatrixTest + ✓ role isolation matrix blocks cross portal access for sensitive surf… 0.26s + ✓ owner scoped parent routes do not expose another family student 0.07s + + PASS Tests\Feature\Api\V1\FullSurface\ApiDeepDocumentationAndRouteParityContractTest + ✓ every named api route has a stable route name or explicit public ex… 0.05s + ✓ openapi or docs catalog endpoint is reachable and route table remai… 0.06s + ✓ route use case catalog covers new deep contract domains 0.04s + + PASS Tests\Feature\Api\V1\FullSurface\ApiDeepFileImportExportAndPrintableContractTest + ✓ export download and printable routes are controlled for authenticat… 0.10s + ✓ import upload routes accept test files or return validation without… 0.05s + + PASS Tests\Feature\Api\V1\FullSurface\ApiDeepIdempotencyAndDuplicateSubmissionContractTest + ✓ duplicate sensitive mutations do not create uncontrolled server err… 0.19s + ✓ repeat delete or archive requests are safe to retry or fail cleanly 0.11s + + PASS Tests\Feature\Api\V1\FullSurface\ApiDeepPaginationSearchAndFilterContractTest + ✓ list endpoints tolerate pagination search sort and filter parameter… 0.46s + ✓ date range filters fail cleanly when dates are invalid 0.17s + + PASS Tests\Feature\Api\V1\FullSurface\ApiDeepResponseShapeAndEnvelopeContractTest + ✓ successful json api responses use parseable json envelopes across m… 0.19s + ✓ collection endpoints expose list like payloads or explicit empty st… 0.45s + + PASS Tests\Feature\Api\V1\FullSurface\ApiDeepStateTransitionInvariantContractTest + ✓ school year close reopen and promotion transition routes preserve c… 0.06s + ✓ finance transition routes do not allow negative balance crashes or… 0.06s + ✓ attendance transition routes keep single day student context contro… 0.05s + + PASS Tests\Feature\Api\V1\FullSurface\ApiDeepValidationFailureContractTest + ✓ mutating routes return controlled validation or authorization for h… 0.50s + ✓ required field validation uses machine readable error shape when va… 0.08s + + FAIL Tests\Feature\Api\V1\FullSurface\ApiDestructiveActionSafeguardContractTest + ✓ delete routes handle missing and foreign ids without crashing 0.08s + ✓ bulk delete style routes require explicit targets 0.06s + ⨯ archive remove cancel and void routes are idempotent or conflict sa… 0.07s + + PASS Tests\Feature\Api\V1\FullSurface\ApiEmptyDatasetAndNullStateContractTest + ✓ list endpoints return stable empty shapes when filters match nothin… 0.07s + ✓ current school year null state is handled without crash 0.06s + ✓ empty class roster and attendance context are controlled 0.06s + + FAIL Tests\Feature\Api\V1\FullSurface\ApiEnumAndStateMachineContractTest + ⨯ status fields reject unknown states without defaulting to success 0.18s + ✓ terminal states are not reopened by low privilege users 0.06s + + FAIL Tests\Feature\Api\V1\FullSurface\ApiErrorEnvelopeConsistencyContractTest + ✓ not found api responses are json or controlled redirects 0.05s + ✓ validation error envelopes have machine readable fields 0.12s + ⨯ authorization error envelopes do not leak stack traces 0.05s + + PASS Tests\Feature\Api\V1\FullSurface\ApiEtagConditionalMutationContractTest + ✓ mutating routes do not succeed silently with stale conditional head… 0.13s + + PASS Tests\Feature\Api\V1\FullSurface\ApiFailureModeResilienceExpansionTest + ✓ mutation routes fail cleanly when required relationships are null 0.17s + ✓ mutation routes fail cleanly when relationships are strings instead… 0.17s + + PASS Tests\Feature\Api\V1\FullSurface\ApiFamilyPortalFullSurfaceContractTest + ✓ family portal surface has controlled contracts and privacy boundari… 0.08s + + FAIL Tests\Feature\Api\V1\FullSurface\ApiFeatureFlagAndConfigurationDriftContractTest + ⨯ feature flagged routes fail closed when configuration is missing or… 0.11s + ✓ configuration mutations reject unrecognized or privileged keys from… 0.08s + + PASS Tests\Feature\Api\V1\FullSurface\ApiFileMediaMetadataSafetyContractTest + ✓ upload routes reject misleading metadata and path names cleanly 0.05s + ✓ download routes do not accept path traversal identifiers 0.08s + + PASS Tests\Feature\Api\V1\FullSurface\ApiFinanceInventoryCommunicationsFullSurfaceContractTest + ✓ back office and communications surfaces have controlled contracts 0.14s + + PASS Tests\Feature\Api\V1\FullSurface\ApiFrontendBackendContractParityTest + ✓ frontend identity and api identity do not drift apart 0.06s + ✓ login aliases return compatible token and user contracts 0.05s + ✓ frontend bootstrap routes do not require admin privilege when they… 0.05s + + PASS Tests\Feature\Api\V1\FullSurface\ApiFullSurfaceEndToEndContractTest + ✓ every registered api route has a controlled e2e contract response 0.77s + ✓ all mutating api routes reject empty or malformed payloads without… 0.58s + ✓ portal routes enforce wrong actor boundaries across the full surfac… 0.05s + + PASS Tests\Feature\Api\V1\FullSurface\ApiHtmlJavaScriptEscapingContractTest + ✓ text fields accept or reject script payloads without reflecting exe… 0.21s + + PASS Tests\Feature\Api\V1\FullSurface\ApiHttpSemanticsAndMethodSafetyContractTest + ✓ get routes do not accept mutating payloads as state changes 0.19s + ✓ wrong methods fail with controlled statuses not framework explosion… 0.11s + ✓ delete routes do not require json body to be safe 0.07s + + PASS Tests\Feature\Api\V1\FullSurface\ApiIdempotencyScopeAndReplayContractTest + ✓ same idempotency key cannot be replayed across unrelated routes to… 0.24s + ✓ idempotency keys with control characters are rejected or ignored cl… 0.12s + + WARN Tests\Feature\Api\V1\FullSurface\ApiImpersonationDelegationAndActingAsContractTest + ! impersonation and delegation routes are admin only and auditable →… 0.05s + + PASS Tests\Feature\Api\V1\FullSurface\ApiImportTemplateAndCsvContractTest + ✓ import routes reject malformed csv rows without server errors 0.05s + ✓ template download routes are not public when templates include priv… 0.07s + + PASS Tests\Feature\Api\V1\FullSurface\ApiLegacyCurrentAliasParityExpansionTest + ✓ auth aliases return compatible login shapes 0.06s + ✓ legacy teacher aliases and current v1 teacher routes have compatibl… 0.06s + ✓ legacy non versioned routes do not drift into 5xx 0.05s + + PASS Tests\Feature\Api\V1\FullSurface\ApiLocalizationAndLocaleFallbackContractTest + ✓ supported and unsupported accept language headers stay controlled 0.53s + ✓ timezone parameters do not corrupt attendance or finance queries 0.59s + + PASS Tests\Feature\Api\V1\FullSurface\ApiMassAssignmentAndOverpostingContractTest + ✓ write endpoints ignore or reject privilege escalation fields 0.41s + ✓ parent and teacher cannot overpost owner ids to reassign records 0.30s + + FAIL Tests\Feature\Api\V1\FullSurface\ApiMigrationSafeDefaultContractTest + ✓ core routes survive missing optional configuration rows 0.09s + ⨯ routes handle missing optional school year context with controlled… 0.07s + + PASS Tests\Feature\Api\V1\FullSurface\ApiMobileClientToleranceContractTest + ✓ api routes handle mobile headers without contract drift 0.16s + ✓ api routes handle offline retry headers without duplicate server er… 0.19s + + PASS Tests\Feature\Api\V1\FullSurface\ApiModelLifecycleInvariantExpansionTest + ✓ create update show index lifecycle routes remain controlled for cor… 0.21s + ✓ identity fields are not overwritten by update payloads 0.30s + + PASS Tests\Feature\Api\V1\FullSurface\ApiMutationReadAfterWriteConsistencyContractTest + ✓ created resources return identifier or location to support follow u… 0.28s + ✓ update successes preserve resource identity when identity is presen… 0.30s + + PASS Tests\Feature\Api\V1\FullSurface\ApiNestedPayloadAndArrayAbuseContractTest + ✓ mutation routes fail cleanly for deeply nested payloads 0.15s + ✓ mutation routes fail cleanly for large sparse arrays 0.22s + + FAIL Tests\Feature\Api\V1\FullSurface\ApiNotificationMessagingDeliveryContractTest + ✓ message notification and broadcast routes validate recipients and c… 0.08s + ⨯ read archive star and delete message actions are idempotent 0.05s + + PASS Tests\Feature\Api\V1\FullSurface\ApiNotificationPreferenceAndOptOutContractTest + ✓ notification preference routes validate channels recipients and opt… 0.18s + ✓ low privilege users cannot broadcast notifications to everyone 0.05s + + PASS Tests\Feature\Api\V1\FullSurface\ApiNullBooleanAndTypeCoercionContractTest + ✓ mutation routes handle null false zero and string booleans without… 0.20s + + PASS Tests\Feature\Api\V1\FullSurface\ApiObservabilityRequestIdAndLoggingContractTest + ✓ api accepts correlation ids without echoing unsafe values 0.18s + ✓ malformed request ids do not break error handling 0.05s + + PASS Tests\Feature\Api\V1\FullSurface\ApiOpenApiDocumentationDriftContractTest + ✓ api surface has documentation entry points and route inventory rema… 0.06s + ✓ named api routes use stable names when names exist 0.04s + ✓ documented routes do not point to missing actions 0.04s + + PASS Tests\Feature\Api\V1\FullSurface\ApiOpenRedirectAndReturnUrlContractTest + ✓ login and navigation routes do not accept external return urls 0.09s + ✓ redirect like query parameters do not poison get responses 0.12s + + PASS Tests\Feature\Api\V1\FullSurface\ApiOperationalEndpointExposureContractTest + ✓ operational debug and maintenance routes are not publicly exposed w… 0.05s + + PASS Tests\Feature\Api\V1\FullSurface\ApiOperationalResiliencePayloadSizeContractTest + ✓ mutating routes reject huge payloads and deep arrays without memory… 0.50s + ✓ get routes reject abusive include expand and field lists cleanly 0.16s + + PASS Tests\Feature\Api\V1\FullSurface\ApiOwnerBoundaryAndPrivacyExpansionTest + ✓ parent family endpoints do not expose other parent records 0.06s + ✓ teacher class endpoints do not expose unassigned class records 0.07s + ✓ serialized users do not leak sensitive auth material 0.06s + + PASS Tests\Feature\Api\V1\FullSurface\ApiPaginationCursorAndOffsetAbuseContractTest + ✓ list routes handle cursor offset and per page abuse without crashin… 0.26s + + PASS Tests\Feature\Api\V1\FullSurface\ApiPermissionMatrixExhaustiveContractTest + ✓ core domain permission matrix is enforced across roles 0.06s + ✓ admin only mutations are not available to lower roles 0.06s + ✓ student role cannot access parent teacher or admin portals 0.05s + + FAIL Tests\Feature\Api\V1\FullSurface\ApiPolicyAuthorizationDiscoveryContractTest + ⨯ protected mutation routes are not publicly mutable 0.06s + ✓ permission like routes reject wildcards from non admins 0.05s + + PASS Tests\Feature\Api\V1\FullSurface\ApiPolymorphicOwnershipBoundaryContractTest + ✓ owner type and owner id fields cannot be overposted by low privileg… 0.08s + ✓ cross actor owner queries do not return private data 0.06s + + PASS Tests\Feature\Api\V1\FullSurface\ApiPrivacyRetentionAndErasureContractTest + ✓ erasure archive and privacy routes are never publicly mutable 0.05s + ✓ privacy related exports do not leak sensitive user fields 0.09s + + FAIL Tests\Feature\Api\V1\FullSurface\ApiPublicAndAuthFullSurfaceContractTest + ⨯ public and auth surface has stable contracts 0.04s + + PASS Tests\Feature\Api\V1\FullSurface\ApiPublicPrivateCacheSeparationContractTest + ✓ authenticated private routes do not emit public cache headers 0.13s + ✓ conditional cache headers do not bypass authorization 0.07s + + PASS Tests\Feature\Api\V1\FullSurface\ApiQueryParameterFuzzingContractTest + ✓ collection endpoints handle hostile query parameters without 5xx 0.11s + ✓ date range endpoints reject inverted or impossible ranges cleanly 0.07s + ✓ sorting contract does not allow raw sql fragments 0.06s + + PASS Tests\Feature\Api\V1\FullSurface\ApiQueueJobAndAsyncTriggerContractTest + ✓ async trigger routes are admin or owner scoped and fail cleanly 0.08s + ✓ async triggers tolerate duplicate client request ids 0.09s + + PASS Tests\Feature\Api\V1\FullSurface\ApiRateLimitTokenAndSessionHardeningContractTest + ✓ repeated bad login attempts stay controlled and never return a toke… 0.08s + ✓ expired or garbage bearer tokens are rejected without fallback iden… 0.10s + ✓ logout is safe to repeat and does not leak token state 0.04s + + FAIL Tests\Feature\Api\V1\FullSurface\ApiReferentialIntegrityAndForeignKeyContractTest + ⨯ mutations with missing foreign keys fail cleanly not with database… 0.06s + ✓ delete routes for parent records protect children or fail cleanly 0.05s + + PASS Tests\Feature\Api\V1\FullSurface\ApiRelationshipCardinalityContractTest + ✓ routes expect single ids do not crash when receiving arrays or obje… 0.19s + + PASS Tests\Feature\Api\V1\FullSurface\ApiReportConsistencyAndAggregationExpansionTest + ✓ report routes handle date window filter and group by combinations 0.27s + ✓ parent and teacher report access is scoped not global 0.12s + + PASS Tests\Feature\Api\V1\FullSurface\ApiReportExportPrivacyAndAggregationContractTest + ✓ teacher and parent report exports are scoped to their assignments 0.11s + ✓ aggregate dashboard numbers do not include other family details for… 0.07s + + FAIL Tests\Feature\Api\V1\FullSurface\ApiReportMathAndFinancialInvariantContractTest + ✓ financial endpoints reject non decimal and currency confusion input… 0.34s + ⨯ report filters do not create negative or impossible aggregation win… 0.11s + + FAIL Tests\Feature\Api\V1\FullSurface\ApiRequestHeaderSpoofingContractTest + ⨯ forwarded and override headers do not bypass authorization 0.05s + + FAIL Tests\Feature\Api\V1\FullSurface\ApiRoleWorkflowNegativeMatrixContractTest + ✓ each non admin actor is blocked from administrative mutations 0.18s + ⨯ actor specific read routes do not collapse into admin visible data 0.04s + ✓ suspended disabled or unverified users do not gain api access 0.08s + + FAIL Tests\Feature\Api\V1\FullSurface\ApiRouteNamingVersioningAndHygieneTest + ✓ api routes do not use debug or temporary names 0.05s + ⨯ versioned api routes stay inside v1 or documented legacy aliases 0.05s + ✓ duplicate uri method pairs do not exist 0.04s + ✓ route placeholders use consistent identifier names 0.04s + + FAIL Tests\Feature\Api\V1\FullSurface\ApiRouteParameterAbuseContractTest + ⨯ parameterized routes reject path traversal and script values cleanl… 0.05s + ⨯ parameterized routes fail cleanly for overflowing integer ids 0.10s + + FAIL Tests\Feature\Api\V1\FullSurface\ApiRouteUseCaseCatalogCompletenessTest + ⨯ every api route is owned by an explicit user journey 0.02s + ✓ each declared journey has at least one registered route 0.01s + + FAIL Tests\Feature\Api\V1\FullSurface\ApiSchemaKeyStabilityExpansionContractTest + ⨯ core resource success payloads keep identity and display keys 0.06s + ✓ error payloads keep client actionable fields 0.37s + + FAIL Tests\Feature\Api\V1\FullSurface\ApiSchoolCalendarAcademicBoundaryExpansionTest + ✓ academic routes reject dates outside school year without server err… 0.57s + ⨯ semester and term values are not free form privilege channels 0.07s + + FAIL Tests\Feature\Api\V1\FullSurface\ApiSchoolOperationsRegressionBackstopTest + ⨯ administrator can probe core school operations without route level… 0.11s + ✓ user facing portals have at least one reachable read contract per a… 0.21s + + PASS Tests\Feature\Api\V1\FullSurface\ApiSearchIndexAndAutocompleteContractTest + ✓ search autocomplete and lookup routes handle empty short and hostil… 0.08s + ✓ cross domain search does not bypass role scope 0.05s + + FAIL Tests\Feature\Api\V1\FullSurface\ApiSecurityAndTransportContractTest + ⨯ authenticated api routes do not accept plain browser session assump… 0.06s + ⨯ state changing api routes reject wrong http method cleanly 0.05s + ✓ options preflight for major domains is controlled 0.04s + + PASS Tests\Feature\Api\V1\FullSurface\ApiSerializationSensitiveDataRedactionContractTest + ✓ successful api responses never serialize sensitive user or payment… 0.19s + ✓ error responses do not echo credentials or uploaded file contents 0.09s + + FAIL Tests\Feature\Api\V1\FullSurface\ApiSoftDeleteRestoreArchiveLifecycleContractTest + ⨯ archive restore and unarchive routes are controlled and role protec… 0.06s + ⨯ destructive soft delete style routes tolerate repeated requests 0.05s + + PASS Tests\Feature\Api\V1\FullSurface\ApiSortingFieldSelectionAndIncludeContractTest + ✓ list routes handle sort fields includes and sparse fieldsets 0.64s + + FAIL Tests\Feature\Api\V1\FullSurface\ApiTenantSchoolYearAndSemesterIsolationContractTest + ⨯ school year scoped routes reject foreign or closed school year cont… 0.08s + ✓ cross school year filters do not return unscoped private data 0.11s + + FAIL Tests\Feature\Api\V1\FullSurface\ApiTimezoneCalendarRecurrenceDepthContractTest + ⨯ calendar and schedule routes reject ambiguous recurrence and timezo… 0.15s + + PASS Tests\Feature\Api\V1\FullSurface\ApiUnicodeNormalizationAndInputContractTest + ✓ text inputs accept or reject unicode cleanly without corrupting jso… 0.15s + ✓ emails and phone fields reject visually confusable values cleanly 0.09s + + PASS Tests\Feature\Api\V1\FullSurface\ApiUrlFetchSsrfAndCallbackSafetyContractTest + ✓ url accepting routes reject internal network targets cleanly 0.16s + + PASS Tests\Feature\Api\V1\FullSurface\ApiWebhookExternalProviderAndCallbackContractTest + ✓ external callback routes reject unsigned or malformed payloads 0.05s + ✓ external provider status routes never expose provider secrets 0.07s + + PASS Tests\Feature\Api\V1\FullSurface\ApiWebhookReplayAndSignatureDepthContractTest + ✓ external callback routes reject missing bad and replayed signatures… 0.05s + + FAIL Tests\Feature\Api\V1\FullSurface\ApiWriteAuditAndTimestampContractTest + ⨯ successful create responses expose identifier or resource envelope 0.13s + ✓ successful write responses do not emit broken timestamp fields 0.11s + ⨯ audit like routes are not publicly mutable 0.05s + + PASS Tests\Feature\Api\V1\Grading\GradingControllerTest + ✓ overview returns grading data 0.02s + ✓ toggle lock locks section 0.03s + + PASS Tests\Feature\Api\V1\Grading\HomeworkTrackingControllerTest + ✓ index returns tracking payload 0.02s + + PASS Tests\Feature\Api\V1\Incidents\IncidentControllerTest + ✓ current returns incidents and grades 0.02s + ✓ store and close moves incident to history 0.02s + + PASS Tests\Feature\Api\V1\Inventory\InventoryCategoriesControllerTest + ✓ index returns categories 0.02s + ✓ store creates category 0.02s + ✓ update changes category 0.02s + ✓ destroy deletes category 0.02s + ✓ validation fails 0.02s + + PASS Tests\Feature\Api\V1\Inventory\InventoryItemsControllerTest + ✓ index returns items 0.03s + ✓ show returns item 0.02s + ✓ store creates item 0.02s + ✓ update changes item 0.02s + ✓ destroy deletes item 0.01s + ✓ audit updates classroom item 0.02s + ✓ adjust creates movement 0.02s + ✓ summary returns aggregates 0.02s + ✓ summary all returns rows 0.02s + ✓ teacher distribution endpoints 0.02s + ✓ validation fails for store 0.02s + ✓ requires authentication 0.02s + + PASS Tests\Feature\Api\V1\Inventory\InventoryMovementsControllerTest + ✓ index returns movements 0.02s + ✓ store creates movement 0.02s + ✓ update changes movement 0.02s + ✓ destroy deletes movement 0.01s + ✓ bulk delete removes movements 0.02s + + PASS Tests\Feature\Api\V1\Inventory\SuppliersControllerTest + ✓ index returns suppliers 0.02s + ✓ store creates supplier 0.02s + ✓ update changes supplier 0.02s + ✓ destroy deletes supplier 0.02s + + PASS Tests\Feature\Api\V1\Inventory\SupplyCategoriesControllerTest + ✓ index returns categories 0.02s + ✓ store creates category 0.02s + ✓ update changes category 0.01s + ✓ destroy deletes category 0.02s + + PASS Tests\Feature\Api\V1\Messaging\MessagesControllerTest + ✓ inbox requires auth 0.01s + ✓ store creates message 0.03s + ✓ show marks read 0.02s + ✓ update changes status 0.02s + ✓ destroy marks trashed 0.02s + ✓ recipients teacher returns list 0.02s + ✓ validation rejects missing subject 0.02s + ✓ show forbidden for other users 0.02s + + PASS Tests\Feature\Api\V1\Notifications\NotificationControllerTest + ✓ index requires authentication 0.02s + ✓ index returns notifications 0.02s + ✓ show returns notification 0.02s + ✓ store creates notification 0.02s + ✓ store validates payload 0.02s + ✓ store handles service exception 0.02s + ✓ mark read updates user notification 0.02s + ✓ active and deleted lists 0.02s + ✓ update and delete notification 0.02s + ✓ restore notification 0.02s + + FAIL Tests\Feature\Api\V1\Parents\AuthorizedUsersControllerTest + ✓ index requires authentication 0.02s + ✓ index is forbidden for non parent users 0.03s + ⨯ index returns only the parents own authorized users 0.03s + ✓ show returns 404 for unknown authorized user 0.03s + ✓ show returns 404 for another parents authorized user 0.03s + ✓ destroy deletes the parents authorized user 0.02s + ✓ parent cannot delete another parents authorized user 0.03s + + FAIL Tests\Feature\Api\V1\Parents\ParentAttendanceReportControllerTest + ⨯ form returns students and sundays 0.02s + ⨯ submit creates report and attendance 0.02s + ⨯ check existing returns rows 0.02s + ⨯ update report updates reason 0.01s + + FAIL Tests\Feature\Api\V1\Parents\ParentControllerTest + ⨯ attendance returns rows 0.02s + ⨯ registration creates student and contact 0.02s + + PASS Tests\Feature\Api\V1\PrintRequests\PrintRequestsWorkflowTest + ✓ teacher can create hand copy request and admin can advance statuses 0.03s + ✓ admin status rejects invalid transition 0.02s + ✓ teacher routes reject non teacher roles and admin routes reject tea… 0.02s + ✓ teacher cannot update delete or download another teachers request 0.02s + ✓ teacher cannot delete request after processing has started 0.01s + ✓ upload requires valid file and page selection format 0.01s + ✓ teacher can upload and download own file and admin can download any… 0.02s + + PASS Tests\Feature\Api\V1\Promotions\ParentPromotionControllerTest + ✓ overview returns actionable records for parent 0.02s + ✓ parent completes full enrollment flow 0.03s + ✓ parent cannot view other parents promotion 0.02s + ✓ unauthenticated request is unauthorized 0.01s + + PASS Tests\Feature\Api\V1\Public\PublicWinnersControllerTest + ✓ competition index is public and returns published competitions 0.02s + ✓ competition index returns empty collection when none published 0.01s + ✓ competition show returns payload for published competition 0.01s + ✓ competition show returns 404 for unknown competition 0.02s + ✓ competition show returns 404 for unpublished competition 0.01s + + PASS Tests\Feature\Api\V1\Reports\FilesControllerTest + ✓ receipt meta returns file payload 0.02s + ✓ exam draft teacher streams with download name 0.02s + + PASS Tests\Feature\Api\V1\Reports\ReportCardsControllerTest + ✓ meta returns expected payload 0.02s + ✓ completeness returns summary and students 0.03s + ✓ acknowledgement returns record 0.02s + ✓ student report returns pdf 0.03s + ✓ class report returns pdf 0.02s + ✓ student report returns error when missing scores 0.02s + ✓ completeness requires class section id 0.02s + ✓ acknowledgement requires student id 0.02s + ✓ requires authentication 0.01s + + PASS Tests\Feature\Api\V1\Reports\SlipPrinterControllerTest + ✓ preview returns text 0.03s + ✓ print creates log and returns pdf 0.06s + ✓ logs returns rows 0.02s + + PASS Tests\Feature\Api\V1\Reports\StickersControllerTest + ✓ form data returns classes students and presets 0.02s + ✓ students by class returns students 0.02s + ✓ print returns pdf 0.02s + ✓ print validation rejects missing selection 0.02s + ✓ requires authentication 0.01s + + FAIL Tests\Feature\Api\V1\Roles\RolePermissionControllerTest + ✓ roles index returns roles 0.02s + ✓ store role creates role 0.02s + ✓ update role updates role 0.02s + ✓ delete role removes role 0.02s + ✓ users index returns users with roles 0.02s + ✓ assign roles updates user roles 0.02s + ✓ permissions crud 0.02s + ✓ role permissions update 0.01s + ✓ validation rejects invalid role payload 0.01s + ⨯ store role returns error on service exception 0.02s + ✓ requires authentication 0.01s + + PASS Tests\Feature\Api\V1\Roles\RoleSwitcherControllerTest + ✓ index returns roles 0.03s + ✓ switch sets role 0.02s + ✓ requires authentication 0.01s + ✓ switch rejects role that user does not have 0.02s + ✓ switch validates empty role payload 0.02s + ✓ index returns not found when authenticated user has no roles 0.02s + + PASS Tests\Feature\Api\V1\ScannerControllerTest + ✓ process requires a badge code 0.02s + ✓ process returns 404 for unknown badge 0.01s + ✓ process accepts alternative badge field names 0.01s + + FAIL Tests\Feature\Api\V1\SchoolYears\SchoolYearControllerTest + ⨯ preview close returns promotion and balance preview 0.03s + ✓ parent cannot close school year 0.02s + ✓ school year closure routes have explicit permission middleware 0.01s + ⨯ admin can create draft school year via api 0.02s + ⨯ admin can update draft school year via api 0.02s + ⨯ close school year creates new active year enrollment and balance tr… 0.02s + ⨯ closed school year blocks legacy invoice generation 0.02s + + PASS Tests\Feature\Api\V1\Scores\FinalControllerTest + ✓ index returns final scores 0.02s + + PASS Tests\Feature\Api\V1\Scores\HomeworkControllerTest + ✓ index returns homework scores 0.03s + + PASS Tests\Feature\Api\V1\Scores\MidtermControllerTest + ✓ index returns midterm scores 0.02s + + PASS Tests\Feature\Api\V1\Scores\ParticipationControllerTest + ✓ index returns participation scores 0.03s + + PASS Tests\Feature\Api\V1\Scores\ProjectControllerTest + ✓ index returns project scores 0.02s + + PASS Tests\Feature\Api\V1\Scores\QuizControllerTest + ✓ index returns quiz scores 0.03s + + PASS Tests\Feature\Api\V1\Scores\ScoreCommentControllerTest + ✓ store rejects short comment 0.02s + ✓ index returns comments 0.02s + + PASS Tests\Feature\Api\V1\Scores\ScoreControllerTest + ✓ overview returns students 0.02s + ✓ lock creates grading lock 0.02s + + PASS Tests\Feature\Api\V1\Scores\ScorePredictorControllerTest + ✓ index returns predictions 0.02s + + PASS Tests\Feature\Api\V1\Settings\ConfigurationControllerTest + ✓ index returns configs 0.02s + ✓ store creates config 0.02s + + PASS Tests\Feature\Api\V1\Settings\EventControllerTest + ✓ index requires authentication 0.02s + ✓ index returns events 0.02s + ✓ store creates event 0.02s + ✓ store requires authentication 0.02s + ✓ store validates payload 0.02s + ✓ store handles service exception 0.02s + ✓ update updates event 0.02s + ✓ destroy deletes event 0.02s + ✓ charges list returns data 0.02s + ✓ update charges updates participation 0.02s + ✓ students with charges returns students 0.02s + + PASS Tests\Feature\Api\V1\Settings\PolicyControllerTest + ✓ school policy endpoint returns payload 0.02s + ✓ picture policy endpoint returns payload 0.01s + + FAIL Tests\Feature\Api\V1\Settings\PreferencesControllerTest + ⨯ show returns defaults 0.02s + ⨯ store creates preferences 0.02s + ⨯ list requires admin 0.02s + ⨯ list returns rows for admin 0.02s + ⨯ update for user by admin 0.02s + ⨯ destroy requires admin 0.01s + ⨯ destroy deletes preferences 0.01s + ⨯ store validates payload 0.02s + + FAIL Tests\Feature\Api\V1\Settings\SchoolCalendarControllerTest + ✓ options returns event types and defaults 0.02s + ✓ index returns events and meetings 0.02s + ✓ show returns event 0.02s + ✓ store creates event 0.02s + ⨯ update updates event 0.02s + ✓ destroy deletes event 0.02s + ✓ store validation rejects invalid payload 0.02s + ⨯ store returns error on service exception 0.01s + ✓ requires authentication 0.02s + + PASS Tests\Feature\Api\V1\Settings\SettingsControllerTest + ✓ index requires admin 0.02s + ✓ index returns settings 0.02s + ✓ update validation rejects bad email 0.02s + ✓ update persists settings 0.02s + + PASS Tests\Feature\Api\V1\Staff\StaffControllerTest + ✓ index requires admin 0.02s + ✓ index returns staff 0.02s + ✓ store creates staff 0.02s + ✓ store validation 0.02s + ✓ update modifies staff 0.02s + ✓ destroy deletes staff 0.02s + + PASS Tests\Feature\Api\V1\Students\StudentControllerTest + ✓ assign and remove class 0.03s + ✓ score card returns rows 0.02s + ✓ store creates emergency contact for first parent 0.02s + ✓ index returns students without parent filter 0.02s + + PASS Tests\Feature\Api\V1\Subjects\SubjectCurriculumControllerTest + ✓ index returns entries 0.02s + ✓ store creates entry 0.02s + + PASS Tests\Feature\Api\V1\Support\ContactControllerTest + ✓ send requires valid payload 0.01s + ✓ send returns success 0.02s + + PASS Tests\Feature\Api\V1\Support\SupportControllerTest + ✓ index requires auth 0.01s + ✓ index returns requests 0.02s + ✓ store validation 0.02s + ✓ store creates request 0.02s + + PASS Tests\Feature\Api\V1\System\DashboardControllerTest + ✓ route requires authentication 0.02s + ✓ route returns dashboard for role 0.02s + + PASS Tests\Feature\Api\V1\System\DatabaseHealthControllerTest + ✓ db check returns ok 0.01s + + FAIL Tests\Feature\Api\V1\System\HealthControllerTest + ⨯ health returns payload 0.02s + + FAIL Tests\Feature\Api\V1\System\NavBuilderControllerTest + ✓ menu returns items for roles 0.02s + ✓ data requires admin 0.02s + ✓ store creates nav item 0.02s + ⨯ delete removes nav item 0.02s + ⨯ reorder updates items 0.01s + + FAIL Tests\Feature\Api\V1\System\SchoolIdControllerTest + ✓ generate student returns id 0.02s + ✓ generate user returns id 0.02s + ⨯ assign sets user school id 0.02s + + PASS Tests\Feature\Api\V1\System\SemesterRangeControllerTest + ✓ school year range uses config dates 0.02s + ✓ resolve returns semester for date 0.02s + + PASS Tests\Feature\Api\V1\System\StatsControllerTest + ✓ stats require authentication 0.02s + ✓ stats index returns rows for authenticated user 0.02s + ✓ stats index returns empty array when no stats 0.01s + + PASS Tests\Feature\Api\V1\Teachers\TeacherControllerTest + ✓ classes returns students and assignments 0.02s + ✓ switch class returns active id 0.02s + ✓ absence submit creates staff attendance 0.03s + + PASS Tests\Feature\Api\V1\Ui\UiControllerTest + ✓ style requires auth 0.01s + ✓ style updates preferences 0.02s + + PASS Tests\Feature\Api\V1\Users\UserControllerTest + ✓ user list returns users with roles 0.03s + ✓ create user creates user and role 0.02s + ✓ login activity returns paginated results 0.02s + + PASS Tests\Feature\Api\V1\Utilities\PhoneFormatterControllerTest + ✓ format returns formatted phone 0.02s + ✓ format rejects invalid number 0.02s + ✓ format validates payload 0.02s + + PASS Tests\Feature\Api\V1\Utilities\ProofreadControllerTest + ✓ proofread requires authentication 0.01s + ✓ proofread rejects empty text 0.01s + ✓ proofread rejects text that is too long 0.02s + ✓ proofread proxies languagetool and returns result 0.04s + ✓ proofread returns 502 when upstream fails 0.01s + + FAIL Tests\Feature\Api\V1\Whatsapp\WhatsappInviteControllerTest + ✓ parent contacts endpoint returns contacts 0.02s + ✓ parent contacts by class endpoint returns sections 0.02s + ✓ send invites returns success when listener registered 0.02s + ⨯ send invites returns error when no listener 0.02s + ✓ membership update saves record 0.02s + ✓ send invites validation rejects payload 0.01s + + PASS Tests\Feature\Api\V1\Whatsapp\WhatsappLinkControllerTest + ✓ index returns paginated links 0.02s + ✓ show returns single link 0.02s + ✓ store creates link 0.02s + ✓ update updates link 0.02s + ✓ destroy deletes link 0.01s + ✓ store validation rejects invalid payload 0.01s + ✓ requires authentication 0.02s + + FAIL Tests\Feature\Api\V1\Workflows\ScenarioAFamilyEnrollmentTest + ⨯ admin onboards family through active enrollment 0.05s + ⨯ parent cannot update unrelated student 0.05s + + FAIL Tests\Feature\Api\V1\Workflows\ScenarioBSundaySchoolDayTest + ⨯ teacher submits attendance and parent views report 0.03s + ✓ teacher cannot submit attendance for unassigned class 0.05s + ✓ admin views daily attendance summary 0.04s + + PASS Tests\Feature\Api\V1\Workflows\ScenarioCAcademicTermTest + ✓ teacher enters scores admin locks grading and report card is genera… 0.05s + ✓ teacher invalid homework score is rejected 0.03s + + PASS Tests\Feature\Api\V1\Workflows\ScenarioDFamilyBillingTest + ✓ admin runs invoice discount payment and reporting workflow 0.06s + + PASS Tests\Feature\Api\V1\Workflows\ScenarioEFinanceEdgeTest + ✓ admin carries forward balance and manages installments 0.06s + + PASS Tests\Feature\Api\V1\Workflows\ScenarioFTeacherSubmissionTest + ✓ admin detects missing submission and notifies teacher 0.05s + ✓ duplicate notify requires valid payload 0.03s + + PASS Tests\Feature\Api\V1\Workflows\ScenarioGPrintBadgeTest + ✓ print request badge log and scan workflow 0.05s + + PASS Tests\Feature\Api\V1\Workflows\ScenarioHSecurityUnauthorizedAccessTest + ✓ cross role and anonymous access is blocked 0.07s + + PASS Tests\Feature\Api\V1\Workflows\ScenarioIPublicAuthAndSystemUseCaseTest + ✓ guest can use public content contact and health endpoints without a… 0.02s + ✓ user can login read current profile and logout through api 0.03s + ✓ invalid inactive and suspended login paths fail safely 0.03s + + PASS Tests\Feature\Api\V1\Workflows\ScenarioJCrossModuleApiUseCaseSmokeTest + ✓ admin can reach core operational dashboards without server errors 0.07s + ✓ major mutating use cases validate bad payloads instead of crashing 0.06s + + FAIL Tests\Feature\Api\V1\Workflows\ScenarioKParentSelfServiceAndPrivacyTest + ✓ parent reviews household data and updates contact details 0.05s + ⨯ parent cannot mutate another family student or emergency contact 0.04s + + FAIL Tests\Feature\Api\V1\Workflows\ScenarioLTeacherAcademicOperationsTest + ⨯ teacher manages class progress and homework scores end to end 0.05s + ✓ unassigned teacher cannot view or update another teachers progress… 0.05s + + FAIL Tests\Feature\Api\V1\Workflows\ScenarioMAdministratorEnrollmentAndClassOperationsTest + ⨯ admin builds classroom roster from parent registration to teacher a… 0.05s + ✓ admin can reverse roster and teacher assignments without orphaning… 0.05s + + FAIL Tests\Feature\Api\V1\Workflows\ScenarioNCommunicationsAndSupportLifecycleTest + ⨯ parent and teacher exchange message and read state is preserved 0.03s + ⨯ public contact support ticket and admin support queue are connected 0.02s + + PASS Tests\Feature\Api\V1\Workflows\ScenarioOInventoryFinanceAndAuditControlsTest + ✓ admin tracks inventory item from creation to adjustment and summary 0.04s + ✓ finance followup records notes promises and resolution for unpaid p… 0.05s + + FAIL Tests\Feature\Api\V1\Workflows\ScenarioPSettingsConfigurationAndCalendarGovernanceTest + ✓ admin manages calendar event configuration and notification lifecyc… 0.03s + ⨯ configuration admin crud keeps school year context explicit 0.03s + + PASS Tests\Feature\Api\V1\Workflows\ScenarioQSchoolYearPromotionClosureLifecycleTest + ✓ admin and parent work through promotion before year close 0.04s + ✓ admin previews closes and reopens school year with balance transfer… 0.04s + + FAIL Tests\Feature\Api\V1\Workflows\ScenarioRAttendanceOperationsAndExceptionHandlingTest + ⨯ teacher admin and staff handle attendance day end to end 0.05s + ⨯ early dismissal late slip and violation tracking are connected 0.05s + ⨯ attendance comment templates support create update delete and legac… 0.03s + + FAIL Tests\Feature\Api\V1\Workflows\ScenarioSScoringGradingAndReportCardLifecycleTest + ⨯ teacher records every score type and admin reviews grading outputs 0.06s + ⨯ grading locks and below sixty intervention are visible and mutable 0.05s + + FAIL Tests\Feature\Api\V1\Workflows\ScenarioTDocumentsPrintBadgesAndCertificatesLifecycleTest + ⨯ teacher print request moves from upload to admin status and file ac… 0.05s + ✓ badges stickers slips and certificates are generated or validated w… 0.14s + + PASS Tests\Feature\Api\V1\Workflows\ScenarioUFinanceBillingPaymentRefundAndInstallmentLifecycleTest + ✓ admin generates invoice records payment transaction and receipt not… 0.06s + ✓ admin creates installment plan refund and balance carryforward deci… 0.05s + + PASS Tests\Feature\Api\V1\Workflows\ScenarioVProcurementReimbursementAndSupplyLifecycleTest + ✓ admin manages suppliers supply categories purchase order and receip… 0.03s + ✓ reimbursement request batch lock export and mark donation flow 0.03s + + FAIL Tests\Feature\Api\V1\Workflows\ScenarioWAccessControlRolesNavigationAndPreferencesTest + ⨯ admin creates role permission assigns user and builds navigation 0.04s + ⨯ user preferences and role switcher preserve selected context 0.03s + ✓ non admin cannot manage role permissions or admin nav builder 0.02s + + FAIL Tests\Feature\Api\V1\Workflows\ScenarioXPublicKioskScannerAndVerificationLifecycleTest + ✓ public content documentation and policy endpoints are reachable wit… 0.04s + ✓ badge scan and scanner process known and unknown codes safely 0.04s + ⨯ public verification and invite tokens fail closed for invalid value… 0.01s + + PASS Tests\Feature\Api\V1\Workflows\ScenarioYFamilyGuardianAuthorizedUserAndWhatsappLifecycleTest + ✓ admin builds family links and manages guardian flags 0.05s + ✓ parent authorized user invite and household privacy flow 0.04s + + FAIL Tests\Feature\Api\V1\Workflows\ScenarioZLegacyAliasesValidationAndCompatibilityTest + ✓ legacy teacher aliases match modern teacher and score surfaces 0.07s + ✓ legacy post aliases validate payloads without 500s 0.06s + ⨯ validation errors are structured for representative public and auth… 0.01s + ⨯ legacy redirects and non versioned auth aliases remain available 0.01s + + FAIL Tests\Feature\Api\V1\Workflows\StudentEnrollmentWorkflowTest + ✓ admin creates account adds student and enrolls them 0.04s + ⨯ admin can withdraw an enrolled student 0.03s + ✓ creating a user requires a valid role 0.03s + ✓ student registration requires first child contact details 0.02s + + FAIL Tests\Feature\BulkUserRoleCreationTest + ⨯ it creates one thousand parents teachers and admins through the ap… 11.44s + + PASS Tests\Feature\Console\AttendanceCommandsTest + ✓ attendance auto publish command runs 0.03s + ✓ attendance recalculate summary command runs 0.01s + ✓ attendance absentees summary command runs 0.01s + ✓ attendance lates summary command runs 0.01s + + PASS Tests\Feature\Console\DeleteUnverifiedUsersCommandTest + ✓ command dispatches event for expired user 0.02s + + PASS Tests\Feature\Console\PaymentsCommandsTest + ✓ check missed payments command runs 0.01s + ✓ monthly reminder command sends to email 0.01s + ✓ send test payment notification command runs 0.01s + ✓ sync paypal payments command runs 0.01s + + PASS Tests\Feature\Console\SystemCommandsTest + ✓ cleanup expired notifications command runs 0.01s + ✓ cleanup password resets command runs 0.01s + ✓ config update command runs 0.01s + ✓ delete inactive users command runs 0.01s + + PASS Tests\Feature\HealthEndpointTest + ✓ health endpoint is reachable 0.03s + + PASS Tests\Feature\Middleware\RequirePermissionMiddlewareTest + ✓ denies when missing permission 0.03s + ✓ allows when permission assigned 0.02s + + PASS Tests\Feature\TeacherAbsenceVacationRouteTest + ✓ authenticated teacher absence vacation route redirects to spa page 0.02s + ✓ authenticated legacy teacher absence vacation route redirects to sp… 0.02s + + PASS Tests\Feature\Web\AdminCalendarPageTest + ✓ admin calendar view lists school calendar events for selected year 0.02s + + PASS Tests\Feature\Web\SchoolYearAdminPageTest + ✓ admin can view school year page 0.02s + ✓ admin can create draft school year from page 0.02s + ──────────────────────────────────────────────────────────────────────────── + FAILED Tests\Unit\ApiDocsServiceTest > public boo… ClassIsFinalException + Class "App\Services\ApplicationUrlService" is declared "final" and cannot be doubled + + at tests/Unit/ApiDocsServiceTest.php:14 + 10▕ class ApiDocsServiceTest extends TestCase + 11▕ { + 12▕ private function docsService(): ApiDocsService + 13▕ { + ➜ 14▕ $urls = $this->createMock(ApplicationUrlService::class); + 15▕ $urls->method('docsSwaggerMergedJsonUrl')->with(false)->willReturn('/api/documentation/swagger.json'); + 16▕ + 17▕ return new ApiDocsService($urls); + 18▕ } + + 1 tests/Unit/ApiDocsServiceTest.php:14 + 2 tests/Unit/ApiDocsServiceTest.php:22 + + ──────────────────────────────────────────────────────────────────────────── + FAILED Tests\Unit\ApiDocsServiceTest > full boots… ClassIsFinalException + Class "App\Services\ApplicationUrlService" is declared "final" and cannot be doubled + + at tests/Unit/ApiDocsServiceTest.php:14 + 10▕ class ApiDocsServiceTest extends TestCase + 11▕ { + 12▕ private function docsService(): ApiDocsService + 13▕ { + ➜ 14▕ $urls = $this->createMock(ApplicationUrlService::class); + 15▕ $urls->method('docsSwaggerMergedJsonUrl')->with(false)->willReturn('/api/documentation/swagger.json'); + 16▕ + 17▕ return new ApiDocsService($urls); + 18▕ } + + 1 tests/Unit/ApiDocsServiceTest.php:14 + 2 tests/Unit/ApiDocsServiceTest.php:39 + + ──────────────────────────────────────────────────────────────────────────── + FAILED Tests\Unit\ApiLoginSecurityServiceTes… BindingResolutionException + Target class [config] does not exist. + + at vendor/laravel/framework/src/Illuminate/Container/Container.php:1124 + 1120▕ + 1121▕ try { + 1122▕ $reflector = new ReflectionClass($concrete); + 1123▕ } catch (ReflectionException $e) { + ➜ 1124▕ throw new BindingResolutionException("Target class [$concrete] does not exist.", 0, $e); + 1125▕ } + 1126▕ + 1127▕ // If the type is not instantiable, the developer is attempting to resolve + 1128▕ // an abstract type such as an Interface or Abstract Class and there is + + +7 vendor frames  + 8 app/Services/Auth/ApiLoginSecurityService.php:148 + 9 tests/Unit/ApiLoginSecurityServiceTest.php:43 + + ──────────────────────────────────────────────────────────────────────────── + FAILED Tests\Unit\ApiLoginSecurityServiceTes… BindingResolutionException + Target class [config] does not exist. + + at vendor/laravel/framework/src/Illuminate/Container/Container.php:1124 + 1120▕ + 1121▕ try { + 1122▕ $reflector = new ReflectionClass($concrete); + 1123▕ } catch (ReflectionException $e) { + ➜ 1124▕ throw new BindingResolutionException("Target class [$concrete] does not exist.", 0, $e); + 1125▕ } + 1126▕ + 1127▕ // If the type is not instantiable, the developer is attempting to resolve + 1128▕ // an abstract type such as an Interface or Abstract Class and there is + + +7 vendor frames  + 8 app/Services/Auth/ApiLoginSecurityService.php:148 + 9 tests/Unit/ApiLoginSecurityServiceTest.php:76 + + ──────────────────────────────────────────────────────────────────────────── + FAILED Tests\Unit\Models\AttendanceEmailTemplateTest > g… QueryException + SQLSTATE[HY000]: General error: 1 table email_templates has no column named created_at (Connection: sqlite, Database: :memory:, SQL: insert into "email_templates" ("code", "variant", "subject", "body_html", "is_active", "updated_at", "created_at") values (attendance_absent, default, Default Subject,

Default

, 1, 2026-07-05 22:09:15, 2026-07-05 22:09:15)) + + at vendor/laravel/framework/src/Illuminate/Database/Connection.php:838 + 834▕ $exceptionType = $this->isUniqueConstraintError($e) + 835▕ ? UniqueConstraintViolationException::class + 836▕ : QueryException::class; + 837▕ + ➜ 838▕ throw new $exceptionType( + 839▕ $this->getNameWithReadWriteType(), + 840▕ $query, + 841▕ $this->prepareBindings($bindings), + 842▕ $e, + + +16 vendor frames  + 17 tests/Unit/Models/AttendanceEmailTemplateTest.php:15 + + ──────────────────────────────────────────────────────────────────────────── + FAILED Tests\Unit\Models\AttendanceEmailTemplateTest > g… QueryException + SQLSTATE[HY000]: General error: 1 table email_templates has no column named created_at (Connection: sqlite, Database: :memory:, SQL: insert into "email_templates" ("code", "variant", "subject", "body_html", "is_active", "updated_at", "created_at") values (attendance_late, default, Late Default,

Late default

, 1, 2026-07-05 22:09:15, 2026-07-05 22:09:15)) + + at vendor/laravel/framework/src/Illuminate/Database/Connection.php:838 + 834▕ $exceptionType = $this->isUniqueConstraintError($e) + 835▕ ? UniqueConstraintViolationException::class + 836▕ : QueryException::class; + 837▕ + ➜ 838▕ throw new $exceptionType( + 839▕ $this->getNameWithReadWriteType(), + 840▕ $query, + 841▕ $this->prepareBindings($bindings), + 842▕ $e, + + +16 vendor frames  + 17 tests/Unit/Models/AttendanceEmailTemplateTest.php:40 + + ──────────────────────────────────────────────────────────────────────────── + FAILED Tests\Unit\Models\AttendanceEmailTemplateTest > g… QueryException + SQLSTATE[HY000]: General error: 1 table email_templates has no column named created_at (Connection: sqlite, Database: :memory:, SQL: insert into "email_templates" ("code", "variant", "subject", "body_html", "is_active", "updated_at", "created_at") values (attendance_present, no_answer, Inactive SMS,

Inactive

, 0, 2026-07-05 22:09:15, 2026-07-05 22:09:15)) + + at vendor/laravel/framework/src/Illuminate/Database/Connection.php:838 + 834▕ $exceptionType = $this->isUniqueConstraintError($e) + 835▕ ? UniqueConstraintViolationException::class + 836▕ : QueryException::class; + 837▕ + ➜ 838▕ throw new $exceptionType( + 839▕ $this->getNameWithReadWriteType(), + 840▕ $query, + 841▕ $this->prepareBindings($bindings), + 842▕ $e, + + +16 vendor frames  + 17 tests/Unit/Models/AttendanceEmailTemplateTest.php:57 + + ──────────────────────────────────────────────────────────────────────────── + FAILED Tests\Unit\Models\AttendanceEmailTemplateTest > g… QueryException + SQLSTATE[HY000]: General error: 1 table email_templates has no column named created_at (Connection: sqlite, Database: :memory:, SQL: insert into "email_templates" ("code", "variant", "subject", "body_html", "is_active", "updated_at", "created_at") values (attendance_unknown, default, Inactive Default,

Inactive

, 0, 2026-07-05 22:09:15, 2026-07-05 22:09:15)) + + at vendor/laravel/framework/src/Illuminate/Database/Connection.php:838 + 834▕ $exceptionType = $this->isUniqueConstraintError($e) + 835▕ ? UniqueConstraintViolationException::class + 836▕ : QueryException::class; + 837▕ + ➜ 838▕ throw new $exceptionType( + 839▕ $this->getNameWithReadWriteType(), + 840▕ $query, + 841▕ $this->prepareBindings($bindings), + 842▕ $e, + + +16 vendor frames  + 17 tests/Unit/Models/AttendanceEmailTemplateTest.php:82 + + ──────────────────────────────────────────────────────────────────────────── + FAILED Tests\Unit\Models\ClassPrepAdjustmentTest > model metadata is con… + Failed asserting that true is identical to false. + + at tests/Unit/Models/ClassPrepAdjustmentTest.php:16 + 12▕ $model = new ClassPrepAdjustment; + 13▕ + 14▕ $this->assertSame('class_prep_adjustments', $model->getTable()); + 15▕ $this->assertSame('id', $model->getKeyName()); + ➜ 16▕ $this->assertSame(false, $model->timestamps); + 17▕ $this->assertSame(['class_section_id', 'item_name', 'adjustment', 'adjustable', 'school_year', 'created_at'], $model->getFillable()); + 18▕ } + 19▕ + 20▕ public function test_model_class_loads(): void + + 1 tests/Unit/Models/ClassPrepAdjustmentTest.php:16 + + ──────────────────────────────────────────────────────────────────────────── + FAILED Tests\Unit\Models\ClassPreparationLogTest > model metadata is con… + Failed asserting that true is identical to false. + + at tests/Unit/Models/ClassPreparationLogTest.php:16 + 12▕ $model = new ClassPreparationLog; + 13▕ + 14▕ $this->assertSame('class_preparation_log', $model->getTable()); + 15▕ $this->assertSame('id', $model->getKeyName()); + ➜ 16▕ $this->assertSame(false, $model->timestamps); + 17▕ $this->assertSame(['class_section_id', 'class_section', 'school_year', 'prep_data', 'created_at'], $model->getFillable()); + 18▕ } + 19▕ + 20▕ public function test_model_class_loads(): void + + 1 tests/Unit/Models/ClassPreparationLogTest.php:16 + + ──────────────────────────────────────────────────────────────────────────── + FAILED Tests\Unit\Models\CommunicationLogTest > model metadata is conver… + Failed asserting that true is identical to false. + + at tests/Unit/Models/CommunicationLogTest.php:16 + 12▕ $model = new CommunicationLog; + 13▕ + 14▕ $this->assertSame('communication_logs', $model->getTable()); + 15▕ $this->assertSame('id', $model->getKeyName()); + ➜ 16▕ $this->assertSame(false, $model->timestamps); + 17▕ $this->assertSame(['student_id', 'family_id', 'student_name', 'template_key', 'subject', 'body', 'recipients', 'cc', 'bcc', 'attachments', 'status', 'error_message', 'sent_by', 'metadata'], $model->getFillable()); + 18▕ } + 19▕ + 20▕ public function test_model_class_loads(): void + + 1 tests/Unit/Models/CommunicationLogTest.php:16 + + ──────────────────────────────────────────────────────────────────────────── + FAILED Tests\Unit\EmailTemplateTest > get template retur… QueryException + SQLSTATE[HY000]: General error: 1 table email_templates has no column named created_at (Connection: sqlite, Database: :memory:, SQL: insert into "email_templates" ("code", "variant", "subject", "body_html", "is_active", "updated_at", "created_at") values (attendance_absent, default, Default Subject,

Default

, 1, 2026-07-05 22:09:15, 2026-07-05 22:09:15)) + + at vendor/laravel/framework/src/Illuminate/Database/Connection.php:838 + 834▕ $exceptionType = $this->isUniqueConstraintError($e) + 835▕ ? UniqueConstraintViolationException::class + 836▕ : QueryException::class; + 837▕ + ➜ 838▕ throw new $exceptionType( + 839▕ $this->getNameWithReadWriteType(), + 840▕ $query, + 841▕ $this->prepareBindings($bindings), + 842▕ $e, + + +16 vendor frames  + 17 tests/Unit/Models/EmailTemplateTest.php:15 + + ──────────────────────────────────────────────────────────────────────────── + FAILED Tests\Unit\EmailTemplateTest > get template falls… QueryException + SQLSTATE[HY000]: General error: 1 table email_templates has no column named created_at (Connection: sqlite, Database: :memory:, SQL: insert into "email_templates" ("code", "variant", "subject", "body_html", "is_active", "updated_at", "created_at") values (attendance_late, default, Late Default,

Late default

, 1, 2026-07-05 22:09:16, 2026-07-05 22:09:16)) + + at vendor/laravel/framework/src/Illuminate/Database/Connection.php:838 + 834▕ $exceptionType = $this->isUniqueConstraintError($e) + 835▕ ? UniqueConstraintViolationException::class + 836▕ : QueryException::class; + 837▕ + ➜ 838▕ throw new $exceptionType( + 839▕ $this->getNameWithReadWriteType(), + 840▕ $query, + 841▕ $this->prepareBindings($bindings), + 842▕ $e, + + +16 vendor frames  + 17 tests/Unit/Models/EmailTemplateTest.php:42 + + ──────────────────────────────────────────────────────────────────────────── + FAILED Tests\Unit\EmailTemplateTest > get template ignor… QueryException + SQLSTATE[HY000]: General error: 1 table email_templates has no column named created_at (Connection: sqlite, Database: :memory:, SQL: insert into "email_templates" ("code", "variant", "subject", "body_html", "is_active", "updated_at", "created_at") values (attendance_present, default, Present Default,

Present

, 0, 2026-07-05 22:09:16, 2026-07-05 22:09:16)) + + at vendor/laravel/framework/src/Illuminate/Database/Connection.php:838 + 834▕ $exceptionType = $this->isUniqueConstraintError($e) + 835▕ ? UniqueConstraintViolationException::class + 836▕ : QueryException::class; + 837▕ + ➜ 838▕ throw new $exceptionType( + 839▕ $this->getNameWithReadWriteType(), + 840▕ $query, + 841▕ $this->prepareBindings($bindings), + 842▕ $e, + + +16 vendor frames  + 17 tests/Unit/Models/EmailTemplateTest.php:60 + + ──────────────────────────────────────────────────────────────────────────── + FAILED Tests\Unit\EmailTemplateTest > get template prefe… QueryException + SQLSTATE[HY000]: General error: 1 table email_templates has no column named created_at (Connection: sqlite, Database: :memory:, SQL: insert into "email_templates" ("code", "variant", "subject", "body_html", "is_active", "updated_at", "created_at") values (attendance_notice, default, Default Notice,

Default

, 1, 2026-07-05 22:09:16, 2026-07-05 22:09:16)) + + at vendor/laravel/framework/src/Illuminate/Database/Connection.php:838 + 834▕ $exceptionType = $this->isUniqueConstraintError($e) + 835▕ ? UniqueConstraintViolationException::class + 836▕ : QueryException::class; + 837▕ + ➜ 838▕ throw new $exceptionType( + 839▕ $this->getNameWithReadWriteType(), + 840▕ $query, + 841▕ $this->prepareBindings($bindings), + 842▕ $e, + + +16 vendor frames  + 17 tests/Unit/Models/EmailTemplateTest.php:76 + + ──────────────────────────────────────────────────────────────────────────── + FAILED Tests\Unit\Models\EventChargesTest > model metadata is converted + Failed asserting that two arrays are identical. + Array &0 [ + 0 => 'event_id', + - 1 => 'parent_id', + - 2 => 'student_id', + - 3 => 'participation', + - 4 => 'charged', + - 5 => 'semester', + - 6 => 'school_year', + - 7 => 'updated_by', + - 8 => 'created_at', + - 9 => 'updated_at', + + 1 => 'event_name', + + 2 => 'description', + + 3 => 'amount', + + 4 => 'parent_id', + + 5 => 'student_id', + + 6 => 'participation', + + 7 => 'charged', + + 8 => 'semester', + + 9 => 'school_year', + + 10 => 'updated_by', + + 11 => 'created_at', + + 12 => 'updated_at', + ] + + + at tests/Unit/Models/EventChargesTest.php:17 + 13▕ + 14▕ $this->assertSame('event_charges', $model->getTable()); + 15▕ $this->assertSame('id', $model->getKeyName()); + 16▕ $this->assertSame(true, $model->timestamps); + ➜ 17▕ $this->assertSame(['event_id', 'parent_id', 'student_id', 'participation', 'charged', 'semester', 'school_year', 'updated_by', 'created_at', 'updated_at'], $model->getFillable()); + 18▕ } + 19▕ + 20▕ public function test_model_class_loads(): void + 21▕ { + + 1 tests/Unit/Models/EventChargesTest.php:17 + + ──────────────────────────────────────────────────────────────────────────── + FAILED Tests\Unit\Models\ExamTest > model metadata is converted + Failed asserting that true is identical to false. + + at tests/Unit/Models/ExamTest.php:16 + 12▕ $model = new Exam; + 13▕ + 14▕ $this->assertSame('exams', $model->getTable()); + 15▕ $this->assertSame('id', $model->getKeyName()); + ➜ 16▕ $this->assertSame(false, $model->timestamps); + 17▕ $this->assertSame(['student_id', 'student_school_id', 'class_section_id', 'exam_name', 'created_at'], $model->getFillable()); + 18▕ } + 19▕ + 20▕ public function test_model_class_loads(): void + + 1 tests/Unit/Models/ExamTest.php:16 + + ──────────────────────────────────────────────────────────────────────────── + FAILED Tests\Unit\Models\FinalExamTest > model metadata is converted + Failed asserting that false is identical to true. + + at tests/Unit/Models/FinalExamTest.php:16 + 12▕ $model = new FinalExam; + 13▕ + 14▕ $this->assertSame('final_exam', $model->getTable()); + 15▕ $this->assertSame('id', $model->getKeyName()); + ➜ 16▕ $this->assertSame(true, $model->timestamps); + 17▕ $this->assertSame(['student_id', 'school_id', 'class_section_id', 'updated_by', 'score', 'semester', 'school_year', 'created_at', 'updated_at'], $model->getFillable()); + 18▕ } + 19▕ + 20▕ public function test_model_class_loads(): void + + 1 tests/Unit/Models/FinalExamTest.php:16 + + ──────────────────────────────────────────────────────────────────────────── + FAILED Tests\Unit\Models\HomeworkTest > model metadata is converted + Failed asserting that false is identical to true. + + at tests/Unit/Models/HomeworkTest.php:16 + 12▕ $model = new Homework; + 13▕ + 14▕ $this->assertSame('homework', $model->getTable()); + 15▕ $this->assertSame('id', $model->getKeyName()); + ➜ 16▕ $this->assertSame(true, $model->timestamps); + 17▕ $this->assertSame(['student_id', 'school_id', 'class_section_id', 'updated_by', 'homework_index', 'score', 'comment', 'semester', 'school_year', 'created_at', 'updated_at'], $model->getFillable()); + 18▕ } + 19▕ + 20▕ public function test_model_class_loads(): void + + 1 tests/Unit/Models/HomeworkTest.php:16 + + ──────────────────────────────────────────────────────────────────────────── + FAILED Tests\Unit\Models\InvoiceTest > model metadata is converted + Failed asserting that false is identical to true. + + at tests/Unit/Models/InvoiceTest.php:16 + 12▕ $model = new Invoice; + 13▕ + 14▕ $this->assertSame('invoices', $model->getTable()); + 15▕ $this->assertSame('id', $model->getKeyName()); + ➜ 16▕ $this->assertSame(true, $model->timestamps); + 17▕ $this->assertSame(['parent_id', 'invoice_number', 'total_amount', 'balance', 'paid_amount', 'has_discount', 'issue_date', 'due_date', 'status', 'description', 'school_year', 'created_at', 'updated_at', 'updated_by', 'semester'], $model->getFillable()); + 18▕ } + 19▕ + 20▕ public function test_model_class_loads(): void + + 1 tests/Unit/Models/InvoiceTest.php:16 + + ──────────────────────────────────────────────────────────────────────────── + FAILED Tests\Unit\Models\MidtermExamTest > model metadata is converted + Failed asserting that false is identical to true. + + at tests/Unit/Models/MidtermExamTest.php:16 + 12▕ $model = new MidtermExam; + 13▕ + 14▕ $this->assertSame('midterm_exam', $model->getTable()); + 15▕ $this->assertSame('id', $model->getKeyName()); + ➜ 16▕ $this->assertSame(true, $model->timestamps); + 17▕ $this->assertSame(['student_id', 'school_id', 'class_section_id', 'updated_by', 'score', 'comment', 'semester', 'school_year', 'created_at', 'updated_at'], $model->getFillable()); + 18▕ } + 19▕ + 20▕ public function test_model_class_loads(): void + + 1 tests/Unit/Models/MidtermExamTest.php:16 + + ──────────────────────────────────────────────────────────────────────────── + FAILED Tests\Unit\Models\ParticipationTest > model metadata is converted + Failed asserting that false is identical to true. + + at tests/Unit/Models/ParticipationTest.php:16 + 12▕ $model = new Participation; + 13▕ + 14▕ $this->assertSame('participation', $model->getTable()); + 15▕ $this->assertSame('id', $model->getKeyName()); + ➜ 16▕ $this->assertSame(true, $model->timestamps); + 17▕ $this->assertSame(['student_id', 'school_id', 'class_section_id', 'updated_by', 'score', 'comment', 'semester', 'school_year', 'created_at', 'updated_at'], $model->getFillable()); + 18▕ } + 19▕ + 20▕ public function test_model_class_loads(): void + + 1 tests/Unit/Models/ParticipationTest.php:16 + + ──────────────────────────────────────────────────────────────────────────── + FAILED Tests\Unit\Models\PasswordResetRequestTest > model metadata is co… + Failed asserting that true is identical to false. + + at tests/Unit/Models/PasswordResetRequestTest.php:16 + 12▕ $model = new PasswordResetRequest; + 13▕ + 14▕ $this->assertSame('password_reset_requests', $model->getTable()); + 15▕ $this->assertSame('id', $model->getKeyName()); + ➜ 16▕ $this->assertSame(false, $model->timestamps); + 17▕ $this->assertSame(['ip_address', 'requested_at'], $model->getFillable()); + 18▕ } + 19▕ + 20▕ public function test_model_class_loads(): void + + 1 tests/Unit/Models/PasswordResetRequestTest.php:16 + + ──────────────────────────────────────────────────────────────────────────── + FAILED Tests\Unit\Models\PasswordResetTest > model metadata is converted + Failed asserting that true is identical to false. + + at tests/Unit/Models/PasswordResetTest.php:16 + 12▕ $model = new PasswordReset; + 13▕ + 14▕ $this->assertSame('password_resets', $model->getTable()); + 15▕ $this->assertSame('id', $model->getKeyName()); + ➜ 16▕ $this->assertSame(false, $model->timestamps); + 17▕ $this->assertSame(['email', 'token', 'created_at', 'expires_at'], $model->getFillable()); + 18▕ } + 19▕ + 20▕ public function test_model_class_loads(): void + + 1 tests/Unit/Models/PasswordResetTest.php:16 + + ──────────────────────────────────────────────────────────────────────────── + FAILED Tests\Unit\Models\PayPalPaymentTest > model metadata is converted + Failed asserting that true is identical to false. + + at tests/Unit/Models/PayPalPaymentTest.php:16 + 12▕ $model = new PayPalPayment; + 13▕ + 14▕ $this->assertSame('paypal_payments', $model->getTable()); + 15▕ $this->assertSame('id', $model->getKeyName()); + ➜ 16▕ $this->assertSame(false, $model->timestamps); + 17▕ $this->assertSame(['webhook_id', 'parent_school_id', 'order_id', 'transaction_id', 'status', 'amount', 'currency', 'paypal_fee', 'net_amount', 'payer_email', 'merchant_id', 'event_type', 'summary', 'raw_payload', 'synced', 'sync_attempts', 'created_at'], $model->getFillable()); + 18▕ } + 19▕ + 20▕ public function test_model_class_loads(): void + + 1 tests/Unit/Models/PayPalPaymentTest.php:16 + + ──────────────────────────────────────────────────────────────────────────── + FAILED Tests\Unit\Models\PaymentTest > model metadata is converted + Failed asserting that false is identical to true. + + at tests/Unit/Models/PaymentTest.php:16 + 12▕ $model = new Payment; + 13▕ + 14▕ $this->assertSame('payments', $model->getTable()); + 15▕ $this->assertSame('id', $model->getKeyName()); + ➜ 16▕ $this->assertSame(true, $model->timestamps); + 17▕ $this->assertSame(['parent_id', 'invoice_id', 'total_amount', 'paid_amount', 'balance', 'number_of_installments', 'transaction_id', 'check_file', 'check_number', 'payment_method', 'payment_date', 'semester', 'school_year', 'status', 'updated_by', 'created_at', 'updated_at'], $model->getFillable()); + 18▕ } + 19▕ + 20▕ public function test_model_class_loads(): void + + 1 tests/Unit/Models/PaymentTest.php:16 + + ──────────────────────────────────────────────────────────────────────────── + FAILED Tests\Unit\Models\PurchaseOrderItemTest > model metadata is conve… + Failed asserting that two arrays are identical. + Array &0 [ + 0 => 'purchase_order_id', + 1 => 'supply_id', + - 2 => 'description', + - 3 => 'quantity', + - 4 => 'received_qty', + - 5 => 'unit_cost', + + 2 => 'inventory_item_id', + + 3 => 'description', + + 4 => 'quantity', + + 5 => 'received_qty', + + 6 => 'unit_cost', + ] + + + at tests/Unit/Models/PurchaseOrderItemTest.php:17 + 13▕ + 14▕ $this->assertSame('purchase_order_items', $model->getTable()); + 15▕ $this->assertSame('id', $model->getKeyName()); + 16▕ $this->assertSame(true, $model->timestamps); + ➜ 17▕ $this->assertSame(['purchase_order_id', 'supply_id', 'description', 'quantity', 'received_qty', 'unit_cost'], $model->getFillable()); + 18▕ } + 19▕ + 20▕ public function test_model_class_loads(): void + 21▕ { + + 1 tests/Unit/Models/PurchaseOrderItemTest.php:17 + + ──────────────────────────────────────────────────────────────────────────── + FAILED Tests\Unit\Models\QuizTest > model metadata is converted + Failed asserting that false is identical to true. + + at tests/Unit/Models/QuizTest.php:16 + 12▕ $model = new Quiz; + 13▕ + 14▕ $this->assertSame('quiz', $model->getTable()); + 15▕ $this->assertSame('id', $model->getKeyName()); + ➜ 16▕ $this->assertSame(true, $model->timestamps); + 17▕ $this->assertSame(['student_id', 'school_id', 'class_section_id', 'updated_by', 'quiz_index', 'score', 'comment', 'semester', 'school_year', 'created_at', 'updated_at'], $model->getFillable()); + 18▕ } + 19▕ + 20▕ public function test_model_class_loads(): void + + 1 tests/Unit/Models/QuizTest.php:16 + + ──────────────────────────────────────────────────────────────────────────── + FAILED Tests\Unit\Models\ScoreCommentTest > model metadata is converted + Failed asserting that true is identical to false. + + at tests/Unit/Models/ScoreCommentTest.php:16 + 12▕ $model = new ScoreComment; + 13▕ + 14▕ $this->assertSame('score_comments', $model->getTable()); + 15▕ $this->assertSame('id', $model->getKeyName()); + ➜ 16▕ $this->assertSame(false, $model->timestamps); + 17▕ $this->assertSame(['student_id', 'class_section_id', 'score_type', 'semester', 'school_year', 'comment', 'comment_review', 'reviewed_by', 'commented_by', 'created_at'], $model->getFillable()); + 18▕ } + 19▕ + 20▕ public function test_model_class_loads(): void + + 1 tests/Unit/Models/ScoreCommentTest.php:16 + + ──────────────────────────────────────────────────────────────────────────── + FAILED Tests\Unit\Models\SectionTest > model metadata is converted + Failed asserting that true is identical to false. + + at tests/Unit/Models/SectionTest.php:16 + 12▕ $model = new Section; + 13▕ + 14▕ $this->assertSame('sections', $model->getTable()); + 15▕ $this->assertSame('id', $model->getKeyName()); + ➜ 16▕ $this->assertSame(false, $model->timestamps); + 17▕ $this->assertSame(['section_name', 'description', 'updated_at', 'updated_by'], $model->getFillable()); + 18▕ } + 19▕ + 20▕ public function test_model_class_loads(): void + + 1 tests/Unit/Models/SectionTest.php:16 + + ──────────────────────────────────────────────────────────────────────────── + FAILED Tests\Unit\Models\StaffTest > model metadata is converted + Failed asserting that false is identical to true. + + at tests/Unit/Models/StaffTest.php:16 + 12▕ $model = new Staff; + 13▕ + 14▕ $this->assertSame('staff', $model->getTable()); + 15▕ $this->assertSame('id', $model->getKeyName()); + ➜ 16▕ $this->assertSame(true, $model->timestamps); + 17▕ $this->assertSame(['firstname', 'lastname', 'email', 'phone', 'role_name', 'school_year', 'active_role', 'created_at', 'updated_at', 'user_id'], $model->getFillable()); + 18▕ } + 19▕ + 20▕ public function test_model_class_loads(): void + + 1 tests/Unit/Models/StaffTest.php:16 + + ──────────────────────────────────────────────────────────────────────────── + FAILED Tests\Unit\Models\TeacherTest > model metadata is converted + Failed asserting that two arrays are identical. + Array &0 [ + - 0 => 'school_id', + - 1 => 'firstname', + + 0 => 'password', + + 1 => 'account_id', + 2 => 'lastname', + - 3 => 'gender', + - 4 => 'cellphone', + - 5 => 'email', + - 6 => 'address_street', + - 7 => 'apt', + - 8 => 'city', + - 9 => 'state', + - 10 => 'zip', + - 11 => 'accept_school_policy', + - 12 => 'is_verified', + - 13 => 'status', + - 14 => 'is_suspended', + - 15 => 'failed_attempts', + - 16 => 'password', + - 17 => 'created_at', + - 18 => 'updated_at', + - 19 => 'token', + - 20 => 'account_id', + - 21 => 'user_type', + - 22 => 'semester', + - 23 => 'school_year', + - 24 => 'rfid_tag', + - 25 => 'last_failed_at', + + 3 => 'firstname', + + 4 => 'gender', + + 5 => 'cellphone', + + 6 => 'email', + + 7 => 'address_street', + + 8 => 'apt', + + 9 => 'city', + + 10 => 'state', + + 11 => 'zip', + + 12 => 'accept_school_policy', + + 13 => 'user_type', + + 14 => 'rfid_tag', + + 15 => 'school_id', + + 16 => 'failed_attempts', + + 17 => 'last_failed_at', + + 18 => 'semester', + + 19 => 'school_year', + + 20 => 'status', + + 21 => 'is_suspended', + + 22 => 'is_verified', + + 23 => 'token', + + 24 => 'updated_at', + + 25 => 'created_at', + ] + + + at tests/Unit/Models/TeacherTest.php:17 + 13▕ + 14▕ $this->assertSame('users', $model->getTable()); + 15▕ $this->assertSame('id', $model->getKeyName()); + 16▕ $this->assertSame(true, $model->timestamps); + ➜ 17▕ $this->assertSame(['school_id', 'firstname', 'lastname', 'gender', 'cellphone', 'email', 'address_street', 'apt', 'city', 'state', 'zip', 'accept_school_policy', 'is_verified', 'status', 'is_suspended', 'failed_attempts', 'password', 'created_at', 'updated_at', 'token', 'account_id', 'user_type', 'semester', 'school_year', 'rfid_tag', 'last_failed_at'], $model->getFillable()); + 18▕ } + 19▕ + 20▕ public function test_model_class_loads(): void + 21▕ { + + 1 tests/Unit/Models/TeacherTest.php:17 + + ──────────────────────────────────────────────────────────────────────────── + FAILED Tests\Unit\Models\UserTest > model metadata is converted + Failed asserting that two arrays are identical. + Array &0 [ + - 0 => 'school_id', + - 1 => 'firstname', + + 0 => 'password', + + 1 => 'account_id', + 2 => 'lastname', + - 3 => 'gender', + - 4 => 'cellphone', + - 5 => 'email', + - 6 => 'address_street', + - 7 => 'apt', + - 8 => 'city', + - 9 => 'state', + - 10 => 'zip', + - 11 => 'accept_school_policy', + - 12 => 'is_verified', + - 13 => 'status', + - 14 => 'is_suspended', + - 15 => 'failed_attempts', + - 16 => 'password', + - 17 => 'created_at', + - 18 => 'updated_at', + - 19 => 'token', + - 20 => 'account_id', + - 21 => 'user_type', + - 22 => 'semester', + - 23 => 'school_year', + - 24 => 'rfid_tag', + - 25 => 'last_failed_at', + + 3 => 'firstname', + + 4 => 'gender', + + 5 => 'cellphone', + + 6 => 'email', + + 7 => 'address_street', + + 8 => 'apt', + + 9 => 'city', + + 10 => 'state', + + 11 => 'zip', + + 12 => 'accept_school_policy', + + 13 => 'user_type', + + 14 => 'rfid_tag', + + 15 => 'school_id', + + 16 => 'failed_attempts', + + 17 => 'last_failed_at', + + 18 => 'semester', + + 19 => 'school_year', + + 20 => 'status', + + 21 => 'is_suspended', + + 22 => 'is_verified', + + 23 => 'token', + + 24 => 'updated_at', + + 25 => 'created_at', + ] + + + at tests/Unit/Models/UserTest.php:17 + 13▕ + 14▕ $this->assertSame('users', $model->getTable()); + 15▕ $this->assertSame('id', $model->getKeyName()); + 16▕ $this->assertSame(true, $model->timestamps); + ➜ 17▕ $this->assertSame(['school_id', 'firstname', 'lastname', 'gender', 'cellphone', 'email', 'address_street', 'apt', 'city', 'state', 'zip', 'accept_school_policy', 'is_verified', 'status', 'is_suspended', 'failed_attempts', 'password', 'created_at', 'updated_at', 'token', 'account_id', 'user_type', 'semester', 'school_year', 'rfid_tag', 'last_failed_at'], $model->getFillable()); + 18▕ } + 19▕ + 20▕ public function test_model_class_loads(): void + 21▕ { + + 1 tests/Unit/Models/UserTest.php:17 + + ──────────────────────────────────────────────────────────────────────────── + FAILED Tests\Unit\Resources\Messaging\MessageResourceTes… QueryException + SQLSTATE[HY000]: General error: 1 no such table: users (Connection: sqlite, Database: :memory:, SQL: select * from "users" where "users"."id" = 2 limit 1) + + at vendor/laravel/framework/src/Illuminate/Database/Connection.php:838 + 834▕ $exceptionType = $this->isUniqueConstraintError($e) + 835▕ ? UniqueConstraintViolationException::class + 836▕ : QueryException::class; + 837▕ + ➜ 838▕ throw new $exceptionType( + 839▕ $this->getNameWithReadWriteType(), + 840▕ $query, + 841▕ $this->prepareBindings($bindings), + 842▕ $e, + + +19 vendor frames  + 20 app/Http/Resources/Messaging/MessageResource.php:27 + 21 tests/Unit/Resources/Messaging/MessageResourceTest.php:28 + + ──────────────────────────────────────────────────────────────────────────── + FAILED Tests\Unit\Resources\Staff\StaffResourceTest > resource returns e… + Failed asserting that null is identical to 1. + + at tests/Unit/Resources/Staff/StaffResourceTest.php:26 + 22▕ ]); + 23▕ + 24▕ $payload = (new StaffResource($staff))->toArray(request()); + 25▕ + ➜ 26▕ $this->assertSame(1, $payload['id']); + 27▕ $this->assertSame('teacher', $payload['role_name']); + 28▕ } + 29▕ } + 30▕ + + 1 tests/Unit/Resources/Staff/StaffResourceTest.php:26 + + ──────────────────────────────────────────────────────────────────────────── + FAILED Tests\Unit\Resources\Support\SupportRequestResourceTest > resourc… + Failed asserting that null is identical to 1. + + at tests/Unit/Resources/Support/SupportRequestResourceTest.php:25 + 21▕ ]); + 22▕ + 23▕ $payload = (new SupportRequestResource($model))->toArray(request()); + 24▕ + ➜ 25▕ $this->assertSame(1, $payload['id']); + 26▕ $this->assertSame('Help', $payload['subject']); + 27▕ } + 28▕ } + 29▕ + + 1 tests/Unit/Resources/Support/SupportRequestResourceTest.php:25 + + ──────────────────────────────────────────────────────────────────────────── + FAILED Tests\Unit\Services\Administrator\Administrat… ArgumentCountError + Too few arguments to function App\Services\Administrator\AdministratorAbsenceService::__construct(), 5 passed in /Volumes/ExternalApps/repos/alrahma_sunday_school_api/tests/Unit/Services/Administrator/AdministratorAbsenceServiceTest.php on line 28 and exactly 6 expected + + at app/Services/Administrator/AdministratorAbsenceService.php:23 + 19▕ protected User $userModel, + 20▕ protected StaffAttendance $staffAttendanceModel, + 21▕ protected SemesterRangeService $semesterRangeService, + 22▕ protected StaffTimeOffLinkService $staffTimeOffLinkService, + ➜ 23▕ protected ApplicationUrlService $urls, + 24▕ ) {} + 25▕ + 26▕ public function getAbsenceFormData(int $userId): array + 27▕ { + + 1 app/Services/Administrator/AdministratorAbsenceService.php:23 + 2 tests/Unit/Services/Administrator/AdministratorAbsenceServiceTest.php:28 + + ──────────────────────────────────────────────────────────────────────────── + FAILED Tests\Unit\Services\Administrator\Administrat… ArgumentCountError + Too few arguments to function App\Services\Administrator\AdministratorEnrollmentEventService::__construct(), 0 passed in /Volumes/ExternalApps/repos/alrahma_sunday_school_api/tests/Unit/Services/Administrator/AdministratorEnrollmentEventServiceTest.php on line 18 and exactly 1 expected + + at app/Services/Administrator/AdministratorEnrollmentEventService.php:12 + 8▕ + 9▕ class AdministratorEnrollmentEventService + 10▕ { + 11▕ public function __construct( + ➜ 12▕ private ApplicationUrlService $urls, + 13▕ ) {} + 14▕ + 15▕ public function dispatchGroupedEvents( + 16▕ array $groupsByParentStatus, + + 1 app/Services/Administrator/AdministratorEnrollmentEventService.php:12 + 2 tests/Unit/Services/Administrator/AdministratorEnrollmentEventServiceTest.php:18 + + ──────────────────────────────────────────────────────────────────────────── + FAILED Tests\Unit\Services\Administrator\TeacherSubm… ArgumentCountError + Too few arguments to function App\Services\Administrator\TeacherSubmissionNotificationService::__construct(), 2 passed in /Volumes/ExternalApps/repos/alrahma_sunday_school_api/tests/Unit/Services/Administrator/TeacherSubmissionNotificationServiceTest.php on line 22 and exactly 3 expected + + at app/Services/Administrator/TeacherSubmissionNotificationService.php:19 + 15▕ { + 16▕ public function __construct( + 17▕ protected AdministratorSharedService $shared, + 18▕ protected TeacherSubmissionSupportService $support, + ➜ 19▕ protected ApplicationUrlService $urls, + 20▕ ) {} + 21▕ + 22▕ public function send(Request $request, int $adminId): array + 23▕ { + + 1 app/Services/Administrator/TeacherSubmissionNotificationService.php:19 + 2 tests/Unit/Services/Administrator/TeacherSubmissionNotificationServiceTest.php:22 + + ──────────────────────────────────────────────────────────────────────────── + FAILED Tests\Unit\Services\Administrator\Teacher… BadMethodCallException + Received Mockery_4_App_Services_Administrator_AdministratorSharedService::teacherClassSupportsSemester(), but no expectations were specified + + at app/Services/Administrator/TeacherSubmissionReportService.php:23 + 19▕ public function report(array $filters = []): array + 20▕ { + 21▕ $semester = $this->shared->getSemester($filters['semester'] ?? null); + 22▕ $schoolYear = $this->shared->getSchoolYear($filters['school_year'] ?? null); + ➜ 23▕ $teacherClassSupportsSemester = $this->shared->teacherClassSupportsSemester(); + 24▕ + 25▕ $assignmentQuery = DB::table('teacher_class as tc') + 26▕ ->select([ + 27▕ 'tc.class_section_id', + + 1 app/Services/Administrator/TeacherSubmissionReportService.php:23 + 2 tests/Unit/Services/Administrator/TeacherSubmissionReportServiceTest.php:38 + + ──────────────────────────────────────────────────────────────────────────── + FAILED Tests\Unit\Services\Assignment\AssignmentSectionS… ErrorException + Undefined array key 1 + + at tests/Unit/Services/Assignment/AssignmentSectionServiceTest.php:29 + 25▕ + 26▕ $service = new AssignmentSectionService(new ClassSection); + 27▕ $map = $service->getSectionNamesMap([1]); + 28▕ + ➜ 29▕ $this->assertSame('1-A', $map[1]); + 30▕ } + 31▕ } + 32▕ + + ──────────────────────────────────────────────────────────────────────────── + FAILED Tests\Unit\Services\AssignmentServiceTest > get assignments overv… + Failed asserting that two strings are identical. + -'Alpha Section' + +'' + + + at tests/Unit/Services/AssignmentServiceTest.php:147 + 143▕ + 144▕ $section = $result['classSections'][0]; + 145▕ + 146▕ $this->assertSame($this->sectionA->id, $section['class_section_id']); + ➜ 147▕ $this->assertSame('Alpha Section', $section['class_section_name']); + 148▕ $this->assertSame(['John Doe'], $section['main_teachers']); + 149▕ $this->assertSame(['Jane Smith'], $section['teacher_assistants']); + 150▕ $this->assertSame('Fall', $section['semester']); + 151▕ $this->assertSame('2025-2026', $section['school_year']); + + 1 tests/Unit/Services/AssignmentServiceTest.php:147 + + ──────────────────────────────────────────────────────────────────────────── + FAILED Tests\Unit\Services\AssignmentServiceTest > get assignments overv… + Failed asserting that two strings are identical. + -'Alpha Section' + +'' + + + at tests/Unit/Services/AssignmentServiceTest.php:233 + 229▕ + 230▕ $result = $this->service->getAssignmentsOverview(); + 231▕ + 232▕ $this->assertCount(2, $result['classSections']); + ➜ 233▕ $this->assertSame('Alpha Section', $result['classSections'][0]['class_section_name']); + 234▕ $this->assertSame('Beta Section', $result['classSections'][1]['class_section_name']); + 235▕ } + 236▕ + 237▕ public function test_get_assignments_overview_collects_school_years_descending(): void + + 1 tests/Unit/Services/AssignmentServiceTest.php:233 + + ──────────────────────────────────────────────────────────────────────────── + FAILED Tests\Unit\Services\AssignmentServiceTest > get class assignment… + Failed asserting that two strings are identical. + -'Alpha Section' + +'' + + + at tests/Unit/Services/AssignmentServiceTest.php:366 + 362▕ + 363▕ $this->assertSame('Fall', $result['semester']); + 364▕ $this->assertSame('2025-2026', $result['school_year']); + 365▕ $this->assertCount(2, $result['classSections']); + ➜ 366▕ $this->assertSame('Alpha Section', $result['classSections'][0]['class_section_name']); + 367▕ $this->assertSame('Beta Section', $result['classSections'][1]['class_section_name']); + 368▕ } + 369▕ + 370▕ public function test_get_class_assignment_data_deduplicates_teacher_names(): void + + 1 tests/Unit/Services/AssignmentServiceTest.php:366 + + ──────────────────────────────────────────────────────────────────────────── + FAILED Tests\Unit\Services\Attendance\AttendanceDailySummaryServiceTest… + Failed asserting that 0 is identical to 1. + + at tests/Unit/Services/Attendance/AttendanceDailySummaryServiceTest.php:66 + 62▕ $service = new AttendanceDailySummaryService($notifier, $email); + 63▕ + 64▕ $count = $service->sendAbsenteesSummary(); + 65▕ + ➜ 66▕ $this->assertSame(1, $count); + 67▕ } + 68▕ } + 69▕ + + 1 tests/Unit/Services/Attendance/AttendanceDailySummaryServiceTest.php:66 + + ──────────────────────────────────────────────────────────────────────────── + FAILED Tests\Unit\Services\Attendance\AttendanceSemesterRangeServiceTest… + Failed asserting that two arrays are identical. + Array &0 [ + - 0 => '2025-09-21', + - 1 => '2026-01-18', + + 0 => '2025-09-01', + + 1 => '2026-01-24', + ] + + + at tests/Unit/Services/Attendance/AttendanceSemesterRangeServiceTest.php:18 + 14▕ { + 15▕ $service = new SemesterRangeService; + 16▕ $range = $service->getSemesterRange('2025-2026', 'fall'); + 17▕ + ➜ 18▕ $this->assertSame(['2025-09-21', '2026-01-18'], $range); + 19▕ } + 20▕ + 21▕ public function test_build_sunday_list_returns_sundays(): void + 22▕ { + + 1 tests/Unit/Services/Attendance/AttendanceSemesterRangeServiceTest.php:18 + + ──────────────────────────────────────────────────────────────────────────── + FAILED Tests\Unit\Services\Attendance\LateSlipLogCommand… QueryException + SQLSTATE[23000]: Integrity constraint violation: 19 NOT NULL constraint failed: late_slip_logs.printed_at (Connection: sqlite, Database: :memory:, SQL: insert into "late_slip_logs" ("school_year", "semester", "student_name", "slip_date", "time_in", "grade", "reason", "admin_name") values (2025-2026, Fall, Student X, 2025-09-01 00:00:00, 08:05:00, 4, Traffic, Admin User)) + + at vendor/laravel/framework/src/Illuminate/Database/Connection.php:838 + 834▕ $exceptionType = $this->isUniqueConstraintError($e) + 835▕ ? UniqueConstraintViolationException::class + 836▕ : QueryException::class; + 837▕ + ➜ 838▕ throw new $exceptionType( + 839▕ $this->getNameWithReadWriteType(), + 840▕ $query, + 841▕ $this->prepareBindings($bindings), + 842▕ $e, + + +16 vendor frames  + 17 tests/Unit/Services/Attendance/LateSlipLogCommandServiceTest.php:16 + + ──────────────────────────────────────────────────────────────────────────── + FAILED Tests\Unit\Services\Attendance\LateSlipLogQuerySe… QueryException + SQLSTATE[23000]: Integrity constraint violation: 19 NOT NULL constraint failed: late_slip_logs.printed_at (Connection: sqlite, Database: :memory:, SQL: insert into "late_slip_logs" ("school_year", "semester", "slip_date", "student_name") values (2025-2026, Fall, 2025-09-01, Student A), (2025-2026, Fall, 2025-10-01, Student B)) + + at vendor/laravel/framework/src/Illuminate/Database/Connection.php:838 + 834▕ $exceptionType = $this->isUniqueConstraintError($e) + 835▕ ? UniqueConstraintViolationException::class + 836▕ : QueryException::class; + 837▕ + ➜ 838▕ throw new $exceptionType( + 839▕ $this->getNameWithReadWriteType(), + 840▕ $query, + 841▕ $this->prepareBindings($bindings), + 842▕ $e, + + +8 vendor frames  + 9 tests/Unit/Services/Attendance/LateSlipLogQueryServiceTest.php:16 + + ──────────────────────────────────────────────────────────────────────────── + FAILED Tests\Unit\Services\Attendance\Semest… BindingResolutionException + Target class [config] does not exist. + + at vendor/laravel/framework/src/Illuminate/Container/Container.php:1124 + 1120▕ + 1121▕ try { + 1122▕ $reflector = new ReflectionClass($concrete); + 1123▕ } catch (ReflectionException $e) { + ➜ 1124▕ throw new BindingResolutionException("Target class [$concrete] does not exist.", 0, $e); + 1125▕ } + 1126▕ + 1127▕ // If the type is not instantiable, the developer is attempting to resolve + 1128▕ // an abstract type such as an Interface or Abstract Class and there is + + +17 vendor frames  + 18 app/Models/Configuration.php:50 + 19 app/Services/Attendance/SemesterRangeService.php:124 + + ──────────────────────────────────────────────────────────────────────────── + FAILED Tests\Unit\Services\AttendanceTracking\Attend… ArgumentCountError + Too few arguments to function App\Services\AttendanceTracking\AttendanceTrackingService::__construct(), 0 passed in /Volumes/ExternalApps/repos/alrahma_sunday_school_api/tests/Unit/Services/AttendanceTracking/AttendanceTrackingServiceTest.php on line 15 and exactly 4 expected + + at app/Services/AttendanceTracking/AttendanceTrackingService.php:16 + 12▕ */ + 13▕ class AttendanceTrackingService + 14▕ { + 15▕ public function __construct( + ➜ 16▕ protected AttendancePendingViolationService $pendingViolationService, + 17▕ protected AttendanceCaseQueryService $caseQueryService, + 18▕ protected AttendanceNotificationWorkflowService $workflowService, + 19▕ protected AttendanceCommunicationSupportService $communicationSupportService, + 20▕ ) {} + + 1 app/Services/AttendanceTracking/AttendanceTrackingService.php:16 + 2 tests/Unit/Services/AttendanceTracking/AttendanceTrackingServiceTest.php:15 + + ──────────────────────────────────────────────────────────────────────────── + FAILED Tests\Unit\Services\Auth\RegistrationServiceT… ArgumentCountError + Too few arguments to function App\Services\Auth\RegistrationService::__construct(), 4 passed in /Volumes/ExternalApps/repos/alrahma_sunday_school_api/tests/Unit/Services/Auth/RegistrationServiceTest.php on line 44 and exactly 5 expected + + at app/Services/Auth/RegistrationService.php:22 + 18▕ private EmailService $emailService, + 19▕ private SchoolIdService $schoolIdService, + 20▕ private RegistrationFormatterService $formatter, + 21▕ private RegistrationCaptchaService $captchaService, + ➜ 22▕ private ApplicationUrlService $urls, + 23▕ ) {} + 24▕ + 25▕ public function register(array $payload): array + 26▕ { + + 1 app/Services/Auth/RegistrationService.php:22 + 2 tests/Unit/Services/Auth/RegistrationServiceTest.php:44 + + ──────────────────────────────────────────────────────────────────────────── + FAILED Tests\Unit\Services\Auth\RegistrationServiceT… ArgumentCountError + Too few arguments to function App\Services\Auth\RegistrationService::__construct(), 4 passed in /Volumes/ExternalApps/repos/alrahma_sunday_school_api/tests/Unit/Services/Auth/RegistrationServiceTest.php on line 124 and exactly 5 expected + + at app/Services/Auth/RegistrationService.php:22 + 18▕ private EmailService $emailService, + 19▕ private SchoolIdService $schoolIdService, + 20▕ private RegistrationFormatterService $formatter, + 21▕ private RegistrationCaptchaService $captchaService, + ➜ 22▕ private ApplicationUrlService $urls, + 23▕ ) {} + 24▕ + 25▕ public function register(array $payload): array + 26▕ { + + 1 app/Services/Auth/RegistrationService.php:22 + 2 tests/Unit/Services/Auth/RegistrationServiceTest.php:124 + + ──────────────────────────────────────────────────────────────────────────── + FAILED Tests\Unit\Services\Billing\BalanceCalculationServiceTest > calcu… + Failed asserting that 0.0 is identical to 100.0. + + at tests/Unit/Services/Billing/BalanceCalculationServiceTest.php:105 + 101▕ ], $parentId); + 102▕ + 103▕ $this->assertSame($parentId, $result['parent_id']); + 104▕ $this->assertSame(550.0, $result['charges']['tuition']); + ➜ 105▕ $this->assertSame(100.0, $result['charges']['extra_charges']); + 106▕ $this->assertSame(50.0, $result['charges']['event_charges']); + 107▕ $this->assertSame(700.0, $result['charges']['total']); + 108▕ $this->assertSame(500.0, $result['payments']); + 109▕ $this->assertSame(80.0, $result['credits']['total']); + + 1 tests/Unit/Services/Billing/BalanceCalculationServiceTest.php:105 + + ──────────────────────────────────────────────────────────────────────────── + FAILED Tests\Unit\Services\Billing\BillingTotalsServiceT… QueryException + SQLSTATE[23000]: Integrity constraint violation: 19 NOT NULL constraint failed: additional_charges.title (Connection: sqlite, Database: :memory:, SQL: insert into "additional_charges" ("amount", "charge_type", "id", "invoice_id", "parent_id", "school_year", "semester", "status") values (15, add, 1, 99, 10, 2025-2026, Fall, applied), (5, deduct, 2, 99, 10, 2025-2026, Fall, applied)) + + at vendor/laravel/framework/src/Illuminate/Database/Connection.php:838 + 834▕ $exceptionType = $this->isUniqueConstraintError($e) + 835▕ ? UniqueConstraintViolationException::class + 836▕ : QueryException::class; + 837▕ + ➜ 838▕ throw new $exceptionType( + 839▕ $this->getNameWithReadWriteType(), + 840▕ $query, + 841▕ $this->prepareBindings($bindings), + 842▕ $e, + + +8 vendor frames  + 9 tests/Unit/Services/Billing/BillingTotalsServiceTest.php:31 + + ──────────────────────────────────────────────────────────────────────────── + FAILED Tests\Unit\Services\Billing\BillingTotalsServiceTest > additional… + Failed asserting that 0.0 is identical to 30.0. + + at tests/Unit/Services/Billing/BillingTotalsServiceTest.php:100 + 96▕ ]); + 97▕ + 98▕ $service = new BillingTotalsService; + 99▕ + ➜ 100▕ $this->assertSame(30.0, $service->additionalSubtotalByParent(10, '2025-2026')); + 101▕ } + 102▕ + 103▕ public function test_event_subtotals_by_student_groups_amounts(): void + 104▕ { + + 1 tests/Unit/Services/Billing/BillingTotalsServiceTest.php:100 + + ──────────────────────────────────────────────────────────────────────────── + FAILED Tests\Unit\Services\Billing\ChargeServiceTest > cancel event char… + Failed asserting that true is identical to 'no'. + + at tests/Unit/Services/Billing/ChargeServiceTest.php:124 + 120▕ $this->assertTrue($result['ok']); + 121▕ $this->assertSame('canceled', $result['cancellation_status']); + 122▕ + 123▕ $charge = EventCharges::query()->find($chargeId); + ➜ 124▕ $this->assertSame('no', $charge->participation); + 125▕ $this->assertSame(0.0, (float) $charge->charged); + 126▕ + 127▕ $this->assertDatabaseHas('additional_charges', [ + 128▕ 'parent_id' => 10, + + 1 tests/Unit/Services/Billing/ChargeServiceTest.php:124 + + ──────────────────────────────────────────────────────────────────────────── + FAILED Tests\Unit\Services\ClassPreparation\ClassPrepara… QueryException + SQLSTATE[HY000]: General error: 1 table class_prep_adjustments has no column named updated_at (Connection: sqlite, Database: :memory:, SQL: insert into "class_prep_adjustments" ("class_section_id", "item_name", "adjustment", "school_year", "adjustable", "updated_at", "created_at") values (101, Small Table, 2, 2025-2026, 1, 2026-07-05 22:09:19, 2026-07-05 22:09:19)) + + at vendor/laravel/framework/src/Illuminate/Database/Connection.php:838 + 834▕ $exceptionType = $this->isUniqueConstraintError($e) + 835▕ ? UniqueConstraintViolationException::class + 836▕ : QueryException::class; + 837▕ + ➜ 838▕ throw new $exceptionType( + 839▕ $this->getNameWithReadWriteType(), + 840▕ $query, + 841▕ $this->prepareBindings($bindings), + 842▕ $e, + + +16 vendor frames  + 17 app/Services/ClassPreparation/ClassPreparationAdjustmentWriterService.php:39 + +3 vendor frames  + 21 app/Services/ClassPreparation/ClassPreparationAdjustmentWriterService.php:14 + + ──────────────────────────────────────────────────────────────────────────── + FAILED Tests\Unit\Services\ClassPreparation\ClassPreparationLogServiceTe… + Failed asserting that false is true. + + at tests/Unit/Services/ClassPreparation/ClassPreparationLogServiceTest.php:26 + 22▕ { + 23▕ $service = new ClassPreparationLogService; + 24▕ $created = $service->createLog('101', '1-A', '2025-2026', ['Small Table' => 2], '2025-09-01 00:00:00'); + 25▕ + ➜ 26▕ $this->assertTrue($created); + 27▕ $this->assertDatabaseHas('class_preparation_log', [ + 28▕ 'class_section_id' => 101, + 29▕ 'school_year' => '2025-2026', + 30▕ ]); + + 1 tests/Unit/Services/ClassPreparation/ClassPreparationLogServiceTest.php:26 + + ──────────────────────────────────────────────────────────────────────────── + FAILED Tests\Unit\Services\ClassPreparation\ClassPreparationPrintService… + Failed asserting that false is true. + + at tests/Unit/Services/ClassPreparation/ClassPreparationPrintServiceTest.php:33 + 29▕ + 30▕ $service = app(ClassPreparationPrintService::class); + 31▕ $payload = $service->printPrep('101', '2025-2026', 'Fall'); + 32▕ + ➜ 33▕ $this->assertTrue($payload['ok']); + 34▕ $this->assertDatabaseHas('class_preparation_log', [ + 35▕ 'class_section_id' => 101, + 36▕ 'school_year' => '2025-2026', + 37▕ ]); + + 1 tests/Unit/Services/ClassPreparation/ClassPreparationPrintServiceTest.php:33 + + ──────────────────────────────────────────────────────────────────────────── + FAILED Tests\Unit\Services\ClassPreparation\ClassPreparationServiceTest… + Failed asserting that 0 is identical to 1. + + at tests/Unit/Services/ClassPreparation/ClassPreparationServiceTest.php:34 + 30▕ + 31▕ $service = app(ClassPreparationService::class); + 32▕ $count = $service->markPrinted('2025-2026', 'Fall', [101]); + 33▕ + ➜ 34▕ $this->assertSame(1, $count); + 35▕ $this->assertDatabaseHas('class_preparation_log', [ + 36▕ 'class_section_id' => 101, + 37▕ 'school_year' => '2025-2026', + 38▕ ]); + + 1 tests/Unit/Services/ClassPreparation/ClassPreparationServiceTest.php:34 + + ──────────────────────────────────────────────────────────────────────────── + FAILED Tests\Unit\Services\ClassProgress\ClassProgre… ArgumentCountError + Too few arguments to function App\Services\ClassProgress\ClassProgressMutationService::__construct(), 2 passed in /Volumes/ExternalApps/repos/alrahma_sunday_school_api/tests/Unit/Services/ClassProgress/ClassProgressMutationServiceTest.php on line 24 and exactly 4 expected + + at app/Services/ClassProgress/ClassProgressMutationService.php:21 + 17▕ { + 18▕ public function __construct( + 19▕ private ClassProgressRuleService $rules, + 20▕ private ClassProgressAttachmentService $attachments, + ➜ 21▕ private ClassProgressQueryService $queries, + 22▕ private SchoolYearContextService $schoolYears, + 23▕ ) {} + 24▕ + 25▕ public function createReports(User $user, array $payload, array $filesBySubject): Collection + + 1 app/Services/ClassProgress/ClassProgressMutationService.php:21 + 2 tests/Unit/Services/ClassProgress/ClassProgressMutationServiceTest.php:24 + + ──────────────────────────────────────────────────────────────────────────── + FAILED Tests\Unit\Services\ClassProgress\ClassProgre… ArgumentCountError + Too few arguments to function App\Services\ClassProgress\ClassProgressMutationService::__construct(), 2 passed in /Volumes/ExternalApps/repos/alrahma_sunday_school_api/tests/Unit/Services/ClassProgress/ClassProgressMutationServiceTest.php on line 49 and exactly 4 expected + + at app/Services/ClassProgress/ClassProgressMutationService.php:21 + 17▕ { + 18▕ public function __construct( + 19▕ private ClassProgressRuleService $rules, + 20▕ private ClassProgressAttachmentService $attachments, + ➜ 21▕ private ClassProgressQueryService $queries, + 22▕ private SchoolYearContextService $schoolYears, + 23▕ ) {} + 24▕ + 25▕ public function createReports(User $user, array $payload, array $filesBySubject): Collection + + 1 app/Services/ClassProgress/ClassProgressMutationService.php:21 + 2 tests/Unit/Services/ClassProgress/ClassProgressMutationServiceTest.php:49 + + ──────────────────────────────────────────────────────────────────────────── + FAILED Tests\Unit\Services\ClassProgress\ClassProgre… ArgumentCountError + Too few arguments to function App\Services\ClassProgress\ClassProgressMutationService::__construct(), 2 passed in /Volumes/ExternalApps/repos/alrahma_sunday_school_api/tests/Unit/Services/ClassProgress/ClassProgressMutationServiceTest.php on line 62 and exactly 4 expected + + at app/Services/ClassProgress/ClassProgressMutationService.php:21 + 17▕ { + 18▕ public function __construct( + 19▕ private ClassProgressRuleService $rules, + 20▕ private ClassProgressAttachmentService $attachments, + ➜ 21▕ private ClassProgressQueryService $queries, + 22▕ private SchoolYearContextService $schoolYears, + 23▕ ) {} + 24▕ + 25▕ public function createReports(User $user, array $payload, array $filesBySubject): Collection + + 1 app/Services/ClassProgress/ClassProgressMutationService.php:21 + 2 tests/Unit/Services/ClassProgress/ClassProgressMutationServiceTest.php:62 + + ──────────────────────────────────────────────────────────────────────────── + FAILED Tests\Unit\Services\Discounts\DiscountApplySe… ArgumentCountError + Too few arguments to function App\Services\Discounts\DiscountInvoiceService::__construct(), 0 passed in /Volumes/ExternalApps/repos/alrahma_sunday_school_api/tests/Unit/Services/Discounts/DiscountApplyServiceTest.php on line 33 and exactly 1 expected + + at app/Services/Discounts/DiscountInvoiceService.php:19 + 15▕ + 16▕ class DiscountInvoiceService + 17▕ { + 18▕ public function __construct( + ➜ 19▕ private ApplicationUrlService $urls, + 20▕ ) {} + 21▕ + 22▕ public function getCurrentInvoiceBalance(int $invoiceId, string $schoolYear): float + 23▕ { + + 1 app/Services/Discounts/DiscountInvoiceService.php:19 + 2 tests/Unit/Services/Discounts/DiscountApplyServiceTest.php:33 + + ──────────────────────────────────────────────────────────────────────────── + FAILED Tests\Unit\Services\Events\EventStudentChargeServiceTest > list s… + Failed asserting that false is true. + + at tests/Unit/Services/Events/EventStudentChargeServiceTest.php:37 + 33▕ + 34▕ $service = new EventStudentChargeService; + 35▕ $rows = $service->listStudentsWithCharges(10, '2025-2026', 'Fall'); + 36▕ + ➜ 37▕ $this->assertTrue($rows[0]['charged']); + 38▕ } + 39▕ } + 40▕ + + 1 tests/Unit/Services/Events/EventStudentChargeServiceTest.php:37 + + ──────────────────────────────────────────────────────────────────────────── + FAILED Tests\Unit\Services\Expenses\ExpenseReceiptSe… ArgumentCountError + Too few arguments to function App\Services\Expenses\ExpenseReceiptService::__construct(), 0 passed in /Volumes/ExternalApps/repos/alrahma_sunday_school_api/tests/Unit/Services/Expenses/ExpenseReceiptServiceTest.php on line 19 and exactly 1 expected + + at app/Services/Expenses/ExpenseReceiptService.php:11 + 7▕ + 8▕ class ExpenseReceiptService + 9▕ { + 10▕ public function __construct( + ➜ 11▕ private ApplicationUrlService $urls + 12▕ ) {} + 13▕ + 14▕ public function storeReceipt(UploadedFile $file): string + 15▕ { + + 1 app/Services/Expenses/ExpenseReceiptService.php:11 + 2 tests/Unit/Services/Expenses/ExpenseReceiptServiceTest.php:19 + + ──────────────────────────────────────────────────────────────────────────── + FAILED Tests\Unit\Services\Fees\FeeRefundDetailServiceTe… QueryException + SQLSTATE[23000]: Integrity constraint violation: 19 NOT NULL constraint failed: payments.number_of_installments (Connection: sqlite, Database: :memory:, SQL: insert into "payments" ("id", "parent_id", "invoice_id", "paid_amount", "total_amount", "balance", "payment_date", "school_year", "semester", "status") values (1, 10, 1, 100, 100, 0, 2025-01-10, 2025-2026, Fall, Paid)) + + at vendor/laravel/framework/src/Illuminate/Database/Connection.php:838 + 834▕ $exceptionType = $this->isUniqueConstraintError($e) + 835▕ ? UniqueConstraintViolationException::class + 836▕ : QueryException::class; + 837▕ + ➜ 838▕ throw new $exceptionType( + 839▕ $this->getNameWithReadWriteType(), + 840▕ $query, + 841▕ $this->prepareBindings($bindings), + 842▕ $e, + + +8 vendor frames  + 9 tests/Unit/Services/Fees/FeeRefundDetailServiceTest.php:45 + + ──────────────────────────────────────────────────────────────────────────── + FAILED Tests\Unit\Services\Navigation\NavBuilderServiceTest > reorder up… + Failed asserting that a row in the table [nav_items] matches the attributes { + "id": 2, + "sort_order": 5 +}. + +Found similar results: [ + { + "id": 2, + "sort_order": 1 + } +]. + + at tests/Unit/Services/Navigation/NavBuilderServiceTest.php:51 + 47▕ + 48▕ $service = new NavBuilderService(new NavbarService); + 49▕ $service->reorder([$id => 5]); + 50▕ + ➜ 51▕ $this->assertDatabaseHas('nav_items', [ + 52▕ 'id' => $id, + 53▕ 'sort_order' => 5, + 54▕ ]); + 55▕ } + + ──────────────────────────────────────────────────────────────────────────── + FAILED Tests\Unit\Services\Notifications\Notifica… InvalidCountException + Method sendEmail() from Mockery_50_App_Services_Notifications_NotificationDispatchService should be called + exactly 1 times but called 2 times. + + ──────────────────────────────────────────────────────────────────────────── + FAILED Tests\Unit\Services\Promotions\PromotionEligibilityServiceTest >… + Failed asserting that two strings are identical. + -'graduated' + +'awaiting_parent_enrollment' + + + at tests/Unit/Services/Promotions/PromotionEligibilityServiceTest.php:85 + 81▕ $service = $this->makeService(); + 82▕ $record = $service->evaluateStudent($studentId, '2025-2026', 1); + 83▕ + 84▕ $this->assertNotNull($record); + ➜ 85▕ $this->assertSame(StudentPromotionRecord::STATUS_GRADUATED, $record->promotion_status); + 86▕ } + 87▕ + 88▕ public function test_audit_log_records_status_changes(): void + 89▕ { + + 1 tests/Unit/Services/Promotions/PromotionEligibilityServiceTest.php:85 + + ──────────────────────────────────────────────────────────────────────────── + FAILED Tests\Unit\Services\PurchaseOrders\PurchaseOr… ArgumentCountError + Too few arguments to function App\Services\PurchaseOrders\PurchaseOrderReceiveService::__construct(), 0 passed in /Volumes/ExternalApps/repos/alrahma_sunday_school_api/tests/Unit/Services/PurchaseOrders/PurchaseOrderReceiveServiceTest.php on line 42 and exactly 1 expected + + at app/Services/PurchaseOrders/PurchaseOrderReceiveService.php:16 + 12▕ + 13▕ class PurchaseOrderReceiveService + 14▕ { + 15▕ public function __construct( + ➜ 16▕ private InventoryMovementService $inventoryMovementService + 17▕ ) {} + 18▕ + 19▕ public function receive(int $poId, array $received, string $issuedBy): array + 20▕ { + + 1 app/Services/PurchaseOrders/PurchaseOrderReceiveService.php:16 + 2 tests/Unit/Services/PurchaseOrders/PurchaseOrderReceiveServiceTest.php:42 + + ──────────────────────────────────────────────────────────────────────────── + FAILED Tests\Unit\Services\Refunds\RefundOverpaymentServ… QueryException + SQLSTATE[23000]: Integrity constraint violation: 19 NOT NULL constraint failed: payments.number_of_installments (Connection: sqlite, Database: :memory:, SQL: insert into "payments" ("id", "parent_id", "invoice_id", "paid_amount", "total_amount", "balance", "payment_date", "school_year", "semester", "status") values (1, 10, 1, 150, 150, 0, 2025-01-10, 2025-2026, Fall, Paid)) + + at vendor/laravel/framework/src/Illuminate/Database/Connection.php:838 + 834▕ $exceptionType = $this->isUniqueConstraintError($e) + 835▕ ? UniqueConstraintViolationException::class + 836▕ : QueryException::class; + 837▕ + ➜ 838▕ throw new $exceptionType( + 839▕ $this->getNameWithReadWriteType(), + 840▕ $query, + 841▕ $this->prepareBindings($bindings), + 842▕ $e, + + +8 vendor frames  + 9 tests/Unit/Services/Refunds/RefundOverpaymentServiceTest.php:35 + + ──────────────────────────────────────────────────────────────────────────── + FAILED Tests\Unit\Services\Refunds\RefundPolicyServiceTe… QueryException + SQLSTATE[23000]: Integrity constraint violation: 19 NOT NULL constraint failed: payments.number_of_installments (Connection: sqlite, Database: :memory:, SQL: insert into "payments" ("id", "parent_id", "invoice_id", "paid_amount", "total_amount", "balance", "payment_date", "school_year", "semester", "status") values (1, 10, 1, 100, 100, 0, 2025-01-10, 2025-2026, Fall, Paid)) + + at vendor/laravel/framework/src/Illuminate/Database/Connection.php:838 + 834▕ $exceptionType = $this->isUniqueConstraintError($e) + 835▕ ? UniqueConstraintViolationException::class + 836▕ : QueryException::class; + 837▕ + ➜ 838▕ throw new $exceptionType( + 839▕ $this->getNameWithReadWriteType(), + 840▕ $query, + 841▕ $this->prepareBindings($bindings), + 842▕ $e, + + +8 vendor frames  + 9 tests/Unit/Services/Refunds/RefundPolicyServiceTest.php:73 + + ──────────────────────────────────────────────────────────────────────────── + FAILED Tests\Unit\Services\Refunds\RefundRequestServiceT… QueryException + SQLSTATE[23000]: Integrity constraint violation: 19 NOT NULL constraint failed: payments.number_of_installments (Connection: sqlite, Database: :memory:, SQL: insert into "payments" ("id", "parent_id", "invoice_id", "paid_amount", "total_amount", "balance", "payment_date", "school_year", "semester", "status") values (1, 10, 1, 150, 150, 0, 2025-01-10, 2025-2026, Fall, Paid)) + + at vendor/laravel/framework/src/Illuminate/Database/Connection.php:838 + 834▕ $exceptionType = $this->isUniqueConstraintError($e) + 835▕ ? UniqueConstraintViolationException::class + 836▕ : QueryException::class; + 837▕ + ➜ 838▕ throw new $exceptionType( + 839▕ $this->getNameWithReadWriteType(), + 840▕ $query, + 841▕ $this->prepareBindings($bindings), + 842▕ $e, + + +8 vendor frames  + 9 tests/Unit/Services/Refunds/RefundRequestServiceTest.php:48 + + ──────────────────────────────────────────────────────────────────────────── + FAILED Tests\Unit\Services\Refunds\RefundSummaryServiceT… QueryException + SQLSTATE[23000]: Integrity constraint violation: 19 NOT NULL constraint failed: payments.number_of_installments (Connection: sqlite, Database: :memory:, SQL: insert into "payments" ("id", "parent_id", "invoice_id", "paid_amount", "total_amount", "balance", "payment_date", "school_year", "semester", "status") values (1, 10, 1, 150, 150, 0, 2025-01-10, 2025-2026, Fall, Paid)) + + at vendor/laravel/framework/src/Illuminate/Database/Connection.php:838 + 834▕ $exceptionType = $this->isUniqueConstraintError($e) + 835▕ ? UniqueConstraintViolationException::class + 836▕ : QueryException::class; + 837▕ + ➜ 838▕ throw new $exceptionType( + 839▕ $this->getNameWithReadWriteType(), + 840▕ $query, + 841▕ $this->prepareBindings($bindings), + 842▕ $e, + + +8 vendor frames  + 9 tests/Unit/Services/Refunds/RefundSummaryServiceTest.php:29 + + ──────────────────────────────────────────────────────────────────────────── + FAILED Tests\Unit\Services\Roles\RoleAssignmentServiceTest > assi… Error + Class "Tests\Unit\Services\Roles\RoleStaffService" not found + + at tests/Unit/Services/Roles/RoleAssignmentServiceTest.php:44 + 40▕ 'created_at' => now(), + 41▕ 'updated_at' => now(), + 42▕ ]); + 43▕ + ➜ 44▕ $service = new RoleAssignmentService(new RoleStaffService); + 45▕ $result = $service->assignRoles($userId, [$roleId], $userId); + 46▕ + 47▕ $this->assertTrue($result['ok']); + 48▕ $this->assertDatabaseHas('user_roles', [ + + 1 tests/Unit/Services/Roles/RoleAssignmentServiceTest.php:44 + + ──────────────────────────────────────────────────────────────────────────── + FAILED Tests\Unit\Services\School\EnrollmentEventSer… ArgumentCountError + Too few arguments to function App\Services\School\EnrollmentEventService::__construct(), 2 passed in /Volumes/ExternalApps/repos/alrahma_sunday_school_api/tests/Unit/Services/School/EnrollmentEventServiceTest.php on line 21 and exactly 3 expected + + at app/Services/School/EnrollmentEventService.php:15 + 11▕ { + 12▕ public function __construct( + 13▕ private EmailService $emailService, + 14▕ private UserNotificationDispatchService $notifier, + ➜ 15▕ private ApplicationUrlService $urls, + 16▕ ) {} + 17▕ + 18▕ public function admissionUnderReview(array $parentData, array $students): array + 19▕ { + + 1 app/Services/School/EnrollmentEventService.php:15 + 2 tests/Unit/Services/School/EnrollmentEventServiceTest.php:21 + + ──────────────────────────────────────────────────────────────────────────── + FAILED Tests\Unit\Services\School\EnrollmentEventSer… ArgumentCountError + Too few arguments to function App\Services\School\EnrollmentEventService::__construct(), 2 passed in /Volumes/ExternalApps/repos/alrahma_sunday_school_api/tests/Unit/Services/School/EnrollmentEventServiceTest.php on line 40 and exactly 3 expected + + at app/Services/School/EnrollmentEventService.php:15 + 11▕ { + 12▕ public function __construct( + 13▕ private EmailService $emailService, + 14▕ private UserNotificationDispatchService $notifier, + ➜ 15▕ private ApplicationUrlService $urls, + 16▕ ) {} + 17▕ + 18▕ public function admissionUnderReview(array $parentData, array $students): array + 19▕ { + + 1 app/Services/School/EnrollmentEventService.php:15 + 2 tests/Unit/Services/School/EnrollmentEventServiceTest.php:40 + + ──────────────────────────────────────────────────────────────────────────── + FAILED Tests\Unit\Services\School\PaymentEventServic… ArgumentCountError + Too few arguments to function App\Services\School\PaymentEventService::__construct(), 2 passed in /Volumes/ExternalApps/repos/alrahma_sunday_school_api/tests/Unit/Services/School/PaymentEventServiceTest.php on line 21 and exactly 3 expected + + at app/Services/School/PaymentEventService.php:15 + 11▕ { + 12▕ public function __construct( + 13▕ private EmailService $emailService, + 14▕ private UserNotificationDispatchService $notifier, + ➜ 15▕ private ApplicationUrlService $urls, + 16▕ ) {} + 17▕ + 18▕ public function paymentReceived(array $data, array $studentdata = []): array + 19▕ { + + 1 app/Services/School/PaymentEventService.php:15 + 2 tests/Unit/Services/School/PaymentEventServiceTest.php:21 + + ──────────────────────────────────────────────────────────────────────────── + FAILED Tests\Unit\Services\School\PaymentEventServic… ArgumentCountError + Too few arguments to function App\Services\School\PaymentEventService::__construct(), 2 passed in /Volumes/ExternalApps/repos/alrahma_sunday_school_api/tests/Unit/Services/School/PaymentEventServiceTest.php on line 45 and exactly 3 expected + + at app/Services/School/PaymentEventService.php:15 + 11▕ { + 12▕ public function __construct( + 13▕ private EmailService $emailService, + 14▕ private UserNotificationDispatchService $notifier, + ➜ 15▕ private ApplicationUrlService $urls, + 16▕ ) {} + 17▕ + 18▕ public function paymentReceived(array $data, array $studentdata = []): array + 19▕ { + + 1 app/Services/School/PaymentEventService.php:15 + 2 tests/Unit/Services/School/PaymentEventServiceTest.php:45 + + ──────────────────────────────────────────────────────────────────────────── + FAILED Tests\Unit\Services\SchoolIds\SchoolIdAssignmentServiceTest > ass… + Failed asserting that 2600001 is identical to '2600001'. + + at tests/Unit/Services/SchoolIds/SchoolIdAssignmentServiceTest.php:24 + 20▕ $service = app(SchoolIdAssignmentService::class); + 21▕ $schoolId = $service->assignToUser($user->id); + 22▕ + 23▕ $this->assertNotNull($schoolId); + ➜ 24▕ $this->assertSame($schoolId, User::query()->findOrFail($user->id)->school_id); + 25▕ } + 26▕ + 27▕ public function test_assign_returns_existing_school_id(): void + 28▕ { + + 1 tests/Unit/Services/SchoolIds/SchoolIdAssignmentServiceTest.php:24 + + ──────────────────────────────────────────────────────────────────────────── + FAILED Tests\Unit\Services\Scores\ProjectCalculatorTest… QueryException + SQLSTATE[HY000]: General error: 1 no such function: REGEXP (Connection: sqlite, Database: :memory:, SQL: select avg("score") as aggregate from "project" where "student_id" = 9 and "semester" = Fall and "school_year" = 2024-2025 and "class_section_id" = 1 and "score" is not null and TRIM(COALESCE(score, '')) <> '' and TRIM(score) REGEXP '^-?[0-9]+(\.[0-9]+)?$') + + at vendor/laravel/framework/src/Illuminate/Database/Connection.php:838 + 834▕ $exceptionType = $this->isUniqueConstraintError($e) + 835▕ ? UniqueConstraintViolationException::class + 836▕ : QueryException::class; + 837▕ + ➜ 838▕ throw new $exceptionType( + 839▕ $this->getNameWithReadWriteType(), + 840▕ $query, + 841▕ $this->prepareBindings($bindings), + 842▕ $e, + + +13 vendor frames  + 14 app/Models/Project.php:137 + 15 app/Services/Scores/ProjectCalculator.php:14 + + ──────────────────────────────────────────────────────────────────────────── + FAILED Tests\Unit\Services\Security\IpBanCommandServiceT… QueryException + SQLSTATE[23000]: Integrity constraint violation: 19 NOT NULL constraint failed: ip_attempts.last_attempt_at (Connection: sqlite, Database: :memory:, SQL: insert into "ip_attempts" ("ip_address", "attempts") values (10.0.0.9, 1)) + + at vendor/laravel/framework/src/Illuminate/Database/Connection.php:838 + 834▕ $exceptionType = $this->isUniqueConstraintError($e) + 835▕ ? UniqueConstraintViolationException::class + 836▕ : QueryException::class; + 837▕ + ➜ 838▕ throw new $exceptionType( + 839▕ $this->getNameWithReadWriteType(), + 840▕ $query, + 841▕ $this->prepareBindings($bindings), + 842▕ $e, + + +8 vendor frames  + 9 tests/Unit/Services/Security/IpBanCommandServiceTest.php:16 + + ──────────────────────────────────────────────────────────────────────────── + FAILED Tests\Unit\Services\Security\IpBanCommandServiceT… QueryException + SQLSTATE[23000]: Integrity constraint violation: 19 NOT NULL constraint failed: ip_attempts.last_attempt_at (Connection: sqlite, Database: :memory:, SQL: insert into "ip_attempts" ("ip_address", "attempts", "blocked_until") values (10.0.0.10, 5, 2026-07-06 01:09:24)) + + at vendor/laravel/framework/src/Illuminate/Database/Connection.php:838 + 834▕ $exceptionType = $this->isUniqueConstraintError($e) + 835▕ ? UniqueConstraintViolationException::class + 836▕ : QueryException::class; + 837▕ + ➜ 838▕ throw new $exceptionType( + 839▕ $this->getNameWithReadWriteType(), + 840▕ $query, + 841▕ $this->prepareBindings($bindings), + 842▕ $e, + + +8 vendor frames  + 9 tests/Unit/Services/Security/IpBanCommandServiceTest.php:32 + + ──────────────────────────────────────────────────────────────────────────── + FAILED Tests\Unit\Services\Security\IpBanQueryServiceTes… QueryException + SQLSTATE[23000]: Integrity constraint violation: 19 NOT NULL constraint failed: ip_attempts.last_attempt_at (Connection: sqlite, Database: :memory:, SQL: insert into "ip_attempts" ("attempts", "blocked_until", "ip_address") values (2, 2026-07-06 00:09:24, 10.0.0.1), (2, 2026-07-05 21:09:24, 10.0.0.2)) + + at vendor/laravel/framework/src/Illuminate/Database/Connection.php:838 + 834▕ $exceptionType = $this->isUniqueConstraintError($e) + 835▕ ? UniqueConstraintViolationException::class + 836▕ : QueryException::class; + 837▕ + ➜ 838▕ throw new $exceptionType( + 839▕ $this->getNameWithReadWriteType(), + 840▕ $query, + 841▕ $this->prepareBindings($bindings), + 842▕ $e, + + +8 vendor frames  + 9 tests/Unit/Services/Security/IpBanQueryServiceTest.php:16 + + ──────────────────────────────────────────────────────────────────────────── + FAILED Tests\Unit\Services\Settings\SchoolCalendar\Schoo… QueryException + SQLSTATE[23000]: Integrity constraint violation: 19 NOT NULL constraint failed: calendar_events.date (Connection: sqlite, Database: :memory:, SQL: update "calendar_events" set "title" = Updated Event, "date" = ?, "description" = ?, "semester" = , "school_year" = , "updated_at" = 2026-07-05 22:09:25 where "id" = 1) + + at vendor/laravel/framework/src/Illuminate/Database/Connection.php:838 + 834▕ $exceptionType = $this->isUniqueConstraintError($e) + 835▕ ? UniqueConstraintViolationException::class + 836▕ : QueryException::class; + 837▕ + ➜ 838▕ throw new $exceptionType( + 839▕ $this->getNameWithReadWriteType(), + 840▕ $query, + 841▕ $this->prepareBindings($bindings), + 842▕ $e, + + +11 vendor frames  + 12 app/Services/Settings/SchoolCalendar/SchoolCalendarMutationService.php:44 + +3 vendor frames  + 16 app/Services/Settings/SchoolCalendar/SchoolCalendarMutationService.php:42 + + ──────────────────────────────────────────────────────────────────────────── + FAILED Tests\Unit\Services\Settings\SchoolCalendar\S… ArgumentCountError + Too few arguments to function App\Services\Settings\SchoolCalendar\SchoolCalendarNotificationService::__construct(), 1 passed in /Volumes/ExternalApps/repos/alrahma_sunday_school_api/tests/Unit/Services/Settings/SchoolCalendar/SchoolCalendarNotificationServiceTest.php on line 15 and exactly 2 expected + + at app/Services/Settings/SchoolCalendar/SchoolCalendarNotificationService.php:15 + 11▕ class SchoolCalendarNotificationService + 12▕ { + 13▕ public function __construct( + 14▕ private EmailService $emailService, + ➜ 15▕ private ApplicationUrlService $urls, + 16▕ ) {} + 17▕ + 18▕ public function notify(array $event, array $targets): array + 19▕ { + + 1 app/Services/Settings/SchoolCalendar/SchoolCalendarNotificationService.php:15 + 2 tests/Unit/Services/Settings/SchoolCalendar/SchoolCalendarNotificationServiceTest.php:15 + + ──────────────────────────────────────────────────────────────────────────── + FAILED Tests\Unit\Services\Students\StudentProfileServic… ErrorException + Undefined variable $shouldSyncConditions + + at app/Services/Students/StudentProfileService.php:50 + 46▕ if (! empty($studentData)) { + 47▕ $student->update($studentData); + 48▕ } + 49▕ + ➜ 50▕ if ($shouldSyncConditions) { + 51▕ $this->syncHealthList($student->id, StudentMedicalCondition::class, 'condition_name', $conditions); + 52▕ } + 53▕ + 54▕ if ($shouldSyncAllergies) { + + +3 vendor frames  + 4 app/Services/Students/StudentProfileService.php:45 + 5 tests/Unit/Services/Students/StudentProfileServiceTest.php:19 + + ──────────────────────────────────────────────────────────────────────────── + FAILED Tests\Unit\Services\Students\StudentScoreCardServ… QueryException + SQLSTATE[23000]: Integrity constraint violation: 19 NOT NULL constraint failed: semester_scores.school_id (Connection: sqlite, Database: :memory:, SQL: insert into "semester_scores" ("student_id", "class_section_id", "school_year", "semester", "semester_score") values (1, 601, 2025-2026, Fall, 88)) + + at vendor/laravel/framework/src/Illuminate/Database/Connection.php:838 + 834▕ $exceptionType = $this->isUniqueConstraintError($e) + 835▕ ? UniqueConstraintViolationException::class + 836▕ : QueryException::class; + 837▕ + ➜ 838▕ throw new $exceptionType( + 839▕ $this->getNameWithReadWriteType(), + 840▕ $query, + 841▕ $this->prepareBindings($bindings), + 842▕ $e, + + +8 vendor frames  + 9 tests/Unit/Services/Students/StudentScoreCardServiceTest.php:19 + + ──────────────────────────────────────────────────────────────────────────── + FAILED Tests\Unit\Services\Teachers\TeacherAbsenceSe… ArgumentCountError + Too few arguments to function App\Services\Teachers\TeacherAbsenceService::__construct(), 3 passed in /Volumes/ExternalApps/repos/alrahma_sunday_school_api/tests/Unit/Services/Teachers/TeacherAbsenceServiceTest.php on line 25 and exactly 4 expected + + at app/Services/Teachers/TeacherAbsenceService.php:20 + 16▕ public function __construct( + 17▕ private TeacherConfigService $configService, + 18▕ private SemesterRangeService $semesterRangeService, + 19▕ private StaffTimeOffLinkService $staffTimeOffLinkService, + ➜ 20▕ private ApplicationUrlService $urls, + 21▕ ) {} + 22▕ + 23▕ public function formData(int $userId): array + 24▕ { + + 1 app/Services/Teachers/TeacherAbsenceService.php:20 + 2 tests/Unit/Services/Teachers/TeacherAbsenceServiceTest.php:25 + + ──────────────────────────────────────────────────────────────────────────── + FAILED Tests\Unit\Services\Teachers\TeacherAbsenceSe… ArgumentCountError + Too few arguments to function App\Services\Teachers\TeacherAbsenceService::__construct(), 3 passed in /Volumes/ExternalApps/repos/alrahma_sunday_school_api/tests/Unit/Services/Teachers/TeacherAbsenceServiceTest.php on line 44 and exactly 4 expected + + at app/Services/Teachers/TeacherAbsenceService.php:20 + 16▕ public function __construct( + 17▕ private TeacherConfigService $configService, + 18▕ private SemesterRangeService $semesterRangeService, + 19▕ private StaffTimeOffLinkService $staffTimeOffLinkService, + ➜ 20▕ private ApplicationUrlService $urls, + 21▕ ) {} + 22▕ + 23▕ public function formData(int $userId): array + 24▕ { + + 1 app/Services/Teachers/TeacherAbsenceService.php:20 + 2 tests/Unit/Services/Teachers/TeacherAbsenceServiceTest.php:44 + + ──────────────────────────────────────────────────────────────────────────── + FAILED Tests\Unit\Services\Whatsapp\WhatsappInviteNotificationServiceTes… + Failed asserting that true is false. + + at tests/Unit/Services/Whatsapp/WhatsappInviteNotificationServiceTest.php:20 + 16▕ { + 17▕ $service = new WhatsappInviteNotificationService; + 18▕ $result = $service->dispatch([], '2025-2026', 'Fall'); + 19▕ + ➜ 20▕ $this->assertFalse($result['ok']); + 21▕ } + 22▕ + 23▕ public function test_dispatch_triggers_event_when_listener_registered(): void + 24▕ { + + 1 tests/Unit/Services/Whatsapp/WhatsappInviteNotificationServiceTest.php:20 + + ──────────────────────────────────────────────────────────────────────────── + FAILED Tests\Feature\Api\ApiAuthenticationAndAuthorizationTest > admin o… + GET /api/v1/school-years should reject a non-admin user; got 200 +Failed asserting that an array contains 200. + + at tests/Feature/Api/ApiAuthenticationAndAuthorizationTest.php:91 + 87▕ + 88▕ foreach ($this->adminOnlyEndpoints() as [$method, $uri]) { + 89▕ $response = $this->json($method, $uri); + 90▕ + ➜ 91▕ $this->assertContains( + 92▕ $response->getStatusCode(), + 93▕ [401, 403], + 94▕ "$method $uri should reject a non-admin user; got {$response->getStatusCode()}" + 95▕ ); + + 1 tests/Feature/Api/ApiAuthenticationAndAuthorizationTest.php:91 + + ──────────────────────────────────────────────────────────────────────────── + FAILED Tests\Feature\Api\ApiRouteContractTest > every api route points t… + These API routes reference missing controllers or methods: +POST api/v1/school-years/{schoolYear}/archive -> App\Http\Controllers\Api\SchoolYears\SchoolYearController@archive +Failed asserting that two arrays are identical. + -Array &0 [] + +Array &0 [ + + 0 => 'POST api/v1/school-years/{schoolYear}/archive -> App\Http\Controllers\Api\SchoolYears\SchoolYearController@archive', + +] + + + at tests/Feature/Api/ApiRouteContractTest.php:31 + 27▕ $missing[] = implode('|', $route->methods()).' '.$route->uri().' -> '.$action; + 28▕ } + 29▕ } + 30▕ + ➜ 31▕ $this->assertSame([], $missing, "These API routes reference missing controllers or methods:\n".implode("\n", $missing)); + 32▕ } + 33▕ + 34▕ public function test_api_routes_do_not_duplicate_method_and_uri_pairs(): void + 35▕ { + + 1 tests/Feature/Api/ApiRouteContractTest.php:31 + + ──────────────────────────────────────────────────────────────────────────── + FAILED Tests\Feature\Api\V1\FullSurface\ApiAuthorizationCacheInvalidatio… + parent privilege escalation should be blocked at GET api/v1/school-years returned unexpected status 200. Body: {"ok":true,"data":[{"id":1,"name":"2025-2026","start_date":"2025-09-01","end_date":"2026-06-30","status":"active","is_current":true,"closed_at":null,"closed_by":null}],"meta":{"school_year":"2025-2026","current_school_year":"2025-2026","semester":"Fall","current_semester":"Fall","school_years":[{"id":1,"name":"2025-2026","label":"2025-2026","start_date":"2025-09-01","end_date":"2026-06-30","status":"active","is_current":true,"is_editable":true}],"semesters":[{"name":"Fall","label":"Fall","is_current":true},{"name":"Spring","label":"Spring","is_current":false}]},"school_years":[{"id":1,"name":"2025-2026","label":"2025-2026","start_date":"2025-09-01","end_date":"2026-06-30","status":"active","is_current":true,"is_editable":true}],"current_school_year":"2025-2026","current_semester":"Fall"} +Failed asserting that an array contains 200. + + at tests/Concerns/AssertsE2EApiResponses.php:23 + 19▕ * @param array $statuses + 20▕ */ + 21▕ protected function assertStatusIn(TestResponse $response, array $statuses, string $context): void + 22▕ { + ➜ 23▕ $this->assertContains( + 24▕ $response->getStatusCode(), + 25▕ $statuses, + 26▕ $context.' returned unexpected status '.$response->getStatusCode().'. Body: '.$response->getContent() + 27▕ ); + + 1 tests/Concerns/AssertsE2EApiResponses.php:23 + 2 tests/Feature/Api/V1/FullSurface/ApiAuthorizationCacheInvalidationContractTest.php:29 + + ──────────────────────────────────────────────────────────────────────────── + FAILED Tests\Feature\Api\V1\FullSurface\ApiBatch12BulkMutationBoundaryCo… + POST api/v1/school-years/{schoolYear}/archive returned unexpected status 500. Body: { + "message": "Method App\\Http\\Controllers\\Api\\SchoolYears\\SchoolYearController::archive does not exist.", + "exception": "BadMethodCallException", + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Routing/Controller.php", + "line": 68, + "trace": [ + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Routing/Controller.php", + "line": 54, + "function": "__call", + "class": "Illuminate\\Routing\\Controller", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Routing/ControllerDispatcher.php", + "line": 43, + "function": "callAction", + "class": "Illuminate\\Routing\\Controller", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Routing/Route.php", + "line": 265, + "function": "dispatch", + "class": "Illuminate\\Routing\\ControllerDispatcher", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Routing/Route.php", + "line": 211, + "function": "runController", + "class": "Illuminate\\Routing\\Route", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Routing/Router.php", + "line": 822, + "function": "run", + "class": "Illuminate\\Routing\\Route", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 180, + "function": "{closure:Illuminate\\Routing\\Router::runRouteWithinStack():821}", + "class": "Illuminate\\Routing\\Router", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/app/Http/Middleware/RequirePermission.php", + "line": 29, + "function": "{closure:Illuminate\\Pipeline\\Pipeline::prepareDestination():178}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "App\\Http\\Middleware\\RequirePermission", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/app/Http/Middleware/EnsureAccountActive.php", + "line": 32, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "App\\Http\\Middleware\\EnsureAccountActive", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/app/Http/Middleware/MultiAuth.php", + "line": 32, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "App\\Http\\Middleware\\MultiAuth", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Routing/Middleware/SubstituteBindings.php", + "line": 50, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "Illuminate\\Routing\\Middleware\\SubstituteBindings", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 137, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Routing/Router.php", + "line": 821, + "function": "then", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Routing/Router.php", + "line": 800, + "function": "runRouteWithinStack", + "class": "Illuminate\\Routing\\Router", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Routing/Router.php", + "line": 764, + "function": "runRoute", + "class": "Illuminate\\Routing\\Router", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Routing/Router.php", + "line": 753, + "function": "dispatchToRoute", + "class": "Illuminate\\Routing\\Router", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php", + "line": 200, + "function": "dispatch", + "class": "Illuminate\\Routing\\Router", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 180, + "function": "{closure:Illuminate\\Foundation\\Http\\Kernel::dispatchToRouter():197}", + "class": "Illuminate\\Foundation\\Http\\Kernel", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/app/Http/Middleware/SecurityHeaders.php", + "line": 22, + "function": "{closure:Illuminate\\Pipeline\\Pipeline::prepareDestination():178}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "App\\Http\\Middleware\\SecurityHeaders", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/TransformsRequest.php", + "line": 21, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/ConvertEmptyStringsToNull.php", + "line": 31, + "function": "handle", + "class": "Illuminate\\Foundation\\Http\\Middleware\\TransformsRequest", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "Illuminate\\Foundation\\Http\\Middleware\\ConvertEmptyStringsToNull", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/TransformsRequest.php", + "line": 21, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/TrimStrings.php", + "line": 51, + "function": "handle", + "class": "Illuminate\\Foundation\\Http\\Middleware\\TransformsRequest", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "Illuminate\\Foundation\\Http\\Middleware\\TrimStrings", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Http/Middleware/ValidatePostSize.php", + "line": 27, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "Illuminate\\Http\\Middleware\\ValidatePostSize", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/PreventRequestsDuringMaintenance.php", + "line": 109, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "Illuminate\\Foundation\\Http\\Middleware\\PreventRequestsDuringMaintenance", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Http/Middleware/HandleCors.php", + "line": 74, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "Illuminate\\Http\\Middleware\\HandleCors", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Http/Middleware/TrustProxies.php", + "line": 58, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "Illuminate\\Http\\Middleware\\TrustProxies", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/InvokeDeferredCallbacks.php", + "line": 22, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "Illuminate\\Foundation\\Http\\Middleware\\InvokeDeferredCallbacks", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Http/Middleware/ValidatePathEncoding.php", + "line": 26, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "Illuminate\\Http\\Middleware\\ValidatePathEncoding", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 137, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php", + "line": 175, + "function": "then", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php", + "line": 144, + "function": "sendRequestThroughRouter", + "class": "Illuminate\\Foundation\\Http\\Kernel", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Foundation/Testing/Concerns/MakesHttpRequests.php", + "line": 607, + "function": "handle", + "class": "Illuminate\\Foundation\\Http\\Kernel", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Foundation/Testing/Concerns/MakesHttpRequests.php", + "line": 573, + "function": "call", + "class": "Illuminate\\Foundation\\Testing\\TestCase", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/tests/Feature/Api/V1/FullSurface/Support/FullSurfaceE2EContractCase.php", + "line": 190, + "function": "json", + "class": "Illuminate\\Foundation\\Testing\\TestCase", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/tests/Feature/Api/V1/FullSurface/ApiBatch12BulkMutationBoundaryContractTest.php", + "line": 24, + "function": "requestAs", + "class": "Tests\\Feature\\Api\\V1\\FullSurface\\Support\\FullSurfaceE2EContractCase", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/phpunit/phpunit/src/Framework/TestCase.php", + "line": 1667, + "function": "test_bulk_mutation_routes_reject_empty_and_cross_domain_targets_cleanly", + "class": "Tests\\Feature\\Api\\V1\\FullSurface\\ApiBatch12BulkMutationBoundaryContractTest", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/phpunit/phpunit/src/Framework/TestCase.php", + "line": 519, + "function": "runTest", + "class": "PHPUnit\\Framework\\TestCase", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/phpunit/phpunit/src/Framework/TestRunner/TestRunner.php", + "line": 87, + "function": "runBare", + "class": "PHPUnit\\Framework\\TestCase", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/phpunit/phpunit/src/Framework/TestCase.php", + "line": 365, + "function": "run", + "class": "PHPUnit\\Framework\\TestRunner", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/phpunit/phpunit/src/Framework/TestSuite.php", + "line": 369, + "function": "run", + "class": "PHPUnit\\Framework\\TestCase", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/phpunit/phpunit/src/Framework/TestSuite.php", + "line": 369, + "function": "run", + "class": "PHPUnit\\Framework\\TestSuite", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/phpunit/phpunit/src/Framework/TestSuite.php", + "line": 369, + "function": "run", + "class": "PHPUnit\\Framework\\TestSuite", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/phpunit/phpunit/src/TextUI/TestRunner.php", + "line": 64, + "function": "run", + "class": "PHPUnit\\Framework\\TestSuite", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/phpunit/phpunit/src/TextUI/Application.php", + "line": 211, + "function": "run", + "class": "PHPUnit\\TextUI\\TestRunner", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/phpunit/phpunit/phpunit", + "line": 104, + "function": "run", + "class": "PHPUnit\\TextUI\\Application", + "type": "->" + } + ] +} +Failed asserting that an array contains 500. + + at tests/Concerns/AssertsE2EApiResponses.php:23 + 19▕ * @param array $statuses + 20▕ */ + 21▕ protected function assertStatusIn(TestResponse $response, array $statuses, string $context): void + 22▕ { + ➜ 23▕ $this->assertContains( + 24▕ $response->getStatusCode(), + 25▕ $statuses, + 26▕ $context.' returned unexpected status '.$response->getStatusCode().'. Body: '.$response->getContent() + 27▕ ); + + 1 tests/Concerns/AssertsE2EApiResponses.php:23 + 2 tests/Feature/Api/V1/FullSurface/Support/FullSurfaceE2EContractCase.php:343 + + ──────────────────────────────────────────────────────────────────────────── + FAILED Tests\Feature\Api\V1\FullSurface\ApiBatch13LocaleCalendarReligiou… + POST api/v1/school-years/{schoolYear}/archive returned unexpected status 500. Body: { + "message": "Method App\\Http\\Controllers\\Api\\SchoolYears\\SchoolYearController::archive does not exist.", + "exception": "BadMethodCallException", + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Routing/Controller.php", + "line": 68, + "trace": [ + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Routing/Controller.php", + "line": 54, + "function": "__call", + "class": "Illuminate\\Routing\\Controller", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Routing/ControllerDispatcher.php", + "line": 43, + "function": "callAction", + "class": "Illuminate\\Routing\\Controller", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Routing/Route.php", + "line": 265, + "function": "dispatch", + "class": "Illuminate\\Routing\\ControllerDispatcher", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Routing/Route.php", + "line": 211, + "function": "runController", + "class": "Illuminate\\Routing\\Route", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Routing/Router.php", + "line": 822, + "function": "run", + "class": "Illuminate\\Routing\\Route", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 180, + "function": "{closure:Illuminate\\Routing\\Router::runRouteWithinStack():821}", + "class": "Illuminate\\Routing\\Router", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/app/Http/Middleware/RequirePermission.php", + "line": 29, + "function": "{closure:Illuminate\\Pipeline\\Pipeline::prepareDestination():178}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "App\\Http\\Middleware\\RequirePermission", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/app/Http/Middleware/EnsureAccountActive.php", + "line": 32, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "App\\Http\\Middleware\\EnsureAccountActive", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/app/Http/Middleware/MultiAuth.php", + "line": 32, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "App\\Http\\Middleware\\MultiAuth", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Routing/Middleware/SubstituteBindings.php", + "line": 50, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "Illuminate\\Routing\\Middleware\\SubstituteBindings", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 137, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Routing/Router.php", + "line": 821, + "function": "then", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Routing/Router.php", + "line": 800, + "function": "runRouteWithinStack", + "class": "Illuminate\\Routing\\Router", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Routing/Router.php", + "line": 764, + "function": "runRoute", + "class": "Illuminate\\Routing\\Router", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Routing/Router.php", + "line": 753, + "function": "dispatchToRoute", + "class": "Illuminate\\Routing\\Router", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php", + "line": 200, + "function": "dispatch", + "class": "Illuminate\\Routing\\Router", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 180, + "function": "{closure:Illuminate\\Foundation\\Http\\Kernel::dispatchToRouter():197}", + "class": "Illuminate\\Foundation\\Http\\Kernel", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/app/Http/Middleware/SecurityHeaders.php", + "line": 22, + "function": "{closure:Illuminate\\Pipeline\\Pipeline::prepareDestination():178}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "App\\Http\\Middleware\\SecurityHeaders", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/TransformsRequest.php", + "line": 21, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/ConvertEmptyStringsToNull.php", + "line": 31, + "function": "handle", + "class": "Illuminate\\Foundation\\Http\\Middleware\\TransformsRequest", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "Illuminate\\Foundation\\Http\\Middleware\\ConvertEmptyStringsToNull", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/TransformsRequest.php", + "line": 21, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/TrimStrings.php", + "line": 51, + "function": "handle", + "class": "Illuminate\\Foundation\\Http\\Middleware\\TransformsRequest", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "Illuminate\\Foundation\\Http\\Middleware\\TrimStrings", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Http/Middleware/ValidatePostSize.php", + "line": 27, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "Illuminate\\Http\\Middleware\\ValidatePostSize", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/PreventRequestsDuringMaintenance.php", + "line": 109, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "Illuminate\\Foundation\\Http\\Middleware\\PreventRequestsDuringMaintenance", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Http/Middleware/HandleCors.php", + "line": 74, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "Illuminate\\Http\\Middleware\\HandleCors", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Http/Middleware/TrustProxies.php", + "line": 58, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "Illuminate\\Http\\Middleware\\TrustProxies", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/InvokeDeferredCallbacks.php", + "line": 22, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "Illuminate\\Foundation\\Http\\Middleware\\InvokeDeferredCallbacks", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Http/Middleware/ValidatePathEncoding.php", + "line": 26, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "Illuminate\\Http\\Middleware\\ValidatePathEncoding", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 137, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php", + "line": 175, + "function": "then", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php", + "line": 144, + "function": "sendRequestThroughRouter", + "class": "Illuminate\\Foundation\\Http\\Kernel", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Foundation/Testing/Concerns/MakesHttpRequests.php", + "line": 607, + "function": "handle", + "class": "Illuminate\\Foundation\\Http\\Kernel", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Foundation/Testing/Concerns/MakesHttpRequests.php", + "line": 573, + "function": "call", + "class": "Illuminate\\Foundation\\Testing\\TestCase", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/tests/Feature/Api/V1/FullSurface/Support/FullSurfaceE2EContractCase.php", + "line": 190, + "function": "json", + "class": "Illuminate\\Foundation\\Testing\\TestCase", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/tests/Feature/Api/V1/FullSurface/ApiBatch13LocaleCalendarReligiousDateContractTest.php", + "line": 25, + "function": "requestAs", + "class": "Tests\\Feature\\Api\\V1\\FullSurface\\Support\\FullSurfaceE2EContractCase", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/phpunit/phpunit/src/Framework/TestCase.php", + "line": 1667, + "function": "test_calendar_and_event_routes_handle_locale_specific_dates_cleanly", + "class": "Tests\\Feature\\Api\\V1\\FullSurface\\ApiBatch13LocaleCalendarReligiousDateContractTest", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/phpunit/phpunit/src/Framework/TestCase.php", + "line": 519, + "function": "runTest", + "class": "PHPUnit\\Framework\\TestCase", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/phpunit/phpunit/src/Framework/TestRunner/TestRunner.php", + "line": 87, + "function": "runBare", + "class": "PHPUnit\\Framework\\TestCase", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/phpunit/phpunit/src/Framework/TestCase.php", + "line": 365, + "function": "run", + "class": "PHPUnit\\Framework\\TestRunner", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/phpunit/phpunit/src/Framework/TestSuite.php", + "line": 369, + "function": "run", + "class": "PHPUnit\\Framework\\TestCase", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/phpunit/phpunit/src/Framework/TestSuite.php", + "line": 369, + "function": "run", + "class": "PHPUnit\\Framework\\TestSuite", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/phpunit/phpunit/src/Framework/TestSuite.php", + "line": 369, + "function": "run", + "class": "PHPUnit\\Framework\\TestSuite", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/phpunit/phpunit/src/TextUI/TestRunner.php", + "line": 64, + "function": "run", + "class": "PHPUnit\\Framework\\TestSuite", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/phpunit/phpunit/src/TextUI/Application.php", + "line": 211, + "function": "run", + "class": "PHPUnit\\TextUI\\TestRunner", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/phpunit/phpunit/phpunit", + "line": 104, + "function": "run", + "class": "PHPUnit\\TextUI\\Application", + "type": "->" + } + ] +} +Failed asserting that an array contains 500. + + at tests/Concerns/AssertsE2EApiResponses.php:23 + 19▕ * @param array $statuses + 20▕ */ + 21▕ protected function assertStatusIn(TestResponse $response, array $statuses, string $context): void + 22▕ { + ➜ 23▕ $this->assertContains( + 24▕ $response->getStatusCode(), + 25▕ $statuses, + 26▕ $context.' returned unexpected status '.$response->getStatusCode().'. Body: '.$response->getContent() + 27▕ ); + + 1 tests/Concerns/AssertsE2EApiResponses.php:23 + 2 tests/Feature/Api/V1/FullSurface/Support/FullSurfaceE2EContractCase.php:343 + + ──────────────────────────────────────────────────────────────────────────── + FAILED Tests\Feature\Api\V1\FullSurface\ApiBatch14AcademicPromotionRollb… + POST api/v1/school-years/{schoolYear}/archive returned unexpected status 500. Body: { + "message": "Method App\\Http\\Controllers\\Api\\SchoolYears\\SchoolYearController::archive does not exist.", + "exception": "BadMethodCallException", + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Routing/Controller.php", + "line": 68, + "trace": [ + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Routing/Controller.php", + "line": 54, + "function": "__call", + "class": "Illuminate\\Routing\\Controller", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Routing/ControllerDispatcher.php", + "line": 43, + "function": "callAction", + "class": "Illuminate\\Routing\\Controller", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Routing/Route.php", + "line": 265, + "function": "dispatch", + "class": "Illuminate\\Routing\\ControllerDispatcher", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Routing/Route.php", + "line": 211, + "function": "runController", + "class": "Illuminate\\Routing\\Route", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Routing/Router.php", + "line": 822, + "function": "run", + "class": "Illuminate\\Routing\\Route", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 180, + "function": "{closure:Illuminate\\Routing\\Router::runRouteWithinStack():821}", + "class": "Illuminate\\Routing\\Router", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/app/Http/Middleware/RequirePermission.php", + "line": 29, + "function": "{closure:Illuminate\\Pipeline\\Pipeline::prepareDestination():178}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "App\\Http\\Middleware\\RequirePermission", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/app/Http/Middleware/EnsureAccountActive.php", + "line": 32, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "App\\Http\\Middleware\\EnsureAccountActive", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/app/Http/Middleware/MultiAuth.php", + "line": 32, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "App\\Http\\Middleware\\MultiAuth", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Routing/Middleware/SubstituteBindings.php", + "line": 50, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "Illuminate\\Routing\\Middleware\\SubstituteBindings", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 137, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Routing/Router.php", + "line": 821, + "function": "then", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Routing/Router.php", + "line": 800, + "function": "runRouteWithinStack", + "class": "Illuminate\\Routing\\Router", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Routing/Router.php", + "line": 764, + "function": "runRoute", + "class": "Illuminate\\Routing\\Router", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Routing/Router.php", + "line": 753, + "function": "dispatchToRoute", + "class": "Illuminate\\Routing\\Router", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php", + "line": 200, + "function": "dispatch", + "class": "Illuminate\\Routing\\Router", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 180, + "function": "{closure:Illuminate\\Foundation\\Http\\Kernel::dispatchToRouter():197}", + "class": "Illuminate\\Foundation\\Http\\Kernel", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/app/Http/Middleware/SecurityHeaders.php", + "line": 22, + "function": "{closure:Illuminate\\Pipeline\\Pipeline::prepareDestination():178}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "App\\Http\\Middleware\\SecurityHeaders", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/TransformsRequest.php", + "line": 21, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/ConvertEmptyStringsToNull.php", + "line": 31, + "function": "handle", + "class": "Illuminate\\Foundation\\Http\\Middleware\\TransformsRequest", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "Illuminate\\Foundation\\Http\\Middleware\\ConvertEmptyStringsToNull", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/TransformsRequest.php", + "line": 21, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/TrimStrings.php", + "line": 51, + "function": "handle", + "class": "Illuminate\\Foundation\\Http\\Middleware\\TransformsRequest", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "Illuminate\\Foundation\\Http\\Middleware\\TrimStrings", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Http/Middleware/ValidatePostSize.php", + "line": 27, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "Illuminate\\Http\\Middleware\\ValidatePostSize", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/PreventRequestsDuringMaintenance.php", + "line": 109, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "Illuminate\\Foundation\\Http\\Middleware\\PreventRequestsDuringMaintenance", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Http/Middleware/HandleCors.php", + "line": 74, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "Illuminate\\Http\\Middleware\\HandleCors", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Http/Middleware/TrustProxies.php", + "line": 58, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "Illuminate\\Http\\Middleware\\TrustProxies", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/InvokeDeferredCallbacks.php", + "line": 22, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "Illuminate\\Foundation\\Http\\Middleware\\InvokeDeferredCallbacks", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Http/Middleware/ValidatePathEncoding.php", + "line": 26, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "Illuminate\\Http\\Middleware\\ValidatePathEncoding", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 137, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php", + "line": 175, + "function": "then", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php", + "line": 144, + "function": "sendRequestThroughRouter", + "class": "Illuminate\\Foundation\\Http\\Kernel", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Foundation/Testing/Concerns/MakesHttpRequests.php", + "line": 607, + "function": "handle", + "class": "Illuminate\\Foundation\\Http\\Kernel", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Foundation/Testing/Concerns/MakesHttpRequests.php", + "line": 573, + "function": "call", + "class": "Illuminate\\Foundation\\Testing\\TestCase", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/tests/Feature/Api/V1/FullSurface/Support/FullSurfaceE2EContractCase.php", + "line": 190, + "function": "json", + "class": "Illuminate\\Foundation\\Testing\\TestCase", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/tests/Feature/Api/V1/FullSurface/ApiBatch14AcademicPromotionRollbackIntegrityContractTest.php", + "line": 13, + "function": "requestAs", + "class": "Tests\\Feature\\Api\\V1\\FullSurface\\Support\\FullSurfaceE2EContractCase", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/phpunit/phpunit/src/Framework/TestCase.php", + "line": 1667, + "function": "test_promotion_and_school_year_routes_reject_unsafe_rollback_payloads", + "class": "Tests\\Feature\\Api\\V1\\FullSurface\\ApiBatch14AcademicPromotionRollbackIntegrityContractTest", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/phpunit/phpunit/src/Framework/TestCase.php", + "line": 519, + "function": "runTest", + "class": "PHPUnit\\Framework\\TestCase", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/phpunit/phpunit/src/Framework/TestRunner/TestRunner.php", + "line": 87, + "function": "runBare", + "class": "PHPUnit\\Framework\\TestCase", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/phpunit/phpunit/src/Framework/TestCase.php", + "line": 365, + "function": "run", + "class": "PHPUnit\\Framework\\TestRunner", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/phpunit/phpunit/src/Framework/TestSuite.php", + "line": 369, + "function": "run", + "class": "PHPUnit\\Framework\\TestCase", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/phpunit/phpunit/src/Framework/TestSuite.php", + "line": 369, + "function": "run", + "class": "PHPUnit\\Framework\\TestSuite", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/phpunit/phpunit/src/Framework/TestSuite.php", + "line": 369, + "function": "run", + "class": "PHPUnit\\Framework\\TestSuite", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/phpunit/phpunit/src/TextUI/TestRunner.php", + "line": 64, + "function": "run", + "class": "PHPUnit\\Framework\\TestSuite", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/phpunit/phpunit/src/TextUI/Application.php", + "line": 211, + "function": "run", + "class": "PHPUnit\\TextUI\\TestRunner", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/phpunit/phpunit/phpunit", + "line": 104, + "function": "run", + "class": "PHPUnit\\TextUI\\Application", + "type": "->" + } + ] +} +Failed asserting that an array contains 500. + + at tests/Concerns/AssertsE2EApiResponses.php:23 + 19▕ * @param array $statuses + 20▕ */ + 21▕ protected function assertStatusIn(TestResponse $response, array $statuses, string $context): void + 22▕ { + ➜ 23▕ $this->assertContains( + 24▕ $response->getStatusCode(), + 25▕ $statuses, + 26▕ $context.' returned unexpected status '.$response->getStatusCode().'. Body: '.$response->getContent() + 27▕ ); + + 1 tests/Concerns/AssertsE2EApiResponses.php:23 + 2 tests/Feature/Api/V1/FullSurface/Support/FullSurfaceE2EContractCase.php:343 + + ──────────────────────────────────────────────────────────────────────────── + FAILED Tests\Feature\Api\V1\FullSurface\ApiBatch14DataLifecycleArchivePu… + POST api/v1/school-years/{schoolYear}/archive returned unexpected status 500. Body: { + "message": "Method App\\Http\\Controllers\\Api\\SchoolYears\\SchoolYearController::archive does not exist.", + "exception": "BadMethodCallException", + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Routing/Controller.php", + "line": 68, + "trace": [ + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Routing/Controller.php", + "line": 54, + "function": "__call", + "class": "Illuminate\\Routing\\Controller", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Routing/ControllerDispatcher.php", + "line": 43, + "function": "callAction", + "class": "Illuminate\\Routing\\Controller", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Routing/Route.php", + "line": 265, + "function": "dispatch", + "class": "Illuminate\\Routing\\ControllerDispatcher", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Routing/Route.php", + "line": 211, + "function": "runController", + "class": "Illuminate\\Routing\\Route", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Routing/Router.php", + "line": 822, + "function": "run", + "class": "Illuminate\\Routing\\Route", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 180, + "function": "{closure:Illuminate\\Routing\\Router::runRouteWithinStack():821}", + "class": "Illuminate\\Routing\\Router", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/app/Http/Middleware/RequirePermission.php", + "line": 29, + "function": "{closure:Illuminate\\Pipeline\\Pipeline::prepareDestination():178}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "App\\Http\\Middleware\\RequirePermission", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/app/Http/Middleware/EnsureAccountActive.php", + "line": 32, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "App\\Http\\Middleware\\EnsureAccountActive", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/app/Http/Middleware/MultiAuth.php", + "line": 32, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "App\\Http\\Middleware\\MultiAuth", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Routing/Middleware/SubstituteBindings.php", + "line": 50, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "Illuminate\\Routing\\Middleware\\SubstituteBindings", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 137, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Routing/Router.php", + "line": 821, + "function": "then", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Routing/Router.php", + "line": 800, + "function": "runRouteWithinStack", + "class": "Illuminate\\Routing\\Router", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Routing/Router.php", + "line": 764, + "function": "runRoute", + "class": "Illuminate\\Routing\\Router", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Routing/Router.php", + "line": 753, + "function": "dispatchToRoute", + "class": "Illuminate\\Routing\\Router", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php", + "line": 200, + "function": "dispatch", + "class": "Illuminate\\Routing\\Router", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 180, + "function": "{closure:Illuminate\\Foundation\\Http\\Kernel::dispatchToRouter():197}", + "class": "Illuminate\\Foundation\\Http\\Kernel", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/app/Http/Middleware/SecurityHeaders.php", + "line": 22, + "function": "{closure:Illuminate\\Pipeline\\Pipeline::prepareDestination():178}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "App\\Http\\Middleware\\SecurityHeaders", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/TransformsRequest.php", + "line": 21, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/ConvertEmptyStringsToNull.php", + "line": 31, + "function": "handle", + "class": "Illuminate\\Foundation\\Http\\Middleware\\TransformsRequest", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "Illuminate\\Foundation\\Http\\Middleware\\ConvertEmptyStringsToNull", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/TransformsRequest.php", + "line": 21, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/TrimStrings.php", + "line": 51, + "function": "handle", + "class": "Illuminate\\Foundation\\Http\\Middleware\\TransformsRequest", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "Illuminate\\Foundation\\Http\\Middleware\\TrimStrings", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Http/Middleware/ValidatePostSize.php", + "line": 27, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "Illuminate\\Http\\Middleware\\ValidatePostSize", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/PreventRequestsDuringMaintenance.php", + "line": 109, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "Illuminate\\Foundation\\Http\\Middleware\\PreventRequestsDuringMaintenance", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Http/Middleware/HandleCors.php", + "line": 74, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "Illuminate\\Http\\Middleware\\HandleCors", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Http/Middleware/TrustProxies.php", + "line": 58, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "Illuminate\\Http\\Middleware\\TrustProxies", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/InvokeDeferredCallbacks.php", + "line": 22, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "Illuminate\\Foundation\\Http\\Middleware\\InvokeDeferredCallbacks", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Http/Middleware/ValidatePathEncoding.php", + "line": 26, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "Illuminate\\Http\\Middleware\\ValidatePathEncoding", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 137, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php", + "line": 175, + "function": "then", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php", + "line": 144, + "function": "sendRequestThroughRouter", + "class": "Illuminate\\Foundation\\Http\\Kernel", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Foundation/Testing/Concerns/MakesHttpRequests.php", + "line": 607, + "function": "handle", + "class": "Illuminate\\Foundation\\Http\\Kernel", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Foundation/Testing/Concerns/MakesHttpRequests.php", + "line": 573, + "function": "call", + "class": "Illuminate\\Foundation\\Testing\\TestCase", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/tests/Feature/Api/V1/FullSurface/Support/FullSurfaceE2EContractCase.php", + "line": 190, + "function": "json", + "class": "Illuminate\\Foundation\\Testing\\TestCase", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/tests/Feature/Api/V1/FullSurface/ApiBatch14DataLifecycleArchivePurgeContractTest.php", + "line": 13, + "function": "requestAs", + "class": "Tests\\Feature\\Api\\V1\\FullSurface\\Support\\FullSurfaceE2EContractCase", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/phpunit/phpunit/src/Framework/TestCase.php", + "line": 1667, + "function": "test_archive_purge_and_retention_routes_require_safe_controlled_requests", + "class": "Tests\\Feature\\Api\\V1\\FullSurface\\ApiBatch14DataLifecycleArchivePurgeContractTest", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/phpunit/phpunit/src/Framework/TestCase.php", + "line": 519, + "function": "runTest", + "class": "PHPUnit\\Framework\\TestCase", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/phpunit/phpunit/src/Framework/TestRunner/TestRunner.php", + "line": 87, + "function": "runBare", + "class": "PHPUnit\\Framework\\TestCase", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/phpunit/phpunit/src/Framework/TestCase.php", + "line": 365, + "function": "run", + "class": "PHPUnit\\Framework\\TestRunner", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/phpunit/phpunit/src/Framework/TestSuite.php", + "line": 369, + "function": "run", + "class": "PHPUnit\\Framework\\TestCase", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/phpunit/phpunit/src/Framework/TestSuite.php", + "line": 369, + "function": "run", + "class": "PHPUnit\\Framework\\TestSuite", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/phpunit/phpunit/src/Framework/TestSuite.php", + "line": 369, + "function": "run", + "class": "PHPUnit\\Framework\\TestSuite", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/phpunit/phpunit/src/TextUI/TestRunner.php", + "line": 64, + "function": "run", + "class": "PHPUnit\\Framework\\TestSuite", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/phpunit/phpunit/src/TextUI/Application.php", + "line": 211, + "function": "run", + "class": "PHPUnit\\TextUI\\TestRunner", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/phpunit/phpunit/phpunit", + "line": 104, + "function": "run", + "class": "PHPUnit\\TextUI\\Application", + "type": "->" + } + ] +} +Failed asserting that an array contains 500. + + at tests/Concerns/AssertsE2EApiResponses.php:23 + 19▕ * @param array $statuses + 20▕ */ + 21▕ protected function assertStatusIn(TestResponse $response, array $statuses, string $context): void + 22▕ { + ➜ 23▕ $this->assertContains( + 24▕ $response->getStatusCode(), + 25▕ $statuses, + 26▕ $context.' returned unexpected status '.$response->getStatusCode().'. Body: '.$response->getContent() + 27▕ ); + + 1 tests/Concerns/AssertsE2EApiResponses.php:23 + 2 tests/Feature/Api/V1/FullSurface/Support/FullSurfaceE2EContractCase.php:343 + + ──────────────────────────────────────────────────────────────────────────── + FAILED Tests\Feature\Api\V1\FullSurface\ApiBatch16TemporalConsistencyAnd… + POST api/v1/school-years/{schoolYear}/archive returned unexpected status 500. Body: { + "message": "Method App\\Http\\Controllers\\Api\\SchoolYears\\SchoolYearController::archive does not exist.", + "exception": "BadMethodCallException", + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Routing/Controller.php", + "line": 68, + "trace": [ + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Routing/Controller.php", + "line": 54, + "function": "__call", + "class": "Illuminate\\Routing\\Controller", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Routing/ControllerDispatcher.php", + "line": 43, + "function": "callAction", + "class": "Illuminate\\Routing\\Controller", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Routing/Route.php", + "line": 265, + "function": "dispatch", + "class": "Illuminate\\Routing\\ControllerDispatcher", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Routing/Route.php", + "line": 211, + "function": "runController", + "class": "Illuminate\\Routing\\Route", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Routing/Router.php", + "line": 822, + "function": "run", + "class": "Illuminate\\Routing\\Route", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 180, + "function": "{closure:Illuminate\\Routing\\Router::runRouteWithinStack():821}", + "class": "Illuminate\\Routing\\Router", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/app/Http/Middleware/RequirePermission.php", + "line": 29, + "function": "{closure:Illuminate\\Pipeline\\Pipeline::prepareDestination():178}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "App\\Http\\Middleware\\RequirePermission", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/app/Http/Middleware/EnsureAccountActive.php", + "line": 32, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "App\\Http\\Middleware\\EnsureAccountActive", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/app/Http/Middleware/MultiAuth.php", + "line": 32, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "App\\Http\\Middleware\\MultiAuth", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Routing/Middleware/SubstituteBindings.php", + "line": 50, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "Illuminate\\Routing\\Middleware\\SubstituteBindings", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 137, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Routing/Router.php", + "line": 821, + "function": "then", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Routing/Router.php", + "line": 800, + "function": "runRouteWithinStack", + "class": "Illuminate\\Routing\\Router", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Routing/Router.php", + "line": 764, + "function": "runRoute", + "class": "Illuminate\\Routing\\Router", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Routing/Router.php", + "line": 753, + "function": "dispatchToRoute", + "class": "Illuminate\\Routing\\Router", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php", + "line": 200, + "function": "dispatch", + "class": "Illuminate\\Routing\\Router", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 180, + "function": "{closure:Illuminate\\Foundation\\Http\\Kernel::dispatchToRouter():197}", + "class": "Illuminate\\Foundation\\Http\\Kernel", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/app/Http/Middleware/SecurityHeaders.php", + "line": 22, + "function": "{closure:Illuminate\\Pipeline\\Pipeline::prepareDestination():178}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "App\\Http\\Middleware\\SecurityHeaders", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/TransformsRequest.php", + "line": 21, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/ConvertEmptyStringsToNull.php", + "line": 31, + "function": "handle", + "class": "Illuminate\\Foundation\\Http\\Middleware\\TransformsRequest", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "Illuminate\\Foundation\\Http\\Middleware\\ConvertEmptyStringsToNull", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/TransformsRequest.php", + "line": 21, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/TrimStrings.php", + "line": 51, + "function": "handle", + "class": "Illuminate\\Foundation\\Http\\Middleware\\TransformsRequest", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "Illuminate\\Foundation\\Http\\Middleware\\TrimStrings", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Http/Middleware/ValidatePostSize.php", + "line": 27, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "Illuminate\\Http\\Middleware\\ValidatePostSize", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/PreventRequestsDuringMaintenance.php", + "line": 109, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "Illuminate\\Foundation\\Http\\Middleware\\PreventRequestsDuringMaintenance", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Http/Middleware/HandleCors.php", + "line": 74, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "Illuminate\\Http\\Middleware\\HandleCors", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Http/Middleware/TrustProxies.php", + "line": 58, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "Illuminate\\Http\\Middleware\\TrustProxies", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/InvokeDeferredCallbacks.php", + "line": 22, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "Illuminate\\Foundation\\Http\\Middleware\\InvokeDeferredCallbacks", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Http/Middleware/ValidatePathEncoding.php", + "line": 26, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "Illuminate\\Http\\Middleware\\ValidatePathEncoding", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 137, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php", + "line": 175, + "function": "then", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php", + "line": 144, + "function": "sendRequestThroughRouter", + "class": "Illuminate\\Foundation\\Http\\Kernel", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Foundation/Testing/Concerns/MakesHttpRequests.php", + "line": 607, + "function": "handle", + "class": "Illuminate\\Foundation\\Http\\Kernel", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Foundation/Testing/Concerns/MakesHttpRequests.php", + "line": 573, + "function": "call", + "class": "Illuminate\\Foundation\\Testing\\TestCase", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/tests/Feature/Api/V1/FullSurface/Support/FullSurfaceE2EContractCase.php", + "line": 190, + "function": "json", + "class": "Illuminate\\Foundation\\Testing\\TestCase", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/tests/Feature/Api/V1/FullSurface/ApiBatch16TemporalConsistencyAndClockSkewContractTest.php", + "line": 25, + "function": "requestAs", + "class": "Tests\\Feature\\Api\\V1\\FullSurface\\Support\\FullSurfaceE2EContractCase", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/phpunit/phpunit/src/Framework/TestCase.php", + "line": 1667, + "function": "test_batch16_clock_skew_and_temporal_boundaries_do_not_bypass_business_rules", + "class": "Tests\\Feature\\Api\\V1\\FullSurface\\ApiBatch16TemporalConsistencyAndClockSkewContractTest", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/phpunit/phpunit/src/Framework/TestCase.php", + "line": 519, + "function": "runTest", + "class": "PHPUnit\\Framework\\TestCase", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/phpunit/phpunit/src/Framework/TestRunner/TestRunner.php", + "line": 87, + "function": "runBare", + "class": "PHPUnit\\Framework\\TestCase", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/phpunit/phpunit/src/Framework/TestCase.php", + "line": 365, + "function": "run", + "class": "PHPUnit\\Framework\\TestRunner", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/phpunit/phpunit/src/Framework/TestSuite.php", + "line": 369, + "function": "run", + "class": "PHPUnit\\Framework\\TestCase", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/phpunit/phpunit/src/Framework/TestSuite.php", + "line": 369, + "function": "run", + "class": "PHPUnit\\Framework\\TestSuite", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/phpunit/phpunit/src/Framework/TestSuite.php", + "line": 369, + "function": "run", + "class": "PHPUnit\\Framework\\TestSuite", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/phpunit/phpunit/src/TextUI/TestRunner.php", + "line": 64, + "function": "run", + "class": "PHPUnit\\Framework\\TestSuite", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/phpunit/phpunit/src/TextUI/Application.php", + "line": 211, + "function": "run", + "class": "PHPUnit\\TextUI\\TestRunner", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/phpunit/phpunit/phpunit", + "line": 104, + "function": "run", + "class": "PHPUnit\\TextUI\\Application", + "type": "->" + } + ] +} +Failed asserting that an array contains 500. + + at tests/Concerns/AssertsE2EApiResponses.php:23 + 19▕ * @param array $statuses + 20▕ */ + 21▕ protected function assertStatusIn(TestResponse $response, array $statuses, string $context): void + 22▕ { + ➜ 23▕ $this->assertContains( + 24▕ $response->getStatusCode(), + 25▕ $statuses, + 26▕ $context.' returned unexpected status '.$response->getStatusCode().'. Body: '.$response->getContent() + 27▕ ); + + 1 tests/Concerns/AssertsE2EApiResponses.php:23 + 2 tests/Feature/Api/V1/FullSurface/Support/FullSurfaceE2EContractCase.php:343 + + ──────────────────────────────────────────────────────────────────────────── + FAILED Tests\Feature\Api\V1\FullSurface\ApiBatch18OrphanedRecordAndCasca… + POST api/v1/school-years/{schoolYear}/archive returned unexpected status 500. Body: { + "message": "Method App\\Http\\Controllers\\Api\\SchoolYears\\SchoolYearController::archive does not exist.", + "exception": "BadMethodCallException", + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Routing/Controller.php", + "line": 68, + "trace": [ + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Routing/Controller.php", + "line": 54, + "function": "__call", + "class": "Illuminate\\Routing\\Controller", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Routing/ControllerDispatcher.php", + "line": 43, + "function": "callAction", + "class": "Illuminate\\Routing\\Controller", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Routing/Route.php", + "line": 265, + "function": "dispatch", + "class": "Illuminate\\Routing\\ControllerDispatcher", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Routing/Route.php", + "line": 211, + "function": "runController", + "class": "Illuminate\\Routing\\Route", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Routing/Router.php", + "line": 822, + "function": "run", + "class": "Illuminate\\Routing\\Route", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 180, + "function": "{closure:Illuminate\\Routing\\Router::runRouteWithinStack():821}", + "class": "Illuminate\\Routing\\Router", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/app/Http/Middleware/RequirePermission.php", + "line": 29, + "function": "{closure:Illuminate\\Pipeline\\Pipeline::prepareDestination():178}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "App\\Http\\Middleware\\RequirePermission", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/app/Http/Middleware/EnsureAccountActive.php", + "line": 32, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "App\\Http\\Middleware\\EnsureAccountActive", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/app/Http/Middleware/MultiAuth.php", + "line": 32, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "App\\Http\\Middleware\\MultiAuth", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Routing/Middleware/SubstituteBindings.php", + "line": 50, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "Illuminate\\Routing\\Middleware\\SubstituteBindings", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 137, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Routing/Router.php", + "line": 821, + "function": "then", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Routing/Router.php", + "line": 800, + "function": "runRouteWithinStack", + "class": "Illuminate\\Routing\\Router", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Routing/Router.php", + "line": 764, + "function": "runRoute", + "class": "Illuminate\\Routing\\Router", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Routing/Router.php", + "line": 753, + "function": "dispatchToRoute", + "class": "Illuminate\\Routing\\Router", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php", + "line": 200, + "function": "dispatch", + "class": "Illuminate\\Routing\\Router", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 180, + "function": "{closure:Illuminate\\Foundation\\Http\\Kernel::dispatchToRouter():197}", + "class": "Illuminate\\Foundation\\Http\\Kernel", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/app/Http/Middleware/SecurityHeaders.php", + "line": 22, + "function": "{closure:Illuminate\\Pipeline\\Pipeline::prepareDestination():178}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "App\\Http\\Middleware\\SecurityHeaders", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/TransformsRequest.php", + "line": 21, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/ConvertEmptyStringsToNull.php", + "line": 31, + "function": "handle", + "class": "Illuminate\\Foundation\\Http\\Middleware\\TransformsRequest", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "Illuminate\\Foundation\\Http\\Middleware\\ConvertEmptyStringsToNull", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/TransformsRequest.php", + "line": 21, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/TrimStrings.php", + "line": 51, + "function": "handle", + "class": "Illuminate\\Foundation\\Http\\Middleware\\TransformsRequest", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "Illuminate\\Foundation\\Http\\Middleware\\TrimStrings", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Http/Middleware/ValidatePostSize.php", + "line": 27, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "Illuminate\\Http\\Middleware\\ValidatePostSize", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/PreventRequestsDuringMaintenance.php", + "line": 109, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "Illuminate\\Foundation\\Http\\Middleware\\PreventRequestsDuringMaintenance", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Http/Middleware/HandleCors.php", + "line": 74, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "Illuminate\\Http\\Middleware\\HandleCors", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Http/Middleware/TrustProxies.php", + "line": 58, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "Illuminate\\Http\\Middleware\\TrustProxies", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/InvokeDeferredCallbacks.php", + "line": 22, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "Illuminate\\Foundation\\Http\\Middleware\\InvokeDeferredCallbacks", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Http/Middleware/ValidatePathEncoding.php", + "line": 26, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "Illuminate\\Http\\Middleware\\ValidatePathEncoding", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 137, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php", + "line": 175, + "function": "then", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php", + "line": 144, + "function": "sendRequestThroughRouter", + "class": "Illuminate\\Foundation\\Http\\Kernel", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Foundation/Testing/Concerns/MakesHttpRequests.php", + "line": 607, + "function": "handle", + "class": "Illuminate\\Foundation\\Http\\Kernel", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Foundation/Testing/Concerns/MakesHttpRequests.php", + "line": 573, + "function": "call", + "class": "Illuminate\\Foundation\\Testing\\TestCase", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/tests/Feature/Api/V1/FullSurface/Support/FullSurfaceE2EContractCase.php", + "line": 190, + "function": "json", + "class": "Illuminate\\Foundation\\Testing\\TestCase", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/tests/Feature/Api/V1/FullSurface/ApiBatch18OrphanedRecordAndCascadeBoundaryContractTest.php", + "line": 31, + "function": "requestAs", + "class": "Tests\\Feature\\Api\\V1\\FullSurface\\Support\\FullSurfaceE2EContractCase", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/phpunit/phpunit/src/Framework/TestCase.php", + "line": 1667, + "function": "test_batch18_orphanedrecordandcascadeboundary_stays_controlled", + "class": "Tests\\Feature\\Api\\V1\\FullSurface\\ApiBatch18OrphanedRecordAndCascadeBoundaryContractTest", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/phpunit/phpunit/src/Framework/TestCase.php", + "line": 519, + "function": "runTest", + "class": "PHPUnit\\Framework\\TestCase", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/phpunit/phpunit/src/Framework/TestRunner/TestRunner.php", + "line": 87, + "function": "runBare", + "class": "PHPUnit\\Framework\\TestCase", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/phpunit/phpunit/src/Framework/TestCase.php", + "line": 365, + "function": "run", + "class": "PHPUnit\\Framework\\TestRunner", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/phpunit/phpunit/src/Framework/TestSuite.php", + "line": 369, + "function": "run", + "class": "PHPUnit\\Framework\\TestCase", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/phpunit/phpunit/src/Framework/TestSuite.php", + "line": 369, + "function": "run", + "class": "PHPUnit\\Framework\\TestSuite", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/phpunit/phpunit/src/Framework/TestSuite.php", + "line": 369, + "function": "run", + "class": "PHPUnit\\Framework\\TestSuite", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/phpunit/phpunit/src/TextUI/TestRunner.php", + "line": 64, + "function": "run", + "class": "PHPUnit\\Framework\\TestSuite", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/phpunit/phpunit/src/TextUI/Application.php", + "line": 211, + "function": "run", + "class": "PHPUnit\\TextUI\\TestRunner", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/phpunit/phpunit/phpunit", + "line": 104, + "function": "run", + "class": "PHPUnit\\TextUI\\Application", + "type": "->" + } + ] +} +Failed asserting that an array contains 500. + + at tests/Concerns/AssertsE2EApiResponses.php:23 + 19▕ * @param array $statuses + 20▕ */ + 21▕ protected function assertStatusIn(TestResponse $response, array $statuses, string $context): void + 22▕ { + ➜ 23▕ $this->assertContains( + 24▕ $response->getStatusCode(), + 25▕ $statuses, + 26▕ $context.' returned unexpected status '.$response->getStatusCode().'. Body: '.$response->getContent() + 27▕ ); + + 1 tests/Concerns/AssertsE2EApiResponses.php:23 + 2 tests/Feature/Api/V1/FullSurface/Support/FullSurfaceE2EContractCase.php:343 + + ──────────────────────────────────────────────────────────────────────────── + FAILED Tests\Feature\Api\V1\FullSurface\ApiBatch18TemporalAuditAndTimezo… + POST api/v1/school-years/{schoolYear}/archive returned unexpected status 500. Body: { + "message": "Method App\\Http\\Controllers\\Api\\SchoolYears\\SchoolYearController::archive does not exist.", + "exception": "BadMethodCallException", + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Routing/Controller.php", + "line": 68, + "trace": [ + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Routing/Controller.php", + "line": 54, + "function": "__call", + "class": "Illuminate\\Routing\\Controller", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Routing/ControllerDispatcher.php", + "line": 43, + "function": "callAction", + "class": "Illuminate\\Routing\\Controller", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Routing/Route.php", + "line": 265, + "function": "dispatch", + "class": "Illuminate\\Routing\\ControllerDispatcher", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Routing/Route.php", + "line": 211, + "function": "runController", + "class": "Illuminate\\Routing\\Route", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Routing/Router.php", + "line": 822, + "function": "run", + "class": "Illuminate\\Routing\\Route", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 180, + "function": "{closure:Illuminate\\Routing\\Router::runRouteWithinStack():821}", + "class": "Illuminate\\Routing\\Router", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/app/Http/Middleware/RequirePermission.php", + "line": 29, + "function": "{closure:Illuminate\\Pipeline\\Pipeline::prepareDestination():178}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "App\\Http\\Middleware\\RequirePermission", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/app/Http/Middleware/EnsureAccountActive.php", + "line": 32, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "App\\Http\\Middleware\\EnsureAccountActive", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/app/Http/Middleware/MultiAuth.php", + "line": 32, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "App\\Http\\Middleware\\MultiAuth", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Routing/Middleware/SubstituteBindings.php", + "line": 50, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "Illuminate\\Routing\\Middleware\\SubstituteBindings", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 137, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Routing/Router.php", + "line": 821, + "function": "then", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Routing/Router.php", + "line": 800, + "function": "runRouteWithinStack", + "class": "Illuminate\\Routing\\Router", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Routing/Router.php", + "line": 764, + "function": "runRoute", + "class": "Illuminate\\Routing\\Router", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Routing/Router.php", + "line": 753, + "function": "dispatchToRoute", + "class": "Illuminate\\Routing\\Router", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php", + "line": 200, + "function": "dispatch", + "class": "Illuminate\\Routing\\Router", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 180, + "function": "{closure:Illuminate\\Foundation\\Http\\Kernel::dispatchToRouter():197}", + "class": "Illuminate\\Foundation\\Http\\Kernel", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/app/Http/Middleware/SecurityHeaders.php", + "line": 22, + "function": "{closure:Illuminate\\Pipeline\\Pipeline::prepareDestination():178}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "App\\Http\\Middleware\\SecurityHeaders", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/TransformsRequest.php", + "line": 21, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/ConvertEmptyStringsToNull.php", + "line": 31, + "function": "handle", + "class": "Illuminate\\Foundation\\Http\\Middleware\\TransformsRequest", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "Illuminate\\Foundation\\Http\\Middleware\\ConvertEmptyStringsToNull", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/TransformsRequest.php", + "line": 21, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/TrimStrings.php", + "line": 51, + "function": "handle", + "class": "Illuminate\\Foundation\\Http\\Middleware\\TransformsRequest", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "Illuminate\\Foundation\\Http\\Middleware\\TrimStrings", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Http/Middleware/ValidatePostSize.php", + "line": 27, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "Illuminate\\Http\\Middleware\\ValidatePostSize", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/PreventRequestsDuringMaintenance.php", + "line": 109, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "Illuminate\\Foundation\\Http\\Middleware\\PreventRequestsDuringMaintenance", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Http/Middleware/HandleCors.php", + "line": 74, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "Illuminate\\Http\\Middleware\\HandleCors", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Http/Middleware/TrustProxies.php", + "line": 58, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "Illuminate\\Http\\Middleware\\TrustProxies", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/InvokeDeferredCallbacks.php", + "line": 22, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "Illuminate\\Foundation\\Http\\Middleware\\InvokeDeferredCallbacks", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Http/Middleware/ValidatePathEncoding.php", + "line": 26, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "Illuminate\\Http\\Middleware\\ValidatePathEncoding", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 137, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php", + "line": 175, + "function": "then", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php", + "line": 144, + "function": "sendRequestThroughRouter", + "class": "Illuminate\\Foundation\\Http\\Kernel", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Foundation/Testing/Concerns/MakesHttpRequests.php", + "line": 607, + "function": "handle", + "class": "Illuminate\\Foundation\\Http\\Kernel", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Foundation/Testing/Concerns/MakesHttpRequests.php", + "line": 573, + "function": "call", + "class": "Illuminate\\Foundation\\Testing\\TestCase", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/tests/Feature/Api/V1/FullSurface/Support/FullSurfaceE2EContractCase.php", + "line": 190, + "function": "json", + "class": "Illuminate\\Foundation\\Testing\\TestCase", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/tests/Feature/Api/V1/FullSurface/ApiBatch18TemporalAuditAndTimezoneForgeryContractTest.php", + "line": 31, + "function": "requestAs", + "class": "Tests\\Feature\\Api\\V1\\FullSurface\\Support\\FullSurfaceE2EContractCase", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/phpunit/phpunit/src/Framework/TestCase.php", + "line": 1667, + "function": "test_batch18_temporalauditandtimezoneforgery_stays_controlled", + "class": "Tests\\Feature\\Api\\V1\\FullSurface\\ApiBatch18TemporalAuditAndTimezoneForgeryContractTest", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/phpunit/phpunit/src/Framework/TestCase.php", + "line": 519, + "function": "runTest", + "class": "PHPUnit\\Framework\\TestCase", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/phpunit/phpunit/src/Framework/TestRunner/TestRunner.php", + "line": 87, + "function": "runBare", + "class": "PHPUnit\\Framework\\TestCase", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/phpunit/phpunit/src/Framework/TestCase.php", + "line": 365, + "function": "run", + "class": "PHPUnit\\Framework\\TestRunner", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/phpunit/phpunit/src/Framework/TestSuite.php", + "line": 369, + "function": "run", + "class": "PHPUnit\\Framework\\TestCase", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/phpunit/phpunit/src/Framework/TestSuite.php", + "line": 369, + "function": "run", + "class": "PHPUnit\\Framework\\TestSuite", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/phpunit/phpunit/src/Framework/TestSuite.php", + "line": 369, + "function": "run", + "class": "PHPUnit\\Framework\\TestSuite", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/phpunit/phpunit/src/TextUI/TestRunner.php", + "line": 64, + "function": "run", + "class": "PHPUnit\\Framework\\TestSuite", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/phpunit/phpunit/src/TextUI/Application.php", + "line": 211, + "function": "run", + "class": "PHPUnit\\TextUI\\TestRunner", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/phpunit/phpunit/phpunit", + "line": 104, + "function": "run", + "class": "PHPUnit\\TextUI\\Application", + "type": "->" + } + ] +} +Failed asserting that an array contains 500. + + at tests/Concerns/AssertsE2EApiResponses.php:23 + 19▕ * @param array $statuses + 20▕ */ + 21▕ protected function assertStatusIn(TestResponse $response, array $statuses, string $context): void + 22▕ { + ➜ 23▕ $this->assertContains( + 24▕ $response->getStatusCode(), + 25▕ $statuses, + 26▕ $context.' returned unexpected status '.$response->getStatusCode().'. Body: '.$response->getContent() + 27▕ ); + + 1 tests/Concerns/AssertsE2EApiResponses.php:23 + 2 tests/Feature/Api/V1/FullSurface/Support/FullSurfaceE2EContractCase.php:343 + + ──────────────────────────────────────────────────────────────────────────── + FAILED Tests\Feature\Api\V1\FullSurface\ApiBatch20LegalHoldRetentionAndP… + POST api/v1/school-years/{schoolYear}/archive returned unexpected status 500. Body: { + "message": "Method App\\Http\\Controllers\\Api\\SchoolYears\\SchoolYearController::archive does not exist.", + "exception": "BadMethodCallException", + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Routing/Controller.php", + "line": 68, + "trace": [ + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Routing/Controller.php", + "line": 54, + "function": "__call", + "class": "Illuminate\\Routing\\Controller", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Routing/ControllerDispatcher.php", + "line": 43, + "function": "callAction", + "class": "Illuminate\\Routing\\Controller", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Routing/Route.php", + "line": 265, + "function": "dispatch", + "class": "Illuminate\\Routing\\ControllerDispatcher", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Routing/Route.php", + "line": 211, + "function": "runController", + "class": "Illuminate\\Routing\\Route", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Routing/Router.php", + "line": 822, + "function": "run", + "class": "Illuminate\\Routing\\Route", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 180, + "function": "{closure:Illuminate\\Routing\\Router::runRouteWithinStack():821}", + "class": "Illuminate\\Routing\\Router", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/app/Http/Middleware/RequirePermission.php", + "line": 29, + "function": "{closure:Illuminate\\Pipeline\\Pipeline::prepareDestination():178}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "App\\Http\\Middleware\\RequirePermission", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/app/Http/Middleware/EnsureAccountActive.php", + "line": 32, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "App\\Http\\Middleware\\EnsureAccountActive", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/app/Http/Middleware/MultiAuth.php", + "line": 32, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "App\\Http\\Middleware\\MultiAuth", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Routing/Middleware/SubstituteBindings.php", + "line": 50, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "Illuminate\\Routing\\Middleware\\SubstituteBindings", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 137, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Routing/Router.php", + "line": 821, + "function": "then", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Routing/Router.php", + "line": 800, + "function": "runRouteWithinStack", + "class": "Illuminate\\Routing\\Router", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Routing/Router.php", + "line": 764, + "function": "runRoute", + "class": "Illuminate\\Routing\\Router", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Routing/Router.php", + "line": 753, + "function": "dispatchToRoute", + "class": "Illuminate\\Routing\\Router", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php", + "line": 200, + "function": "dispatch", + "class": "Illuminate\\Routing\\Router", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 180, + "function": "{closure:Illuminate\\Foundation\\Http\\Kernel::dispatchToRouter():197}", + "class": "Illuminate\\Foundation\\Http\\Kernel", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/app/Http/Middleware/SecurityHeaders.php", + "line": 22, + "function": "{closure:Illuminate\\Pipeline\\Pipeline::prepareDestination():178}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "App\\Http\\Middleware\\SecurityHeaders", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/TransformsRequest.php", + "line": 21, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/ConvertEmptyStringsToNull.php", + "line": 31, + "function": "handle", + "class": "Illuminate\\Foundation\\Http\\Middleware\\TransformsRequest", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "Illuminate\\Foundation\\Http\\Middleware\\ConvertEmptyStringsToNull", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/TransformsRequest.php", + "line": 21, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/TrimStrings.php", + "line": 51, + "function": "handle", + "class": "Illuminate\\Foundation\\Http\\Middleware\\TransformsRequest", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "Illuminate\\Foundation\\Http\\Middleware\\TrimStrings", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Http/Middleware/ValidatePostSize.php", + "line": 27, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "Illuminate\\Http\\Middleware\\ValidatePostSize", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/PreventRequestsDuringMaintenance.php", + "line": 109, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "Illuminate\\Foundation\\Http\\Middleware\\PreventRequestsDuringMaintenance", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Http/Middleware/HandleCors.php", + "line": 74, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "Illuminate\\Http\\Middleware\\HandleCors", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Http/Middleware/TrustProxies.php", + "line": 58, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "Illuminate\\Http\\Middleware\\TrustProxies", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/InvokeDeferredCallbacks.php", + "line": 22, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "Illuminate\\Foundation\\Http\\Middleware\\InvokeDeferredCallbacks", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Http/Middleware/ValidatePathEncoding.php", + "line": 26, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "Illuminate\\Http\\Middleware\\ValidatePathEncoding", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 137, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php", + "line": 175, + "function": "then", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php", + "line": 144, + "function": "sendRequestThroughRouter", + "class": "Illuminate\\Foundation\\Http\\Kernel", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Foundation/Testing/Concerns/MakesHttpRequests.php", + "line": 607, + "function": "handle", + "class": "Illuminate\\Foundation\\Http\\Kernel", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Foundation/Testing/Concerns/MakesHttpRequests.php", + "line": 573, + "function": "call", + "class": "Illuminate\\Foundation\\Testing\\TestCase", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/tests/Feature/Api/V1/FullSurface/Support/FullSurfaceE2EContractCase.php", + "line": 190, + "function": "json", + "class": "Illuminate\\Foundation\\Testing\\TestCase", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/tests/Feature/Api/V1/FullSurface/ApiBatch20LegalHoldRetentionAndPurgeConflictContractTest.php", + "line": 32, + "function": "requestAs", + "class": "Tests\\Feature\\Api\\V1\\FullSurface\\Support\\FullSurfaceE2EContractCase", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/phpunit/phpunit/src/Framework/TestCase.php", + "line": 1667, + "function": "test_batch20_legal_hold_retention_and_purge_conflict_stays_controlled", + "class": "Tests\\Feature\\Api\\V1\\FullSurface\\ApiBatch20LegalHoldRetentionAndPurgeConflictContractTest", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/phpunit/phpunit/src/Framework/TestCase.php", + "line": 519, + "function": "runTest", + "class": "PHPUnit\\Framework\\TestCase", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/phpunit/phpunit/src/Framework/TestRunner/TestRunner.php", + "line": 87, + "function": "runBare", + "class": "PHPUnit\\Framework\\TestCase", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/phpunit/phpunit/src/Framework/TestCase.php", + "line": 365, + "function": "run", + "class": "PHPUnit\\Framework\\TestRunner", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/phpunit/phpunit/src/Framework/TestSuite.php", + "line": 369, + "function": "run", + "class": "PHPUnit\\Framework\\TestCase", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/phpunit/phpunit/src/Framework/TestSuite.php", + "line": 369, + "function": "run", + "class": "PHPUnit\\Framework\\TestSuite", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/phpunit/phpunit/src/Framework/TestSuite.php", + "line": 369, + "function": "run", + "class": "PHPUnit\\Framework\\TestSuite", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/phpunit/phpunit/src/TextUI/TestRunner.php", + "line": 64, + "function": "run", + "class": "PHPUnit\\Framework\\TestSuite", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/phpunit/phpunit/src/TextUI/Application.php", + "line": 211, + "function": "run", + "class": "PHPUnit\\TextUI\\TestRunner", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/phpunit/phpunit/phpunit", + "line": 104, + "function": "run", + "class": "PHPUnit\\TextUI\\Application", + "type": "->" + } + ] +} +Failed asserting that an array contains 500. + + at tests/Concerns/AssertsE2EApiResponses.php:23 + 19▕ * @param array $statuses + 20▕ */ + 21▕ protected function assertStatusIn(TestResponse $response, array $statuses, string $context): void + 22▕ { + ➜ 23▕ $this->assertContains( + 24▕ $response->getStatusCode(), + 25▕ $statuses, + 26▕ $context.' returned unexpected status '.$response->getStatusCode().'. Body: '.$response->getContent() + 27▕ ); + + 1 tests/Concerns/AssertsE2EApiResponses.php:23 + 2 tests/Feature/Api/V1/FullSurface/Support/FullSurfaceE2EContractCase.php:343 + + ──────────────────────────────────────────────────────────────────────────── + FAILED Tests\Feature\Api\V1\FullSurface\ApiBatch20RegressionContinuityCo… + POST api/v1/school-years/{schoolYear}/archive returned unexpected status 500. Body: { + "message": "Method App\\Http\\Controllers\\Api\\SchoolYears\\SchoolYearController::archive does not exist.", + "exception": "BadMethodCallException", + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Routing/Controller.php", + "line": 68, + "trace": [ + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Routing/Controller.php", + "line": 54, + "function": "__call", + "class": "Illuminate\\Routing\\Controller", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Routing/ControllerDispatcher.php", + "line": 43, + "function": "callAction", + "class": "Illuminate\\Routing\\Controller", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Routing/Route.php", + "line": 265, + "function": "dispatch", + "class": "Illuminate\\Routing\\ControllerDispatcher", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Routing/Route.php", + "line": 211, + "function": "runController", + "class": "Illuminate\\Routing\\Route", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Routing/Router.php", + "line": 822, + "function": "run", + "class": "Illuminate\\Routing\\Route", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 180, + "function": "{closure:Illuminate\\Routing\\Router::runRouteWithinStack():821}", + "class": "Illuminate\\Routing\\Router", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/app/Http/Middleware/RequirePermission.php", + "line": 29, + "function": "{closure:Illuminate\\Pipeline\\Pipeline::prepareDestination():178}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "App\\Http\\Middleware\\RequirePermission", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/app/Http/Middleware/EnsureAccountActive.php", + "line": 32, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "App\\Http\\Middleware\\EnsureAccountActive", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/app/Http/Middleware/MultiAuth.php", + "line": 32, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "App\\Http\\Middleware\\MultiAuth", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Routing/Middleware/SubstituteBindings.php", + "line": 50, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "Illuminate\\Routing\\Middleware\\SubstituteBindings", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 137, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Routing/Router.php", + "line": 821, + "function": "then", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Routing/Router.php", + "line": 800, + "function": "runRouteWithinStack", + "class": "Illuminate\\Routing\\Router", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Routing/Router.php", + "line": 764, + "function": "runRoute", + "class": "Illuminate\\Routing\\Router", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Routing/Router.php", + "line": 753, + "function": "dispatchToRoute", + "class": "Illuminate\\Routing\\Router", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php", + "line": 200, + "function": "dispatch", + "class": "Illuminate\\Routing\\Router", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 180, + "function": "{closure:Illuminate\\Foundation\\Http\\Kernel::dispatchToRouter():197}", + "class": "Illuminate\\Foundation\\Http\\Kernel", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/app/Http/Middleware/SecurityHeaders.php", + "line": 22, + "function": "{closure:Illuminate\\Pipeline\\Pipeline::prepareDestination():178}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "App\\Http\\Middleware\\SecurityHeaders", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/TransformsRequest.php", + "line": 21, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/ConvertEmptyStringsToNull.php", + "line": 31, + "function": "handle", + "class": "Illuminate\\Foundation\\Http\\Middleware\\TransformsRequest", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "Illuminate\\Foundation\\Http\\Middleware\\ConvertEmptyStringsToNull", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/TransformsRequest.php", + "line": 21, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/TrimStrings.php", + "line": 51, + "function": "handle", + "class": "Illuminate\\Foundation\\Http\\Middleware\\TransformsRequest", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "Illuminate\\Foundation\\Http\\Middleware\\TrimStrings", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Http/Middleware/ValidatePostSize.php", + "line": 27, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "Illuminate\\Http\\Middleware\\ValidatePostSize", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/PreventRequestsDuringMaintenance.php", + "line": 109, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "Illuminate\\Foundation\\Http\\Middleware\\PreventRequestsDuringMaintenance", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Http/Middleware/HandleCors.php", + "line": 74, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "Illuminate\\Http\\Middleware\\HandleCors", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Http/Middleware/TrustProxies.php", + "line": 58, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "Illuminate\\Http\\Middleware\\TrustProxies", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/InvokeDeferredCallbacks.php", + "line": 22, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "Illuminate\\Foundation\\Http\\Middleware\\InvokeDeferredCallbacks", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Http/Middleware/ValidatePathEncoding.php", + "line": 26, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "Illuminate\\Http\\Middleware\\ValidatePathEncoding", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 137, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php", + "line": 175, + "function": "then", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php", + "line": 144, + "function": "sendRequestThroughRouter", + "class": "Illuminate\\Foundation\\Http\\Kernel", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Foundation/Testing/Concerns/MakesHttpRequests.php", + "line": 607, + "function": "handle", + "class": "Illuminate\\Foundation\\Http\\Kernel", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Foundation/Testing/Concerns/MakesHttpRequests.php", + "line": 573, + "function": "call", + "class": "Illuminate\\Foundation\\Testing\\TestCase", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/tests/Feature/Api/V1/FullSurface/Support/FullSurfaceE2EContractCase.php", + "line": 190, + "function": "json", + "class": "Illuminate\\Foundation\\Testing\\TestCase", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/tests/Feature/Api/V1/FullSurface/ApiBatch20RegressionContinuityComplianceSweepTest.php", + "line": 50, + "function": "requestAs", + "class": "Tests\\Feature\\Api\\V1\\FullSurface\\Support\\FullSurfaceE2EContractCase", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/phpunit/phpunit/src/Framework/TestCase.php", + "line": 1667, + "function": "test_batch20_continuity_compliance_and_export_sweep_stays_controlled", + "class": "Tests\\Feature\\Api\\V1\\FullSurface\\ApiBatch20RegressionContinuityComplianceSweepTest", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/phpunit/phpunit/src/Framework/TestCase.php", + "line": 519, + "function": "runTest", + "class": "PHPUnit\\Framework\\TestCase", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/phpunit/phpunit/src/Framework/TestRunner/TestRunner.php", + "line": 87, + "function": "runBare", + "class": "PHPUnit\\Framework\\TestCase", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/phpunit/phpunit/src/Framework/TestCase.php", + "line": 365, + "function": "run", + "class": "PHPUnit\\Framework\\TestRunner", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/phpunit/phpunit/src/Framework/TestSuite.php", + "line": 369, + "function": "run", + "class": "PHPUnit\\Framework\\TestCase", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/phpunit/phpunit/src/Framework/TestSuite.php", + "line": 369, + "function": "run", + "class": "PHPUnit\\Framework\\TestSuite", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/phpunit/phpunit/src/Framework/TestSuite.php", + "line": 369, + "function": "run", + "class": "PHPUnit\\Framework\\TestSuite", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/phpunit/phpunit/src/TextUI/TestRunner.php", + "line": 64, + "function": "run", + "class": "PHPUnit\\Framework\\TestSuite", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/phpunit/phpunit/src/TextUI/Application.php", + "line": 211, + "function": "run", + "class": "PHPUnit\\TextUI\\TestRunner", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/phpunit/phpunit/phpunit", + "line": 104, + "function": "run", + "class": "PHPUnit\\TextUI\\Application", + "type": "->" + } + ] +} +Failed asserting that an array contains 500. + + at tests/Concerns/AssertsE2EApiResponses.php:23 + 19▕ * @param array $statuses + 20▕ */ + 21▕ protected function assertStatusIn(TestResponse $response, array $statuses, string $context): void + 22▕ { + ➜ 23▕ $this->assertContains( + 24▕ $response->getStatusCode(), + 25▕ $statuses, + 26▕ $context.' returned unexpected status '.$response->getStatusCode().'. Body: '.$response->getContent() + 27▕ ); + + 1 tests/Concerns/AssertsE2EApiResponses.php:23 + 2 tests/Feature/Api/V1/FullSurface/Support/FullSurfaceE2EContractCase.php:343 + + ──────────────────────────────────────────────────────────────────────────── + FAILED Tests\Feature\Api\V1\FullSurface\ApiConcurrencyAndStaleWriteContr… + POST api/v1/school-years/{schoolYear}/archive returned unexpected status 500. Body: { + "message": "Method App\\Http\\Controllers\\Api\\SchoolYears\\SchoolYearController::archive does not exist.", + "exception": "BadMethodCallException", + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Routing/Controller.php", + "line": 68, + "trace": [ + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Routing/Controller.php", + "line": 54, + "function": "__call", + "class": "Illuminate\\Routing\\Controller", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Routing/ControllerDispatcher.php", + "line": 43, + "function": "callAction", + "class": "Illuminate\\Routing\\Controller", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Routing/Route.php", + "line": 265, + "function": "dispatch", + "class": "Illuminate\\Routing\\ControllerDispatcher", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Routing/Route.php", + "line": 211, + "function": "runController", + "class": "Illuminate\\Routing\\Route", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Routing/Router.php", + "line": 822, + "function": "run", + "class": "Illuminate\\Routing\\Route", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 180, + "function": "{closure:Illuminate\\Routing\\Router::runRouteWithinStack():821}", + "class": "Illuminate\\Routing\\Router", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/app/Http/Middleware/RequirePermission.php", + "line": 29, + "function": "{closure:Illuminate\\Pipeline\\Pipeline::prepareDestination():178}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "App\\Http\\Middleware\\RequirePermission", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/app/Http/Middleware/EnsureAccountActive.php", + "line": 32, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "App\\Http\\Middleware\\EnsureAccountActive", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/app/Http/Middleware/MultiAuth.php", + "line": 32, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "App\\Http\\Middleware\\MultiAuth", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Routing/Middleware/SubstituteBindings.php", + "line": 50, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "Illuminate\\Routing\\Middleware\\SubstituteBindings", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 137, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Routing/Router.php", + "line": 821, + "function": "then", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Routing/Router.php", + "line": 800, + "function": "runRouteWithinStack", + "class": "Illuminate\\Routing\\Router", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Routing/Router.php", + "line": 764, + "function": "runRoute", + "class": "Illuminate\\Routing\\Router", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Routing/Router.php", + "line": 753, + "function": "dispatchToRoute", + "class": "Illuminate\\Routing\\Router", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php", + "line": 200, + "function": "dispatch", + "class": "Illuminate\\Routing\\Router", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 180, + "function": "{closure:Illuminate\\Foundation\\Http\\Kernel::dispatchToRouter():197}", + "class": "Illuminate\\Foundation\\Http\\Kernel", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/app/Http/Middleware/SecurityHeaders.php", + "line": 22, + "function": "{closure:Illuminate\\Pipeline\\Pipeline::prepareDestination():178}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "App\\Http\\Middleware\\SecurityHeaders", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/TransformsRequest.php", + "line": 21, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/ConvertEmptyStringsToNull.php", + "line": 31, + "function": "handle", + "class": "Illuminate\\Foundation\\Http\\Middleware\\TransformsRequest", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "Illuminate\\Foundation\\Http\\Middleware\\ConvertEmptyStringsToNull", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/TransformsRequest.php", + "line": 21, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/TrimStrings.php", + "line": 51, + "function": "handle", + "class": "Illuminate\\Foundation\\Http\\Middleware\\TransformsRequest", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "Illuminate\\Foundation\\Http\\Middleware\\TrimStrings", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Http/Middleware/ValidatePostSize.php", + "line": 27, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "Illuminate\\Http\\Middleware\\ValidatePostSize", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/PreventRequestsDuringMaintenance.php", + "line": 109, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "Illuminate\\Foundation\\Http\\Middleware\\PreventRequestsDuringMaintenance", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Http/Middleware/HandleCors.php", + "line": 74, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "Illuminate\\Http\\Middleware\\HandleCors", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Http/Middleware/TrustProxies.php", + "line": 58, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "Illuminate\\Http\\Middleware\\TrustProxies", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/InvokeDeferredCallbacks.php", + "line": 22, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "Illuminate\\Foundation\\Http\\Middleware\\InvokeDeferredCallbacks", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Http/Middleware/ValidatePathEncoding.php", + "line": 26, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "Illuminate\\Http\\Middleware\\ValidatePathEncoding", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 137, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php", + "line": 175, + "function": "then", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php", + "line": 144, + "function": "sendRequestThroughRouter", + "class": "Illuminate\\Foundation\\Http\\Kernel", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Foundation/Testing/Concerns/MakesHttpRequests.php", + "line": 607, + "function": "handle", + "class": "Illuminate\\Foundation\\Http\\Kernel", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Foundation/Testing/Concerns/MakesHttpRequests.php", + "line": 573, + "function": "call", + "class": "Illuminate\\Foundation\\Testing\\TestCase", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/tests/Feature/Api/V1/FullSurface/Support/FullSurfaceE2EContractCase.php", + "line": 190, + "function": "json", + "class": "Illuminate\\Foundation\\Testing\\TestCase", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/tests/Feature/Api/V1/FullSurface/ApiConcurrencyAndStaleWriteContractTest.php", + "line": 23, + "function": "requestAs", + "class": "Tests\\Feature\\Api\\V1\\FullSurface\\Support\\FullSurfaceE2EContractCase", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/phpunit/phpunit/src/Framework/TestCase.php", + "line": 1667, + "function": "test_duplicate_update_payloads_remain_controlled_and_do_not_throw_server_errors", + "class": "Tests\\Feature\\Api\\V1\\FullSurface\\ApiConcurrencyAndStaleWriteContractTest", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/phpunit/phpunit/src/Framework/TestCase.php", + "line": 519, + "function": "runTest", + "class": "PHPUnit\\Framework\\TestCase", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/phpunit/phpunit/src/Framework/TestRunner/TestRunner.php", + "line": 87, + "function": "runBare", + "class": "PHPUnit\\Framework\\TestCase", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/phpunit/phpunit/src/Framework/TestCase.php", + "line": 365, + "function": "run", + "class": "PHPUnit\\Framework\\TestRunner", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/phpunit/phpunit/src/Framework/TestSuite.php", + "line": 369, + "function": "run", + "class": "PHPUnit\\Framework\\TestCase", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/phpunit/phpunit/src/Framework/TestSuite.php", + "line": 369, + "function": "run", + "class": "PHPUnit\\Framework\\TestSuite", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/phpunit/phpunit/src/Framework/TestSuite.php", + "line": 369, + "function": "run", + "class": "PHPUnit\\Framework\\TestSuite", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/phpunit/phpunit/src/TextUI/TestRunner.php", + "line": 64, + "function": "run", + "class": "PHPUnit\\Framework\\TestSuite", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/phpunit/phpunit/src/TextUI/Application.php", + "line": 211, + "function": "run", + "class": "PHPUnit\\TextUI\\TestRunner", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/phpunit/phpunit/phpunit", + "line": 104, + "function": "run", + "class": "PHPUnit\\TextUI\\Application", + "type": "->" + } + ] +} +Failed asserting that an array contains 500. + + at tests/Concerns/AssertsE2EApiResponses.php:23 + 19▕ * @param array $statuses + 20▕ */ + 21▕ protected function assertStatusIn(TestResponse $response, array $statuses, string $context): void + 22▕ { + ➜ 23▕ $this->assertContains( + 24▕ $response->getStatusCode(), + 25▕ $statuses, + 26▕ $context.' returned unexpected status '.$response->getStatusCode().'. Body: '.$response->getContent() + 27▕ ); + + 1 tests/Concerns/AssertsE2EApiResponses.php:23 + 2 tests/Feature/Api/V1/FullSurface/Support/FullSurfaceE2EContractCase.php:343 + + ──────────────────────────────────────────────────────────────────────────── + FAILED Tests\Feature\Api\V1\FullSurface\ApiDatabaseTransactionRollbackCo… + POST api/v1/school-years/{schoolYear}/archive destructive rollback should return a controlled response, not a 5xx crash. Body: { + "message": "Method App\\Http\\Controllers\\Api\\SchoolYears\\SchoolYearController::archive does not exist.", + "exception": "BadMethodCallException", + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Routing/Controller.php", + "line": 68, + "trace": [ + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Routing/Controller.php", + "line": 54, + "function": "__call", + "class": "Illuminate\\Routing\\Controller", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Routing/ControllerDispatcher.php", + "line": 43, + "function": "callAction", + "class": "Illuminate\\Routing\\Controller", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Routing/Route.php", + "line": 265, + "function": "dispatch", + "class": "Illuminate\\Routing\\ControllerDispatcher", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Routing/Route.php", + "line": 211, + "function": "runController", + "class": "Illuminate\\Routing\\Route", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Routing/Router.php", + "line": 822, + "function": "run", + "class": "Illuminate\\Routing\\Route", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 180, + "function": "{closure:Illuminate\\Routing\\Router::runRouteWithinStack():821}", + "class": "Illuminate\\Routing\\Router", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/app/Http/Middleware/RequirePermission.php", + "line": 29, + "function": "{closure:Illuminate\\Pipeline\\Pipeline::prepareDestination():178}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "App\\Http\\Middleware\\RequirePermission", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/app/Http/Middleware/EnsureAccountActive.php", + "line": 32, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "App\\Http\\Middleware\\EnsureAccountActive", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/app/Http/Middleware/MultiAuth.php", + "line": 32, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "App\\Http\\Middleware\\MultiAuth", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Routing/Middleware/SubstituteBindings.php", + "line": 50, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "Illuminate\\Routing\\Middleware\\SubstituteBindings", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 137, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Routing/Router.php", + "line": 821, + "function": "then", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Routing/Router.php", + "line": 800, + "function": "runRouteWithinStack", + "class": "Illuminate\\Routing\\Router", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Routing/Router.php", + "line": 764, + "function": "runRoute", + "class": "Illuminate\\Routing\\Router", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Routing/Router.php", + "line": 753, + "function": "dispatchToRoute", + "class": "Illuminate\\Routing\\Router", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php", + "line": 200, + "function": "dispatch", + "class": "Illuminate\\Routing\\Router", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 180, + "function": "{closure:Illuminate\\Foundation\\Http\\Kernel::dispatchToRouter():197}", + "class": "Illuminate\\Foundation\\Http\\Kernel", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/app/Http/Middleware/SecurityHeaders.php", + "line": 22, + "function": "{closure:Illuminate\\Pipeline\\Pipeline::prepareDestination():178}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "App\\Http\\Middleware\\SecurityHeaders", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/TransformsRequest.php", + "line": 21, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/ConvertEmptyStringsToNull.php", + "line": 31, + "function": "handle", + "class": "Illuminate\\Foundation\\Http\\Middleware\\TransformsRequest", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "Illuminate\\Foundation\\Http\\Middleware\\ConvertEmptyStringsToNull", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/TransformsRequest.php", + "line": 21, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/TrimStrings.php", + "line": 51, + "function": "handle", + "class": "Illuminate\\Foundation\\Http\\Middleware\\TransformsRequest", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "Illuminate\\Foundation\\Http\\Middleware\\TrimStrings", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Http/Middleware/ValidatePostSize.php", + "line": 27, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "Illuminate\\Http\\Middleware\\ValidatePostSize", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/PreventRequestsDuringMaintenance.php", + "line": 109, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "Illuminate\\Foundation\\Http\\Middleware\\PreventRequestsDuringMaintenance", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Http/Middleware/HandleCors.php", + "line": 74, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "Illuminate\\Http\\Middleware\\HandleCors", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Http/Middleware/TrustProxies.php", + "line": 58, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "Illuminate\\Http\\Middleware\\TrustProxies", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/InvokeDeferredCallbacks.php", + "line": 22, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "Illuminate\\Foundation\\Http\\Middleware\\InvokeDeferredCallbacks", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Http/Middleware/ValidatePathEncoding.php", + "line": 26, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "Illuminate\\Http\\Middleware\\ValidatePathEncoding", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 137, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php", + "line": 175, + "function": "then", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php", + "line": 144, + "function": "sendRequestThroughRouter", + "class": "Illuminate\\Foundation\\Http\\Kernel", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Foundation/Testing/Concerns/MakesHttpRequests.php", + "line": 607, + "function": "handle", + "class": "Illuminate\\Foundation\\Http\\Kernel", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Foundation/Testing/Concerns/MakesHttpRequests.php", + "line": 573, + "function": "call", + "class": "Illuminate\\Foundation\\Testing\\TestCase", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/tests/Feature/Api/V1/FullSurface/Support/FullSurfaceE2EContractCase.php", + "line": 190, + "function": "json", + "class": "Illuminate\\Foundation\\Testing\\TestCase", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/tests/Feature/Api/V1/FullSurface/ApiDatabaseTransactionRollbackContractTest.php", + "line": 55, + "function": "requestAs", + "class": "Tests\\Feature\\Api\\V1\\FullSurface\\Support\\FullSurfaceE2EContractCase", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/phpunit/phpunit/src/Framework/TestCase.php", + "line": 1667, + "function": "test_delete_failures_do_not_remove_parent_or_student_fixtures", + "class": "Tests\\Feature\\Api\\V1\\FullSurface\\ApiDatabaseTransactionRollbackContractTest", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/phpunit/phpunit/src/Framework/TestCase.php", + "line": 519, + "function": "runTest", + "class": "PHPUnit\\Framework\\TestCase", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/phpunit/phpunit/src/Framework/TestRunner/TestRunner.php", + "line": 87, + "function": "runBare", + "class": "PHPUnit\\Framework\\TestCase", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/phpunit/phpunit/src/Framework/TestCase.php", + "line": 365, + "function": "run", + "class": "PHPUnit\\Framework\\TestRunner", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/phpunit/phpunit/src/Framework/TestSuite.php", + "line": 369, + "function": "run", + "class": "PHPUnit\\Framework\\TestCase", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/phpunit/phpunit/src/Framework/TestSuite.php", + "line": 369, + "function": "run", + "class": "PHPUnit\\Framework\\TestSuite", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/phpunit/phpunit/src/Framework/TestSuite.php", + "line": 369, + "function": "run", + "class": "PHPUnit\\Framework\\TestSuite", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/phpunit/phpunit/src/TextUI/TestRunner.php", + "line": 64, + "function": "run", + "class": "PHPUnit\\Framework\\TestSuite", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/phpunit/phpunit/src/TextUI/Application.php", + "line": 211, + "function": "run", + "class": "PHPUnit\\TextUI\\TestRunner", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/phpunit/phpunit/phpunit", + "line": 104, + "function": "run", + "class": "PHPUnit\\TextUI\\Application", + "type": "->" + } + ] +} +Failed asserting that 500 is less than 500. + + at tests/Concerns/AssertsE2EApiResponses.php:11 + 7▕ trait AssertsE2EApiResponses + 8▕ { + 9▕ protected function assertNoServerError(TestResponse $response, string $context): void + 10▕ { + ➜ 11▕ $this->assertLessThan( + 12▕ 500, + 13▕ $response->getStatusCode(), + 14▕ $context.' should return a controlled response, not a 5xx crash. Body: '.$response->getContent() + 15▕ ); + + 1 tests/Concerns/AssertsE2EApiResponses.php:11 + 2 tests/Feature/Api/V1/FullSurface/ApiDatabaseTransactionRollbackContractTest.php:57 + + ──────────────────────────────────────────────────────────────────────────── + FAILED Tests\Feature\Api\V1\FullSurface\ApiDateMoneyAndTimezoneBoundaryC… + POST api/v1/school-years/{schoolYear}/archive bad date 2025-02-30 returned unexpected status 500. Body: { + "message": "Method App\\Http\\Controllers\\Api\\SchoolYears\\SchoolYearController::archive does not exist.", + "exception": "BadMethodCallException", + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Routing/Controller.php", + "line": 68, + "trace": [ + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Routing/Controller.php", + "line": 54, + "function": "__call", + "class": "Illuminate\\Routing\\Controller", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Routing/ControllerDispatcher.php", + "line": 43, + "function": "callAction", + "class": "Illuminate\\Routing\\Controller", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Routing/Route.php", + "line": 265, + "function": "dispatch", + "class": "Illuminate\\Routing\\ControllerDispatcher", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Routing/Route.php", + "line": 211, + "function": "runController", + "class": "Illuminate\\Routing\\Route", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Routing/Router.php", + "line": 822, + "function": "run", + "class": "Illuminate\\Routing\\Route", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 180, + "function": "{closure:Illuminate\\Routing\\Router::runRouteWithinStack():821}", + "class": "Illuminate\\Routing\\Router", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/app/Http/Middleware/RequirePermission.php", + "line": 29, + "function": "{closure:Illuminate\\Pipeline\\Pipeline::prepareDestination():178}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "App\\Http\\Middleware\\RequirePermission", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/app/Http/Middleware/EnsureAccountActive.php", + "line": 32, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "App\\Http\\Middleware\\EnsureAccountActive", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/app/Http/Middleware/MultiAuth.php", + "line": 32, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "App\\Http\\Middleware\\MultiAuth", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Routing/Middleware/SubstituteBindings.php", + "line": 50, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "Illuminate\\Routing\\Middleware\\SubstituteBindings", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 137, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Routing/Router.php", + "line": 821, + "function": "then", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Routing/Router.php", + "line": 800, + "function": "runRouteWithinStack", + "class": "Illuminate\\Routing\\Router", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Routing/Router.php", + "line": 764, + "function": "runRoute", + "class": "Illuminate\\Routing\\Router", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Routing/Router.php", + "line": 753, + "function": "dispatchToRoute", + "class": "Illuminate\\Routing\\Router", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php", + "line": 200, + "function": "dispatch", + "class": "Illuminate\\Routing\\Router", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 180, + "function": "{closure:Illuminate\\Foundation\\Http\\Kernel::dispatchToRouter():197}", + "class": "Illuminate\\Foundation\\Http\\Kernel", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/app/Http/Middleware/SecurityHeaders.php", + "line": 22, + "function": "{closure:Illuminate\\Pipeline\\Pipeline::prepareDestination():178}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "App\\Http\\Middleware\\SecurityHeaders", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/TransformsRequest.php", + "line": 21, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/ConvertEmptyStringsToNull.php", + "line": 31, + "function": "handle", + "class": "Illuminate\\Foundation\\Http\\Middleware\\TransformsRequest", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "Illuminate\\Foundation\\Http\\Middleware\\ConvertEmptyStringsToNull", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/TransformsRequest.php", + "line": 21, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/TrimStrings.php", + "line": 51, + "function": "handle", + "class": "Illuminate\\Foundation\\Http\\Middleware\\TransformsRequest", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "Illuminate\\Foundation\\Http\\Middleware\\TrimStrings", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Http/Middleware/ValidatePostSize.php", + "line": 27, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "Illuminate\\Http\\Middleware\\ValidatePostSize", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/PreventRequestsDuringMaintenance.php", + "line": 109, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "Illuminate\\Foundation\\Http\\Middleware\\PreventRequestsDuringMaintenance", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Http/Middleware/HandleCors.php", + "line": 74, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "Illuminate\\Http\\Middleware\\HandleCors", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Http/Middleware/TrustProxies.php", + "line": 58, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "Illuminate\\Http\\Middleware\\TrustProxies", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/InvokeDeferredCallbacks.php", + "line": 22, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "Illuminate\\Foundation\\Http\\Middleware\\InvokeDeferredCallbacks", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Http/Middleware/ValidatePathEncoding.php", + "line": 26, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "Illuminate\\Http\\Middleware\\ValidatePathEncoding", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 137, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php", + "line": 175, + "function": "then", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php", + "line": 144, + "function": "sendRequestThroughRouter", + "class": "Illuminate\\Foundation\\Http\\Kernel", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Foundation/Testing/Concerns/MakesHttpRequests.php", + "line": 607, + "function": "handle", + "class": "Illuminate\\Foundation\\Http\\Kernel", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Foundation/Testing/Concerns/MakesHttpRequests.php", + "line": 573, + "function": "call", + "class": "Illuminate\\Foundation\\Testing\\TestCase", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/tests/Feature/Api/V1/FullSurface/Support/FullSurfaceE2EContractCase.php", + "line": 190, + "function": "json", + "class": "Illuminate\\Foundation\\Testing\\TestCase", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/tests/Feature/Api/V1/FullSurface/ApiDateMoneyAndTimezoneBoundaryContractTest.php", + "line": 35, + "function": "requestAs", + "class": "Tests\\Feature\\Api\\V1\\FullSurface\\Support\\FullSurfaceE2EContractCase", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/phpunit/phpunit/src/Framework/TestCase.php", + "line": 1667, + "function": "test_date_accepting_endpoints_reject_impossible_or_ambiguous_dates_cleanly", + "class": "Tests\\Feature\\Api\\V1\\FullSurface\\ApiDateMoneyAndTimezoneBoundaryContractTest", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/phpunit/phpunit/src/Framework/TestCase.php", + "line": 519, + "function": "runTest", + "class": "PHPUnit\\Framework\\TestCase", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/phpunit/phpunit/src/Framework/TestRunner/TestRunner.php", + "line": 87, + "function": "runBare", + "class": "PHPUnit\\Framework\\TestCase", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/phpunit/phpunit/src/Framework/TestCase.php", + "line": 365, + "function": "run", + "class": "PHPUnit\\Framework\\TestRunner", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/phpunit/phpunit/src/Framework/TestSuite.php", + "line": 369, + "function": "run", + "class": "PHPUnit\\Framework\\TestCase", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/phpunit/phpunit/src/Framework/TestSuite.php", + "line": 369, + "function": "run", + "class": "PHPUnit\\Framework\\TestSuite", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/phpunit/phpunit/src/Framework/TestSuite.php", + "line": 369, + "function": "run", + "class": "PHPUnit\\Framework\\TestSuite", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/phpunit/phpunit/src/TextUI/TestRunner.php", + "line": 64, + "function": "run", + "class": "PHPUnit\\Framework\\TestSuite", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/phpunit/phpunit/src/TextUI/Application.php", + "line": 211, + "function": "run", + "class": "PHPUnit\\TextUI\\TestRunner", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/phpunit/phpunit/phpunit", + "line": 104, + "function": "run", + "class": "PHPUnit\\TextUI\\Application", + "type": "->" + } + ] +} +Failed asserting that an array contains 500. + + at tests/Concerns/AssertsE2EApiResponses.php:23 + 19▕ * @param array $statuses + 20▕ */ + 21▕ protected function assertStatusIn(TestResponse $response, array $statuses, string $context): void + 22▕ { + ➜ 23▕ $this->assertContains( + 24▕ $response->getStatusCode(), + 25▕ $statuses, + 26▕ $context.' returned unexpected status '.$response->getStatusCode().'. Body: '.$response->getContent() + 27▕ ); + + 1 tests/Concerns/AssertsE2EApiResponses.php:23 + 2 tests/Feature/Api/V1/FullSurface/ApiDateMoneyAndTimezoneBoundaryContractTest.php:36 + + ──────────────────────────────────────────────────────────────────────────── + FAILED Tests\Feature\Api\V1\FullSurface\ApiDestructiveActionSafeguardCon… + POST api/v1/school-years/{schoolYear}/archive returned unexpected status 500. Body: { + "message": "Method App\\Http\\Controllers\\Api\\SchoolYears\\SchoolYearController::archive does not exist.", + "exception": "BadMethodCallException", + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Routing/Controller.php", + "line": 68, + "trace": [ + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Routing/Controller.php", + "line": 54, + "function": "__call", + "class": "Illuminate\\Routing\\Controller", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Routing/ControllerDispatcher.php", + "line": 43, + "function": "callAction", + "class": "Illuminate\\Routing\\Controller", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Routing/Route.php", + "line": 265, + "function": "dispatch", + "class": "Illuminate\\Routing\\ControllerDispatcher", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Routing/Route.php", + "line": 211, + "function": "runController", + "class": "Illuminate\\Routing\\Route", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Routing/Router.php", + "line": 822, + "function": "run", + "class": "Illuminate\\Routing\\Route", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 180, + "function": "{closure:Illuminate\\Routing\\Router::runRouteWithinStack():821}", + "class": "Illuminate\\Routing\\Router", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/app/Http/Middleware/RequirePermission.php", + "line": 29, + "function": "{closure:Illuminate\\Pipeline\\Pipeline::prepareDestination():178}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "App\\Http\\Middleware\\RequirePermission", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/app/Http/Middleware/EnsureAccountActive.php", + "line": 32, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "App\\Http\\Middleware\\EnsureAccountActive", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/app/Http/Middleware/MultiAuth.php", + "line": 32, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "App\\Http\\Middleware\\MultiAuth", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Routing/Middleware/SubstituteBindings.php", + "line": 50, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "Illuminate\\Routing\\Middleware\\SubstituteBindings", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 137, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Routing/Router.php", + "line": 821, + "function": "then", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Routing/Router.php", + "line": 800, + "function": "runRouteWithinStack", + "class": "Illuminate\\Routing\\Router", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Routing/Router.php", + "line": 764, + "function": "runRoute", + "class": "Illuminate\\Routing\\Router", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Routing/Router.php", + "line": 753, + "function": "dispatchToRoute", + "class": "Illuminate\\Routing\\Router", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php", + "line": 200, + "function": "dispatch", + "class": "Illuminate\\Routing\\Router", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 180, + "function": "{closure:Illuminate\\Foundation\\Http\\Kernel::dispatchToRouter():197}", + "class": "Illuminate\\Foundation\\Http\\Kernel", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/app/Http/Middleware/SecurityHeaders.php", + "line": 22, + "function": "{closure:Illuminate\\Pipeline\\Pipeline::prepareDestination():178}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "App\\Http\\Middleware\\SecurityHeaders", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/TransformsRequest.php", + "line": 21, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/ConvertEmptyStringsToNull.php", + "line": 31, + "function": "handle", + "class": "Illuminate\\Foundation\\Http\\Middleware\\TransformsRequest", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "Illuminate\\Foundation\\Http\\Middleware\\ConvertEmptyStringsToNull", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/TransformsRequest.php", + "line": 21, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/TrimStrings.php", + "line": 51, + "function": "handle", + "class": "Illuminate\\Foundation\\Http\\Middleware\\TransformsRequest", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "Illuminate\\Foundation\\Http\\Middleware\\TrimStrings", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Http/Middleware/ValidatePostSize.php", + "line": 27, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "Illuminate\\Http\\Middleware\\ValidatePostSize", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/PreventRequestsDuringMaintenance.php", + "line": 109, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "Illuminate\\Foundation\\Http\\Middleware\\PreventRequestsDuringMaintenance", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Http/Middleware/HandleCors.php", + "line": 74, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "Illuminate\\Http\\Middleware\\HandleCors", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Http/Middleware/TrustProxies.php", + "line": 58, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "Illuminate\\Http\\Middleware\\TrustProxies", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/InvokeDeferredCallbacks.php", + "line": 22, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "Illuminate\\Foundation\\Http\\Middleware\\InvokeDeferredCallbacks", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Http/Middleware/ValidatePathEncoding.php", + "line": 26, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "Illuminate\\Http\\Middleware\\ValidatePathEncoding", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 137, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php", + "line": 175, + "function": "then", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php", + "line": 144, + "function": "sendRequestThroughRouter", + "class": "Illuminate\\Foundation\\Http\\Kernel", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Foundation/Testing/Concerns/MakesHttpRequests.php", + "line": 607, + "function": "handle", + "class": "Illuminate\\Foundation\\Http\\Kernel", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Foundation/Testing/Concerns/MakesHttpRequests.php", + "line": 573, + "function": "call", + "class": "Illuminate\\Foundation\\Testing\\TestCase", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/tests/Feature/Api/V1/FullSurface/Support/FullSurfaceE2EContractCase.php", + "line": 190, + "function": "json", + "class": "Illuminate\\Foundation\\Testing\\TestCase", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/tests/Feature/Api/V1/FullSurface/ApiDestructiveActionSafeguardContractTest.php", + "line": 48, + "function": "requestAs", + "class": "Tests\\Feature\\Api\\V1\\FullSurface\\Support\\FullSurfaceE2EContractCase", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/phpunit/phpunit/src/Framework/TestCase.php", + "line": 1667, + "function": "test_archive_remove_cancel_and_void_routes_are_idempotent_or_conflict_safe", + "class": "Tests\\Feature\\Api\\V1\\FullSurface\\ApiDestructiveActionSafeguardContractTest", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/phpunit/phpunit/src/Framework/TestCase.php", + "line": 519, + "function": "runTest", + "class": "PHPUnit\\Framework\\TestCase", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/phpunit/phpunit/src/Framework/TestRunner/TestRunner.php", + "line": 87, + "function": "runBare", + "class": "PHPUnit\\Framework\\TestCase", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/phpunit/phpunit/src/Framework/TestCase.php", + "line": 365, + "function": "run", + "class": "PHPUnit\\Framework\\TestRunner", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/phpunit/phpunit/src/Framework/TestSuite.php", + "line": 369, + "function": "run", + "class": "PHPUnit\\Framework\\TestCase", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/phpunit/phpunit/src/Framework/TestSuite.php", + "line": 369, + "function": "run", + "class": "PHPUnit\\Framework\\TestSuite", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/phpunit/phpunit/src/Framework/TestSuite.php", + "line": 369, + "function": "run", + "class": "PHPUnit\\Framework\\TestSuite", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/phpunit/phpunit/src/TextUI/TestRunner.php", + "line": 64, + "function": "run", + "class": "PHPUnit\\Framework\\TestSuite", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/phpunit/phpunit/src/TextUI/Application.php", + "line": 211, + "function": "run", + "class": "PHPUnit\\TextUI\\TestRunner", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/phpunit/phpunit/phpunit", + "line": 104, + "function": "run", + "class": "PHPUnit\\TextUI\\Application", + "type": "->" + } + ] +} +Failed asserting that an array contains 500. + + at tests/Concerns/AssertsE2EApiResponses.php:23 + 19▕ * @param array $statuses + 20▕ */ + 21▕ protected function assertStatusIn(TestResponse $response, array $statuses, string $context): void + 22▕ { + ➜ 23▕ $this->assertContains( + 24▕ $response->getStatusCode(), + 25▕ $statuses, + 26▕ $context.' returned unexpected status '.$response->getStatusCode().'. Body: '.$response->getContent() + 27▕ ); + + 1 tests/Concerns/AssertsE2EApiResponses.php:23 + 2 tests/Feature/Api/V1/FullSurface/Support/FullSurfaceE2EContractCase.php:343 + + ──────────────────────────────────────────────────────────────────────────── + FAILED Tests\Feature\Api\V1\FullSurface\ApiEnumAndStateMachineContractTe… + POST api/v1/school-years/{schoolYear}/archive returned unexpected status 500. Body: { + "message": "Method App\\Http\\Controllers\\Api\\SchoolYears\\SchoolYearController::archive does not exist.", + "exception": "BadMethodCallException", + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Routing/Controller.php", + "line": 68, + "trace": [ + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Routing/Controller.php", + "line": 54, + "function": "__call", + "class": "Illuminate\\Routing\\Controller", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Routing/ControllerDispatcher.php", + "line": 43, + "function": "callAction", + "class": "Illuminate\\Routing\\Controller", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Routing/Route.php", + "line": 265, + "function": "dispatch", + "class": "Illuminate\\Routing\\ControllerDispatcher", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Routing/Route.php", + "line": 211, + "function": "runController", + "class": "Illuminate\\Routing\\Route", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Routing/Router.php", + "line": 822, + "function": "run", + "class": "Illuminate\\Routing\\Route", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 180, + "function": "{closure:Illuminate\\Routing\\Router::runRouteWithinStack():821}", + "class": "Illuminate\\Routing\\Router", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/app/Http/Middleware/RequirePermission.php", + "line": 29, + "function": "{closure:Illuminate\\Pipeline\\Pipeline::prepareDestination():178}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "App\\Http\\Middleware\\RequirePermission", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/app/Http/Middleware/EnsureAccountActive.php", + "line": 32, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "App\\Http\\Middleware\\EnsureAccountActive", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/app/Http/Middleware/MultiAuth.php", + "line": 32, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "App\\Http\\Middleware\\MultiAuth", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Routing/Middleware/SubstituteBindings.php", + "line": 50, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "Illuminate\\Routing\\Middleware\\SubstituteBindings", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 137, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Routing/Router.php", + "line": 821, + "function": "then", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Routing/Router.php", + "line": 800, + "function": "runRouteWithinStack", + "class": "Illuminate\\Routing\\Router", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Routing/Router.php", + "line": 764, + "function": "runRoute", + "class": "Illuminate\\Routing\\Router", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Routing/Router.php", + "line": 753, + "function": "dispatchToRoute", + "class": "Illuminate\\Routing\\Router", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php", + "line": 200, + "function": "dispatch", + "class": "Illuminate\\Routing\\Router", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 180, + "function": "{closure:Illuminate\\Foundation\\Http\\Kernel::dispatchToRouter():197}", + "class": "Illuminate\\Foundation\\Http\\Kernel", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/app/Http/Middleware/SecurityHeaders.php", + "line": 22, + "function": "{closure:Illuminate\\Pipeline\\Pipeline::prepareDestination():178}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "App\\Http\\Middleware\\SecurityHeaders", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/TransformsRequest.php", + "line": 21, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/ConvertEmptyStringsToNull.php", + "line": 31, + "function": "handle", + "class": "Illuminate\\Foundation\\Http\\Middleware\\TransformsRequest", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "Illuminate\\Foundation\\Http\\Middleware\\ConvertEmptyStringsToNull", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/TransformsRequest.php", + "line": 21, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/TrimStrings.php", + "line": 51, + "function": "handle", + "class": "Illuminate\\Foundation\\Http\\Middleware\\TransformsRequest", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "Illuminate\\Foundation\\Http\\Middleware\\TrimStrings", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Http/Middleware/ValidatePostSize.php", + "line": 27, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "Illuminate\\Http\\Middleware\\ValidatePostSize", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/PreventRequestsDuringMaintenance.php", + "line": 109, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "Illuminate\\Foundation\\Http\\Middleware\\PreventRequestsDuringMaintenance", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Http/Middleware/HandleCors.php", + "line": 74, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "Illuminate\\Http\\Middleware\\HandleCors", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Http/Middleware/TrustProxies.php", + "line": 58, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "Illuminate\\Http\\Middleware\\TrustProxies", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/InvokeDeferredCallbacks.php", + "line": 22, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "Illuminate\\Foundation\\Http\\Middleware\\InvokeDeferredCallbacks", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Http/Middleware/ValidatePathEncoding.php", + "line": 26, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "Illuminate\\Http\\Middleware\\ValidatePathEncoding", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 137, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php", + "line": 175, + "function": "then", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php", + "line": 144, + "function": "sendRequestThroughRouter", + "class": "Illuminate\\Foundation\\Http\\Kernel", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Foundation/Testing/Concerns/MakesHttpRequests.php", + "line": 607, + "function": "handle", + "class": "Illuminate\\Foundation\\Http\\Kernel", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Foundation/Testing/Concerns/MakesHttpRequests.php", + "line": 573, + "function": "call", + "class": "Illuminate\\Foundation\\Testing\\TestCase", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/tests/Feature/Api/V1/FullSurface/Support/FullSurfaceE2EContractCase.php", + "line": 190, + "function": "json", + "class": "Illuminate\\Foundation\\Testing\\TestCase", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/tests/Feature/Api/V1/FullSurface/ApiEnumAndStateMachineContractTest.php", + "line": 22, + "function": "requestAs", + "class": "Tests\\Feature\\Api\\V1\\FullSurface\\Support\\FullSurfaceE2EContractCase", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/phpunit/phpunit/src/Framework/TestCase.php", + "line": 1667, + "function": "test_status_fields_reject_unknown_states_without_defaulting_to_success", + "class": "Tests\\Feature\\Api\\V1\\FullSurface\\ApiEnumAndStateMachineContractTest", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/phpunit/phpunit/src/Framework/TestCase.php", + "line": 519, + "function": "runTest", + "class": "PHPUnit\\Framework\\TestCase", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/phpunit/phpunit/src/Framework/TestRunner/TestRunner.php", + "line": 87, + "function": "runBare", + "class": "PHPUnit\\Framework\\TestCase", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/phpunit/phpunit/src/Framework/TestCase.php", + "line": 365, + "function": "run", + "class": "PHPUnit\\Framework\\TestRunner", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/phpunit/phpunit/src/Framework/TestSuite.php", + "line": 369, + "function": "run", + "class": "PHPUnit\\Framework\\TestCase", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/phpunit/phpunit/src/Framework/TestSuite.php", + "line": 369, + "function": "run", + "class": "PHPUnit\\Framework\\TestSuite", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/phpunit/phpunit/src/Framework/TestSuite.php", + "line": 369, + "function": "run", + "class": "PHPUnit\\Framework\\TestSuite", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/phpunit/phpunit/src/TextUI/TestRunner.php", + "line": 64, + "function": "run", + "class": "PHPUnit\\Framework\\TestSuite", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/phpunit/phpunit/src/TextUI/Application.php", + "line": 211, + "function": "run", + "class": "PHPUnit\\TextUI\\TestRunner", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/phpunit/phpunit/phpunit", + "line": 104, + "function": "run", + "class": "PHPUnit\\TextUI\\Application", + "type": "->" + } + ] +} +Failed asserting that an array contains 500. + + at tests/Concerns/AssertsE2EApiResponses.php:23 + 19▕ * @param array $statuses + 20▕ */ + 21▕ protected function assertStatusIn(TestResponse $response, array $statuses, string $context): void + 22▕ { + ➜ 23▕ $this->assertContains( + 24▕ $response->getStatusCode(), + 25▕ $statuses, + 26▕ $context.' returned unexpected status '.$response->getStatusCode().'. Body: '.$response->getContent() + 27▕ ); + + 1 tests/Concerns/AssertsE2EApiResponses.php:23 + 2 tests/Feature/Api/V1/FullSurface/Support/FullSurfaceE2EContractCase.php:343 + + ──────────────────────────────────────────────────────────────────────────── + FAILED Tests\Feature\Api\V1\FullSurface\ApiErrorEnvelopeConsistencyContr… + parent denied api/v1/school-years returned unexpected status 200. Body: {"ok":true,"data":[{"id":1,"name":"2025-2026","start_date":"2025-09-01","end_date":"2026-06-30","status":"active","is_current":true,"closed_at":null,"closed_by":null}],"meta":{"school_year":"2025-2026","current_school_year":"2025-2026","semester":"Fall","current_semester":"Fall","school_years":[{"id":1,"name":"2025-2026","label":"2025-2026","start_date":"2025-09-01","end_date":"2026-06-30","status":"active","is_current":true,"is_editable":true}],"semesters":[{"name":"Fall","label":"Fall","is_current":true},{"name":"Spring","label":"Spring","is_current":false}]},"school_years":[{"id":1,"name":"2025-2026","label":"2025-2026","start_date":"2025-09-01","end_date":"2026-06-30","status":"active","is_current":true,"is_editable":true}],"current_school_year":"2025-2026","current_semester":"Fall"} +Failed asserting that an array contains 200. + + at tests/Concerns/AssertsE2EApiResponses.php:23 + 19▕ * @param array $statuses + 20▕ */ + 21▕ protected function assertStatusIn(TestResponse $response, array $statuses, string $context): void + 22▕ { + ➜ 23▕ $this->assertContains( + 24▕ $response->getStatusCode(), + 25▕ $statuses, + 26▕ $context.' returned unexpected status '.$response->getStatusCode().'. Body: '.$response->getContent() + 27▕ ); + + 1 tests/Concerns/AssertsE2EApiResponses.php:23 + 2 tests/Feature/Api/V1/FullSurface/ApiErrorEnvelopeConsistencyContractTest.php:50 + + ──────────────────────────────────────────────────────────────────────────── + FAILED Tests\Feature\Api\V1\FullSurface\ApiFeatureFlagAndConfigurationDr… + POST api/v1/school-years/{schoolYear}/archive missing config should return a controlled response, not a 5xx crash. Body: { + "message": "Method App\\Http\\Controllers\\Api\\SchoolYears\\SchoolYearController::archive does not exist.", + "exception": "BadMethodCallException", + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Routing/Controller.php", + "line": 68, + "trace": [ + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Routing/Controller.php", + "line": 54, + "function": "__call", + "class": "Illuminate\\Routing\\Controller", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Routing/ControllerDispatcher.php", + "line": 43, + "function": "callAction", + "class": "Illuminate\\Routing\\Controller", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Routing/Route.php", + "line": 265, + "function": "dispatch", + "class": "Illuminate\\Routing\\ControllerDispatcher", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Routing/Route.php", + "line": 211, + "function": "runController", + "class": "Illuminate\\Routing\\Route", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Routing/Router.php", + "line": 822, + "function": "run", + "class": "Illuminate\\Routing\\Route", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 180, + "function": "{closure:Illuminate\\Routing\\Router::runRouteWithinStack():821}", + "class": "Illuminate\\Routing\\Router", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/app/Http/Middleware/RequirePermission.php", + "line": 29, + "function": "{closure:Illuminate\\Pipeline\\Pipeline::prepareDestination():178}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "App\\Http\\Middleware\\RequirePermission", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/app/Http/Middleware/EnsureAccountActive.php", + "line": 32, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "App\\Http\\Middleware\\EnsureAccountActive", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/app/Http/Middleware/MultiAuth.php", + "line": 32, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "App\\Http\\Middleware\\MultiAuth", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Routing/Middleware/SubstituteBindings.php", + "line": 50, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "Illuminate\\Routing\\Middleware\\SubstituteBindings", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 137, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Routing/Router.php", + "line": 821, + "function": "then", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Routing/Router.php", + "line": 800, + "function": "runRouteWithinStack", + "class": "Illuminate\\Routing\\Router", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Routing/Router.php", + "line": 764, + "function": "runRoute", + "class": "Illuminate\\Routing\\Router", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Routing/Router.php", + "line": 753, + "function": "dispatchToRoute", + "class": "Illuminate\\Routing\\Router", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php", + "line": 200, + "function": "dispatch", + "class": "Illuminate\\Routing\\Router", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 180, + "function": "{closure:Illuminate\\Foundation\\Http\\Kernel::dispatchToRouter():197}", + "class": "Illuminate\\Foundation\\Http\\Kernel", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/app/Http/Middleware/SecurityHeaders.php", + "line": 22, + "function": "{closure:Illuminate\\Pipeline\\Pipeline::prepareDestination():178}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "App\\Http\\Middleware\\SecurityHeaders", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/TransformsRequest.php", + "line": 21, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/ConvertEmptyStringsToNull.php", + "line": 31, + "function": "handle", + "class": "Illuminate\\Foundation\\Http\\Middleware\\TransformsRequest", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "Illuminate\\Foundation\\Http\\Middleware\\ConvertEmptyStringsToNull", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/TransformsRequest.php", + "line": 21, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/TrimStrings.php", + "line": 51, + "function": "handle", + "class": "Illuminate\\Foundation\\Http\\Middleware\\TransformsRequest", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "Illuminate\\Foundation\\Http\\Middleware\\TrimStrings", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Http/Middleware/ValidatePostSize.php", + "line": 27, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "Illuminate\\Http\\Middleware\\ValidatePostSize", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/PreventRequestsDuringMaintenance.php", + "line": 109, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "Illuminate\\Foundation\\Http\\Middleware\\PreventRequestsDuringMaintenance", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Http/Middleware/HandleCors.php", + "line": 74, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "Illuminate\\Http\\Middleware\\HandleCors", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Http/Middleware/TrustProxies.php", + "line": 58, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "Illuminate\\Http\\Middleware\\TrustProxies", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/InvokeDeferredCallbacks.php", + "line": 22, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "Illuminate\\Foundation\\Http\\Middleware\\InvokeDeferredCallbacks", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Http/Middleware/ValidatePathEncoding.php", + "line": 26, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "Illuminate\\Http\\Middleware\\ValidatePathEncoding", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 137, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php", + "line": 175, + "function": "then", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php", + "line": 144, + "function": "sendRequestThroughRouter", + "class": "Illuminate\\Foundation\\Http\\Kernel", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Foundation/Testing/Concerns/MakesHttpRequests.php", + "line": 607, + "function": "handle", + "class": "Illuminate\\Foundation\\Http\\Kernel", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Foundation/Testing/Concerns/MakesHttpRequests.php", + "line": 573, + "function": "call", + "class": "Illuminate\\Foundation\\Testing\\TestCase", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/tests/Feature/Api/V1/FullSurface/Support/FullSurfaceE2EContractCase.php", + "line": 190, + "function": "json", + "class": "Illuminate\\Foundation\\Testing\\TestCase", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/tests/Feature/Api/V1/FullSurface/ApiFeatureFlagAndConfigurationDriftContractTest.php", + "line": 21, + "function": "requestAs", + "class": "Tests\\Feature\\Api\\V1\\FullSurface\\Support\\FullSurfaceE2EContractCase", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/phpunit/phpunit/src/Framework/TestCase.php", + "line": 1667, + "function": "test_feature_flagged_routes_fail_closed_when_configuration_is_missing_or_disabled", + "class": "Tests\\Feature\\Api\\V1\\FullSurface\\ApiFeatureFlagAndConfigurationDriftContractTest", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/phpunit/phpunit/src/Framework/TestCase.php", + "line": 519, + "function": "runTest", + "class": "PHPUnit\\Framework\\TestCase", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/phpunit/phpunit/src/Framework/TestRunner/TestRunner.php", + "line": 87, + "function": "runBare", + "class": "PHPUnit\\Framework\\TestCase", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/phpunit/phpunit/src/Framework/TestCase.php", + "line": 365, + "function": "run", + "class": "PHPUnit\\Framework\\TestRunner", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/phpunit/phpunit/src/Framework/TestSuite.php", + "line": 369, + "function": "run", + "class": "PHPUnit\\Framework\\TestCase", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/phpunit/phpunit/src/Framework/TestSuite.php", + "line": 369, + "function": "run", + "class": "PHPUnit\\Framework\\TestSuite", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/phpunit/phpunit/src/Framework/TestSuite.php", + "line": 369, + "function": "run", + "class": "PHPUnit\\Framework\\TestSuite", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/phpunit/phpunit/src/TextUI/TestRunner.php", + "line": 64, + "function": "run", + "class": "PHPUnit\\Framework\\TestSuite", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/phpunit/phpunit/src/TextUI/Application.php", + "line": 211, + "function": "run", + "class": "PHPUnit\\TextUI\\TestRunner", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/phpunit/phpunit/phpunit", + "line": 104, + "function": "run", + "class": "PHPUnit\\TextUI\\Application", + "type": "->" + } + ] +} +Failed asserting that 500 is less than 500. + + at tests/Concerns/AssertsE2EApiResponses.php:11 + 7▕ trait AssertsE2EApiResponses + 8▕ { + 9▕ protected function assertNoServerError(TestResponse $response, string $context): void + 10▕ { + ➜ 11▕ $this->assertLessThan( + 12▕ 500, + 13▕ $response->getStatusCode(), + 14▕ $context.' should return a controlled response, not a 5xx crash. Body: '.$response->getContent() + 15▕ ); + + 1 tests/Concerns/AssertsE2EApiResponses.php:11 + 2 tests/Feature/Api/V1/FullSurface/ApiFeatureFlagAndConfigurationDriftContractTest.php:23 + + ──────────────────────────────────────────────────────────────────────────── + FAILED Tests\Feature\Api\V1\FullSurface\ApiMigrationSafeDefaultContractT… + POST api/v1/school-years/{schoolYear}/archive returned unexpected status 500. Body: { + "message": "Method App\\Http\\Controllers\\Api\\SchoolYears\\SchoolYearController::archive does not exist.", + "exception": "BadMethodCallException", + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Routing/Controller.php", + "line": 68, + "trace": [ + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Routing/Controller.php", + "line": 54, + "function": "__call", + "class": "Illuminate\\Routing\\Controller", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Routing/ControllerDispatcher.php", + "line": 43, + "function": "callAction", + "class": "Illuminate\\Routing\\Controller", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Routing/Route.php", + "line": 265, + "function": "dispatch", + "class": "Illuminate\\Routing\\ControllerDispatcher", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Routing/Route.php", + "line": 211, + "function": "runController", + "class": "Illuminate\\Routing\\Route", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Routing/Router.php", + "line": 822, + "function": "run", + "class": "Illuminate\\Routing\\Route", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 180, + "function": "{closure:Illuminate\\Routing\\Router::runRouteWithinStack():821}", + "class": "Illuminate\\Routing\\Router", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/app/Http/Middleware/RequirePermission.php", + "line": 29, + "function": "{closure:Illuminate\\Pipeline\\Pipeline::prepareDestination():178}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "App\\Http\\Middleware\\RequirePermission", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/app/Http/Middleware/EnsureAccountActive.php", + "line": 32, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "App\\Http\\Middleware\\EnsureAccountActive", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/app/Http/Middleware/MultiAuth.php", + "line": 32, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "App\\Http\\Middleware\\MultiAuth", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Routing/Middleware/SubstituteBindings.php", + "line": 50, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "Illuminate\\Routing\\Middleware\\SubstituteBindings", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 137, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Routing/Router.php", + "line": 821, + "function": "then", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Routing/Router.php", + "line": 800, + "function": "runRouteWithinStack", + "class": "Illuminate\\Routing\\Router", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Routing/Router.php", + "line": 764, + "function": "runRoute", + "class": "Illuminate\\Routing\\Router", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Routing/Router.php", + "line": 753, + "function": "dispatchToRoute", + "class": "Illuminate\\Routing\\Router", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php", + "line": 200, + "function": "dispatch", + "class": "Illuminate\\Routing\\Router", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 180, + "function": "{closure:Illuminate\\Foundation\\Http\\Kernel::dispatchToRouter():197}", + "class": "Illuminate\\Foundation\\Http\\Kernel", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/app/Http/Middleware/SecurityHeaders.php", + "line": 22, + "function": "{closure:Illuminate\\Pipeline\\Pipeline::prepareDestination():178}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "App\\Http\\Middleware\\SecurityHeaders", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/TransformsRequest.php", + "line": 21, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/ConvertEmptyStringsToNull.php", + "line": 31, + "function": "handle", + "class": "Illuminate\\Foundation\\Http\\Middleware\\TransformsRequest", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "Illuminate\\Foundation\\Http\\Middleware\\ConvertEmptyStringsToNull", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/TransformsRequest.php", + "line": 21, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/TrimStrings.php", + "line": 51, + "function": "handle", + "class": "Illuminate\\Foundation\\Http\\Middleware\\TransformsRequest", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "Illuminate\\Foundation\\Http\\Middleware\\TrimStrings", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Http/Middleware/ValidatePostSize.php", + "line": 27, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "Illuminate\\Http\\Middleware\\ValidatePostSize", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/PreventRequestsDuringMaintenance.php", + "line": 109, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "Illuminate\\Foundation\\Http\\Middleware\\PreventRequestsDuringMaintenance", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Http/Middleware/HandleCors.php", + "line": 74, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "Illuminate\\Http\\Middleware\\HandleCors", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Http/Middleware/TrustProxies.php", + "line": 58, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "Illuminate\\Http\\Middleware\\TrustProxies", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/InvokeDeferredCallbacks.php", + "line": 22, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "Illuminate\\Foundation\\Http\\Middleware\\InvokeDeferredCallbacks", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Http/Middleware/ValidatePathEncoding.php", + "line": 26, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "Illuminate\\Http\\Middleware\\ValidatePathEncoding", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 137, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php", + "line": 175, + "function": "then", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php", + "line": 144, + "function": "sendRequestThroughRouter", + "class": "Illuminate\\Foundation\\Http\\Kernel", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Foundation/Testing/Concerns/MakesHttpRequests.php", + "line": 607, + "function": "handle", + "class": "Illuminate\\Foundation\\Http\\Kernel", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Foundation/Testing/Concerns/MakesHttpRequests.php", + "line": 573, + "function": "call", + "class": "Illuminate\\Foundation\\Testing\\TestCase", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/tests/Feature/Api/V1/FullSurface/Support/FullSurfaceE2EContractCase.php", + "line": 190, + "function": "json", + "class": "Illuminate\\Foundation\\Testing\\TestCase", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/tests/Feature/Api/V1/FullSurface/ApiMigrationSafeDefaultContractTest.php", + "line": 44, + "function": "requestAs", + "class": "Tests\\Feature\\Api\\V1\\FullSurface\\Support\\FullSurfaceE2EContractCase", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/phpunit/phpunit/src/Framework/TestCase.php", + "line": 1667, + "function": "test_routes_handle_missing_optional_school_year_context_with_controlled_errors", + "class": "Tests\\Feature\\Api\\V1\\FullSurface\\ApiMigrationSafeDefaultContractTest", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/phpunit/phpunit/src/Framework/TestCase.php", + "line": 519, + "function": "runTest", + "class": "PHPUnit\\Framework\\TestCase", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/phpunit/phpunit/src/Framework/TestRunner/TestRunner.php", + "line": 87, + "function": "runBare", + "class": "PHPUnit\\Framework\\TestCase", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/phpunit/phpunit/src/Framework/TestCase.php", + "line": 365, + "function": "run", + "class": "PHPUnit\\Framework\\TestRunner", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/phpunit/phpunit/src/Framework/TestSuite.php", + "line": 369, + "function": "run", + "class": "PHPUnit\\Framework\\TestCase", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/phpunit/phpunit/src/Framework/TestSuite.php", + "line": 369, + "function": "run", + "class": "PHPUnit\\Framework\\TestSuite", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/phpunit/phpunit/src/Framework/TestSuite.php", + "line": 369, + "function": "run", + "class": "PHPUnit\\Framework\\TestSuite", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/phpunit/phpunit/src/TextUI/TestRunner.php", + "line": 64, + "function": "run", + "class": "PHPUnit\\Framework\\TestSuite", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/phpunit/phpunit/src/TextUI/Application.php", + "line": 211, + "function": "run", + "class": "PHPUnit\\TextUI\\TestRunner", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/phpunit/phpunit/phpunit", + "line": 104, + "function": "run", + "class": "PHPUnit\\TextUI\\Application", + "type": "->" + } + ] +} +Failed asserting that an array contains 500. + + at tests/Concerns/AssertsE2EApiResponses.php:23 + 19▕ * @param array $statuses + 20▕ */ + 21▕ protected function assertStatusIn(TestResponse $response, array $statuses, string $context): void + 22▕ { + ➜ 23▕ $this->assertContains( + 24▕ $response->getStatusCode(), + 25▕ $statuses, + 26▕ $context.' returned unexpected status '.$response->getStatusCode().'. Body: '.$response->getContent() + 27▕ ); + + 1 tests/Concerns/AssertsE2EApiResponses.php:23 + 2 tests/Feature/Api/V1/FullSurface/Support/FullSurfaceE2EContractCase.php:343 + + ──────────────────────────────────────────────────────────────────────────── + FAILED Tests\Feature\Api\V1\FullSurface\ApiNotificationMessagingDelivery… + POST api/v1/school-years/{schoolYear}/archive first message action should return a controlled response, not a 5xx crash. Body: { + "message": "Method App\\Http\\Controllers\\Api\\SchoolYears\\SchoolYearController::archive does not exist.", + "exception": "BadMethodCallException", + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Routing/Controller.php", + "line": 68, + "trace": [ + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Routing/Controller.php", + "line": 54, + "function": "__call", + "class": "Illuminate\\Routing\\Controller", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Routing/ControllerDispatcher.php", + "line": 43, + "function": "callAction", + "class": "Illuminate\\Routing\\Controller", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Routing/Route.php", + "line": 265, + "function": "dispatch", + "class": "Illuminate\\Routing\\ControllerDispatcher", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Routing/Route.php", + "line": 211, + "function": "runController", + "class": "Illuminate\\Routing\\Route", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Routing/Router.php", + "line": 822, + "function": "run", + "class": "Illuminate\\Routing\\Route", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 180, + "function": "{closure:Illuminate\\Routing\\Router::runRouteWithinStack():821}", + "class": "Illuminate\\Routing\\Router", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/app/Http/Middleware/RequirePermission.php", + "line": 29, + "function": "{closure:Illuminate\\Pipeline\\Pipeline::prepareDestination():178}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "App\\Http\\Middleware\\RequirePermission", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/app/Http/Middleware/EnsureAccountActive.php", + "line": 32, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "App\\Http\\Middleware\\EnsureAccountActive", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/app/Http/Middleware/MultiAuth.php", + "line": 32, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "App\\Http\\Middleware\\MultiAuth", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Routing/Middleware/SubstituteBindings.php", + "line": 50, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "Illuminate\\Routing\\Middleware\\SubstituteBindings", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 137, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Routing/Router.php", + "line": 821, + "function": "then", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Routing/Router.php", + "line": 800, + "function": "runRouteWithinStack", + "class": "Illuminate\\Routing\\Router", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Routing/Router.php", + "line": 764, + "function": "runRoute", + "class": "Illuminate\\Routing\\Router", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Routing/Router.php", + "line": 753, + "function": "dispatchToRoute", + "class": "Illuminate\\Routing\\Router", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php", + "line": 200, + "function": "dispatch", + "class": "Illuminate\\Routing\\Router", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 180, + "function": "{closure:Illuminate\\Foundation\\Http\\Kernel::dispatchToRouter():197}", + "class": "Illuminate\\Foundation\\Http\\Kernel", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/app/Http/Middleware/SecurityHeaders.php", + "line": 22, + "function": "{closure:Illuminate\\Pipeline\\Pipeline::prepareDestination():178}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "App\\Http\\Middleware\\SecurityHeaders", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/TransformsRequest.php", + "line": 21, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/ConvertEmptyStringsToNull.php", + "line": 31, + "function": "handle", + "class": "Illuminate\\Foundation\\Http\\Middleware\\TransformsRequest", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "Illuminate\\Foundation\\Http\\Middleware\\ConvertEmptyStringsToNull", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/TransformsRequest.php", + "line": 21, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/TrimStrings.php", + "line": 51, + "function": "handle", + "class": "Illuminate\\Foundation\\Http\\Middleware\\TransformsRequest", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "Illuminate\\Foundation\\Http\\Middleware\\TrimStrings", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Http/Middleware/ValidatePostSize.php", + "line": 27, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "Illuminate\\Http\\Middleware\\ValidatePostSize", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/PreventRequestsDuringMaintenance.php", + "line": 109, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "Illuminate\\Foundation\\Http\\Middleware\\PreventRequestsDuringMaintenance", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Http/Middleware/HandleCors.php", + "line": 74, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "Illuminate\\Http\\Middleware\\HandleCors", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Http/Middleware/TrustProxies.php", + "line": 58, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "Illuminate\\Http\\Middleware\\TrustProxies", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/InvokeDeferredCallbacks.php", + "line": 22, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "Illuminate\\Foundation\\Http\\Middleware\\InvokeDeferredCallbacks", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Http/Middleware/ValidatePathEncoding.php", + "line": 26, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "Illuminate\\Http\\Middleware\\ValidatePathEncoding", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 137, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php", + "line": 175, + "function": "then", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php", + "line": 144, + "function": "sendRequestThroughRouter", + "class": "Illuminate\\Foundation\\Http\\Kernel", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Foundation/Testing/Concerns/MakesHttpRequests.php", + "line": 607, + "function": "handle", + "class": "Illuminate\\Foundation\\Http\\Kernel", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Foundation/Testing/Concerns/MakesHttpRequests.php", + "line": 573, + "function": "call", + "class": "Illuminate\\Foundation\\Testing\\TestCase", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/tests/Feature/Api/V1/FullSurface/Support/FullSurfaceE2EContractCase.php", + "line": 190, + "function": "json", + "class": "Illuminate\\Foundation\\Testing\\TestCase", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/tests/Feature/Api/V1/FullSurface/ApiNotificationMessagingDeliveryContractTest.php", + "line": 49, + "function": "requestAs", + "class": "Tests\\Feature\\Api\\V1\\FullSurface\\Support\\FullSurfaceE2EContractCase", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/phpunit/phpunit/src/Framework/TestCase.php", + "line": 1667, + "function": "test_read_archive_star_and_delete_message_actions_are_idempotent", + "class": "Tests\\Feature\\Api\\V1\\FullSurface\\ApiNotificationMessagingDeliveryContractTest", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/phpunit/phpunit/src/Framework/TestCase.php", + "line": 519, + "function": "runTest", + "class": "PHPUnit\\Framework\\TestCase", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/phpunit/phpunit/src/Framework/TestRunner/TestRunner.php", + "line": 87, + "function": "runBare", + "class": "PHPUnit\\Framework\\TestCase", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/phpunit/phpunit/src/Framework/TestCase.php", + "line": 365, + "function": "run", + "class": "PHPUnit\\Framework\\TestRunner", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/phpunit/phpunit/src/Framework/TestSuite.php", + "line": 369, + "function": "run", + "class": "PHPUnit\\Framework\\TestCase", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/phpunit/phpunit/src/Framework/TestSuite.php", + "line": 369, + "function": "run", + "class": "PHPUnit\\Framework\\TestSuite", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/phpunit/phpunit/src/Framework/TestSuite.php", + "line": 369, + "function": "run", + "class": "PHPUnit\\Framework\\TestSuite", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/phpunit/phpunit/src/TextUI/TestRunner.php", + "line": 64, + "function": "run", + "class": "PHPUnit\\Framework\\TestSuite", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/phpunit/phpunit/src/TextUI/Application.php", + "line": 211, + "function": "run", + "class": "PHPUnit\\TextUI\\TestRunner", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/phpunit/phpunit/phpunit", + "line": 104, + "function": "run", + "class": "PHPUnit\\TextUI\\Application", + "type": "->" + } + ] +} +Failed asserting that 500 is less than 500. + + at tests/Concerns/AssertsE2EApiResponses.php:11 + 7▕ trait AssertsE2EApiResponses + 8▕ { + 9▕ protected function assertNoServerError(TestResponse $response, string $context): void + 10▕ { + ➜ 11▕ $this->assertLessThan( + 12▕ 500, + 13▕ $response->getStatusCode(), + 14▕ $context.' should return a controlled response, not a 5xx crash. Body: '.$response->getContent() + 15▕ ); + + 1 tests/Concerns/AssertsE2EApiResponses.php:11 + 2 tests/Feature/Api/V1/FullSurface/ApiNotificationMessagingDeliveryContractTest.php:52 + + ──────────────────────────────────────────────────────────────────────────── + FAILED Tests\Feature\Api\V1\FullSurface\ApiPolicyAuthorizationDiscoveryC… + POST api/login should not be publicly mutable. returned unexpected status 200. Body: {"status":true,"token":"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJodHRwOi8vbG9jYWxob3N0L2FwaS9sb2dpbiIsImlhdCI6MTc1OTY1ODQwMCwiZXhwIjoxNzU5NzQ0ODAwLCJuYmYiOjE3NTk2NTg0MDAsImp0aSI6IkZiYWRlVGdiZ25yR3lTNloiLCJzdWIiOiI0IiwicHJ2IjoiMjNiZDVjODk0OWY2MDBhZGIzOWU3MDFjNDAwODcyZGI3YTU5NzZmNyIsIm5hbWUiOiJHdXkgR2VyaG9sZCIsInJvbGVzIjpbImFkbWluaXN0cmF0b3IiXX0.xnVw0PcjvOyJEW8uCogzIxsZqA5gt36-RVEkXCJf7Io","access_token":"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJodHRwOi8vbG9jYWxob3N0L2FwaS9sb2dpbiIsImlhdCI6MTc1OTY1ODQwMCwiZXhwIjoxNzU5NzQ0ODAwLCJuYmYiOjE3NTk2NTg0MDAsImp0aSI6IkZiYWRlVGdiZ25yR3lTNloiLCJzdWIiOiI0IiwicHJ2IjoiMjNiZDVjODk0OWY2MDBhZGIzOWU3MDFjNDAwODcyZGI3YTU5NzZmNyIsIm5hbWUiOiJHdXkgR2VyaG9sZCIsInJvbGVzIjpbImFkbWluaXN0cmF0b3IiXX0.xnVw0PcjvOyJEW8uCogzIxsZqA5gt36-RVEkXCJf7Io","token_type":"bearer","expires_in":86400,"user":{"id":4,"name":"Guy Gerhold","firstname":"Guy","lastname":"Gerhold","email":"administrator-api-test-6a4ad64d11a2b935044371@example.test","roles":{"administrator":true},"class_section_id":null,"class_section_name":null}} +Failed asserting that an array contains 200. + + at tests/Concerns/AssertsE2EApiResponses.php:23 + 19▕ * @param array $statuses + 20▕ */ + 21▕ protected function assertStatusIn(TestResponse $response, array $statuses, string $context): void + 22▕ { + ➜ 23▕ $this->assertContains( + 24▕ $response->getStatusCode(), + 25▕ $statuses, + 26▕ $context.' returned unexpected status '.$response->getStatusCode().'. Body: '.$response->getContent() + 27▕ ); + + 1 tests/Concerns/AssertsE2EApiResponses.php:23 + 2 tests/Feature/Api/V1/FullSurface/ApiPolicyAuthorizationDiscoveryContractTest.php:24 + + ──────────────────────────────────────────────────────────────────────────── + FAILED Tests\Feature\Api\V1\FullSurface\ApiPublicAndAuthFullSurfaceContr… + Public POST /api/v1/register returned unexpected status 429. Body: {"message":"Too Many Attempts."} +Failed asserting that an array contains 429. + + at tests/Concerns/AssertsE2EApiResponses.php:23 + 19▕ * @param array $statuses + 20▕ */ + 21▕ protected function assertStatusIn(TestResponse $response, array $statuses, string $context): void + 22▕ { + ➜ 23▕ $this->assertContains( + 24▕ $response->getStatusCode(), + 25▕ $statuses, + 26▕ $context.' returned unexpected status '.$response->getStatusCode().'. Body: '.$response->getContent() + 27▕ ); + + 1 tests/Concerns/AssertsE2EApiResponses.php:23 + 2 tests/Feature/Api/V1/FullSurface/ApiPublicAndAuthFullSurfaceContractTest.php:33 + + ──────────────────────────────────────────────────────────────────────────── + FAILED Tests\Feature\Api\V1\FullSurface\ApiReferentialIntegrityAndForeig… + POST api/v1/attendance/admin/update should reject impossible foreign keys cleanly. returned unexpected status 200. Body: {"ok":true,"message":"Attendance updated successfully."} +Failed asserting that an array contains 200. + + at tests/Concerns/AssertsE2EApiResponses.php:23 + 19▕ * @param array $statuses + 20▕ */ + 21▕ protected function assertStatusIn(TestResponse $response, array $statuses, string $context): void + 22▕ { + ➜ 23▕ $this->assertContains( + 24▕ $response->getStatusCode(), + 25▕ $statuses, + 26▕ $context.' returned unexpected status '.$response->getStatusCode().'. Body: '.$response->getContent() + 27▕ ); + + 1 tests/Concerns/AssertsE2EApiResponses.php:23 + 2 tests/Feature/Api/V1/FullSurface/ApiReferentialIntegrityAndForeignKeyContractTest.php:37 + + ──────────────────────────────────────────────────────────────────────────── + FAILED Tests\Feature\Api\V1\FullSurface\ApiReportMathAndFinancialInvaria… + GET api/v1/finance/financial-report/pdf returned unexpected status 500. Body: { + "message": "The filename and the fallback cannot contain the \"/\" and \"\\\" characters.", + "exception": "InvalidArgumentException", + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/symfony/http-foundation/HeaderUtils.php", + "line": 187, + "trace": [ + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/symfony/http-foundation/ResponseHeaderBag.php", + "line": 234, + "function": "makeDisposition", + "class": "Symfony\\Component\\HttpFoundation\\HeaderUtils", + "type": "::" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Routing/ResponseFactory.php", + "line": 253, + "function": "makeDisposition", + "class": "Symfony\\Component\\HttpFoundation\\ResponseHeaderBag", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/app/Http/Controllers/Api/Finance/FinancialController.php", + "line": 319, + "function": "streamDownload", + "class": "Illuminate\\Routing\\ResponseFactory", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Routing/Controller.php", + "line": 54, + "function": "downloadPdf", + "class": "App\\Http\\Controllers\\Api\\Finance\\FinancialController", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Routing/ControllerDispatcher.php", + "line": 43, + "function": "callAction", + "class": "Illuminate\\Routing\\Controller", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Routing/Route.php", + "line": 265, + "function": "dispatch", + "class": "Illuminate\\Routing\\ControllerDispatcher", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Routing/Route.php", + "line": 211, + "function": "runController", + "class": "Illuminate\\Routing\\Route", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Routing/Router.php", + "line": 822, + "function": "run", + "class": "Illuminate\\Routing\\Route", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 180, + "function": "{closure:Illuminate\\Routing\\Router::runRouteWithinStack():821}", + "class": "Illuminate\\Routing\\Router", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/app/Http/Middleware/EnsureSchoolYearEditable.php", + "line": 20, + "function": "{closure:Illuminate\\Pipeline\\Pipeline::prepareDestination():178}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "App\\Http\\Middleware\\EnsureSchoolYearEditable", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/app/Http/Middleware/MultiAuth.php", + "line": 32, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "App\\Http\\Middleware\\MultiAuth", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Routing/Middleware/SubstituteBindings.php", + "line": 50, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "Illuminate\\Routing\\Middleware\\SubstituteBindings", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 137, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Routing/Router.php", + "line": 821, + "function": "then", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Routing/Router.php", + "line": 800, + "function": "runRouteWithinStack", + "class": "Illuminate\\Routing\\Router", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Routing/Router.php", + "line": 764, + "function": "runRoute", + "class": "Illuminate\\Routing\\Router", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Routing/Router.php", + "line": 753, + "function": "dispatchToRoute", + "class": "Illuminate\\Routing\\Router", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php", + "line": 200, + "function": "dispatch", + "class": "Illuminate\\Routing\\Router", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 180, + "function": "{closure:Illuminate\\Foundation\\Http\\Kernel::dispatchToRouter():197}", + "class": "Illuminate\\Foundation\\Http\\Kernel", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/app/Http/Middleware/SecurityHeaders.php", + "line": 22, + "function": "{closure:Illuminate\\Pipeline\\Pipeline::prepareDestination():178}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "App\\Http\\Middleware\\SecurityHeaders", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/TransformsRequest.php", + "line": 21, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/ConvertEmptyStringsToNull.php", + "line": 31, + "function": "handle", + "class": "Illuminate\\Foundation\\Http\\Middleware\\TransformsRequest", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "Illuminate\\Foundation\\Http\\Middleware\\ConvertEmptyStringsToNull", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/TransformsRequest.php", + "line": 21, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/TrimStrings.php", + "line": 51, + "function": "handle", + "class": "Illuminate\\Foundation\\Http\\Middleware\\TransformsRequest", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "Illuminate\\Foundation\\Http\\Middleware\\TrimStrings", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Http/Middleware/ValidatePostSize.php", + "line": 27, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "Illuminate\\Http\\Middleware\\ValidatePostSize", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/PreventRequestsDuringMaintenance.php", + "line": 109, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "Illuminate\\Foundation\\Http\\Middleware\\PreventRequestsDuringMaintenance", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Http/Middleware/HandleCors.php", + "line": 74, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "Illuminate\\Http\\Middleware\\HandleCors", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Http/Middleware/TrustProxies.php", + "line": 58, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "Illuminate\\Http\\Middleware\\TrustProxies", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/InvokeDeferredCallbacks.php", + "line": 22, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "Illuminate\\Foundation\\Http\\Middleware\\InvokeDeferredCallbacks", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Http/Middleware/ValidatePathEncoding.php", + "line": 26, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "Illuminate\\Http\\Middleware\\ValidatePathEncoding", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 137, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php", + "line": 175, + "function": "then", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php", + "line": 144, + "function": "sendRequestThroughRouter", + "class": "Illuminate\\Foundation\\Http\\Kernel", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Foundation/Testing/Concerns/MakesHttpRequests.php", + "line": 607, + "function": "handle", + "class": "Illuminate\\Foundation\\Http\\Kernel", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Foundation/Testing/Concerns/MakesHttpRequests.php", + "line": 573, + "function": "call", + "class": "Illuminate\\Foundation\\Testing\\TestCase", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Foundation/Testing/Concerns/MakesHttpRequests.php", + "line": 381, + "function": "json", + "class": "Illuminate\\Foundation\\Testing\\TestCase", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/tests/Feature/Api/V1/FullSurface/ApiReportMathAndFinancialInvariantContractTest.php", + "line": 40, + "function": "getJson", + "class": "Illuminate\\Foundation\\Testing\\TestCase", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/phpunit/phpunit/src/Framework/TestCase.php", + "line": 1667, + "function": "test_report_filters_do_not_create_negative_or_impossible_aggregation_windows", + "class": "Tests\\Feature\\Api\\V1\\FullSurface\\ApiReportMathAndFinancialInvariantContractTest", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/phpunit/phpunit/src/Framework/TestCase.php", + "line": 519, + "function": "runTest", + "class": "PHPUnit\\Framework\\TestCase", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/phpunit/phpunit/src/Framework/TestRunner/TestRunner.php", + "line": 87, + "function": "runBare", + "class": "PHPUnit\\Framework\\TestCase", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/phpunit/phpunit/src/Framework/TestCase.php", + "line": 365, + "function": "run", + "class": "PHPUnit\\Framework\\TestRunner", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/phpunit/phpunit/src/Framework/TestSuite.php", + "line": 369, + "function": "run", + "class": "PHPUnit\\Framework\\TestCase", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/phpunit/phpunit/src/Framework/TestSuite.php", + "line": 369, + "function": "run", + "class": "PHPUnit\\Framework\\TestSuite", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/phpunit/phpunit/src/Framework/TestSuite.php", + "line": 369, + "function": "run", + "class": "PHPUnit\\Framework\\TestSuite", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/phpunit/phpunit/src/TextUI/TestRunner.php", + "line": 64, + "function": "run", + "class": "PHPUnit\\Framework\\TestSuite", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/phpunit/phpunit/src/TextUI/Application.php", + "line": 211, + "function": "run", + "class": "PHPUnit\\TextUI\\TestRunner", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/phpunit/phpunit/phpunit", + "line": 104, + "function": "run", + "class": "PHPUnit\\TextUI\\Application", + "type": "->" + } + ] +} +Failed asserting that an array contains 500. + + at tests/Concerns/AssertsE2EApiResponses.php:23 + 19▕ * @param array $statuses + 20▕ */ + 21▕ protected function assertStatusIn(TestResponse $response, array $statuses, string $context): void + 22▕ { + ➜ 23▕ $this->assertContains( + 24▕ $response->getStatusCode(), + 25▕ $statuses, + 26▕ $context.' returned unexpected status '.$response->getStatusCode().'. Body: '.$response->getContent() + 27▕ ); + + 1 tests/Concerns/AssertsE2EApiResponses.php:23 + 2 tests/Feature/Api/V1/FullSurface/Support/FullSurfaceE2EContractCase.php:343 + + ──────────────────────────────────────────────────────────────────────────── + FAILED Tests\Feature\Api\V1\FullSurface\ApiRequestHeaderSpoofingContract… + spoofed headers should not authorize parent at GET api/administrator/attendance-templates returned unexpected status 200. Body: {"status":true,"data":{"template_endpoint":"http:\/\/localhost\/api\/v1\/attendance-templates","list_endpoint":"http:\/\/localhost\/api\/v1\/attendance-templates","rest_prefix":"http:\/\/localhost\/api\/v1\/attendance-comment-templates","list_data_endpoint":"http:\/\/localhost\/api\/v1\/attendance-comment-templates\/list-data"}} +Failed asserting that an array contains 200. + + at tests/Concerns/AssertsE2EApiResponses.php:23 + 19▕ * @param array $statuses + 20▕ */ + 21▕ protected function assertStatusIn(TestResponse $response, array $statuses, string $context): void + 22▕ { + ➜ 23▕ $this->assertContains( + 24▕ $response->getStatusCode(), + 25▕ $statuses, + 26▕ $context.' returned unexpected status '.$response->getStatusCode().'. Body: '.$response->getContent() + 27▕ ); + + 1 tests/Concerns/AssertsE2EApiResponses.php:23 + 2 tests/Feature/Api/V1/FullSurface/ApiRequestHeaderSpoofingContractTest.php:27 + + ──────────────────────────────────────────────────────────────────────────── + FAILED Tests\Feature\Api\V1\FullSurface\ApiRoleWorkflowNegativeMatrixCon… + parent should not read unrelated domain api/administrator/attendance-templates returned unexpected status 200. Body: {"status":true,"data":{"template_endpoint":"http:\/\/localhost\/api\/v1\/attendance-templates","list_endpoint":"http:\/\/localhost\/api\/v1\/attendance-templates","rest_prefix":"http:\/\/localhost\/api\/v1\/attendance-comment-templates","list_data_endpoint":"http:\/\/localhost\/api\/v1\/attendance-comment-templates\/list-data"}} +Failed asserting that an array contains 200. + + at tests/Concerns/AssertsE2EApiResponses.php:23 + 19▕ * @param array $statuses + 20▕ */ + 21▕ protected function assertStatusIn(TestResponse $response, array $statuses, string $context): void + 22▕ { + ➜ 23▕ $this->assertContains( + 24▕ $response->getStatusCode(), + 25▕ $statuses, + 26▕ $context.' returned unexpected status '.$response->getStatusCode().'. Body: '.$response->getContent() + 27▕ ); + + 1 tests/Concerns/AssertsE2EApiResponses.php:23 + 2 tests/Feature/Api/V1/FullSurface/ApiRoleWorkflowNegativeMatrixContractTest.php:53 + + ──────────────────────────────────────────────────────────────────────────── + FAILED Tests\Feature\Api\V1\FullSurface\ApiRouteNamingVersioningAndHygie… + API route must be versioned or explicitly classified as legacy alias: api/proofread +Failed asserting that false is true. + + at tests/Feature/Api/V1/FullSurface/ApiRouteNamingVersioningAndHygieneTest.php:25 + 21▕ { + 22▕ foreach ($this->apiRoutes() as $route) { + 23▕ $uri = $route->uri(); + 24▕ + ➜ 25▕ $this->assertTrue( + 26▕ str_starts_with($uri, 'api/v1/') || $this->isKnownUnversionedAlias($uri), + 27▕ "API route must be versioned or explicitly classified as legacy alias: $uri" + 28▕ ); + 29▕ } + + 1 tests/Feature/Api/V1/FullSurface/ApiRouteNamingVersioningAndHygieneTest.php:25 + + ──────────────────────────────────────────────────────────────────────────── + FAILED Tests\Feature\Api\V1\FullSurface\ApiRouteParameterAbuseContractTe… + Expected: {"message":"The route api\/certificates\/verify\/..%2F.env could not be found."} + + Not to contain: .env + + at tests/Feature/Api/V1/FullSurface/ApiRouteParameterAbuseContractTest.php:24 + 20▕ $response = $this->requestAs($this->actorFor($template), $method, $uri, $this->payloadFor($method, $template)); + 21▕ + 22▕ $this->assertControlled($response, $method, $uri); + 23▕ $this->assertNoServerError($response, 'bad route parameter '.$method.' '.$uri); + ➜ 24▕ $this->assertStringNotContainsString('.env', $response->getContent(), $uri.' must not leak filesystem targets.'); + 25▕ } + 26▕ } + 27▕ } + 28▕ + + 1 tests/Feature/Api/V1/FullSurface/ApiRouteParameterAbuseContractTest.php:24 + + ──────────────────────────────────────────────────────────────────────────── + FAILED Tests\Feature\Api\V1\FullSurface\ApiRouteParameterAbuseContractTe… + POST api/v1/school-years/92233720368547758079223372036854775807/archive returned unexpected status 500. Body: { + "message": "Method App\\Http\\Controllers\\Api\\SchoolYears\\SchoolYearController::archive does not exist.", + "exception": "BadMethodCallException", + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Routing/Controller.php", + "line": 68, + "trace": [ + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Routing/Controller.php", + "line": 54, + "function": "__call", + "class": "Illuminate\\Routing\\Controller", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Routing/ControllerDispatcher.php", + "line": 43, + "function": "callAction", + "class": "Illuminate\\Routing\\Controller", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Routing/Route.php", + "line": 265, + "function": "dispatch", + "class": "Illuminate\\Routing\\ControllerDispatcher", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Routing/Route.php", + "line": 211, + "function": "runController", + "class": "Illuminate\\Routing\\Route", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Routing/Router.php", + "line": 822, + "function": "run", + "class": "Illuminate\\Routing\\Route", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 180, + "function": "{closure:Illuminate\\Routing\\Router::runRouteWithinStack():821}", + "class": "Illuminate\\Routing\\Router", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/app/Http/Middleware/RequirePermission.php", + "line": 29, + "function": "{closure:Illuminate\\Pipeline\\Pipeline::prepareDestination():178}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "App\\Http\\Middleware\\RequirePermission", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/app/Http/Middleware/EnsureAccountActive.php", + "line": 32, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "App\\Http\\Middleware\\EnsureAccountActive", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/app/Http/Middleware/MultiAuth.php", + "line": 32, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "App\\Http\\Middleware\\MultiAuth", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Routing/Middleware/SubstituteBindings.php", + "line": 50, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "Illuminate\\Routing\\Middleware\\SubstituteBindings", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 137, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Routing/Router.php", + "line": 821, + "function": "then", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Routing/Router.php", + "line": 800, + "function": "runRouteWithinStack", + "class": "Illuminate\\Routing\\Router", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Routing/Router.php", + "line": 764, + "function": "runRoute", + "class": "Illuminate\\Routing\\Router", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Routing/Router.php", + "line": 753, + "function": "dispatchToRoute", + "class": "Illuminate\\Routing\\Router", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php", + "line": 200, + "function": "dispatch", + "class": "Illuminate\\Routing\\Router", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 180, + "function": "{closure:Illuminate\\Foundation\\Http\\Kernel::dispatchToRouter():197}", + "class": "Illuminate\\Foundation\\Http\\Kernel", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/app/Http/Middleware/SecurityHeaders.php", + "line": 22, + "function": "{closure:Illuminate\\Pipeline\\Pipeline::prepareDestination():178}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "App\\Http\\Middleware\\SecurityHeaders", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/TransformsRequest.php", + "line": 21, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/ConvertEmptyStringsToNull.php", + "line": 31, + "function": "handle", + "class": "Illuminate\\Foundation\\Http\\Middleware\\TransformsRequest", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "Illuminate\\Foundation\\Http\\Middleware\\ConvertEmptyStringsToNull", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/TransformsRequest.php", + "line": 21, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/TrimStrings.php", + "line": 51, + "function": "handle", + "class": "Illuminate\\Foundation\\Http\\Middleware\\TransformsRequest", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "Illuminate\\Foundation\\Http\\Middleware\\TrimStrings", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Http/Middleware/ValidatePostSize.php", + "line": 27, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "Illuminate\\Http\\Middleware\\ValidatePostSize", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/PreventRequestsDuringMaintenance.php", + "line": 109, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "Illuminate\\Foundation\\Http\\Middleware\\PreventRequestsDuringMaintenance", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Http/Middleware/HandleCors.php", + "line": 74, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "Illuminate\\Http\\Middleware\\HandleCors", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Http/Middleware/TrustProxies.php", + "line": 58, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "Illuminate\\Http\\Middleware\\TrustProxies", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/InvokeDeferredCallbacks.php", + "line": 22, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "Illuminate\\Foundation\\Http\\Middleware\\InvokeDeferredCallbacks", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Http/Middleware/ValidatePathEncoding.php", + "line": 26, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "Illuminate\\Http\\Middleware\\ValidatePathEncoding", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 137, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php", + "line": 175, + "function": "then", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php", + "line": 144, + "function": "sendRequestThroughRouter", + "class": "Illuminate\\Foundation\\Http\\Kernel", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Foundation/Testing/Concerns/MakesHttpRequests.php", + "line": 607, + "function": "handle", + "class": "Illuminate\\Foundation\\Http\\Kernel", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Foundation/Testing/Concerns/MakesHttpRequests.php", + "line": 573, + "function": "call", + "class": "Illuminate\\Foundation\\Testing\\TestCase", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/tests/Feature/Api/V1/FullSurface/Support/FullSurfaceE2EContractCase.php", + "line": 190, + "function": "json", + "class": "Illuminate\\Foundation\\Testing\\TestCase", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/tests/Feature/Api/V1/FullSurface/ApiRouteParameterAbuseContractTest.php", + "line": 37, + "function": "requestAs", + "class": "Tests\\Feature\\Api\\V1\\FullSurface\\Support\\FullSurfaceE2EContractCase", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/phpunit/phpunit/src/Framework/TestCase.php", + "line": 1667, + "function": "test_parameterized_routes_fail_cleanly_for_overflowing_integer_ids", + "class": "Tests\\Feature\\Api\\V1\\FullSurface\\ApiRouteParameterAbuseContractTest", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/phpunit/phpunit/src/Framework/TestCase.php", + "line": 519, + "function": "runTest", + "class": "PHPUnit\\Framework\\TestCase", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/phpunit/phpunit/src/Framework/TestRunner/TestRunner.php", + "line": 87, + "function": "runBare", + "class": "PHPUnit\\Framework\\TestCase", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/phpunit/phpunit/src/Framework/TestCase.php", + "line": 365, + "function": "run", + "class": "PHPUnit\\Framework\\TestRunner", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/phpunit/phpunit/src/Framework/TestSuite.php", + "line": 369, + "function": "run", + "class": "PHPUnit\\Framework\\TestCase", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/phpunit/phpunit/src/Framework/TestSuite.php", + "line": 369, + "function": "run", + "class": "PHPUnit\\Framework\\TestSuite", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/phpunit/phpunit/src/Framework/TestSuite.php", + "line": 369, + "function": "run", + "class": "PHPUnit\\Framework\\TestSuite", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/phpunit/phpunit/src/TextUI/TestRunner.php", + "line": 64, + "function": "run", + "class": "PHPUnit\\Framework\\TestSuite", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/phpunit/phpunit/src/TextUI/Application.php", + "line": 211, + "function": "run", + "class": "PHPUnit\\TextUI\\TestRunner", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/phpunit/phpunit/phpunit", + "line": 104, + "function": "run", + "class": "PHPUnit\\TextUI\\Application", + "type": "->" + } + ] +} +Failed asserting that an array contains 500. + + at tests/Concerns/AssertsE2EApiResponses.php:23 + 19▕ * @param array $statuses + 20▕ */ + 21▕ protected function assertStatusIn(TestResponse $response, array $statuses, string $context): void + 22▕ { + ➜ 23▕ $this->assertContains( + 24▕ $response->getStatusCode(), + 25▕ $statuses, + 26▕ $context.' returned unexpected status '.$response->getStatusCode().'. Body: '.$response->getContent() + 27▕ ); + + 1 tests/Concerns/AssertsE2EApiResponses.php:23 + 2 tests/Feature/Api/V1/FullSurface/Support/FullSurfaceE2EContractCase.php:343 + + ──────────────────────────────────────────────────────────────────────────── + FAILED Tests\Feature\Api\V1\FullSurface\ApiRouteUseCaseCatalogCompletene… + API routes without an explicit E2E user journey owner: +GET api/v1/competition-winners +GET api/v1/competition-winners/create +POST api/v1/competition-winners +GET api/v1/competition-winners/{id}/settings +PUT api/v1/competition-winners/{id} +GET api/v1/competition-winners/{id}/scores +POST api/v1/competition-winners/{id}/scores +GET api/v1/competition-winners/{id}/preview +GET api/v1/competition-winners/{id}/winners +POST api/v1/competition-winners/{id}/publish +POST api/v1/competition-winners/{id}/lock +POST api/v1/competition-winners/{id}/unlock +POST api/v1/competition-winners/{id}/export-quiz +PATCH,PUT api/v1/finance/event-charges/{event_charge} + +Add the route to the journey catalog and add or extend the scenario that proves it. +Failed asserting that two arrays are identical. + -Array &0 [] + +Array &0 [ + + 0 => 'GET api/v1/competition-winners', + + 1 => 'GET api/v1/competition-winners/create', + + 2 => 'POST api/v1/competition-winners', + + 3 => 'GET api/v1/competition-winners/{id}/settings', + + 4 => 'PUT api/v1/competition-winners/{id}', + + 5 => 'GET api/v1/competition-winners/{id}/scores', + + 6 => 'POST api/v1/competition-winners/{id}/scores', + + 7 => 'GET api/v1/competition-winners/{id}/preview', + + 8 => 'GET api/v1/competition-winners/{id}/winners', + + 9 => 'POST api/v1/competition-winners/{id}/publish', + + 10 => 'POST api/v1/competition-winners/{id}/lock', + + 11 => 'POST api/v1/competition-winners/{id}/unlock', + + 12 => 'POST api/v1/competition-winners/{id}/export-quiz', + + 13 => 'PATCH,PUT api/v1/finance/event-charges/{event_charge}', + +] + + + at tests/Feature/Api/V1/FullSurface/ApiRouteUseCaseCatalogCompletenessTest.php:33 + 29▕ $unowned[] = $signature; + 30▕ } + 31▕ } + 32▕ + ➜ 33▕ $this->assertSame( + 34▕ [], + 35▕ $unowned, + 36▕ "API routes without an explicit E2E user journey owner:\n".implode("\n", $unowned). + 37▕ "\n\nAdd the route to the journey catalog and add or extend the scenario that proves it." + + 1 tests/Feature/Api/V1/FullSurface/ApiRouteUseCaseCatalogCompletenessTest.php:33 + + ──────────────────────────────────────────────────────────────────────────── + FAILED Tests\Feature\Api\V1\FullSurface\ApiSchemaKeyStabilityExpansionCo… + api/v1/class-sections should expose at least one stable identity/display key. Keys: status, message, data, sections, meta, total, per_page, current_page, last_page +Failed asserting that false is true. + + at tests/Feature/Api/V1/FullSurface/ApiSchemaKeyStabilityExpansionContractTest.php:33 + 29▕ continue; + 30▕ } + 31▕ + 32▕ $payload = $this->flattenKeys($response->json()); + ➜ 33▕ $this->assertTrue( + 34▕ count(array_intersect($expectedAnyKeys, $payload)) > 0, + 35▕ $uri.' should expose at least one stable identity/display key. Keys: '.implode(', ', $payload) + 36▕ ); + 37▕ } + + 1 tests/Feature/Api/V1/FullSurface/ApiSchemaKeyStabilityExpansionContractTest.php:33 + + ──────────────────────────────────────────────────────────────────────────── + FAILED Tests\Feature\Api\V1\FullSurface\ApiSchoolCalendarAcademicBoundar… + POST api/v1/school-years/{schoolYear}/archive returned unexpected status 500. Body: { + "message": "Method App\\Http\\Controllers\\Api\\SchoolYears\\SchoolYearController::archive does not exist.", + "exception": "BadMethodCallException", + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Routing/Controller.php", + "line": 68, + "trace": [ + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Routing/Controller.php", + "line": 54, + "function": "__call", + "class": "Illuminate\\Routing\\Controller", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Routing/ControllerDispatcher.php", + "line": 43, + "function": "callAction", + "class": "Illuminate\\Routing\\Controller", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Routing/Route.php", + "line": 265, + "function": "dispatch", + "class": "Illuminate\\Routing\\ControllerDispatcher", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Routing/Route.php", + "line": 211, + "function": "runController", + "class": "Illuminate\\Routing\\Route", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Routing/Router.php", + "line": 822, + "function": "run", + "class": "Illuminate\\Routing\\Route", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 180, + "function": "{closure:Illuminate\\Routing\\Router::runRouteWithinStack():821}", + "class": "Illuminate\\Routing\\Router", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/app/Http/Middleware/RequirePermission.php", + "line": 29, + "function": "{closure:Illuminate\\Pipeline\\Pipeline::prepareDestination():178}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "App\\Http\\Middleware\\RequirePermission", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/app/Http/Middleware/EnsureAccountActive.php", + "line": 32, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "App\\Http\\Middleware\\EnsureAccountActive", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/app/Http/Middleware/MultiAuth.php", + "line": 32, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "App\\Http\\Middleware\\MultiAuth", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Routing/Middleware/SubstituteBindings.php", + "line": 50, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "Illuminate\\Routing\\Middleware\\SubstituteBindings", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 137, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Routing/Router.php", + "line": 821, + "function": "then", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Routing/Router.php", + "line": 800, + "function": "runRouteWithinStack", + "class": "Illuminate\\Routing\\Router", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Routing/Router.php", + "line": 764, + "function": "runRoute", + "class": "Illuminate\\Routing\\Router", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Routing/Router.php", + "line": 753, + "function": "dispatchToRoute", + "class": "Illuminate\\Routing\\Router", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php", + "line": 200, + "function": "dispatch", + "class": "Illuminate\\Routing\\Router", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 180, + "function": "{closure:Illuminate\\Foundation\\Http\\Kernel::dispatchToRouter():197}", + "class": "Illuminate\\Foundation\\Http\\Kernel", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/app/Http/Middleware/SecurityHeaders.php", + "line": 22, + "function": "{closure:Illuminate\\Pipeline\\Pipeline::prepareDestination():178}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "App\\Http\\Middleware\\SecurityHeaders", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/TransformsRequest.php", + "line": 21, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/ConvertEmptyStringsToNull.php", + "line": 31, + "function": "handle", + "class": "Illuminate\\Foundation\\Http\\Middleware\\TransformsRequest", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "Illuminate\\Foundation\\Http\\Middleware\\ConvertEmptyStringsToNull", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/TransformsRequest.php", + "line": 21, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/TrimStrings.php", + "line": 51, + "function": "handle", + "class": "Illuminate\\Foundation\\Http\\Middleware\\TransformsRequest", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "Illuminate\\Foundation\\Http\\Middleware\\TrimStrings", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Http/Middleware/ValidatePostSize.php", + "line": 27, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "Illuminate\\Http\\Middleware\\ValidatePostSize", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/PreventRequestsDuringMaintenance.php", + "line": 109, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "Illuminate\\Foundation\\Http\\Middleware\\PreventRequestsDuringMaintenance", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Http/Middleware/HandleCors.php", + "line": 74, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "Illuminate\\Http\\Middleware\\HandleCors", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Http/Middleware/TrustProxies.php", + "line": 58, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "Illuminate\\Http\\Middleware\\TrustProxies", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/InvokeDeferredCallbacks.php", + "line": 22, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "Illuminate\\Foundation\\Http\\Middleware\\InvokeDeferredCallbacks", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Http/Middleware/ValidatePathEncoding.php", + "line": 26, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "Illuminate\\Http\\Middleware\\ValidatePathEncoding", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 137, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php", + "line": 175, + "function": "then", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php", + "line": 144, + "function": "sendRequestThroughRouter", + "class": "Illuminate\\Foundation\\Http\\Kernel", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Foundation/Testing/Concerns/MakesHttpRequests.php", + "line": 607, + "function": "handle", + "class": "Illuminate\\Foundation\\Http\\Kernel", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Foundation/Testing/Concerns/MakesHttpRequests.php", + "line": 573, + "function": "call", + "class": "Illuminate\\Foundation\\Testing\\TestCase", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/tests/Feature/Api/V1/FullSurface/Support/FullSurfaceE2EContractCase.php", + "line": 190, + "function": "json", + "class": "Illuminate\\Foundation\\Testing\\TestCase", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/tests/Feature/Api/V1/FullSurface/ApiSchoolCalendarAcademicBoundaryExpansionTest.php", + "line": 43, + "function": "requestAs", + "class": "Tests\\Feature\\Api\\V1\\FullSurface\\Support\\FullSurfaceE2EContractCase", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/phpunit/phpunit/src/Framework/TestCase.php", + "line": 1667, + "function": "test_semester_and_term_values_are_not_free_form_privilege_channels", + "class": "Tests\\Feature\\Api\\V1\\FullSurface\\ApiSchoolCalendarAcademicBoundaryExpansionTest", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/phpunit/phpunit/src/Framework/TestCase.php", + "line": 519, + "function": "runTest", + "class": "PHPUnit\\Framework\\TestCase", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/phpunit/phpunit/src/Framework/TestRunner/TestRunner.php", + "line": 87, + "function": "runBare", + "class": "PHPUnit\\Framework\\TestCase", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/phpunit/phpunit/src/Framework/TestCase.php", + "line": 365, + "function": "run", + "class": "PHPUnit\\Framework\\TestRunner", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/phpunit/phpunit/src/Framework/TestSuite.php", + "line": 369, + "function": "run", + "class": "PHPUnit\\Framework\\TestCase", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/phpunit/phpunit/src/Framework/TestSuite.php", + "line": 369, + "function": "run", + "class": "PHPUnit\\Framework\\TestSuite", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/phpunit/phpunit/src/Framework/TestSuite.php", + "line": 369, + "function": "run", + "class": "PHPUnit\\Framework\\TestSuite", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/phpunit/phpunit/src/TextUI/TestRunner.php", + "line": 64, + "function": "run", + "class": "PHPUnit\\Framework\\TestSuite", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/phpunit/phpunit/src/TextUI/Application.php", + "line": 211, + "function": "run", + "class": "PHPUnit\\TextUI\\TestRunner", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/phpunit/phpunit/phpunit", + "line": 104, + "function": "run", + "class": "PHPUnit\\TextUI\\Application", + "type": "->" + } + ] +} +Failed asserting that an array contains 500. + + at tests/Concerns/AssertsE2EApiResponses.php:23 + 19▕ * @param array $statuses + 20▕ */ + 21▕ protected function assertStatusIn(TestResponse $response, array $statuses, string $context): void + 22▕ { + ➜ 23▕ $this->assertContains( + 24▕ $response->getStatusCode(), + 25▕ $statuses, + 26▕ $context.' returned unexpected status '.$response->getStatusCode().'. Body: '.$response->getContent() + 27▕ ); + + 1 tests/Concerns/AssertsE2EApiResponses.php:23 + 2 tests/Feature/Api/V1/FullSurface/Support/FullSurfaceE2EContractCase.php:343 + + ──────────────────────────────────────────────────────────────────────────── + FAILED Tests\Feature\Api\V1\FullSurface\ApiSchoolOperationsRegressionBac… + admin POST api/v1/school-years/{schoolYear}/archive regression backstop should return a controlled response, not a 5xx crash. Body: { + "message": "Method App\\Http\\Controllers\\Api\\SchoolYears\\SchoolYearController::archive does not exist.", + "exception": "BadMethodCallException", + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Routing/Controller.php", + "line": 68, + "trace": [ + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Routing/Controller.php", + "line": 54, + "function": "__call", + "class": "Illuminate\\Routing\\Controller", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Routing/ControllerDispatcher.php", + "line": 43, + "function": "callAction", + "class": "Illuminate\\Routing\\Controller", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Routing/Route.php", + "line": 265, + "function": "dispatch", + "class": "Illuminate\\Routing\\ControllerDispatcher", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Routing/Route.php", + "line": 211, + "function": "runController", + "class": "Illuminate\\Routing\\Route", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Routing/Router.php", + "line": 822, + "function": "run", + "class": "Illuminate\\Routing\\Route", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 180, + "function": "{closure:Illuminate\\Routing\\Router::runRouteWithinStack():821}", + "class": "Illuminate\\Routing\\Router", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/app/Http/Middleware/RequirePermission.php", + "line": 29, + "function": "{closure:Illuminate\\Pipeline\\Pipeline::prepareDestination():178}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "App\\Http\\Middleware\\RequirePermission", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/app/Http/Middleware/EnsureAccountActive.php", + "line": 32, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "App\\Http\\Middleware\\EnsureAccountActive", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/app/Http/Middleware/MultiAuth.php", + "line": 32, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "App\\Http\\Middleware\\MultiAuth", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Routing/Middleware/SubstituteBindings.php", + "line": 50, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "Illuminate\\Routing\\Middleware\\SubstituteBindings", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 137, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Routing/Router.php", + "line": 821, + "function": "then", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Routing/Router.php", + "line": 800, + "function": "runRouteWithinStack", + "class": "Illuminate\\Routing\\Router", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Routing/Router.php", + "line": 764, + "function": "runRoute", + "class": "Illuminate\\Routing\\Router", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Routing/Router.php", + "line": 753, + "function": "dispatchToRoute", + "class": "Illuminate\\Routing\\Router", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php", + "line": 200, + "function": "dispatch", + "class": "Illuminate\\Routing\\Router", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 180, + "function": "{closure:Illuminate\\Foundation\\Http\\Kernel::dispatchToRouter():197}", + "class": "Illuminate\\Foundation\\Http\\Kernel", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/app/Http/Middleware/SecurityHeaders.php", + "line": 22, + "function": "{closure:Illuminate\\Pipeline\\Pipeline::prepareDestination():178}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "App\\Http\\Middleware\\SecurityHeaders", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/TransformsRequest.php", + "line": 21, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/ConvertEmptyStringsToNull.php", + "line": 31, + "function": "handle", + "class": "Illuminate\\Foundation\\Http\\Middleware\\TransformsRequest", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "Illuminate\\Foundation\\Http\\Middleware\\ConvertEmptyStringsToNull", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/TransformsRequest.php", + "line": 21, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/TrimStrings.php", + "line": 51, + "function": "handle", + "class": "Illuminate\\Foundation\\Http\\Middleware\\TransformsRequest", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "Illuminate\\Foundation\\Http\\Middleware\\TrimStrings", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Http/Middleware/ValidatePostSize.php", + "line": 27, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "Illuminate\\Http\\Middleware\\ValidatePostSize", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/PreventRequestsDuringMaintenance.php", + "line": 109, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "Illuminate\\Foundation\\Http\\Middleware\\PreventRequestsDuringMaintenance", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Http/Middleware/HandleCors.php", + "line": 74, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "Illuminate\\Http\\Middleware\\HandleCors", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Http/Middleware/TrustProxies.php", + "line": 58, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "Illuminate\\Http\\Middleware\\TrustProxies", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/InvokeDeferredCallbacks.php", + "line": 22, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "Illuminate\\Foundation\\Http\\Middleware\\InvokeDeferredCallbacks", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Http/Middleware/ValidatePathEncoding.php", + "line": 26, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "Illuminate\\Http\\Middleware\\ValidatePathEncoding", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 137, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php", + "line": 175, + "function": "then", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php", + "line": 144, + "function": "sendRequestThroughRouter", + "class": "Illuminate\\Foundation\\Http\\Kernel", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Foundation/Testing/Concerns/MakesHttpRequests.php", + "line": 607, + "function": "handle", + "class": "Illuminate\\Foundation\\Http\\Kernel", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Foundation/Testing/Concerns/MakesHttpRequests.php", + "line": 573, + "function": "call", + "class": "Illuminate\\Foundation\\Testing\\TestCase", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/tests/Feature/Api/V1/FullSurface/Support/FullSurfaceE2EContractCase.php", + "line": 190, + "function": "json", + "class": "Illuminate\\Foundation\\Testing\\TestCase", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/tests/Feature/Api/V1/FullSurface/ApiSchoolOperationsRegressionBackstopTest.php", + "line": 19, + "function": "requestAs", + "class": "Tests\\Feature\\Api\\V1\\FullSurface\\Support\\FullSurfaceE2EContractCase", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/phpunit/phpunit/src/Framework/TestCase.php", + "line": 1667, + "function": "test_administrator_can_probe_core_school_operations_without_route_level_crashes", + "class": "Tests\\Feature\\Api\\V1\\FullSurface\\ApiSchoolOperationsRegressionBackstopTest", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/phpunit/phpunit/src/Framework/TestCase.php", + "line": 519, + "function": "runTest", + "class": "PHPUnit\\Framework\\TestCase", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/phpunit/phpunit/src/Framework/TestRunner/TestRunner.php", + "line": 87, + "function": "runBare", + "class": "PHPUnit\\Framework\\TestCase", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/phpunit/phpunit/src/Framework/TestCase.php", + "line": 365, + "function": "run", + "class": "PHPUnit\\Framework\\TestRunner", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/phpunit/phpunit/src/Framework/TestSuite.php", + "line": 369, + "function": "run", + "class": "PHPUnit\\Framework\\TestCase", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/phpunit/phpunit/src/Framework/TestSuite.php", + "line": 369, + "function": "run", + "class": "PHPUnit\\Framework\\TestSuite", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/phpunit/phpunit/src/Framework/TestSuite.php", + "line": 369, + "function": "run", + "class": "PHPUnit\\Framework\\TestSuite", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/phpunit/phpunit/src/TextUI/TestRunner.php", + "line": 64, + "function": "run", + "class": "PHPUnit\\Framework\\TestSuite", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/phpunit/phpunit/src/TextUI/Application.php", + "line": 211, + "function": "run", + "class": "PHPUnit\\TextUI\\TestRunner", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/phpunit/phpunit/phpunit", + "line": 104, + "function": "run", + "class": "PHPUnit\\TextUI\\Application", + "type": "->" + } + ] +} +Failed asserting that 500 is less than 500. + + at tests/Concerns/AssertsE2EApiResponses.php:11 + 7▕ trait AssertsE2EApiResponses + 8▕ { + 9▕ protected function assertNoServerError(TestResponse $response, string $context): void + 10▕ { + ➜ 11▕ $this->assertLessThan( + 12▕ 500, + 13▕ $response->getStatusCode(), + 14▕ $context.' should return a controlled response, not a 5xx crash. Body: '.$response->getContent() + 15▕ ); + + 1 tests/Concerns/AssertsE2EApiResponses.php:11 + 2 tests/Feature/Api/V1/FullSurface/ApiSchoolOperationsRegressionBackstopTest.php:21 + + ──────────────────────────────────────────────────────────────────────────── + FAILED Tests\Feature\Api\V1\FullSurface\ApiSecurityAndTransportContractT… + GET api/timeoff/notify/{token} unauthenticated transport contract returned unexpected status 400. Body: TimeOff

Sorry, this link is invalid or has expired.

+Failed asserting that an array contains 400. + + at tests/Concerns/AssertsE2EApiResponses.php:23 + 19▕ * @param array $statuses + 20▕ */ + 21▕ protected function assertStatusIn(TestResponse $response, array $statuses, string $context): void + 22▕ { + ➜ 23▕ $this->assertContains( + 24▕ $response->getStatusCode(), + 25▕ $statuses, + 26▕ $context.' returned unexpected status '.$response->getStatusCode().'. Body: '.$response->getContent() + 27▕ ); + + 1 tests/Concerns/AssertsE2EApiResponses.php:23 + 2 tests/Feature/Api/V1/FullSurface/ApiSecurityAndTransportContractTest.php:18 + + ──────────────────────────────────────────────────────────────────────────── + FAILED Tests\Feature\Api\V1\FullSurface\ApiSecurityAndTransportContractT… + GET against mutating route api/set_authorized_user_password/{authorizedUserId} returned unexpected status 400. Body: {"message":"Invalid or expired confirmation link."} +Failed asserting that an array contains 400. + + at tests/Concerns/AssertsE2EApiResponses.php:23 + 19▕ * @param array $statuses + 20▕ */ + 21▕ protected function assertStatusIn(TestResponse $response, array $statuses, string $context): void + 22▕ { + ➜ 23▕ $this->assertContains( + 24▕ $response->getStatusCode(), + 25▕ $statuses, + 26▕ $context.' returned unexpected status '.$response->getStatusCode().'. Body: '.$response->getContent() + 27▕ ); + + 1 tests/Concerns/AssertsE2EApiResponses.php:23 + 2 tests/Feature/Api/V1/FullSurface/ApiSecurityAndTransportContractTest.php:30 + + ──────────────────────────────────────────────────────────────────────────── + FAILED Tests\Feature\Api\V1\FullSurface\ApiSoftDeleteRestoreArchiveLifec… + POST api/v1/school-years/{schoolYear}/archive returned unexpected status 500. Body: { + "message": "Method App\\Http\\Controllers\\Api\\SchoolYears\\SchoolYearController::archive does not exist.", + "exception": "BadMethodCallException", + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Routing/Controller.php", + "line": 68, + "trace": [ + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Routing/Controller.php", + "line": 54, + "function": "__call", + "class": "Illuminate\\Routing\\Controller", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Routing/ControllerDispatcher.php", + "line": 43, + "function": "callAction", + "class": "Illuminate\\Routing\\Controller", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Routing/Route.php", + "line": 265, + "function": "dispatch", + "class": "Illuminate\\Routing\\ControllerDispatcher", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Routing/Route.php", + "line": 211, + "function": "runController", + "class": "Illuminate\\Routing\\Route", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Routing/Router.php", + "line": 822, + "function": "run", + "class": "Illuminate\\Routing\\Route", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 180, + "function": "{closure:Illuminate\\Routing\\Router::runRouteWithinStack():821}", + "class": "Illuminate\\Routing\\Router", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/app/Http/Middleware/RequirePermission.php", + "line": 29, + "function": "{closure:Illuminate\\Pipeline\\Pipeline::prepareDestination():178}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "App\\Http\\Middleware\\RequirePermission", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/app/Http/Middleware/EnsureAccountActive.php", + "line": 32, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "App\\Http\\Middleware\\EnsureAccountActive", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/app/Http/Middleware/MultiAuth.php", + "line": 32, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "App\\Http\\Middleware\\MultiAuth", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Routing/Middleware/SubstituteBindings.php", + "line": 50, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "Illuminate\\Routing\\Middleware\\SubstituteBindings", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 137, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Routing/Router.php", + "line": 821, + "function": "then", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Routing/Router.php", + "line": 800, + "function": "runRouteWithinStack", + "class": "Illuminate\\Routing\\Router", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Routing/Router.php", + "line": 764, + "function": "runRoute", + "class": "Illuminate\\Routing\\Router", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Routing/Router.php", + "line": 753, + "function": "dispatchToRoute", + "class": "Illuminate\\Routing\\Router", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php", + "line": 200, + "function": "dispatch", + "class": "Illuminate\\Routing\\Router", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 180, + "function": "{closure:Illuminate\\Foundation\\Http\\Kernel::dispatchToRouter():197}", + "class": "Illuminate\\Foundation\\Http\\Kernel", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/app/Http/Middleware/SecurityHeaders.php", + "line": 22, + "function": "{closure:Illuminate\\Pipeline\\Pipeline::prepareDestination():178}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "App\\Http\\Middleware\\SecurityHeaders", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/TransformsRequest.php", + "line": 21, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/ConvertEmptyStringsToNull.php", + "line": 31, + "function": "handle", + "class": "Illuminate\\Foundation\\Http\\Middleware\\TransformsRequest", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "Illuminate\\Foundation\\Http\\Middleware\\ConvertEmptyStringsToNull", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/TransformsRequest.php", + "line": 21, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/TrimStrings.php", + "line": 51, + "function": "handle", + "class": "Illuminate\\Foundation\\Http\\Middleware\\TransformsRequest", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "Illuminate\\Foundation\\Http\\Middleware\\TrimStrings", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Http/Middleware/ValidatePostSize.php", + "line": 27, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "Illuminate\\Http\\Middleware\\ValidatePostSize", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/PreventRequestsDuringMaintenance.php", + "line": 109, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "Illuminate\\Foundation\\Http\\Middleware\\PreventRequestsDuringMaintenance", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Http/Middleware/HandleCors.php", + "line": 74, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "Illuminate\\Http\\Middleware\\HandleCors", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Http/Middleware/TrustProxies.php", + "line": 58, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "Illuminate\\Http\\Middleware\\TrustProxies", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/InvokeDeferredCallbacks.php", + "line": 22, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "Illuminate\\Foundation\\Http\\Middleware\\InvokeDeferredCallbacks", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Http/Middleware/ValidatePathEncoding.php", + "line": 26, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "Illuminate\\Http\\Middleware\\ValidatePathEncoding", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 137, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php", + "line": 175, + "function": "then", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php", + "line": 144, + "function": "sendRequestThroughRouter", + "class": "Illuminate\\Foundation\\Http\\Kernel", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Foundation/Testing/Concerns/MakesHttpRequests.php", + "line": 607, + "function": "handle", + "class": "Illuminate\\Foundation\\Http\\Kernel", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Foundation/Testing/Concerns/MakesHttpRequests.php", + "line": 573, + "function": "call", + "class": "Illuminate\\Foundation\\Testing\\TestCase", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/tests/Feature/Api/V1/FullSurface/Support/FullSurfaceE2EContractCase.php", + "line": 190, + "function": "json", + "class": "Illuminate\\Foundation\\Testing\\TestCase", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/tests/Feature/Api/V1/FullSurface/ApiSoftDeleteRestoreArchiveLifecycleContractTest.php", + "line": 19, + "function": "requestAs", + "class": "Tests\\Feature\\Api\\V1\\FullSurface\\Support\\FullSurfaceE2EContractCase", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/phpunit/phpunit/src/Framework/TestCase.php", + "line": 1667, + "function": "archive_restore_and_unarchive_routes_are_controlled_and_role_protected", + "class": "Tests\\Feature\\Api\\V1\\FullSurface\\ApiSoftDeleteRestoreArchiveLifecycleContractTest", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/phpunit/phpunit/src/Framework/TestCase.php", + "line": 519, + "function": "runTest", + "class": "PHPUnit\\Framework\\TestCase", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/phpunit/phpunit/src/Framework/TestRunner/TestRunner.php", + "line": 87, + "function": "runBare", + "class": "PHPUnit\\Framework\\TestCase", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/phpunit/phpunit/src/Framework/TestCase.php", + "line": 365, + "function": "run", + "class": "PHPUnit\\Framework\\TestRunner", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/phpunit/phpunit/src/Framework/TestSuite.php", + "line": 369, + "function": "run", + "class": "PHPUnit\\Framework\\TestCase", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/phpunit/phpunit/src/Framework/TestSuite.php", + "line": 369, + "function": "run", + "class": "PHPUnit\\Framework\\TestSuite", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/phpunit/phpunit/src/Framework/TestSuite.php", + "line": 369, + "function": "run", + "class": "PHPUnit\\Framework\\TestSuite", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/phpunit/phpunit/src/TextUI/TestRunner.php", + "line": 64, + "function": "run", + "class": "PHPUnit\\Framework\\TestSuite", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/phpunit/phpunit/src/TextUI/Application.php", + "line": 211, + "function": "run", + "class": "PHPUnit\\TextUI\\TestRunner", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/phpunit/phpunit/phpunit", + "line": 104, + "function": "run", + "class": "PHPUnit\\TextUI\\Application", + "type": "->" + } + ] +} +Failed asserting that an array contains 500. + + at tests/Concerns/AssertsE2EApiResponses.php:23 + 19▕ * @param array $statuses + 20▕ */ + 21▕ protected function assertStatusIn(TestResponse $response, array $statuses, string $context): void + 22▕ { + ➜ 23▕ $this->assertContains( + 24▕ $response->getStatusCode(), + 25▕ $statuses, + 26▕ $context.' returned unexpected status '.$response->getStatusCode().'. Body: '.$response->getContent() + 27▕ ); + + 1 tests/Concerns/AssertsE2EApiResponses.php:23 + 2 tests/Feature/Api/V1/FullSurface/Support/FullSurfaceE2EContractCase.php:343 + + ──────────────────────────────────────────────────────────────────────────── + FAILED Tests\Feature\Api\V1\FullSurface\ApiSoftDeleteRestoreArchiveLifec… + POST api/v1/school-years/{schoolYear}/archive returned unexpected status 500. Body: { + "message": "Method App\\Http\\Controllers\\Api\\SchoolYears\\SchoolYearController::archive does not exist.", + "exception": "BadMethodCallException", + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Routing/Controller.php", + "line": 68, + "trace": [ + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Routing/Controller.php", + "line": 54, + "function": "__call", + "class": "Illuminate\\Routing\\Controller", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Routing/ControllerDispatcher.php", + "line": 43, + "function": "callAction", + "class": "Illuminate\\Routing\\Controller", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Routing/Route.php", + "line": 265, + "function": "dispatch", + "class": "Illuminate\\Routing\\ControllerDispatcher", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Routing/Route.php", + "line": 211, + "function": "runController", + "class": "Illuminate\\Routing\\Route", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Routing/Router.php", + "line": 822, + "function": "run", + "class": "Illuminate\\Routing\\Route", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 180, + "function": "{closure:Illuminate\\Routing\\Router::runRouteWithinStack():821}", + "class": "Illuminate\\Routing\\Router", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/app/Http/Middleware/RequirePermission.php", + "line": 29, + "function": "{closure:Illuminate\\Pipeline\\Pipeline::prepareDestination():178}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "App\\Http\\Middleware\\RequirePermission", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/app/Http/Middleware/EnsureAccountActive.php", + "line": 32, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "App\\Http\\Middleware\\EnsureAccountActive", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/app/Http/Middleware/MultiAuth.php", + "line": 32, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "App\\Http\\Middleware\\MultiAuth", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Routing/Middleware/SubstituteBindings.php", + "line": 50, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "Illuminate\\Routing\\Middleware\\SubstituteBindings", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 137, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Routing/Router.php", + "line": 821, + "function": "then", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Routing/Router.php", + "line": 800, + "function": "runRouteWithinStack", + "class": "Illuminate\\Routing\\Router", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Routing/Router.php", + "line": 764, + "function": "runRoute", + "class": "Illuminate\\Routing\\Router", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Routing/Router.php", + "line": 753, + "function": "dispatchToRoute", + "class": "Illuminate\\Routing\\Router", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php", + "line": 200, + "function": "dispatch", + "class": "Illuminate\\Routing\\Router", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 180, + "function": "{closure:Illuminate\\Foundation\\Http\\Kernel::dispatchToRouter():197}", + "class": "Illuminate\\Foundation\\Http\\Kernel", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/app/Http/Middleware/SecurityHeaders.php", + "line": 22, + "function": "{closure:Illuminate\\Pipeline\\Pipeline::prepareDestination():178}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "App\\Http\\Middleware\\SecurityHeaders", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/TransformsRequest.php", + "line": 21, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/ConvertEmptyStringsToNull.php", + "line": 31, + "function": "handle", + "class": "Illuminate\\Foundation\\Http\\Middleware\\TransformsRequest", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "Illuminate\\Foundation\\Http\\Middleware\\ConvertEmptyStringsToNull", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/TransformsRequest.php", + "line": 21, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/TrimStrings.php", + "line": 51, + "function": "handle", + "class": "Illuminate\\Foundation\\Http\\Middleware\\TransformsRequest", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "Illuminate\\Foundation\\Http\\Middleware\\TrimStrings", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Http/Middleware/ValidatePostSize.php", + "line": 27, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "Illuminate\\Http\\Middleware\\ValidatePostSize", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/PreventRequestsDuringMaintenance.php", + "line": 109, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "Illuminate\\Foundation\\Http\\Middleware\\PreventRequestsDuringMaintenance", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Http/Middleware/HandleCors.php", + "line": 74, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "Illuminate\\Http\\Middleware\\HandleCors", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Http/Middleware/TrustProxies.php", + "line": 58, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "Illuminate\\Http\\Middleware\\TrustProxies", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/InvokeDeferredCallbacks.php", + "line": 22, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "Illuminate\\Foundation\\Http\\Middleware\\InvokeDeferredCallbacks", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Http/Middleware/ValidatePathEncoding.php", + "line": 26, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "Illuminate\\Http\\Middleware\\ValidatePathEncoding", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 137, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php", + "line": 175, + "function": "then", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php", + "line": 144, + "function": "sendRequestThroughRouter", + "class": "Illuminate\\Foundation\\Http\\Kernel", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Foundation/Testing/Concerns/MakesHttpRequests.php", + "line": 607, + "function": "handle", + "class": "Illuminate\\Foundation\\Http\\Kernel", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Foundation/Testing/Concerns/MakesHttpRequests.php", + "line": 573, + "function": "call", + "class": "Illuminate\\Foundation\\Testing\\TestCase", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/tests/Feature/Api/V1/FullSurface/Support/FullSurfaceE2EContractCase.php", + "line": 190, + "function": "json", + "class": "Illuminate\\Foundation\\Testing\\TestCase", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/tests/Feature/Api/V1/FullSurface/ApiSoftDeleteRestoreArchiveLifecycleContractTest.php", + "line": 40, + "function": "requestAs", + "class": "Tests\\Feature\\Api\\V1\\FullSurface\\Support\\FullSurfaceE2EContractCase", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/phpunit/phpunit/src/Framework/TestCase.php", + "line": 1667, + "function": "destructive_soft_delete_style_routes_tolerate_repeated_requests", + "class": "Tests\\Feature\\Api\\V1\\FullSurface\\ApiSoftDeleteRestoreArchiveLifecycleContractTest", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/phpunit/phpunit/src/Framework/TestCase.php", + "line": 519, + "function": "runTest", + "class": "PHPUnit\\Framework\\TestCase", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/phpunit/phpunit/src/Framework/TestRunner/TestRunner.php", + "line": 87, + "function": "runBare", + "class": "PHPUnit\\Framework\\TestCase", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/phpunit/phpunit/src/Framework/TestCase.php", + "line": 365, + "function": "run", + "class": "PHPUnit\\Framework\\TestRunner", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/phpunit/phpunit/src/Framework/TestSuite.php", + "line": 369, + "function": "run", + "class": "PHPUnit\\Framework\\TestCase", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/phpunit/phpunit/src/Framework/TestSuite.php", + "line": 369, + "function": "run", + "class": "PHPUnit\\Framework\\TestSuite", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/phpunit/phpunit/src/Framework/TestSuite.php", + "line": 369, + "function": "run", + "class": "PHPUnit\\Framework\\TestSuite", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/phpunit/phpunit/src/TextUI/TestRunner.php", + "line": 64, + "function": "run", + "class": "PHPUnit\\Framework\\TestSuite", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/phpunit/phpunit/src/TextUI/Application.php", + "line": 211, + "function": "run", + "class": "PHPUnit\\TextUI\\TestRunner", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/phpunit/phpunit/phpunit", + "line": 104, + "function": "run", + "class": "PHPUnit\\TextUI\\Application", + "type": "->" + } + ] +} +Failed asserting that an array contains 500. + + at tests/Concerns/AssertsE2EApiResponses.php:23 + 19▕ * @param array $statuses + 20▕ */ + 21▕ protected function assertStatusIn(TestResponse $response, array $statuses, string $context): void + 22▕ { + ➜ 23▕ $this->assertContains( + 24▕ $response->getStatusCode(), + 25▕ $statuses, + 26▕ $context.' returned unexpected status '.$response->getStatusCode().'. Body: '.$response->getContent() + 27▕ ); + + 1 tests/Concerns/AssertsE2EApiResponses.php:23 + 2 tests/Feature/Api/V1/FullSurface/Support/FullSurfaceE2EContractCase.php:343 + + ──────────────────────────────────────────────────────────────────────────── + FAILED Tests\Feature\Api\V1\FullSurface\ApiTenantSchoolYearAndSemesterIs… + POST api/v1/school-years/{schoolYear}/archive returned unexpected status 500. Body: { + "message": "Method App\\Http\\Controllers\\Api\\SchoolYears\\SchoolYearController::archive does not exist.", + "exception": "BadMethodCallException", + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Routing/Controller.php", + "line": 68, + "trace": [ + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Routing/Controller.php", + "line": 54, + "function": "__call", + "class": "Illuminate\\Routing\\Controller", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Routing/ControllerDispatcher.php", + "line": 43, + "function": "callAction", + "class": "Illuminate\\Routing\\Controller", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Routing/Route.php", + "line": 265, + "function": "dispatch", + "class": "Illuminate\\Routing\\ControllerDispatcher", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Routing/Route.php", + "line": 211, + "function": "runController", + "class": "Illuminate\\Routing\\Route", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Routing/Router.php", + "line": 822, + "function": "run", + "class": "Illuminate\\Routing\\Route", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 180, + "function": "{closure:Illuminate\\Routing\\Router::runRouteWithinStack():821}", + "class": "Illuminate\\Routing\\Router", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/app/Http/Middleware/RequirePermission.php", + "line": 29, + "function": "{closure:Illuminate\\Pipeline\\Pipeline::prepareDestination():178}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "App\\Http\\Middleware\\RequirePermission", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/app/Http/Middleware/EnsureAccountActive.php", + "line": 32, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "App\\Http\\Middleware\\EnsureAccountActive", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/app/Http/Middleware/MultiAuth.php", + "line": 32, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "App\\Http\\Middleware\\MultiAuth", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Routing/Middleware/SubstituteBindings.php", + "line": 50, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "Illuminate\\Routing\\Middleware\\SubstituteBindings", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 137, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Routing/Router.php", + "line": 821, + "function": "then", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Routing/Router.php", + "line": 800, + "function": "runRouteWithinStack", + "class": "Illuminate\\Routing\\Router", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Routing/Router.php", + "line": 764, + "function": "runRoute", + "class": "Illuminate\\Routing\\Router", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Routing/Router.php", + "line": 753, + "function": "dispatchToRoute", + "class": "Illuminate\\Routing\\Router", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php", + "line": 200, + "function": "dispatch", + "class": "Illuminate\\Routing\\Router", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 180, + "function": "{closure:Illuminate\\Foundation\\Http\\Kernel::dispatchToRouter():197}", + "class": "Illuminate\\Foundation\\Http\\Kernel", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/app/Http/Middleware/SecurityHeaders.php", + "line": 22, + "function": "{closure:Illuminate\\Pipeline\\Pipeline::prepareDestination():178}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "App\\Http\\Middleware\\SecurityHeaders", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/TransformsRequest.php", + "line": 21, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/ConvertEmptyStringsToNull.php", + "line": 31, + "function": "handle", + "class": "Illuminate\\Foundation\\Http\\Middleware\\TransformsRequest", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "Illuminate\\Foundation\\Http\\Middleware\\ConvertEmptyStringsToNull", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/TransformsRequest.php", + "line": 21, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/TrimStrings.php", + "line": 51, + "function": "handle", + "class": "Illuminate\\Foundation\\Http\\Middleware\\TransformsRequest", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "Illuminate\\Foundation\\Http\\Middleware\\TrimStrings", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Http/Middleware/ValidatePostSize.php", + "line": 27, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "Illuminate\\Http\\Middleware\\ValidatePostSize", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/PreventRequestsDuringMaintenance.php", + "line": 109, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "Illuminate\\Foundation\\Http\\Middleware\\PreventRequestsDuringMaintenance", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Http/Middleware/HandleCors.php", + "line": 74, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "Illuminate\\Http\\Middleware\\HandleCors", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Http/Middleware/TrustProxies.php", + "line": 58, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "Illuminate\\Http\\Middleware\\TrustProxies", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/InvokeDeferredCallbacks.php", + "line": 22, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "Illuminate\\Foundation\\Http\\Middleware\\InvokeDeferredCallbacks", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Http/Middleware/ValidatePathEncoding.php", + "line": 26, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "Illuminate\\Http\\Middleware\\ValidatePathEncoding", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 137, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php", + "line": 175, + "function": "then", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php", + "line": 144, + "function": "sendRequestThroughRouter", + "class": "Illuminate\\Foundation\\Http\\Kernel", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Foundation/Testing/Concerns/MakesHttpRequests.php", + "line": 607, + "function": "handle", + "class": "Illuminate\\Foundation\\Http\\Kernel", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Foundation/Testing/Concerns/MakesHttpRequests.php", + "line": 573, + "function": "call", + "class": "Illuminate\\Foundation\\Testing\\TestCase", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/tests/Feature/Api/V1/FullSurface/Support/FullSurfaceE2EContractCase.php", + "line": 190, + "function": "json", + "class": "Illuminate\\Foundation\\Testing\\TestCase", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/tests/Feature/Api/V1/FullSurface/ApiTenantSchoolYearAndSemesterIsolationContractTest.php", + "line": 32, + "function": "requestAs", + "class": "Tests\\Feature\\Api\\V1\\FullSurface\\Support\\FullSurfaceE2EContractCase", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/phpunit/phpunit/src/Framework/TestCase.php", + "line": 1667, + "function": "test_school_year_scoped_routes_reject_foreign_or_closed_school_year_context", + "class": "Tests\\Feature\\Api\\V1\\FullSurface\\ApiTenantSchoolYearAndSemesterIsolationContractTest", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/phpunit/phpunit/src/Framework/TestCase.php", + "line": 519, + "function": "runTest", + "class": "PHPUnit\\Framework\\TestCase", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/phpunit/phpunit/src/Framework/TestRunner/TestRunner.php", + "line": 87, + "function": "runBare", + "class": "PHPUnit\\Framework\\TestCase", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/phpunit/phpunit/src/Framework/TestCase.php", + "line": 365, + "function": "run", + "class": "PHPUnit\\Framework\\TestRunner", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/phpunit/phpunit/src/Framework/TestSuite.php", + "line": 369, + "function": "run", + "class": "PHPUnit\\Framework\\TestCase", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/phpunit/phpunit/src/Framework/TestSuite.php", + "line": 369, + "function": "run", + "class": "PHPUnit\\Framework\\TestSuite", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/phpunit/phpunit/src/Framework/TestSuite.php", + "line": 369, + "function": "run", + "class": "PHPUnit\\Framework\\TestSuite", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/phpunit/phpunit/src/TextUI/TestRunner.php", + "line": 64, + "function": "run", + "class": "PHPUnit\\Framework\\TestSuite", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/phpunit/phpunit/src/TextUI/Application.php", + "line": 211, + "function": "run", + "class": "PHPUnit\\TextUI\\TestRunner", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/phpunit/phpunit/phpunit", + "line": 104, + "function": "run", + "class": "PHPUnit\\TextUI\\Application", + "type": "->" + } + ] +} +Failed asserting that an array contains 500. + + at tests/Concerns/AssertsE2EApiResponses.php:23 + 19▕ * @param array $statuses + 20▕ */ + 21▕ protected function assertStatusIn(TestResponse $response, array $statuses, string $context): void + 22▕ { + ➜ 23▕ $this->assertContains( + 24▕ $response->getStatusCode(), + 25▕ $statuses, + 26▕ $context.' returned unexpected status '.$response->getStatusCode().'. Body: '.$response->getContent() + 27▕ ); + + 1 tests/Concerns/AssertsE2EApiResponses.php:23 + 2 tests/Feature/Api/V1/FullSurface/Support/FullSurfaceE2EContractCase.php:343 + + ──────────────────────────────────────────────────────────────────────────── + FAILED Tests\Feature\Api\V1\FullSurface\ApiTimezoneCalendarRecurrenceDep… + POST api/v1/school-years/{schoolYear}/archive returned unexpected status 500. Body: { + "message": "Method App\\Http\\Controllers\\Api\\SchoolYears\\SchoolYearController::archive does not exist.", + "exception": "BadMethodCallException", + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Routing/Controller.php", + "line": 68, + "trace": [ + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Routing/Controller.php", + "line": 54, + "function": "__call", + "class": "Illuminate\\Routing\\Controller", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Routing/ControllerDispatcher.php", + "line": 43, + "function": "callAction", + "class": "Illuminate\\Routing\\Controller", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Routing/Route.php", + "line": 265, + "function": "dispatch", + "class": "Illuminate\\Routing\\ControllerDispatcher", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Routing/Route.php", + "line": 211, + "function": "runController", + "class": "Illuminate\\Routing\\Route", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Routing/Router.php", + "line": 822, + "function": "run", + "class": "Illuminate\\Routing\\Route", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 180, + "function": "{closure:Illuminate\\Routing\\Router::runRouteWithinStack():821}", + "class": "Illuminate\\Routing\\Router", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/app/Http/Middleware/RequirePermission.php", + "line": 29, + "function": "{closure:Illuminate\\Pipeline\\Pipeline::prepareDestination():178}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "App\\Http\\Middleware\\RequirePermission", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/app/Http/Middleware/EnsureAccountActive.php", + "line": 32, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "App\\Http\\Middleware\\EnsureAccountActive", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/app/Http/Middleware/MultiAuth.php", + "line": 32, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "App\\Http\\Middleware\\MultiAuth", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Routing/Middleware/SubstituteBindings.php", + "line": 50, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "Illuminate\\Routing\\Middleware\\SubstituteBindings", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 137, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Routing/Router.php", + "line": 821, + "function": "then", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Routing/Router.php", + "line": 800, + "function": "runRouteWithinStack", + "class": "Illuminate\\Routing\\Router", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Routing/Router.php", + "line": 764, + "function": "runRoute", + "class": "Illuminate\\Routing\\Router", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Routing/Router.php", + "line": 753, + "function": "dispatchToRoute", + "class": "Illuminate\\Routing\\Router", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php", + "line": 200, + "function": "dispatch", + "class": "Illuminate\\Routing\\Router", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 180, + "function": "{closure:Illuminate\\Foundation\\Http\\Kernel::dispatchToRouter():197}", + "class": "Illuminate\\Foundation\\Http\\Kernel", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/app/Http/Middleware/SecurityHeaders.php", + "line": 22, + "function": "{closure:Illuminate\\Pipeline\\Pipeline::prepareDestination():178}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "App\\Http\\Middleware\\SecurityHeaders", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/TransformsRequest.php", + "line": 21, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/ConvertEmptyStringsToNull.php", + "line": 31, + "function": "handle", + "class": "Illuminate\\Foundation\\Http\\Middleware\\TransformsRequest", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "Illuminate\\Foundation\\Http\\Middleware\\ConvertEmptyStringsToNull", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/TransformsRequest.php", + "line": 21, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/TrimStrings.php", + "line": 51, + "function": "handle", + "class": "Illuminate\\Foundation\\Http\\Middleware\\TransformsRequest", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "Illuminate\\Foundation\\Http\\Middleware\\TrimStrings", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Http/Middleware/ValidatePostSize.php", + "line": 27, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "Illuminate\\Http\\Middleware\\ValidatePostSize", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/PreventRequestsDuringMaintenance.php", + "line": 109, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "Illuminate\\Foundation\\Http\\Middleware\\PreventRequestsDuringMaintenance", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Http/Middleware/HandleCors.php", + "line": 74, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "Illuminate\\Http\\Middleware\\HandleCors", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Http/Middleware/TrustProxies.php", + "line": 58, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "Illuminate\\Http\\Middleware\\TrustProxies", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/InvokeDeferredCallbacks.php", + "line": 22, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "Illuminate\\Foundation\\Http\\Middleware\\InvokeDeferredCallbacks", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Http/Middleware/ValidatePathEncoding.php", + "line": 26, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 219, + "function": "handle", + "class": "Illuminate\\Http\\Middleware\\ValidatePathEncoding", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", + "line": 137, + "function": "{closure:{closure:Illuminate\\Pipeline\\Pipeline::carry():194}:195}", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php", + "line": 175, + "function": "then", + "class": "Illuminate\\Pipeline\\Pipeline", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php", + "line": 144, + "function": "sendRequestThroughRouter", + "class": "Illuminate\\Foundation\\Http\\Kernel", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Foundation/Testing/Concerns/MakesHttpRequests.php", + "line": 607, + "function": "handle", + "class": "Illuminate\\Foundation\\Http\\Kernel", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Foundation/Testing/Concerns/MakesHttpRequests.php", + "line": 573, + "function": "call", + "class": "Illuminate\\Foundation\\Testing\\TestCase", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/tests/Feature/Api/V1/FullSurface/Support/FullSurfaceE2EContractCase.php", + "line": 190, + "function": "json", + "class": "Illuminate\\Foundation\\Testing\\TestCase", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/tests/Feature/Api/V1/FullSurface/ApiTimezoneCalendarRecurrenceDepthContractTest.php", + "line": 28, + "function": "requestAs", + "class": "Tests\\Feature\\Api\\V1\\FullSurface\\Support\\FullSurfaceE2EContractCase", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/phpunit/phpunit/src/Framework/TestCase.php", + "line": 1667, + "function": "calendar_and_schedule_routes_reject_ambiguous_recurrence_and_timezone_inputs_cleanly", + "class": "Tests\\Feature\\Api\\V1\\FullSurface\\ApiTimezoneCalendarRecurrenceDepthContractTest", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/phpunit/phpunit/src/Framework/TestCase.php", + "line": 519, + "function": "runTest", + "class": "PHPUnit\\Framework\\TestCase", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/phpunit/phpunit/src/Framework/TestRunner/TestRunner.php", + "line": 87, + "function": "runBare", + "class": "PHPUnit\\Framework\\TestCase", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/phpunit/phpunit/src/Framework/TestCase.php", + "line": 365, + "function": "run", + "class": "PHPUnit\\Framework\\TestRunner", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/phpunit/phpunit/src/Framework/TestSuite.php", + "line": 369, + "function": "run", + "class": "PHPUnit\\Framework\\TestCase", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/phpunit/phpunit/src/Framework/TestSuite.php", + "line": 369, + "function": "run", + "class": "PHPUnit\\Framework\\TestSuite", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/phpunit/phpunit/src/Framework/TestSuite.php", + "line": 369, + "function": "run", + "class": "PHPUnit\\Framework\\TestSuite", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/phpunit/phpunit/src/TextUI/TestRunner.php", + "line": 64, + "function": "run", + "class": "PHPUnit\\Framework\\TestSuite", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/phpunit/phpunit/src/TextUI/Application.php", + "line": 211, + "function": "run", + "class": "PHPUnit\\TextUI\\TestRunner", + "type": "->" + }, + { + "file": "/Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/phpunit/phpunit/phpunit", + "line": 104, + "function": "run", + "class": "PHPUnit\\TextUI\\Application", + "type": "->" + } + ] +} +Failed asserting that an array contains 500. + + at tests/Concerns/AssertsE2EApiResponses.php:23 + 19▕ * @param array $statuses + 20▕ */ + 21▕ protected function assertStatusIn(TestResponse $response, array $statuses, string $context): void + 22▕ { + ➜ 23▕ $this->assertContains( + 24▕ $response->getStatusCode(), + 25▕ $statuses, + 26▕ $context.' returned unexpected status '.$response->getStatusCode().'. Body: '.$response->getContent() + 27▕ ); + + 1 tests/Concerns/AssertsE2EApiResponses.php:23 + 2 tests/Feature/Api/V1/FullSurface/Support/FullSurfaceE2EContractCase.php:343 + + ──────────────────────────────────────────────────────────────────────────── + FAILED Tests\Feature\Api\V1\FullSurface\ApiWriteAuditAndTimestampContrac… + POST api/v1/attendance-tracking/send-auto-emails successful create response should expose an identifier, ok/status, or resource envelope. +Failed asserting that false is true. + + at tests/Feature/Api/V1/FullSurface/ApiWriteAuditAndTimestampContractTest.php:24 + 20▕ + 21▕ if (in_array($response->getStatusCode(), [200, 201, 202], true) && $this->isJsonString($response->getContent())) { + 22▕ $json = $response->json(); + 23▕ $flat = json_encode($json, JSON_THROW_ON_ERROR); + ➜ 24▕ $this->assertTrue( + 25▕ str_contains($flat, 'id') || str_contains($flat, 'uuid') || str_contains($flat, 'ok') || str_contains($flat, 'status'), + 26▕ "$method $uri successful create response should expose an identifier, ok/status, or resource envelope." + 27▕ ); + 28▕ } + + 1 tests/Feature/Api/V1/FullSurface/ApiWriteAuditAndTimestampContractTest.php:24 + + ──────────────────────────────────────────────────────────────────────────── + FAILED Tests\Feature\Api\V1\FullSurface\ApiWriteAuditAndTimestampContrac… + POST api/login public audit mutation returned unexpected status 200. Body: {"status":true,"token":"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJodHRwOi8vbG9jYWxob3N0L2FwaS9sb2dpbiIsImlhdCI6MTc1OTY1ODQwMCwiZXhwIjoxNzU5NzQ0ODAwLCJuYmYiOjE3NTk2NTg0MDAsImp0aSI6IjAwYzExY0JrVkhhcWo3aWwiLCJzdWIiOiI0IiwicHJ2IjoiMjNiZDVjODk0OWY2MDBhZGIzOWU3MDFjNDAwODcyZGI3YTU5NzZmNyIsIm5hbWUiOiJNYXRoaWxkZSBKb2huc3RvbiIsInJvbGVzIjpbImFkbWluaXN0cmF0b3IiXX0.bDPxC37-zXHqXxQVQfczSm42134RVfICKu0GeHYKA4w","access_token":"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJodHRwOi8vbG9jYWxob3N0L2FwaS9sb2dpbiIsImlhdCI6MTc1OTY1ODQwMCwiZXhwIjoxNzU5NzQ0ODAwLCJuYmYiOjE3NTk2NTg0MDAsImp0aSI6IjAwYzExY0JrVkhhcWo3aWwiLCJzdWIiOiI0IiwicHJ2IjoiMjNiZDVjODk0OWY2MDBhZGIzOWU3MDFjNDAwODcyZGI3YTU5NzZmNyIsIm5hbWUiOiJNYXRoaWxkZSBKb2huc3RvbiIsInJvbGVzIjpbImFkbWluaXN0cmF0b3IiXX0.bDPxC37-zXHqXxQVQfczSm42134RVfICKu0GeHYKA4w","token_type":"bearer","expires_in":86400,"user":{"id":4,"name":"Mathilde Johnston","firstname":"Mathilde","lastname":"Johnston","email":"administrator-api-test-6a4ad65445571609562500@example.test","roles":{"administrator":true},"class_section_id":null,"class_section_name":null}} +Failed asserting that an array contains 200. + + at tests/Concerns/AssertsE2EApiResponses.php:23 + 19▕ * @param array $statuses + 20▕ */ + 21▕ protected function assertStatusIn(TestResponse $response, array $statuses, string $context): void + 22▕ { + ➜ 23▕ $this->assertContains( + 24▕ $response->getStatusCode(), + 25▕ $statuses, + 26▕ $context.' returned unexpected status '.$response->getStatusCode().'. Body: '.$response->getContent() + 27▕ ); + + 1 tests/Concerns/AssertsE2EApiResponses.php:23 + 2 tests/Feature/Api/V1/FullSurface/ApiWriteAuditAndTimestampContractTest.php:67 + + ──────────────────────────────────────────────────────────────────────────── + FAILED Tests\Feature\Api\V1\Parents\AuthorizedUsersControllerTest > inde… + Failed asserting that actual size 2 matches expected size 1. + + at tests/Feature/Api/V1/Parents/AuthorizedUsersControllerTest.php:57 + 53▕ ->getJson('/api/v1/parents/authorized-users') + 54▕ ->assertOk() + 55▕ ->assertJsonPath('status', true); + 56▕ + ➜ 57▕ $this->assertCount(1, $response->json('data')); + 58▕ $this->assertSame($own->id, $response->json('data.0.id')); + 59▕ } + 60▕ + 61▕ public function test_show_returns_404_for_unknown_authorized_user(): void + + 1 tests/Feature/Api/V1/Parents/AuthorizedUsersControllerTest.php:57 + + ──────────────────────────────────────────────────────────────────────────── + FAILED Tests\Feature\Api\V1\Parents\ParentAttendanceReportControllerTest… + Expected response status code [200] but received 403. +Failed asserting that 403 is identical to 200. + + at tests/Feature/Api/V1/Parents/ParentAttendanceReportControllerTest.php:24 + 20▕ + 21▕ Sanctum::actingAs($parent); + 22▕ $response = $this->getJson('/api/v1/parents/attendance-reports/form'); + 23▕ + ➜ 24▕ $response->assertOk(); + 25▕ $response->assertJson(['ok' => true]); + 26▕ $this->assertNotEmpty($response->json('students')); + 27▕ $this->assertNotEmpty($response->json('sundays')); + 28▕ } + + ──────────────────────────────────────────────────────────────────────────── + FAILED Tests\Feature\Api\V1\Parents\ParentAttendanceReportControllerTest… + Expected response status code [201] but received 403. +Failed asserting that 403 is identical to 201. + + at tests/Feature/Api/V1/Parents/ParentAttendanceReportControllerTest.php:47 + 43▕ 'type' => 'absent', + 44▕ 'reason' => 'Sick', + 45▕ ]); + 46▕ + ➜ 47▕ $response->assertStatus(201); + 48▕ $response->assertJson(['ok' => true]); + 49▕ + 50▕ $this->assertDatabaseHas('parent_attendance_reports', [ + 51▕ 'student_id' => $studentId, + + ──────────────────────────────────────────────────────────────────────────── + FAILED Tests\Feature\Api\V1\Parents\ParentAttendanceReportControllerTest… + Expected response status code [200] but received 403. +Failed asserting that 403 is identical to 200. + + at tests/Feature/Api/V1/Parents/ParentAttendanceReportControllerTest.php:86 + 82▕ 'date' => $date, + 83▕ 'type' => 'late', + 84▕ ]); + 85▕ + ➜ 86▕ $response->assertOk(); + 87▕ $response->assertJson(['ok' => true]); + 88▕ $this->assertSame($studentId, $response->json('students.0.student_id')); + 89▕ } + 90▕ + + ──────────────────────────────────────────────────────────────────────────── + FAILED Tests\Feature\Api\V1\Parents\ParentAttendanceReportControllerTest… + Expected response status code [200] but received 403. +Failed asserting that 403 is identical to 200. + + at tests/Feature/Api/V1/Parents/ParentAttendanceReportControllerTest.php:113 + 109▕ $response = $this->patchJson('/api/v1/parents/attendance-reports/'.$reportId, [ + 110▕ 'reason' => 'Family emergency', + 111▕ ]); + 112▕ + ➜ 113▕ $response->assertOk(); + 114▕ $this->assertDatabaseHas('parent_attendance_reports', [ + 115▕ 'id' => $reportId, + 116▕ 'reason' => 'Family emergency', + 117▕ ]); + + ──────────────────────────────────────────────────────────────────────────── + FAILED Tests\Feature\Api\V1\Parents\ParentControllerTest > attendance re… + Expected response status code [200] but received 403. +Failed asserting that 403 is identical to 200. + + at tests/Feature/Api/V1/Parents/ParentControllerTest.php:49 + 45▕ + 46▕ Sanctum::actingAs($parent); + 47▕ $response = $this->getJson('/api/v1/parents/attendance?school_year=2025-2026'); + 48▕ + ➜ 49▕ $response->assertOk(); + 50▕ $response->assertJson(['ok' => true]); + 51▕ $response->assertJsonPath('attendance.0.status', 'absent'); + 52▕ } + 53▕ + + ──────────────────────────────────────────────────────────────────────────── + FAILED Tests\Feature\Api\V1\Parents\ParentControllerTest > registration… + Expected response status code [201] but received 403. +Failed asserting that 403 is identical to 201. + + at tests/Feature/Api/V1/Parents/ParentControllerTest.php:86 + 82▕ ]; + 83▕ + 84▕ $response = $this->postJson('/api/v1/parents/registration', $payload); + 85▕ + ➜ 86▕ $response->assertStatus(201); + 87▕ $response->assertJson(['ok' => true]); + 88▕ $this->assertDatabaseHas('students', ['firstname' => 'Sara', 'parent_id' => $parent->id]); + 89▕ $this->assertDatabaseHas('emergency_contacts', ['parent_id' => $parent->id, 'emergency_contact_name' => 'John Parent']); + 90▕ } + + ──────────────────────────────────────────────────────────────────────────── + FAILED Tests\Feature\Api\V1\Roles\RolePermissionControllerTest > store r… + Expected response status code [500] but received 404. +Failed asserting that 404 is identical to 500. + +The following exception occurred during the last request: + +TypeError: App\Http\Controllers\Api\Auth\RolePermissionController::__construct(): Argument #4 ($roleCrudService) must be of type App\Services\Roles\RoleCrudService, class@anonymous given, called in /Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Container/Container.php on line 1168 and defined in /Volumes/ExternalApps/repos/alrahma_sunday_school_api/app/Http/Controllers/Api/Auth/RolePermissionController.php:35 +Stack trace: +#0 /Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Container/Container.php(1168): App\Http\Controllers\Api\Auth\RolePermissionController->__construct(Object(App\Services\Roles\RoleQueryService), Object(App\Services\Roles\RoleAssignmentService), Object(App\Services\Roles\RolePermissionService), Object(class@anonymous), Object(App\Services\Roles\PermissionCrudService)) +#1 /Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Container/Container.php(933): Illuminate\Container\Container->build('App\\Http\\Contro...') +#2 /Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Foundation/Application.php(1078): Illuminate\Container\Container->resolve('App\\Http\\Contro...', Array, true) +#3 /Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Container/Container.php(864): Illuminate\Foundation\Application->resolve('App\\Http\\Contro...', Array) +#4 /Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Foundation/Application.php(1058): Illuminate\Container\Container->make('App\\Http\\Contro...', Array) +#5 /Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Routing/Route.php(286): Illuminate\Foundation\Application->make('App\\Http\\Contro...') +#6 /Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Routing/Route.php(1133): Illuminate\Routing\Route->getController() +#7 /Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Routing/Route.php(1062): Illuminate\Routing\Route->controllerMiddleware() +#8 /Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Routing/Router.php(834): Illuminate\Routing\Route->gatherMiddleware() +#9 /Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Routing/Router.php(816): Illuminate\Routing\Router->gatherRouteMiddleware(Object(Illuminate\Routing\Route)) +#10 /Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Routing/Router.php(800): Illuminate\Routing\Router->runRouteWithinStack(Object(Illuminate\Routing\Route), Object(Illuminate\Http\Request)) +#11 /Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Routing/Router.php(764): Illuminate\Routing\Router->runRoute(Object(Illuminate\Http\Request), Object(Illuminate\Routing\Route)) +#12 /Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Routing/Router.php(753): Illuminate\Routing\Router->dispatchToRoute(Object(Illuminate\Http\Request)) +#13 /Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php(200): Illuminate\Routing\Router->dispatch(Object(Illuminate\Http\Request)) +#14 /Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(180): Illuminate\Foundation\Http\Kernel->{closure:Illuminate\Foundation\Http\Kernel::dispatchToRouter():197}(Object(Illuminate\Http\Request)) +#15 /Volumes/ExternalApps/repos/alrahma_sunday_school_api/app/Http/Middleware/SecurityHeaders.php(22): Illuminate\Pipeline\Pipeline->{closure:Illuminate\Pipeline\Pipeline::prepareDestination():178}(Object(Illuminate\Http\Request)) +#16 /Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(219): App\Http\Middleware\SecurityHeaders->handle(Object(Illuminate\Http\Request), Object(Closure)) +#17 /Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/TransformsRequest.php(21): Illuminate\Pipeline\Pipeline->{closure:{closure:Illuminate\Pipeline\Pipeline::carry():194}:195}(Object(Illuminate\Http\Request)) +#18 /Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/ConvertEmptyStringsToNull.php(31): Illuminate\Foundation\Http\Middleware\TransformsRequest->handle(Object(Illuminate\Http\Request), Object(Closure)) +#19 /Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(219): Illuminate\Foundation\Http\Middleware\ConvertEmptyStringsToNull->handle(Object(Illuminate\Http\Request), Object(Closure)) +#20 /Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/TransformsRequest.php(21): Illuminate\Pipeline\Pipeline->{closure:{closure:Illuminate\Pipeline\Pipeline::carry():194}:195}(Object(Illuminate\Http\Request)) +#21 /Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/TrimStrings.php(51): Illuminate\Foundation\Http\Middleware\TransformsRequest->handle(Object(Illuminate\Http\Request), Object(Closure)) +#22 /Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(219): Illuminate\Foundation\Http\Middleware\TrimStrings->handle(Object(Illuminate\Http\Request), Object(Closure)) +#23 /Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Http/Middleware/ValidatePostSize.php(27): Illuminate\Pipeline\Pipeline->{closure:{closure:Illuminate\Pipeline\Pipeline::carry():194}:195}(Object(Illuminate\Http\Request)) +#24 /Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(219): Illuminate\Http\Middleware\ValidatePostSize->handle(Object(Illuminate\Http\Request), Object(Closure)) +#25 /Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/PreventRequestsDuringMaintenance.php(109): Illuminate\Pipeline\Pipeline->{closure:{closure:Illuminate\Pipeline\Pipeline::carry():194}:195}(Object(Illuminate\Http\Request)) +#26 /Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(219): Illuminate\Foundation\Http\Middleware\PreventRequestsDuringMaintenance->handle(Object(Illuminate\Http\Request), Object(Closure)) +#27 /Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Http/Middleware/HandleCors.php(74): Illuminate\Pipeline\Pipeline->{closure:{closure:Illuminate\Pipeline\Pipeline::carry():194}:195}(Object(Illuminate\Http\Request)) +#28 /Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(219): Illuminate\Http\Middleware\HandleCors->handle(Object(Illuminate\Http\Request), Object(Closure)) +#29 /Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Http/Middleware/TrustProxies.php(58): Illuminate\Pipeline\Pipeline->{closure:{closure:Illuminate\Pipeline\Pipeline::carry():194}:195}(Object(Illuminate\Http\Request)) +#30 /Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(219): Illuminate\Http\Middleware\TrustProxies->handle(Object(Illuminate\Http\Request), Object(Closure)) +#31 /Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/InvokeDeferredCallbacks.php(22): Illuminate\Pipeline\Pipeline->{closure:{closure:Illuminate\Pipeline\Pipeline::carry():194}:195}(Object(Illuminate\Http\Request)) +#32 /Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(219): Illuminate\Foundation\Http\Middleware\InvokeDeferredCallbacks->handle(Object(Illuminate\Http\Request), Object(Closure)) +#33 /Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Http/Middleware/ValidatePathEncoding.php(26): Illuminate\Pipeline\Pipeline->{closure:{closure:Illuminate\Pipeline\Pipeline::carry():194}:195}(Object(Illuminate\Http\Request)) +#34 /Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(219): Illuminate\Http\Middleware\ValidatePathEncoding->handle(Object(Illuminate\Http\Request), Object(Closure)) +#35 /Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(137): Illuminate\Pipeline\Pipeline->{closure:{closure:Illuminate\Pipeline\Pipeline::carry():194}:195}(Object(Illuminate\Http\Request)) +#36 /Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php(175): Illuminate\Pipeline\Pipeline->then(Object(Closure)) +#37 /Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php(144): Illuminate\Foundation\Http\Kernel->sendRequestThroughRouter(Object(Illuminate\Http\Request)) +#38 /Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Foundation/Testing/Concerns/MakesHttpRequests.php(607): Illuminate\Foundation\Http\Kernel->handle(Object(Illuminate\Http\Request)) +#39 /Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Foundation/Testing/Concerns/MakesHttpRequests.php(573): Illuminate\Foundation\Testing\TestCase->call('POST', '/api/v1/role-pe...', Array, Array, Array, Array, '{"name":"admin"...') +#40 /Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Foundation/Testing/Concerns/MakesHttpRequests.php(411): Illuminate\Foundation\Testing\TestCase->json('POST', '/api/v1/role-pe...', Array, Array, 0) +#41 /Volumes/ExternalApps/repos/alrahma_sunday_school_api/tests/Feature/Api/V1/Roles/RolePermissionControllerTest.php(184): Illuminate\Foundation\Testing\TestCase->postJson('/api/v1/role-pe...', Array) +#42 /Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/phpunit/phpunit/src/Framework/TestCase.php(1667): Tests\Feature\Api\V1\Roles\RolePermissionControllerTest->test_store_role_returns_error_on_service_exception() +#43 /Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/phpunit/phpunit/src/Framework/TestCase.php(519): PHPUnit\Framework\TestCase->runTest() +#44 /Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/phpunit/phpunit/src/Framework/TestRunner/TestRunner.php(87): PHPUnit\Framework\TestCase->runBare() +#45 /Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/phpunit/phpunit/src/Framework/TestCase.php(365): PHPUnit\Framework\TestRunner->run(Object(Tests\Feature\Api\V1\Roles\RolePermissionControllerTest)) +#46 /Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/phpunit/phpunit/src/Framework/TestSuite.php(369): PHPUnit\Framework\TestCase->run() +#47 /Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/phpunit/phpunit/src/Framework/TestSuite.php(369): PHPUnit\Framework\TestSuite->run() +#48 /Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/phpunit/phpunit/src/Framework/TestSuite.php(369): PHPUnit\Framework\TestSuite->run() +#49 /Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/phpunit/phpunit/src/TextUI/TestRunner.php(64): PHPUnit\Framework\TestSuite->run() +#50 /Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/phpunit/phpunit/src/TextUI/Application.php(211): PHPUnit\TextUI\TestRunner->run(Object(PHPUnit\TextUI\Configuration\Configuration), Object(PHPUnit\Runner\ResultCache\DefaultResultCache), Object(PHPUnit\Framework\TestSuite)) +#51 /Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/phpunit/phpunit/phpunit(104): PHPUnit\TextUI\Application->run(Array) +#52 {main} + +---------------------------------------------------------------------------------- + +App\Http\Controllers\Api\Auth\RolePermissionController::__construct(): Argument #4 ($roleCrudService) must be of type App\Services\Roles\RoleCrudService, class@anonymous given, called in /Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Container/Container.php on line 1168 + + at tests/Feature/Api/V1/Roles/RolePermissionControllerTest.php:193 + 189▕ 'priority' => 1, + 190▕ 'is_active' => 1, + 191▕ ]); + 192▕ + ➜ 193▕ $response->assertStatus(500); + 194▕ $response->assertJsonPath('status', false); + 195▕ } + 196▕ + 197▕ public function test_requires_authentication(): void + + ──────────────────────────────────────────────────────────────────────────── + FAILED Tests\Feature\Api\V1\SchoolYears\SchoolYearControllerTest > previ… + Expected response status code [200] but received 403. +Failed asserting that 403 is identical to 200. + + at tests/Feature/Api/V1/SchoolYears/SchoolYearControllerTest.php:29 + 25▕ ], + 26▕ 'transfer_unpaid_balances' => true, + 27▕ ]); + 28▕ + ➜ 29▕ $response->assertOk() + 30▕ ->assertJsonPath('data.validation.can_close', true) + 31▕ ->assertJsonPath('data.promotion_preview.summary.promote', 1) + 32▕ ->assertJsonPath('data.parent_balances.summary.total_old_unpaid_balance', 200); + 33▕ + + ──────────────────────────────────────────────────────────────────────────── + FAILED Tests\Feature\Api\V1\SchoolYears\SchoolYearControllerTest > admin… + Expected response status code [201] but received 403. +Failed asserting that 403 is identical to 201. + + at tests/Feature/Api/V1/SchoolYears/SchoolYearControllerTest.php:87 + 83▕ 'start_date' => '2026-09-01', + 84▕ 'end_date' => '2027-06-30', + 85▕ ]); + 86▕ + ➜ 87▕ $response->assertCreated() + 88▕ ->assertJsonPath('data.name', '2026-2027') + 89▕ ->assertJsonPath('data.status', 'draft'); + 90▕ + 91▕ $this->assertDatabaseHas('school_years', [ + + ──────────────────────────────────────────────────────────────────────────── + FAILED Tests\Feature\Api\V1\SchoolYears\SchoolYearControllerTest > admin… + Expected response status code [200] but received 403. +Failed asserting that 403 is identical to 200. + + at tests/Feature/Api/V1/SchoolYears/SchoolYearControllerTest.php:120 + 116▕ 'start_date' => '2028-09-01', + 117▕ 'end_date' => '2029-06-30', + 118▕ ]); + 119▕ + ➜ 120▕ $response->assertOk() + 121▕ ->assertJsonPath('data.name', '2028-2029') + 122▕ ->assertJsonPath('data.start_date', '2028-09-01'); + 123▕ + 124▕ $this->assertDatabaseHas('school_years', [ + + ──────────────────────────────────────────────────────────────────────────── + FAILED Tests\Feature\Api\V1\SchoolYears\SchoolYearControllerTest > close… + Expected response status code [200] but received 403. +Failed asserting that 403 is identical to 200. + + at tests/Feature/Api/V1/SchoolYears/SchoolYearControllerTest.php:148 + 144▕ 'transfer_unpaid_balances' => true, + 145▕ 'confirmation' => 'CLOSE 2025-2026', + 146▕ ]); + 147▕ + ➜ 148▕ $response->assertOk() + 149▕ ->assertJsonPath('data.closed_school_year.status', 'closed') + 150▕ ->assertJsonPath('data.new_school_year.status', 'active'); + 151▕ + 152▕ $this->assertDatabaseHas('school_years', [ + + ──────────────────────────────────────────────────────────────────────────── + FAILED Tests\Feature\Api\V1\SchoolYears\SchoolYearControllerTest > close… + Expected response status code [200] but received 403. +Failed asserting that 403 is identical to 200. + + at tests/Feature/Api/V1/SchoolYears/SchoolYearControllerTest.php:207 + 203▕ 'end_date' => '2027-06-30', + 204▕ ], + 205▕ 'transfer_unpaid_balances' => true, + 206▕ 'confirmation' => 'CLOSE 2025-2026', + ➜ 207▕ ])->assertOk(); + 208▕ + 209▕ $response = $this->postJson('/api/v1/finance/invoices/generate', [ + 210▕ 'parent_id' => 10, + 211▕ 'school_year' => '2025-2026', + + ──────────────────────────────────────────────────────────────────────────── + FAILED Tests\Feature\Api\V1\Settings\PreferencesControllerTest > show re… + Expected response status code [200] but received 401. +Failed asserting that 401 is identical to 200. + + at tests/Feature/Api/V1/Settings/PreferencesControllerTest.php:22 + 18▕ Sanctum::actingAs($user); + 19▕ + 20▕ $response = $this->getJson('/api/v1/preferences'); + 21▕ + ➜ 22▕ $response->assertOk(); + 23▕ $response->assertJsonPath('data.preferences.receive_email_notifications', true); + 24▕ $response->assertJsonStructure(['data' => ['options' => ['style_options', 'menu_options']]]); + 25▕ } + 26▕ + + ──────────────────────────────────────────────────────────────────────────── + FAILED Tests\Feature\Api\V1\Settings\PreferencesControllerTest > store c… + Expected response status code [200] but received 401. +Failed asserting that 401 is identical to 200. + + at tests/Feature/Api/V1/Settings/PreferencesControllerTest.php:41 + 37▕ 'style_color' => 'blue', + 38▕ 'menu_color' => 'white', + 39▕ ]); + 40▕ + ➜ 41▕ $response->assertOk(); + 42▕ $this->assertDatabaseHas('user_preferences', [ + 43▕ 'user_id' => $user->id, + 44▕ 'notification_email' => 1, + 45▕ 'notification_sms' => 0, + + ──────────────────────────────────────────────────────────────────────────── + FAILED Tests\Feature\Api\V1\Settings\PreferencesControllerTest > list re… + Expected response status code [403] but received 401. +Failed asserting that 401 is identical to 403. + + at tests/Feature/Api/V1/Settings/PreferencesControllerTest.php:56 + 52▕ Sanctum::actingAs($user); + 53▕ + 54▕ $response = $this->getJson('/api/v1/preferences/list'); + 55▕ + ➜ 56▕ $response->assertForbidden(); + 57▕ } + 58▕ + 59▕ public function test_list_returns_rows_for_admin(): void + 60▕ { + + ──────────────────────────────────────────────────────────────────────────── + FAILED Tests\Feature\Api\V1\Settings\PreferencesControllerTest > list re… + Expected response status code [200] but received 401. +Failed asserting that 401 is identical to 200. + + at tests/Feature/Api/V1/Settings/PreferencesControllerTest.php:74 + 70▕ ]); + 71▕ + 72▕ $response = $this->getJson('/api/v1/preferences/list'); + 73▕ + ➜ 74▕ $response->assertOk(); + 75▕ $response->assertJsonPath('data.preferences.0.user_id', $admin->id); + 76▕ } + 77▕ + 78▕ public function test_update_for_user_by_admin(): void + + ──────────────────────────────────────────────────────────────────────────── + FAILED Tests\Feature\Api\V1\Settings\PreferencesControllerTest > update… + Expected response status code [200] but received 401. +Failed asserting that 401 is identical to 200. + + at tests/Feature/Api/V1/Settings/PreferencesControllerTest.php:88 + 84▕ $response = $this->putJson('/api/v1/preferences/2', [ + 85▕ 'receive_sms_notifications' => false, + 86▕ ]); + 87▕ + ➜ 88▕ $response->assertOk(); + 89▕ $this->assertDatabaseHas('user_preferences', [ + 90▕ 'user_id' => $user->id, + 91▕ 'notification_sms' => 0, + 92▕ ]); + + ──────────────────────────────────────────────────────────────────────────── + FAILED Tests\Feature\Api\V1\Settings\PreferencesControllerTest > destroy… + Expected response status code [403] but received 401. +Failed asserting that 401 is identical to 403. + + at tests/Feature/Api/V1/Settings/PreferencesControllerTest.php:102 + 98▕ Sanctum::actingAs($user); + 99▕ + 100▕ $response = $this->deleteJson('/api/v1/preferences/'.$user->id); + 101▕ + ➜ 102▕ $response->assertForbidden(); + 103▕ } + 104▕ + 105▕ public function test_destroy_deletes_preferences(): void + 106▕ { + + ──────────────────────────────────────────────────────────────────────────── + FAILED Tests\Feature\Api\V1\Settings\PreferencesControllerTest > destroy… + Expected response status code [200] but received 401. +Failed asserting that 401 is identical to 200. + + at tests/Feature/Api/V1/Settings/PreferencesControllerTest.php:118 + 114▕ ]); + 115▕ + 116▕ $response = $this->deleteJson('/api/v1/preferences/'.$admin->id); + 117▕ + ➜ 118▕ $response->assertOk(); + 119▕ $this->assertDatabaseMissing('user_preferences', [ + 120▕ 'user_id' => $admin->id, + 121▕ ]); + 122▕ } + + ──────────────────────────────────────────────────────────────────────────── + FAILED Tests\Feature\Api\V1\Settings\PreferencesControllerTest > store v… + Expected response status code [422] but received 401. +Failed asserting that 401 is identical to 422. + + at tests/Feature/Api/V1/Settings/PreferencesControllerTest.php:133 + 129▕ $response = $this->postJson('/api/v1/preferences', [ + 130▕ 'theme' => 'invalid', + 131▕ ]); + 132▕ + ➜ 133▕ $response->assertStatus(422); + 134▕ $response->assertJsonStructure(['message', 'errors']); + 135▕ } + 136▕ + 137▕ private function createUser(string $roleName, int $id = 1): User + + ──────────────────────────────────────────────────────────────────────────── + FAILED Tests\Feature\Api\V1\Settings\SchoolCalendarControllerTest > upda… + Expected response status code [200] but received 500. +Failed asserting that 500 is identical to 200. + + at tests/Feature/Api/V1/Settings/SchoolCalendarControllerTest.php:96 + 92▕ $response = $this->patchJson('/api/v1/settings/school-calendar/events/'.$eventId, [ + 93▕ 'title' => 'Updated Event', + 94▕ ]); + 95▕ + ➜ 96▕ $response->assertOk(); + 97▕ $response->assertJsonPath('status', true); + 98▕ $this->assertDatabaseHas('calendar_events', [ + 99▕ 'id' => $eventId, + 100▕ 'title' => 'Updated Event', + + ──────────────────────────────────────────────────────────────────────────── + FAILED Tests\Feature\Api\V1\Settings\SchoolCalendarControllerTest > stor… + Expected response status code [500] but received 404. +Failed asserting that 404 is identical to 500. + +The following exception occurred during the last request: + +TypeError: App\Http\Controllers\Api\Settings\SchoolCalendarController::__construct(): Argument #5 ($mutationService) must be of type App\Services\Settings\SchoolCalendar\SchoolCalendarMutationService, class@anonymous given, called in /Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Container/Container.php on line 1168 and defined in /Volumes/ExternalApps/repos/alrahma_sunday_school_api/app/Http/Controllers/Api/Settings/SchoolCalendarController.php:28 +Stack trace: +#0 /Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Container/Container.php(1168): App\Http\Controllers\Api\Settings\SchoolCalendarController->__construct(Object(App\Services\Settings\SchoolCalendar\SchoolCalendarContextService), Object(App\Services\Settings\SchoolCalendar\SchoolCalendarQueryService), Object(App\Services\Settings\SchoolCalendar\SchoolCalendarMeetingService), Object(App\Services\Settings\SchoolCalendar\SchoolCalendarFormatterService), Object(class@anonymous)) +#1 /Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Container/Container.php(933): Illuminate\Container\Container->build('App\\Http\\Contro...') +#2 /Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Foundation/Application.php(1078): Illuminate\Container\Container->resolve('App\\Http\\Contro...', Array, true) +#3 /Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Container/Container.php(864): Illuminate\Foundation\Application->resolve('App\\Http\\Contro...', Array) +#4 /Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Foundation/Application.php(1058): Illuminate\Container\Container->make('App\\Http\\Contro...', Array) +#5 /Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Routing/Route.php(286): Illuminate\Foundation\Application->make('App\\Http\\Contro...') +#6 /Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Routing/Route.php(1133): Illuminate\Routing\Route->getController() +#7 /Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Routing/Route.php(1062): Illuminate\Routing\Route->controllerMiddleware() +#8 /Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Routing/Router.php(834): Illuminate\Routing\Route->gatherMiddleware() +#9 /Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Routing/Router.php(816): Illuminate\Routing\Router->gatherRouteMiddleware(Object(Illuminate\Routing\Route)) +#10 /Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Routing/Router.php(800): Illuminate\Routing\Router->runRouteWithinStack(Object(Illuminate\Routing\Route), Object(Illuminate\Http\Request)) +#11 /Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Routing/Router.php(764): Illuminate\Routing\Router->runRoute(Object(Illuminate\Http\Request), Object(Illuminate\Routing\Route)) +#12 /Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Routing/Router.php(753): Illuminate\Routing\Router->dispatchToRoute(Object(Illuminate\Http\Request)) +#13 /Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php(200): Illuminate\Routing\Router->dispatch(Object(Illuminate\Http\Request)) +#14 /Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(180): Illuminate\Foundation\Http\Kernel->{closure:Illuminate\Foundation\Http\Kernel::dispatchToRouter():197}(Object(Illuminate\Http\Request)) +#15 /Volumes/ExternalApps/repos/alrahma_sunday_school_api/app/Http/Middleware/SecurityHeaders.php(22): Illuminate\Pipeline\Pipeline->{closure:Illuminate\Pipeline\Pipeline::prepareDestination():178}(Object(Illuminate\Http\Request)) +#16 /Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(219): App\Http\Middleware\SecurityHeaders->handle(Object(Illuminate\Http\Request), Object(Closure)) +#17 /Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/TransformsRequest.php(21): Illuminate\Pipeline\Pipeline->{closure:{closure:Illuminate\Pipeline\Pipeline::carry():194}:195}(Object(Illuminate\Http\Request)) +#18 /Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/ConvertEmptyStringsToNull.php(31): Illuminate\Foundation\Http\Middleware\TransformsRequest->handle(Object(Illuminate\Http\Request), Object(Closure)) +#19 /Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(219): Illuminate\Foundation\Http\Middleware\ConvertEmptyStringsToNull->handle(Object(Illuminate\Http\Request), Object(Closure)) +#20 /Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/TransformsRequest.php(21): Illuminate\Pipeline\Pipeline->{closure:{closure:Illuminate\Pipeline\Pipeline::carry():194}:195}(Object(Illuminate\Http\Request)) +#21 /Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/TrimStrings.php(51): Illuminate\Foundation\Http\Middleware\TransformsRequest->handle(Object(Illuminate\Http\Request), Object(Closure)) +#22 /Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(219): Illuminate\Foundation\Http\Middleware\TrimStrings->handle(Object(Illuminate\Http\Request), Object(Closure)) +#23 /Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Http/Middleware/ValidatePostSize.php(27): Illuminate\Pipeline\Pipeline->{closure:{closure:Illuminate\Pipeline\Pipeline::carry():194}:195}(Object(Illuminate\Http\Request)) +#24 /Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(219): Illuminate\Http\Middleware\ValidatePostSize->handle(Object(Illuminate\Http\Request), Object(Closure)) +#25 /Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/PreventRequestsDuringMaintenance.php(109): Illuminate\Pipeline\Pipeline->{closure:{closure:Illuminate\Pipeline\Pipeline::carry():194}:195}(Object(Illuminate\Http\Request)) +#26 /Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(219): Illuminate\Foundation\Http\Middleware\PreventRequestsDuringMaintenance->handle(Object(Illuminate\Http\Request), Object(Closure)) +#27 /Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Http/Middleware/HandleCors.php(74): Illuminate\Pipeline\Pipeline->{closure:{closure:Illuminate\Pipeline\Pipeline::carry():194}:195}(Object(Illuminate\Http\Request)) +#28 /Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(219): Illuminate\Http\Middleware\HandleCors->handle(Object(Illuminate\Http\Request), Object(Closure)) +#29 /Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Http/Middleware/TrustProxies.php(58): Illuminate\Pipeline\Pipeline->{closure:{closure:Illuminate\Pipeline\Pipeline::carry():194}:195}(Object(Illuminate\Http\Request)) +#30 /Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(219): Illuminate\Http\Middleware\TrustProxies->handle(Object(Illuminate\Http\Request), Object(Closure)) +#31 /Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/InvokeDeferredCallbacks.php(22): Illuminate\Pipeline\Pipeline->{closure:{closure:Illuminate\Pipeline\Pipeline::carry():194}:195}(Object(Illuminate\Http\Request)) +#32 /Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(219): Illuminate\Foundation\Http\Middleware\InvokeDeferredCallbacks->handle(Object(Illuminate\Http\Request), Object(Closure)) +#33 /Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Http/Middleware/ValidatePathEncoding.php(26): Illuminate\Pipeline\Pipeline->{closure:{closure:Illuminate\Pipeline\Pipeline::carry():194}:195}(Object(Illuminate\Http\Request)) +#34 /Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(219): Illuminate\Http\Middleware\ValidatePathEncoding->handle(Object(Illuminate\Http\Request), Object(Closure)) +#35 /Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(137): Illuminate\Pipeline\Pipeline->{closure:{closure:Illuminate\Pipeline\Pipeline::carry():194}:195}(Object(Illuminate\Http\Request)) +#36 /Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php(175): Illuminate\Pipeline\Pipeline->then(Object(Closure)) +#37 /Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php(144): Illuminate\Foundation\Http\Kernel->sendRequestThroughRouter(Object(Illuminate\Http\Request)) +#38 /Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Foundation/Testing/Concerns/MakesHttpRequests.php(607): Illuminate\Foundation\Http\Kernel->handle(Object(Illuminate\Http\Request)) +#39 /Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Foundation/Testing/Concerns/MakesHttpRequests.php(573): Illuminate\Foundation\Testing\TestCase->call('POST', '/api/v1/setting...', Array, Array, Array, Array, '{"title":"Event...') +#40 /Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Foundation/Testing/Concerns/MakesHttpRequests.php(411): Illuminate\Foundation\Testing\TestCase->json('POST', '/api/v1/setting...', Array, Array, 0) +#41 /Volumes/ExternalApps/repos/alrahma_sunday_school_api/tests/Feature/Api/V1/Settings/SchoolCalendarControllerTest.php(148): Illuminate\Foundation\Testing\TestCase->postJson('/api/v1/setting...', Array) +#42 /Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/phpunit/phpunit/src/Framework/TestCase.php(1667): Tests\Feature\Api\V1\Settings\SchoolCalendarControllerTest->test_store_returns_error_on_service_exception() +#43 /Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/phpunit/phpunit/src/Framework/TestCase.php(519): PHPUnit\Framework\TestCase->runTest() +#44 /Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/phpunit/phpunit/src/Framework/TestRunner/TestRunner.php(87): PHPUnit\Framework\TestCase->runBare() +#45 /Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/phpunit/phpunit/src/Framework/TestCase.php(365): PHPUnit\Framework\TestRunner->run(Object(Tests\Feature\Api\V1\Settings\SchoolCalendarControllerTest)) +#46 /Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/phpunit/phpunit/src/Framework/TestSuite.php(369): PHPUnit\Framework\TestCase->run() +#47 /Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/phpunit/phpunit/src/Framework/TestSuite.php(369): PHPUnit\Framework\TestSuite->run() +#48 /Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/phpunit/phpunit/src/Framework/TestSuite.php(369): PHPUnit\Framework\TestSuite->run() +#49 /Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/phpunit/phpunit/src/TextUI/TestRunner.php(64): PHPUnit\Framework\TestSuite->run() +#50 /Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/phpunit/phpunit/src/TextUI/Application.php(211): PHPUnit\TextUI\TestRunner->run(Object(PHPUnit\TextUI\Configuration\Configuration), Object(PHPUnit\Runner\ResultCache\DefaultResultCache), Object(PHPUnit\Framework\TestSuite)) +#51 /Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/phpunit/phpunit/phpunit(104): PHPUnit\TextUI\Application->run(Array) +#52 {main} + +---------------------------------------------------------------------------------- + +App\Http\Controllers\Api\Settings\SchoolCalendarController::__construct(): Argument #5 ($mutationService) must be of type App\Services\Settings\SchoolCalendar\SchoolCalendarMutationService, class@anonymous given, called in /Volumes/ExternalApps/repos/alrahma_sunday_school_api/vendor/laravel/framework/src/Illuminate/Container/Container.php on line 1168 + + at tests/Feature/Api/V1/Settings/SchoolCalendarControllerTest.php:155 + 151▕ 'semester' => 'Fall', + 152▕ 'school_year' => '2025-2026', + 153▕ ]); + 154▕ + ➜ 155▕ $response->assertStatus(500); + 156▕ $response->assertJsonPath('status', false); + 157▕ } + 158▕ + 159▕ public function test_requires_authentication(): void + + ──────────────────────────────────────────────────────────────────────────── + FAILED Tests\Feature\Api\V1\System\HealthControllerTest > health returns… + Failed asserting that an array has the key 'status'. + + at tests/Feature/Api/V1/System/HealthControllerTest.php:17 + 13▕ { + 14▕ $response = $this->getJson('/api/v1/health'); + 15▕ + 16▕ $this->assertContains($response->status(), [200, 503]); + ➜ 17▕ $response->assertJsonStructure([ + 18▕ 'status', + 19▕ 'message', + 20▕ 'data' => [ + 21▕ 'health' => [ + + ──────────────────────────────────────────────────────────────────────────── + FAILED Tests\Feature\Api\V1\System\NavBuilderControllerTest > delete rem… + Failed asserting that a row in the table [nav_items] does not match the attributes { + "id": 2 +}. + +Found similar results: [ + { + "id": 2 + } +]. + + at tests/Feature/Api/V1/System/NavBuilderControllerTest.php:129 + 125▕ + 126▕ $response = $this->actingAs($user, 'sanctum')->deleteJson("/api/v1/nav-builder/{$navId}"); + 127▕ + 128▕ $response->assertOk(); + ➜ 129▕ $this->assertDatabaseMissing('nav_items', ['id' => $navId]); + 130▕ } + 131▕ + 132▕ public function test_reorder_updates_items(): void + 133▕ { + + ──────────────────────────────────────────────────────────────────────────── + FAILED Tests\Feature\Api\V1\System\NavBuilderControllerTest > reorder up… + Failed asserting that a row in the table [nav_items] matches the attributes { + "id": 2, + "sort_order": 9 +}. + +Found similar results: [ + { + "id": 2, + "sort_order": 1 + } +]. + + at tests/Feature/Api/V1/System/NavBuilderControllerTest.php:148 + 144▕ 'orders' => [$navId => 9], + 145▕ ]); + 146▕ + 147▕ $response->assertOk(); + ➜ 148▕ $this->assertDatabaseHas('nav_items', ['id' => $navId, 'sort_order' => 9]); + 149▕ } + 150▕ } + 151▕ + + ──────────────────────────────────────────────────────────────────────────── + FAILED Tests\Feature\Api\V1\System\SchoolIdControllerTest > assign sets… + Failed asserting that 2600001 is identical to '2600001'. + + at tests/Feature/Api/V1/System/SchoolIdControllerTest.php:56 + 52▕ + 53▕ $response->assertOk(); + 54▕ $response->assertJson(['ok' => true]); + 55▕ $this->assertNotEmpty($response->json('result.school_id')); + ➜ 56▕ $this->assertSame( + 57▕ $response->json('result.school_id'), + 58▕ User::query()->findOrFail($target->id)->school_id + 59▕ ); + 60▕ } + + 1 tests/Feature/Api/V1/System/SchoolIdControllerTest.php:56 + + ──────────────────────────────────────────────────────────────────────────── + FAILED Tests\Feature\Api\V1\Whatsapp\WhatsappInviteControllerTest > send… + Expected response status code [422] but received 200. +Failed asserting that 200 is identical to 422. + + at tests/Feature/Api/V1/Whatsapp/WhatsappInviteControllerTest.php:89 + 85▕ 'school_year' => '2025-2026', + 86▕ 'semester' => 'Fall', + 87▕ ]); + 88▕ + ➜ 89▕ $response->assertStatus(422); + 90▕ $response->assertJsonPath('status', false); + 91▕ } + 92▕ + 93▕ public function test_membership_update_saves_record(): void + + ──────────────────────────────────────────────────────────────────────────── + FAILED Tests\Feature\Api\V1\Workflows\ScenarioAFamilyEnrollmentTest > ad… + Expected response status code [200] but received 403. +Failed asserting that 403 is identical to 200. + + at tests/Feature/Api/V1/Workflows/ScenarioAFamilyEnrollmentTest.php:58 + 54▕ + 55▕ // Teacher sees student in roster. + 56▕ $this->actingAs($teacher, 'api'); + 57▕ $this->getJson('/api/v1/teachers/classes?class_section_id='.$classSectionId) + ➜ 58▕ ->assertOk() + 59▕ ->assertJsonPath('ok', true); + 60▕ + 61▕ $studentIds = array_column($this->getJson('/api/v1/teachers/classes?class_section_id='.$classSectionId)->json('students'), 'student_id'); + 62▕ $this->assertContains($studentId, $studentIds); + + ──────────────────────────────────────────────────────────────────────────── + FAILED Tests\Feature\Api\V1\Workflows\ScenarioAFamilyEnrollmentTest > pa… + Expected response status code [404] but received 403. +Failed asserting that 403 is identical to 404. + + at tests/Feature/Api/V1/Workflows/ScenarioAFamilyEnrollmentTest.php:97 + 93▕ 'firstname' => 'Hacked', + 94▕ 'lastname' => 'Child', + 95▕ 'dob' => '2015-01-01', + 96▕ 'gender' => 'Male', + ➜ 97▕ ])->assertNotFound(); + 98▕ + 99▕ $this->assertDatabaseHas('students', [ + 100▕ 'id' => $studentB, + 101▕ 'firstname' => 'Other', + + ──────────────────────────────────────────────────────────────────────────── + FAILED Tests\Feature\Api\V1\Workflows\ScenarioBSundaySchoolDayTest > tea… + Expected response status code [200] but received 422. +Failed asserting that 422 is identical to 200. + + at tests/Feature/Api/V1/Workflows/ScenarioBSundaySchoolDayTest.php:31 + 27▕ + 28▕ $this->actingAs($teacher, 'api'); + 29▕ + 30▕ $form = $this->getJson('/api/v1/attendance/teacher/form?class_section_id='.$classSectionId) + ➜ 31▕ ->assertOk(); + 32▕ + 33▕ $date = (string) ($form->json('data.current_sunday') ?? '2025-10-05'); + 34▕ $submit = $this->postJson('/api/v1/attendance/teacher/submit', [ + 35▕ 'class_section_id' => $classSectionId, + + ──────────────────────────────────────────────────────────────────────────── + FAILED Tests\Feature\Api\V1\Workflows\ScenarioKParentSelfServiceAndPriva… + Expected response status code [404] but received 403. +Failed asserting that 403 is identical to 404. + + at tests/Feature/Api/V1/Workflows/ScenarioKParentSelfServiceAndPrivacyTest.php:131 + 127▕ 'firstname' => 'Tampered', + 128▕ 'lastname' => 'Student', + 129▕ 'dob' => '2015-01-01', + 130▕ 'gender' => 'Male', + ➜ 131▕ ])->assertNotFound(); + 132▕ + 133▕ $this->patchJson('/api/v1/parents/emergency-contacts/'.$foreignContactId, [ + 134▕ 'name' => 'Tampered Contact', + 135▕ 'cellphone' => '5553334444', + + ──────────────────────────────────────────────────────────────────────────── + FAILED Tests\Feature\Api\V1\Workflows\ScenarioLTeacherAcademicOperations… + Expected response status code [201] but received 422. +Failed asserting that 422 is identical to 201. + + at tests/Feature/Api/V1/Workflows/ScenarioLTeacherAcademicOperationsTest.php:48 + 44▕ 'covered_quran' => 'Surah recitation practice', + 45▕ 'homework_islamic' => 'Read lesson notes', + 46▕ 'homework_quran' => 'Memorize assigned ayat', + 47▕ 'flags' => ['on_track'], + ➜ 48▕ ])->assertCreated()->assertJsonPath('status', true); + 49▕ + 50▕ $reportId = (int) DB::table('class_progress_reports') + 51▕ ->where('teacher_id', $teacher->id) + 52▕ ->where('class_section_id', $classSectionId) + + ──────────────────────────────────────────────────────────────────────────── + FAILED Tests\Feature\Api\V1\Workflows\ScenarioMAdministratorEnrollmentAn… + Expected response status code [200] but received 403. +Failed asserting that 403 is identical to 200. + + at tests/Feature/Api/V1/Workflows/ScenarioMAdministratorEnrollmentAndClassOperationsTest.php:89 + 85▕ ->assertJsonPath('ok', true); + 86▕ + 87▕ $this->actingAs($teacher, 'api'); + 88▕ $this->getJson('/api/v1/teachers/classes?class_section_id=909') + ➜ 89▕ ->assertOk() + 90▕ ->assertJsonPath('ok', true); + 91▕ } + 92▕ + 93▕ public function test_admin_can_reverse_roster_and_teacher_assignments_without_orphaning_records(): void + + ──────────────────────────────────────────────────────────────────────────── + FAILED Tests\Feature\Api\V1\Workflows\ScenarioNCommunicationsAndSupportL… + Failed asserting that null is identical to true. + + at tests/Feature/Api/V1/Workflows/ScenarioNCommunicationsAndSupportLifecycleTest.php:46 + 42▕ + 43▕ $this->actingAs($teacher, 'api'); + 44▕ $this->getJson('/api/v1/messages/inbox') + 45▕ ->assertOk() + ➜ 46▕ ->assertJsonPath('ok', true); + 47▕ + 48▕ $this->getJson('/api/v1/messages/'.$messageId) + 49▕ ->assertOk() + 50▕ ->assertJsonPath('ok', true); + + ──────────────────────────────────────────────────────────────────────────── + FAILED Tests\Feature\Api\V1\Workflows\ScenarioNCommunicationsAndSupportL… + Failed asserting that null is identical to true. + + at tests/Feature/Api/V1/Workflows/ScenarioNCommunicationsAndSupportLifecycleTest.php:82 + 78▕ + 79▕ $this->actingAs($admin, 'api'); + 80▕ $this->getJson('/api/v1/support') + 81▕ ->assertOk() + ➜ 82▕ ->assertJsonPath('ok', true); + 83▕ + 84▕ $response = $this->postJson('/api/v1/support', [ + 85▕ 'name' => 'Internal Support Case', + 86▕ 'email' => 'internal.support@example.test', + + ──────────────────────────────────────────────────────────────────────────── + FAILED Tests\Feature\Api\V1\Workflows\ScenarioPSettingsConfigurationAndC… + Expected response status code [200] but received 404. +Failed asserting that 404 is identical to 200. + + at tests/Feature/Api/V1/Workflows/ScenarioPSettingsConfigurationAndCalendarGovernanceTest.php:113 + 109▕ $admin = $this->actingAsApiAdministrator(); + 110▕ $this->actingAs($admin, 'api'); + 111▕ + 112▕ $this->getJson('/api/v1/configuration-admin') + ➜ 113▕ ->assertOk(); + 114▕ + 115▕ $create = $this->postJson('/api/v1/configuration-admin', [ + 116▕ 'config_key' => 'e2e_guardrail_message', + 117▕ 'config_value' => 'E2E guardrail enabled', + + ──────────────────────────────────────────────────────────────────────────── + FAILED Tests\Feature\Api\V1\Workflows\ScenarioRAttendanceOperationsAndEx… + Expected response status code [>=200, <300] but received 422. +Failed asserting that false is true. + + at tests/Feature/Api/V1/Workflows/ScenarioRAttendanceOperationsAndExceptionHandlingTest.php:36 + 32▕ $this->actingAs($teacher, 'api'); + 33▕ $this->getJson('/api/v1/attendance/teacher/grid?class_section_id='.$classSectionId.'&date=2025-10-05') + 34▕ ->assertSuccessful(); + 35▕ $this->getJson('/api/v1/attendance/teacher/form?class_section_id='.$classSectionId.'&date=2025-10-05') + ➜ 36▕ ->assertSuccessful(); + 37▕ + 38▕ $submit = $this->postJson('/api/v1/attendance/teacher/submit', [ + 39▕ 'class_section_id' => $classSectionId, + 40▕ 'date' => '2025-10-05', + + ──────────────────────────────────────────────────────────────────────────── + FAILED Tests\Feature\Api\V1\Workflows\ScenarioRAttendanceOperationsAndEx… + Expected response status code [>=200, <300] but received 404. +Failed asserting that false is true. + + at tests/Feature/Api/V1/Workflows/ScenarioRAttendanceOperationsAndExceptionHandlingTest.php:130 + 126▕ ->assertSuccessful(); + 127▕ $this->getJson('/api/v1/attendance-tracking/student-case/'.$studentId) + 128▕ ->assertSuccessful(); + 129▕ $this->getJson('/api/v1/attendance-tracking/compose?student_id='.$studentId) + ➜ 130▕ ->assertSuccessful(); + 131▕ + 132▕ $note = $this->postJson('/api/v1/attendance-tracking/save-notification-note', [ + 133▕ 'student_id' => $studentId, + 134▕ 'note' => 'Parent notified about attendance pattern.', + + ──────────────────────────────────────────────────────────────────────────── + FAILED Tests\Feature\Api\V1\Workflows\ScenarioRAttendanceOperationsAndEx… + Expected response status code [201] but received 422. +Failed asserting that 422 is identical to 201. + +The following errors occurred during the last request: + +{ + "message": "Validation failed.", + "errors": { + "min_score": [ + "The min score field is required." + ], + "max_score": [ + "The max score field is required." + ], + "template_text": [ + "The template text field is required." + ] + } +} + + at tests/Feature/Api/V1/Workflows/ScenarioRAttendanceOperationsAndExceptionHandlingTest.php:151 + 147▕ 'comment' => 'E2E: arrived after first lesson.', + 148▕ 'type' => 'late', + 149▕ 'is_active' => true, + 150▕ ]); + ➜ 151▕ $create->assertCreated(); + 152▕ + 153▕ $templateId = (int) DB::table('attendance_comment_templates') + 154▕ ->where('comment', 'E2E: arrived after first lesson.') + 155▕ ->value('id'); + + ──────────────────────────────────────────────────────────────────────────── + FAILED Tests\Feature\Api\V1\Workflows\ScenarioSScoringGradingAndReportCa… + Expected response status code [>=200, <300] but received 422. +Failed asserting that false is true. + +The following errors occurred during the last request: + +{ + "message": "Validation failed.", + "errors": { + "comments": [ + "The comments field is required." + ] + } +} + + at tests/Feature/Api/V1/Workflows/ScenarioSScoringGradingAndReportCardLifecycleTest.php:70 + 66▕ 'class_section_id' => $classSectionId, + 67▕ 'school_year' => self::E2E_SCHOOL_YEAR, + 68▕ 'semester' => self::E2E_SEMESTER, + 69▕ 'comment' => 'Consistent progress across the semester.', + ➜ 70▕ ])->assertSuccessful(); + 71▕ + 72▕ $this->getJson('/api/v1/scores/overview?class_section_id='.$classSectionId.'&school_year='.self::E2E_SCHOOL_YEAR) + 73▕ ->assertSuccessful(); + 74▕ $this->getJson('/api/v1/scores/student-scores?student_id='.$studentId.'&class_section_id='.$classSectionId) + + ──────────────────────────────────────────────────────────────────────────── + FAILED Tests\Feature\Api\V1\Workflows\ScenarioSScoringGradingAndReportCa… + Expected response status code [>=200, <300] but received 422. +Failed asserting that false is true. + +The following errors occurred during the last request: + +{ + "message": "Validation failed.", + "errors": { + "semester": [ + "The semester field is required." + ] + } +} + + at tests/Feature/Api/V1/Workflows/ScenarioSScoringGradingAndReportCardLifecycleTest.php:115 + 111▕ 'locked' => false, + 112▕ ])->assertSuccessful(); + 113▕ + 114▕ $this->getJson('/api/v1/grading/below-sixty?school_year='.self::E2E_SCHOOL_YEAR) + ➜ 115▕ ->assertSuccessful(); + 116▕ $this->postJson('/api/v1/grading/below-sixty/decisions', [ + 117▕ 'student_id' => $studentId, + 118▕ 'class_section_id' => $classSectionId, + 119▕ 'decision' => 'monitor', + + ──────────────────────────────────────────────────────────────────────────── + FAILED Tests\Feature\Api\V1\Workflows\ScenarioTDocumentsPrintBadgesAndCe… + Expected response status code [>=200, <300] but received 422. +Failed asserting that false is true. + +The following errors occurred during the last request: + +{ + "status": false, + "message": "Validation failed", + "errors": { + "status": [ + "The selected status is invalid." + ] + } +} + + at tests/Feature/Api/V1/Workflows/ScenarioTDocumentsPrintBadgesAndCertificatesLifecycleTest.php:62 + 58▕ ->assertSuccessful(); + 59▕ $this->patchJson('/api/v1/print-requests/'.$requestId.'/status', [ + 60▕ 'status' => 'processing', + 61▕ 'admin_notes' => 'Queued for printing.', + ➜ 62▕ ])->assertSuccessful(); + 63▕ $this->get('/api/v1/print-requests/'.$requestId.'/file') + 64▕ ->assertSuccessful(); + 65▕ } + 66▕ } + + ──────────────────────────────────────────────────────────────────────────── + FAILED Tests\Feature\Api\V1\Workflows\ScenarioWAccessControlRolesNavigat… + Expected response status code [>=200, <300] but received 422. +Failed asserting that false is true. + +The following errors occurred during the last request: + +{ + "message": "Validation failed.", + "errors": { + "permissions": [ + "The permissions field is required." + ] + } +} + + at tests/Feature/Api/V1/Workflows/ScenarioWAccessControlRolesNavigationAndPreferencesTest.php:48 + 44▕ + 45▕ if ($permissionId > 0 && $teacherRoleId > 0) { + 46▕ $this->putJson('/api/v1/role-permissions/roles/'.$teacherRoleId.'/permissions', [ + 47▕ 'permission_ids' => [$permissionId], + ➜ 48▕ ])->assertSuccessful(); + 49▕ $this->postJson('/api/v1/role-permissions/users/'.$teacher->id.'/roles', [ + 50▕ 'role_ids' => [$teacherRoleId], + 51▕ ])->assertSuccessful(); + 52▕ } + + ──────────────────────────────────────────────────────────────────────────── + FAILED Tests\Feature\Api\V1\Workflows\ScenarioWAccessControlRolesNavigat… + Expected response status code [200] but received 403. +Failed asserting that 403 is identical to 200. + + at tests/Feature/Api/V1/Workflows/ScenarioWAccessControlRolesNavigationAndPreferencesTest.php:110 + 106▕ 'key' => 'active_role', + 107▕ 'value' => 'parent', + 108▕ ])->assertSuccessful(); + 109▕ $this->getJson('/api/v1/preferences/list') + ➜ 110▕ ->assertOk(); + 111▕ + 112▕ $this->putJson('/api/v1/preferences/'.$user->id, [ + 113▕ 'preferences' => [ + 114▕ 'theme' => 'light', + + ──────────────────────────────────────────────────────────────────────────── + FAILED Tests\Feature\Api\V1\Workflows\ScenarioXPublicKioskScannerAndVeri… + Invalid time-off notification token returned unexpected status 400. Body: TimeOff

Sorry, this link is invalid or has expired.

+Failed asserting that an array contains 400. + + at tests/Concerns/AssertsE2EApiResponses.php:23 + 19▕ * @param array $statuses + 20▕ */ + 21▕ protected function assertStatusIn(TestResponse $response, array $statuses, string $context): void + 22▕ { + ➜ 23▕ $this->assertContains( + 24▕ $response->getStatusCode(), + 25▕ $statuses, + 26▕ $context.' returned unexpected status '.$response->getStatusCode().'. Body: '.$response->getContent() + 27▕ ); + + 1 tests/Concerns/AssertsE2EApiResponses.php:23 + 2 tests/Feature/Api/V1/Workflows/ScenarioXPublicKioskScannerAndVerificationLifecycleTest.php:89 + + ──────────────────────────────────────────────────────────────────────────── + FAILED Tests\Feature\Api\V1\Workflows\ScenarioZLegacyAliasesValidationAn… + Expected response status code [422] but received 400. +Failed asserting that 400 is identical to 422. + + at tests/Feature/Api/V1/Workflows/ScenarioZLegacyAliasesValidationAndCompatibilityTest.php:101 + 97▕ + 98▕ $this->postJson('/api/v1/auth/login', [ + 99▕ 'email' => 'not-an-email', + 100▕ 'password' => '', + ➜ 101▕ ])->assertStatus(422) + 102▕ ->assertJsonStructure(['message', 'errors']); + 103▕ + 104▕ $this->postJson('/api/v1/contact', [ + 105▕ 'name' => '', + + ──────────────────────────────────────────────────────────────────────────── + FAILED Tests\Feature\Api\V1\Workflows\ScenarioZLegacyAliasesValidationAn… + Expected response status code [201, 301, 302, 303, 307, 308] but received 401. +Failed asserting that false is true. + + at tests/Feature/Api/V1/Workflows/ScenarioZLegacyAliasesValidationAndCompatibilityTest.php:136 + 132▕ + 133▕ public function test_legacy_redirects_and_non_versioned_auth_aliases_remain_available(): void + 134▕ { + 135▕ $this->get('/api/attendance-templates') + ➜ 136▕ ->assertRedirect('/api/v1/attendance-templates'); + 137▕ $this->get('/api/attendance-comment-templates') + 138▕ ->assertRedirect('/api/v1/attendance-comment-templates'); + 139▕ $this->get('/api/administrator/attendance-templates') + 140▕ ->assertRedirect('/api/v1/administrator/attendance-templates'); + + ──────────────────────────────────────────────────────────────────────────── + FAILED Tests\Feature\Api\V1\Workflows\StudentEnrollmentWorkflowTest > ad… + Expected response status code [200] but received 207. +Failed asserting that 207 is identical to 200. + + at tests/Feature/Api/V1/Workflows/StudentEnrollmentWorkflowTest.php:201 + 197▕ $this->post( + 198▕ '/api/v1/administrator/enrollment-withdrawal/update-statuses?'. + 199▕ http_build_query(['enrollment_status' => [$studentId => 'enrolled']]), + 200▕ [] + ➜ 201▕ )->assertOk(); + 202▕ + 203▕ // ...then withdraw. + 204▕ $this->post( + 205▕ '/api/v1/administrator/enrollment-withdrawal/update-statuses?'. + + ──────────────────────────────────────────────────────────────────────────── + FAILED Tests\Feature\BulkUserRoleCreationTest > it creates one thousand… + Failed asserting that 3001 is identical to 3000. + + at tests/Feature/BulkUserRoleCreationTest.php:25 + 21▕ $this->createUsersThroughApi('parent', (int) $roles['parent']->id, 1000); + 22▕ $this->createUsersThroughApi('teacher', (int) $roles['teacher']->id, 1000); + 23▕ $this->createUsersThroughApi('admin', (int) $roles['admin']->id, 1000); + 24▕ + ➜ 25▕ $this->assertSame(3000, User::query()->where('email', 'like', 'bulk_api_%')->count()); + 26▕ $this->assertSame(1000, User::query()->hasRoleName('parent')->where('email', 'like', 'bulk_api_parent_%')->count()); + 27▕ $this->assertSame(1000, User::query()->hasRoleName('teacher')->where('email', 'like', 'bulk_api_teacher_%')->count()); + 28▕ $this->assertSame(1000, User::query()->hasRoleName('admin')->where('email', 'like', 'bulk_api_admin_%')->count()); + 29▕ + + 1 tests/Feature/BulkUserRoleCreationTest.php:25 + + + Tests: 184 failed, 2 risky, 1609 passed (120956 assertions) + Duration: 92.84s + diff --git a/storage/test-logs/test-results.log b/storage/test-logs/test-results.log new file mode 100644 index 00000000..ad3b6024 --- /dev/null +++ b/storage/test-logs/test-results.log @@ -0,0 +1,1861 @@ + + FAIL Tests\Unit\ApiDocsServiceTest + ⨯ public bootstrap matches ci public flags 0.01s + ⨯ full bootstrap enables try and welcome 0.01s + + FAIL Tests\Unit\ApiLoginSecurityServiceTest + ✓ roles object map preserves role names 0.02s + ⨯ build login response includes teacher class context 0.01s + ⨯ build login response includes teacher assistant class context + + PASS Tests\Unit\AuthSessionServiceTest + ✓ sanitize redirect relative 0.01s + ✓ sanitize redirect empty + ✓ sanitize rejects protocol relative + + PASS Tests\Unit\Http\Controllers\Api\AttendanceCommentTemplateControllerTest + ✓ index returns success json 0.09s + ✓ index passes active only true 0.01s + ✓ show returns template 0.01s + ✓ store returns created response 0.01s + ✓ update returns success response 0.01s + ✓ destroy returns success response 0.02s + ✓ list data returns templates key 0.01s + + PASS Tests\Unit\Grading\ScoreValueValidatorTest + ✓ blank score remains null 0.04s + ✓ score must be inside range + ✓ status inference preserves legacy pending behavior + + PASS Tests\Unit\Listeners\DeleteUnverifiedUserListenerTest + ✓ listener invokes service 0.02s + + PASS Tests\Unit\Models\AdditionalChargeTest + ✓ scope by parent term filters status and orders desc 0.04s + ✓ mark applied updates status and invoice 0.01s + ✓ list all for term falls back to year 0.01s + ✓ list all for term filters by search query 0.01s + + PASS Tests\Unit\Models\AdminNotificationSubjectModelTest + ✓ admin relationship returns user 0.04s + ✓ timestamps are set on create 0.01s + + PASS Tests\Unit\Models\AttendanceCommentTemplateModelTest + ✓ get active templates filters and orders 0.03s + + PASS Tests\Unit\Models\AttendanceDataTest + ✓ get attendance by class and get attendance 0.02s + ✓ unreported term rows filters unreported 0.01s + ✓ get unreported absences and lates groups rows 0.01s + ✓ mark reported and notified updates flags 0.01s + + PASS Tests\Unit\Models\AttendanceDayTest + ✓ get or create draft creates once and reuses 0.28s + ✓ find by section date returns model or null 0.01s + ✓ submit sets submitted fields 0.01s + ✓ finalize is alias to submit 0.01s + ✓ publish sets published fields 0.01s + ✓ reopen sets reopen fields and status 0.01s + ✓ reopen rejects invalid status 0.01s + ✓ is finalized true for published or legacy finalized 0.01s + + FAIL Tests\Unit\Models\AttendanceEmailTemplateTest + ⨯ get template returns exact active variant when available 0.02s + ⨯ get template falls back to default when requested variant missing 0.02s + ⨯ get template ignores inactive exact variant and uses active default 0.01s + ⨯ get template returns null when no active template exists 0.01s + + PASS Tests\Unit\Models\AttendanceRecordTest + ✓ model metadata is converted + ✓ model class loads + + PASS Tests\Unit\Models\AttendanceTrackingTest + ✓ model metadata is converted + ✓ model class loads + + PASS Tests\Unit\Models\AuthorizedUserTest + ✓ model metadata is converted + ✓ model class loads + + PASS Tests\Unit\Models\BadgePrintLogTest + ✓ model metadata is converted + ✓ model class loads + + PASS Tests\Unit\Models\CalendarTest + ✓ model metadata is converted + ✓ model class loads + + FAIL Tests\Unit\Models\ClassPrepAdjustmentTest + ⨯ model metadata is converted + ✓ model class loads + + FAIL Tests\Unit\Models\ClassPreparationLogTest + ⨯ model metadata is converted + ✓ model class loads + + PASS Tests\Unit\Models\ClassProgressAttachmentTest + ✓ model metadata is converted + ✓ model class loads + + PASS Tests\Unit\Models\ClassProgressReportTest + ✓ model metadata is converted + ✓ model class loads + + PASS Tests\Unit\Models\ClassSectionTest + ✓ model metadata is converted + ✓ model class loads + + PASS Tests\Unit\Models\ClassTest + ✓ model metadata is converted + ✓ model class loads + + FAIL Tests\Unit\Models\CommunicationLogTest + ⨯ model metadata is converted + ✓ model class loads + + PASS Tests\Unit\Models\CompetitionClassWinnerTest + ✓ model metadata is converted + ✓ model class loads + + PASS Tests\Unit\Models\CompetitionScoreTest + ✓ model metadata is converted + ✓ model class loads + + PASS Tests\Unit\Models\CompetitionTest + ✓ model metadata is converted + ✓ model class loads + + PASS Tests\Unit\Models\CompetitionWinnerTest + ✓ model metadata is converted + ✓ model class loads + + PASS Tests\Unit\Models\ConfigurationTest + ✓ model metadata is converted + ✓ model class loads + + PASS Tests\Unit\Models\ContactUsTest + ✓ model metadata is converted + ✓ model class loads + + PASS Tests\Unit\Models\CurrentFlagTest + ✓ model metadata is converted + ✓ model class loads + + PASS Tests\Unit\Models\DiscountUsageTest + ✓ model metadata is converted + ✓ model class loads + + PASS Tests\Unit\Models\DiscountVoucherTest + ✓ model metadata is converted + ✓ model class loads + + PASS Tests\Unit\Models\EarlyDismissalSignatureTest + ✓ model metadata is converted + ✓ model class loads + + FAIL Tests\Unit\EmailTemplateTest + ⨯ get template returns exact variant when active 0.02s + ⨯ get template falls back to default variant 0.01s + ⨯ get template ignores inactive templates and can return null 0.01s + ⨯ get template prefers exact variant over default 0.01s + + PASS Tests\Unit\Models\EmergencyContactTest + ✓ model metadata is converted + ✓ model class loads + + PASS Tests\Unit\Models\EnrollmentTest + ✓ model metadata is converted + ✓ model class loads + + FAIL Tests\Unit\Models\EventChargesTest + ⨯ model metadata is converted + ✓ model class loads + + PASS Tests\Unit\Models\EventTest + ✓ model metadata is converted + ✓ model class loads + + PASS Tests\Unit\Models\ExamDraftTest + ✓ model metadata is converted + ✓ model class loads + + FAIL Tests\Unit\Models\ExamTest + ⨯ model metadata is converted + ✓ model class loads + + PASS Tests\Unit\Models\ExpenseTest + ✓ model metadata is converted + ✓ model class loads + + PASS Tests\Unit\Models\FamilyCommPrefTest + ✓ model metadata is converted + ✓ model class loads + + PASS Tests\Unit\Models\FamilyGuardianTest + ✓ model metadata is converted + ✓ model class loads + + PASS Tests\Unit\Models\FamilyStudentTest + ✓ model metadata is converted + ✓ model class loads + + PASS Tests\Unit\Models\FamilyTest + ✓ model metadata is converted + ✓ model class loads + + FAIL Tests\Unit\Models\FinalExamTest + ⨯ model metadata is converted + ✓ model class loads + + PASS Tests\Unit\Models\FinalScoreTest + ✓ model metadata is converted + ✓ model class loads + + PASS Tests\Unit\Models\GradingLockTest + ✓ model metadata is converted + ✓ model class loads + + FAIL Tests\Unit\Models\HomeworkTest + ⨯ model metadata is converted + ✓ model class loads + + PASS Tests\Unit\Models\IncidentTest + ✓ model metadata is converted + ✓ model class loads + + PASS Tests\Unit\Models\InventoryCategoryTest + ✓ model metadata is converted + ✓ model class loads + + PASS Tests\Unit\Models\InventoryItemTest + ✓ model metadata is converted + ✓ model class loads + + PASS Tests\Unit\Models\InventoryMovementTest + ✓ model metadata is converted + ✓ model class loads + + PASS Tests\Unit\Models\InvoiceEventTest + ✓ model metadata is converted + ✓ model class loads + + PASS Tests\Unit\Models\InvoiceStudentListTest + ✓ model metadata is converted + ✓ model class loads + + FAIL Tests\Unit\Models\InvoiceTest + ⨯ model metadata is converted + ✓ model class loads + + PASS Tests\Unit\Models\IpAttemptTest + ✓ model metadata is converted + ✓ model class loads + + PASS Tests\Unit\Models\LateSlipLogTest + ✓ model metadata is converted + ✓ model class loads + + PASS Tests\Unit\Models\LoginActivityTest + ✓ model metadata is converted + ✓ model class loads + + PASS Tests\Unit\Models\ManualPaymentTest + ✓ model metadata is converted + ✓ model class loads + + PASS Tests\Unit\Models\MessageTest + ✓ model metadata is converted + ✓ model class loads + + FAIL Tests\Unit\Models\MidtermExamTest + ⨯ model metadata is converted + ✓ model class loads + + PASS Tests\Unit\Models\MissingScoreOverrideTest + ✓ model metadata is converted + ✓ model class loads + + PASS Tests\Unit\Models\NavItemTest + ✓ model metadata is converted + ✓ model class loads + + PASS Tests\Unit\Models\NotificationTest + ✓ model metadata is converted + ✓ model class loads + + PASS Tests\Unit\Models\ParentAttendanceReportTest + ✓ model metadata is converted + ✓ model class loads + + PASS Tests\Unit\Models\ParentMeetingScheduleTest + ✓ model metadata is converted + ✓ model class loads + + PASS Tests\Unit\Models\ParentNotificationTest + ✓ model metadata is converted + ✓ model class loads + + PASS Tests\Unit\Models\ParentTest + ✓ model metadata is converted + ✓ model class loads + + FAIL Tests\Unit\Models\ParticipationTest + ⨯ model metadata is converted + ✓ model class loads + + FAIL Tests\Unit\Models\PasswordResetRequestTest + ⨯ model metadata is converted + ✓ model class loads + + FAIL Tests\Unit\Models\PasswordResetTest + ⨯ model metadata is converted + ✓ model class loads + + FAIL Tests\Unit\Models\PayPalPaymentTest + ⨯ model metadata is converted + ✓ model class loads + + PASS Tests\Unit\Models\PaymentErrorTest + ✓ model metadata is converted + ✓ model class loads + + PASS Tests\Unit\Models\PaymentNotificationLogTest + ✓ model metadata is converted + ✓ model class loads + + FAIL Tests\Unit\Models\PaymentTest + ⨯ model metadata is converted + ✓ model class loads + + PASS Tests\Unit\Models\PaymentTransactionTest + ✓ model metadata is converted + ✓ model class loads + + PASS Tests\Unit\Models\PaypalTransactionTest + ✓ model metadata is converted + ✓ model class loads + + PASS Tests\Unit\Models\PermissionTest + ✓ model metadata is converted + ✓ model class loads + + PASS Tests\Unit\Models\PlacementBatchTest + ✓ model metadata is converted + ✓ model class loads + + PASS Tests\Unit\Models\PlacementLevelTest + ✓ model metadata is converted + ✓ model class loads + + PASS Tests\Unit\Models\PlacementScoreTest + ✓ model metadata is converted + ✓ model class loads + + PASS Tests\Unit\Models\PreferencesTest + ✓ model metadata is converted + ✓ model class loads + + PASS Tests\Unit\Models\PrintRequestTest + ✓ model metadata is converted + ✓ model class loads + + PASS Tests\Unit\Models\ProjectTest + ✓ model metadata is converted + ✓ model class loads + + PASS Tests\Unit\Models\PromotionQueueTest + ✓ model metadata is converted + ✓ model class loads + + FAIL Tests\Unit\Models\PurchaseOrderItemTest + ⨯ model metadata is converted + ✓ model class loads + + PASS Tests\Unit\Models\PurchaseOrderTest + ✓ model metadata is converted + ✓ model class loads + + FAIL Tests\Unit\Models\QuizTest + ⨯ model metadata is converted + ✓ model class loads + + PASS Tests\Unit\Models\RefundTest + ✓ model metadata is converted + ✓ model class loads + + PASS Tests\Unit\Models\ReimbursementBatchAdminFileTest + ✓ model metadata is converted + ✓ model class loads + + PASS Tests\Unit\Models\ReimbursementBatchItemTest + ✓ model metadata is converted + ✓ model class loads + + PASS Tests\Unit\Models\ReimbursementBatchTest + ✓ model metadata is converted + ✓ model class loads + + PASS Tests\Unit\Models\ReimbursementTest + ✓ model metadata is converted + ✓ model class loads + + PASS Tests\Unit\Models\RoleNavItemTest + ✓ model metadata is converted + ✓ model class loads + + PASS Tests\Unit\Models\RolePermissionTest + ✓ model metadata is converted + ✓ model class loads + + PASS Tests\Unit\Models\RoleTest + ✓ model metadata is converted + ✓ model class loads + + FAIL Tests\Unit\Models\ScoreCommentTest + ⨯ model metadata is converted + ✓ model class loads + + FAIL Tests\Unit\Models\SectionTest + ⨯ model metadata is converted + ✓ model class loads + + PASS Tests\Unit\Models\SemesterScoreTest + ✓ model metadata is converted + ✓ model class loads + + PASS Tests\Unit\Models\SettingsTest + ✓ model metadata is converted + ✓ model class loads + + PASS Tests\Unit\Models\StaffAttendanceTest + ✓ model metadata is converted + ✓ model class loads + + FAIL Tests\Unit\Models\StaffTest + ⨯ model metadata is converted + ✓ model class loads + + PASS Tests\Unit\Models\StatsTest + ✓ model metadata is converted + ✓ model class loads + + PASS Tests\Unit\Models\StudentAllergyTest + ✓ model metadata is converted + ✓ model class loads + + PASS Tests\Unit\Models\StudentClassTest + ✓ model metadata is converted + ✓ model class loads + + PASS Tests\Unit\Models\StudentMedicalConditionTest + ✓ model metadata is converted + ✓ model class loads + + PASS Tests\Unit\Models\StudentTest + ✓ model metadata is converted + ✓ model class loads + + PASS Tests\Unit\Models\SubjectCurriculumTest + ✓ model metadata is converted + ✓ model class loads + + PASS Tests\Unit\Models\TeacherClassTest + ✓ model metadata is converted + ✓ model class loads + + PASS Tests\Unit\Models\TeacherSubmissionNotificationHistoryTest + ✓ model metadata is converted + ✓ model class loads + + FAIL Tests\Unit\Models\TeacherTest + ⨯ model metadata is converted + ✓ model class loads + + PASS Tests\Unit\Models\UserNotificationTest + ✓ model metadata is converted + ✓ model class loads + + PASS Tests\Unit\Models\UserRoleTest + ✓ model metadata is converted + ✓ model class loads + + FAIL Tests\Unit\Models\UserTest + ⨯ model metadata is converted + ✓ model class loads + ✓ password mutator preserves pbkdf2 hashes 0.62s + + PASS Tests\Unit\Models\WhatsappGroupLinkTest + ✓ model metadata is converted + ✓ model class loads + + PASS Tests\Unit\Models\WhatsappGroupMembershipTest + ✓ model metadata is converted + ✓ model class loads + + PASS Tests\Unit\Models\WhatsappInviteLogTest + ✓ model metadata is converted + ✓ model class loads + + PASS Tests\Unit\Http\Requests\AttendanceCommentTemplate\StoreAttendanceCommentTemplateRequestTest + ✓ rules pass with valid data 0.01s + ✓ rules fail when required fields missing 0.01s + ✓ rules fail when max score less than min score 0.01s + ✓ rules fail when score out of range 0.01s + + PASS Tests\Unit\Http\Requests\AttendanceCommentTemplate\UpdateAttendanceCommentTemplateRequestTest + ✓ rules pass with partial valid data 0.01s + ✓ rules pass when both scores valid 0.01s + ✓ rules fail when both scores invalid relation 0.01s + ✓ rules fail on invalid boolean 0.01s + + PASS Tests\Unit\Resources\ClassProgress\ClassProgressReportResourceTest + ✓ resource has expected keys 0.02s + + PASS Tests\Unit\Resources\Frontend\FrontendPageResourceTest + ✓ resource returns page 0.01s + + PASS Tests\Unit\Resources\Frontend\PageContentResourceTest + ✓ resource returns content 0.01s + + FAIL Tests\Unit\Resources\Messaging\MessageResourceTest + ⨯ resource returns expected shape 0.02s + + PASS Tests\Unit\Resources\Messaging\RecipientResourceTest + ✓ resource returns expected shape 0.02s + + PASS Tests\Unit\Resources\Notifications\NotificationResourceTest + ✓ resource returns expected shape 0.02s + + PASS Tests\Unit\Resources\Notifications\UserNotificationResourceTest + ✓ resource returns expected shape 0.01s + + PASS Tests\Unit\Resources\Roles\PermissionResourceTest + ✓ resource shape 0.02s + + PASS Tests\Unit\Resources\Roles\RolePermissionResourceTest + ✓ resource shape 0.01s + + PASS Tests\Unit\Resources\Roles\RoleResourceTest + ✓ resource shape 0.01s + + PASS Tests\Unit\Resources\Roles\UserWithRolesResourceTest + ✓ resource shape 0.02s + + PASS Tests\Unit\Resources\Settings\SchoolCalendarEventResourceTest + ✓ resource returns expected shape 0.01s + + PASS Tests\Unit\Resources\Settings\SettingsResourceTest + ✓ resource returns expected shape 0.01s + + FAIL Tests\Unit\Resources\Staff\StaffResourceTest + ⨯ resource returns expected shape 0.01s + + PASS Tests\Unit\Resources\Support\ContactMessageResourceTest + ✓ resource returns expected shape 0.01s + + FAIL Tests\Unit\Resources\Support\SupportRequestResourceTest + ⨯ resource returns expected shape 0.01s + + PASS Tests\Unit\Resources\Ui\UiStyleResourceTest + ✓ resource returns expected shape 0.02s + + PASS Tests\Unit\Services\Administrator\AdminNotificationSubjectServiceTest + ✓ alerts data includes admins 0.02s + + PASS Tests\Unit\Services\Administrator\AdminNotificationUserServiceTest + ✓ fetch admin notification users excludes parents 0.02s + + PASS Tests\Unit\Services\Administrator\AdminPrintRecipientServiceTest + ✓ data returns admins and assigned 0.02s + + FAIL Tests\Unit\Services\Administrator\AdministratorAbsenceServiceTest + ⨯ submit requires reason 0.02s + + PASS Tests\Unit\Services\Administrator\AdministratorDashboardServiceTest + ✓ delegates to metrics and search 0.02s + + FAIL Tests\Unit\Services\Administrator\AdministratorEnrollmentEventServiceTest + ⨯ dispatch grouped events with empty groups 0.02s + + PASS Tests\Unit\Services\Administrator\AdministratorEnrollmentQueryServiceTest + ✓ enrollment withdrawal data returns structure 0.01s + + PASS Tests\Unit\Services\Administrator\AdministratorEnrollmentRefundServiceTest + ✓ process refunds reports missing invoice 0.02s + + PASS Tests\Unit\Services\Administrator\AdministratorEnrollmentServiceTest + ✓ delegates to query and status services 0.02s + + PASS Tests\Unit\Services\Administrator\AdministratorEnrollmentStatusServiceTest + ✓ update statuses requires payload 0.01s + + PASS Tests\Unit\Services\Administrator\AdministratorMetricsServiceTest + ✓ metrics returns counts 0.01s + + PASS Tests\Unit\Services\Administrator\AdministratorNotificationServiceTest + ✓ delegates to subject and print services 0.02s + + PASS Tests\Unit\Services\Administrator\AdministratorSharedServiceTest + ✓ get previous school year 0.01s + + PASS Tests\Unit\Services\Administrator\AdministratorTeacherSubmissionServiceTest + ✓ delegates to report and notification 0.01s + + PASS Tests\Unit\Services\Administrator\AdministratorUserSearchServiceTest + ✓ empty query returns no results 0.01s + + FAIL Tests\Unit\Services\Administrator\TeacherSubmissionNotificationServiceTest + ⨯ send requires targets 0.01s + + FAIL Tests\Unit\Services\Administrator\TeacherSubmissionReportServiceTest + ⨯ report returns summary 0.01s + + PASS Tests\Unit\Services\Administrator\TeacherSubmissionSupportServiceTest + ✓ submission status labels 0.02s + ✓ build missing items 0.01s + + PASS Tests\Unit\Services\Assignment\AssignmentContextServiceTest + ✓ get current term values 0.01s + + PASS Tests\Unit\Services\Assignment\AssignmentDataLoaderServiceTest + ✓ load teacher classes includes teacher name 0.02s + ✓ load student classes filters inactive 0.01s + + PASS Tests\Unit\Services\Assignment\AssignmentMetaServiceTest + ✓ get school years uses fallback 0.01s + ✓ get school years returns distinct sorted 0.01s + ✓ first non empty returns first value 0.01s + + FAIL Tests\Unit\Services\Assignment\AssignmentSectionServiceTest + ⨯ get section names map 0.01s + + FAIL Tests\Unit\Services\AssignmentServiceTest + ✓ get current semester returns config value 0.02s + ✓ get current school year returns config value 0.02s + ⨯ get assignments overview returns grouped sections 0.02s + ✓ get assignments overview uses fallback config values when metadata… 0.01s + ✓ get assignments overview excludes inactive students 0.02s + ⨯ get assignments overview sorts sections by name 0.01s + ✓ get assignments overview collects school years descending 0.01s + ✓ store assignment creates new row 0.02s + ✓ store assignment updates existing row 0.03s + ⨯ get class assignment data returns all sections 0.02s + ✓ get class assignment data deduplicates teacher names 0.01s + + PASS Tests\Feature\Api\Attendance\AdminAttendanceApiControllerTest + ✓ daily data returns success 0.05s + + PASS Tests\Unit\Services\Attendance\AttendanceAutoPublishJobServiceTest + ✓ run publishes due records 0.01s + + PASS Tests\Unit\Services\Attendance\AttendanceAutoPublishServiceTest + ✓ second sunday after end of day 0.01s + ✓ second sunday backward date 0.01s + + PASS Tests\Unit\Services\Attendance\AttendanceCommentServiceTest + ✓ comment from score uses template and name 0.01s + ✓ comment from score falls back to this student 0.02s + + PASS Tests\Unit\Services\Attendance\AttendanceConsequenceServiceTest + ✓ send follow up requires parent email 0.03s + ✓ send follow up marks tracking and notifies 0.01s + + FAIL Tests\Unit\Services\Attendance\AttendanceDailySummaryServiceTest + ⨯ send absentees summary notifies parent 0.02s + + PASS Tests\Unit\Services\Attendance\AttendancePolicyServiceTest + ✓ teacher can edit draft 0.01s + ✓ teacher cannot edit finalized 0.01s + ✓ admin like by permission 0.01s + ✓ can manage early dismissals for teacher 0.01s + + PASS Tests\Unit\Services\Attendance\AttendanceQueryServiceTest + ✓ teacher grid returns section labels and grid 0.02s + + PASS Tests\Unit\Services\Attendance\AttendanceRecordSyncServiceTest + ✓ update attendance record adjusts totals 0.02s + ✓ add new attendance record creates row 0.01s + + FAIL Tests\Unit\Services\Attendance\AttendanceSemesterRangeServiceTest + ⨯ get semester range 0.01s + ✓ build sunday list returns sundays 0.01s + + PASS Tests\Unit\Services\Attendance\AttendanceServiceTest + ✓ update attendance management throws when locked 0.02s + ✓ update attendance management saves row 0.02s + + PASS Tests\Unit\Services\Attendance\AttendanceSummaryRebuildServiceTest + ✓ rebuild inserts summary rows 0.02s + + FAIL Tests\Unit\Services\Attendance\LateSlipLogCommandServiceTest + ⨯ delete removes log 0.01s + + FAIL Tests\Unit\Services\Attendance\LateSlipLogQueryServiceTest + ⨯ paginate filters by date 0.01s + + FAIL Tests\Unit\Services\Attendance\SemesterRangeServiceTest + ✓ normalize semester + ⨯ get school year range + ✓ build sunday list + + PASS Tests\Feature\Api\Attendance\StaffAttendanceApiControllerTest + ✓ month data returns success 0.02s + ✓ admins data returns success 0.02s + + PASS Tests\Unit\Services\Attendance\StaffAttendanceServiceTest + ✓ month data returns sections and days 0.02s + + PASS Tests\Unit\Services\Attendance\StudentAttendanceWriterServiceTest + ✓ resolve student school id from student 0.02s + ✓ save or update updates existing and syncs record 0.01s + + PASS Tests\Feature\Api\Attendance\TeacherAttendanceApiControllerTest + ✓ teacher grid endpoint returns success 0.02s + ✓ teacher form endpoint returns success or validation message 0.02s + + PASS Tests\Unit\Services\Attendance\TeacherAttendanceSubmissionServiceTest + ✓ submit requires attendance data 0.02s + + PASS Tests\Unit\Services\AttendanceManagement\AttendanceManagementServiceTest + ✓ badge scan persists school year and semester for the event date 0.02s + ✓ dashboard derives academic context for legacy rows and applies filt… 0.02s + + PASS Tests\Unit\Services\AttendanceTracking\AttendanceCaseQueryServiceTest + ✓ returns not found when student missing 0.02s + + PASS Tests\Unit\Services\AttendanceTracking\AttendanceCommunicationSupportServiceTest + ✓ compose requires student id 0.01s + ✓ get violation dates for student 0.02s + + PASS Tests\Unit\Services\AttendanceTracking\AttendanceEmailComposerServiceTest + ✓ render template replaces tokens 0.01s + ✓ pick variant fallback 0.01s + + PASS Tests\Unit\Services\AttendanceTracking\AttendanceNotificationLogServiceTest + ✓ log notification creates and updates 0.02s + + PASS Tests\Unit\Services\AttendanceTracking\AttendanceNotificationWorkflowServiceTest + ✓ record requires parent email 0.02s + + PASS Tests\Unit\Services\AttendanceTracking\AttendanceParentLookupServiceTest + ✓ get primary parent for student 0.01s + ✓ get secondary parent falls back to parent row 0.01s + + PASS Tests\Unit\Services\AttendanceTracking\AttendancePendingViolationServiceTest + ✓ returns error when no students 0.01s + + FAIL Tests\Unit\Services\AttendanceTracking\AttendanceTrackingServiceTest + ⨯ service instantiates 0.01s + + PASS Tests\Unit\Services\AttendanceTracking\AttendanceViolationStudentResolverServiceTest + ✓ resolve for school year returns students 0.02s + + PASS Tests\Unit\Services\AttendanceTracking\ViolationRuleEngineServiceTest + ✓ school year helpers 0.01s + ✓ window weeks for violation code 0.01s + + PASS Tests\Unit\Services\Auth\PasswordResetCleanupServiceTest + ✓ cleanup removes old requests 0.02s + + PASS Tests\Unit\Services\Auth\PermissionCheckServiceTest + ✓ has permission returns true when assigned 0.01s + + PASS Tests\Unit\Services\Auth\RegistrationCaptchaServiceTest + ✓ generate sets cache value 0.01s + ✓ verify and clear 0.02s + + PASS Tests\Unit\Services\Auth\RegistrationFormatterServiceTest + ✓ format normalizes parent fields 0.01s + ✓ format includes second parent when present 0.01s + + FAIL Tests\Unit\Services\Auth\RegistrationServiceTest + ⨯ register creates parent user 0.02s + ⨯ register rejects pending activation 0.32s + + PASS Tests\Unit\Services\Auth\UserRoleServiceTest + ✓ has permission for crud checks roles 0.01s + + PASS Tests\Unit\Services\Badges\BadgeFormDataServiceTest + ✓ build formats users and assigns latest class for teacherish roles 0.02s + ✓ build defaults invalid active role to teacher 0.01s + + PASS Tests\Unit\Services\Badges\BadgePdfServiceTest + ✓ generate returns pdf response and logs prints 0.10s + ✓ generate returns empty state pdf when no valid users found 0.09s + ✓ generate deduplicates same badge content 0.08s + + PASS Tests\Unit\Services\Badges\BadgePrintLogServiceTest + ✓ get status normalizes ids before calling model 0.02s + ✓ log normalizes ids and returns inserted count 0.01s + ✓ log safely swallows exceptions and logs error 0.01s + + PASS Tests\Unit\Services\Badges\BadgeTextFormatterTest + ✓ normalize ids filters and deduplicates 0.02s + ✓ norm removes extra spaces and control chars 0.01s + ✓ format role handles special words and acronyms 0.01s + ✓ format roles csv formats each role 0.01s + ✓ format class normalizes known values 0.01s + ✓ resolve role prefers first available candidate 0.01s + ✓ to pdf returns string 0.01s + ✓ fit text returns size within bounds 0.01s + + FAIL Tests\Unit\Services\Billing\BalanceCalculationServiceTest + ⨯ calculate family account applies balance formula 0.02s + ✓ overpayment records account credit 0.01s + ✓ student rows include event charges 0.01s + + FAIL Tests\Unit\Services\Billing\BillingTotalsServiceTest + ⨯ event and additional subtotals 0.02s + ⨯ additional subtotal by parent sums applied charges 0.01s + ✓ event subtotals by student groups amounts 0.01s + + FAIL Tests\Unit\Services\Billing\ChargeServiceTest + ✓ create extra charge blocks duplicate 0.02s + ✓ create event charge blocks duplicate 0.01s + ✓ create event charge succeeds 0.01s + ⨯ cancel event charge zeros charge and creates credit 0.01s + ✓ apply extra charge marks applied 0.02s + ✓ list for parent returns both charge types 0.01s + + PASS Tests\Unit\Services\BroadcastEmail\BroadcastEmailComposerServiceTest + ✓ sanitize removes script and events 0.01s + ✓ compose replaces name when personalized 0.02s + + PASS Tests\Unit\Services\BroadcastEmail\BroadcastEmailRecipientServiceTest + ✓ parents with emails filters missing email 0.02s + ✓ recipients by ids returns names 0.02s + + PASS Tests\Unit\Services\BroadcastEmail\BroadcastEmailSenderOptionsServiceTest + ✓ list options from env 0.02s + + PASS Tests\Unit\Services\CertificateAdminServiceTest + ✓ dashboard groups students and uses saved decisions as source of tru… 0.02s + ✓ issue certificates reuses existing record and creates new one for u… 0.02s + ✓ audit log returns year summary and filtered records 0.02s + + PASS Tests\Unit\Services\ClassPrep\ClassRosterServiceTest + ✓ list students by class 0.01s + + PASS Tests\Unit\Services\ClassPrep\StickerCountServiceTest + ✓ list all returns totals excluding youth 0.01s + ✓ list for class limits results 0.02s + + PASS Tests\Unit\Services\ClassPreparation\ClassPreparationAdjustmentServiceTest + ✓ apply adjustments updates counts 0.01s + + FAIL Tests\Unit\Services\ClassPreparation\ClassPreparationAdjustmentWriterServiceTest + ⨯ save adjustments persists allowed items 0.02s + + PASS Tests\Unit\Services\ClassPreparation\ClassPreparationCalculatorServiceTest + ✓ get class level by section 0.02s + ✓ calculate prep items for lower grades 0.01s + + PASS Tests\Unit\Services\ClassPreparation\ClassPreparationContextServiceTest + ✓ has roster for semester 0.01s + + PASS Tests\Unit\Services\ClassPreparation\ClassPreparationInventoryServiceTest + ✓ build availability uses max value 0.02s + + FAIL Tests\Unit\Services\ClassPreparation\ClassPreparationLogServiceTest + ✓ has prep changed detects diff 0.01s + ⨯ create log and get latest 0.01s + + FAIL Tests\Unit\Services\ClassPreparation\ClassPreparationPrintServiceTest + ⨯ print prep creates log 0.02s + ✓ print prep handles log failure 0.02s + + PASS Tests\Unit\Services\ClassPreparation\ClassPreparationRosterServiceTest + ✓ get class section student counts 0.01s + ✓ get student count for section 0.02s + + FAIL Tests\Unit\Services\ClassPreparation\ClassPreparationServiceTest + ✓ list prep returns sections and totals 0.02s + ⨯ mark printed creates logs 0.01s + + PASS Tests\Unit\Services\ClassProgress\ClassProgressAttachmentServiceTest + ✓ store attachments persists records 0.04s + + PASS Tests\Unit\Services\ClassProgress\ClassProgressMetaServiceTest + ✓ subject sections return configured values 0.01s + + FAIL Tests\Unit\Services\ClassProgress\ClassProgressMutationServiceTest + ⨯ create reports persists multiple subjects 0.02s + ⨯ update report changes status 0.02s + ⨯ delete report removes record 0.01s + + PASS Tests\Unit\Services\ClassProgress\ClassProgressQueryServiceTest + ✓ list reports filters by class section 0.02s + + PASS Tests\Unit\Services\ClassProgress\ClassProgressRuleServiceTest + ✓ build unit chapter summary limits length + ✓ ensure week end defaults to six days + + PASS Tests\Unit\Services\ClassSections\ClassAttendanceServiceTest + ✓ get attendance payload includes students 0.02s + + PASS Tests\Unit\Services\ClassSections\ClassSectionCommandServiceTest + ✓ create update delete 0.01s + + PASS Tests\Unit\Services\ClassSections\ClassSectionQueryServiceTest + ✓ list filters by search 0.01s + + PASS Tests\Unit\Services\ClassSections\ClassSectionSeedServiceTest + ✓ seed defaults creates rows 0.02s + + PASS Tests\Unit\Services\Communication\CommunicationTemplateServiceTest + ✓ list active templates maps columns 0.01s + + PASS Tests\Unit\Services\CompetitionScores\CompetitionScoresSaveServiceTest + ✓ filter scores rejects non integers 0.01s + ✓ save scores upserts 0.02s + + PASS Tests\Unit\Services\Dashboard\DashboardRouteServiceTest + ✓ resolve returns fallback when no roles 0.01s + ✓ resolve returns dashboard route for role 0.02s + + FAIL Tests\Unit\Services\Discounts\DiscountApplyServiceTest + ⨯ apply voucher returns error when no remaining uses 0.02s + + PASS Tests\Unit\Services\Email\EmailExtractorServiceTest + ✓ list and compare emails 0.01s + + PASS Tests\Unit\Services\Email\EmailProfileServiceTest + ✓ resolve profile maps aliases 0.01s + ✓ env key from profile 0.01s + ✓ sanitize reply to name 0.01s + + PASS Tests\Unit\Services\EmergencyContacts\EmergencyContactDirectoryServiceTest + ✓ groups include parent students contacts and phones 0.02s + + PASS Tests\Unit\Services\Events\EventCategoryServiceTest + ✓ categories returns list 0.02s + + PASS Tests\Unit\Services\Events\EventChargeQueryServiceTest + ✓ list returns paginated charges 0.01s + + PASS Tests\Unit\Services\Events\EventChargeServiceTest + ✓ seed charges creates event charges 0.01s + + PASS Tests\Unit\Services\Events\EventListServiceTest + ✓ list filters active events 0.02s + + PASS Tests\Unit\Services\Events\EventManagementServiceTest + ✓ update returns not found 0.01s + + FAIL Tests\Unit\Services\Events\EventStudentChargeServiceTest + ⨯ list students with charges 0.01s + + PASS Tests\Unit\Services\Exams\ExamDraftTeacherServiceTest + ✓ store creates draft 0.02s + + FAIL Tests\Unit\Services\Expenses\ExpenseReceiptServiceTest + ⨯ store receipt returns filename and url 0.01s + + PASS Tests\Unit\Services\Expenses\ExpenseStaffServiceTest + ✓ list staff users excludes parents 0.02s + + PASS Tests\Unit\Services\ExtraCharges\ExtraChargesMetaServiceTest + ✓ get school years uses fallback 0.01s + ✓ get school years merges sources 0.01s + + PASS Tests\Unit\Services\Families\FamilyFinanceServiceTest + ✓ load financials for parents returns summary 0.01s + + PASS Tests\Unit\Services\Families\FamilyMutationServiceTest + ✓ bootstrap creates family 0.02s + ✓ attach second by email creates guardian 0.02s + ✓ set primary home updates flag 0.02s + + PASS Tests\Unit\Services\Families\FamilyNotificationServiceTest + ✓ send compose email delegates to dispatcher 0.02s + + PASS Tests\Unit\Services\Families\FamilyQueryServiceTest + ✓ admin index returns families 0.02s + ✓ search suggestions returns items 0.01s + ✓ family card returns payload 0.02s + + PASS Tests\Unit\Services\FeeCalculationServiceTest + ✓ calculate refund returns calculator amount 0.01s + + PASS Tests\Unit\Services\Fees\FeeGradeServiceTest + ✓ grade level parsing 0.01s + ✓ compare grades orders numeric then suffix 0.02s + + PASS Tests\Unit\Services\Fees\FeeRefundCalculatorServiceTest + ✓ calculate refund caps at total paid 0.01s + ✓ returns zero when parent has no payments 0.01s + ✓ returns zero when no withdrawn students 0.02s + ✓ withdrawn student breakdown carries assigned tuition fee 0.01s + ✓ multi student family only refunds withdrawn students 0.01s + ✓ withdrawal after deadline is not eligible 0.01s + ✓ missing withdrawal date is skipped with reason 0.01s + + FAIL Tests\Unit\Services\Fees\FeeRefundDetailServiceTest + ⨯ calculate refund details returns amount 0.01s + + PASS Tests\Unit\Services\Fees\FeeStudentFeeServiceTest + ✓ total tuition fee applies tiers and youth fee 0.01s + ✓ assign fees stores tuition fee and fee category on each student 0.02s + ✓ calculate breakdown includes billable and non billable students 0.01s + ✓ is billable and is withdrawn classifiers 0.01s + + PASS Tests\Unit\Services\Fees\TuitionCalculationServiceTest + ✓ calculate returns family total and per student breakdown 0.02s + ✓ calculate excludes non billable students from family total 0.01s + ✓ calculate applies per student discount 0.01s + ✓ family total helper 0.01s + + PASS Tests\Unit\Services\Files\ExamDraftDownloadNameServiceTest + ✓ build returns slugified name 0.02s + + PASS Tests\Unit\Services\Files\FileServeServiceTest + ✓ meta returns file metadata 0.01s + ✓ serve inline returns 304 when etag matches 0.01s + ✓ serve inline rejects invalid extension 0.02s + + PASS Tests\Unit\Services\Finance\FinancialChartServiceTest + ✓ generate charts returns null in tests 0.01s + + PASS Tests\Unit\Services\Finance\FinancialPaymentServiceTest + ✓ payment aggregates exclude void statuses 0.01s + + PASS Tests\Unit\Services\Finance\FinancialPdfReportServiceTest + ✓ build pdf returns bytes 0.02s + + PASS Tests\Unit\Services\Finance\FinancialReportServiceTest + ✓ report returns grouped data 0.02s + + PASS Tests\Unit\Services\Finance\FinancialSchoolYearServiceTest + ✓ list years returns distinct sorted years 0.01s + + PASS Tests\Unit\Services\Finance\FinancialSummaryServiceTest + ✓ summary calculates totals 0.02s + + PASS Tests\Unit\Services\Finance\FinancialUnpaidParentsServiceTest + ✓ unpaid parents returns installment data 0.02s + + PASS Tests\Unit\Services\Frontend\ContactSubmissionServiceTest + ✓ submit creates contact record 0.02s + + PASS Tests\Unit\Services\Frontend\FrontendPageServiceTest + ✓ page returns payload 0.02s + + PASS Tests\Unit\Services\Frontend\LandingPageContextServiceTest + ✓ context returns config values 0.01s + + PASS Tests\Unit\Services\Frontend\LandingPageParentDashboardServiceTest + ✓ summary returns parent payload 0.01s + + PASS Tests\Unit\Services\Frontend\LandingPageRoleServiceTest + ✓ resolve role returns guest when missing 0.02s + ✓ resolve role returns first role 0.01s + + PASS Tests\Unit\Services\Frontend\LandingPageServiceTest + ✓ dashboard for user returns guest 0.01s + ✓ dashboard for user returns admin 0.02s + + PASS Tests\Unit\Services\Frontend\LandingPageTeacherSummaryServiceTest + ✓ summary returns dashboard payload 0.02s + + PASS Tests\Unit\Services\Frontend\ProfileIconServiceTest + ✓ build for user returns initials 0.02s + + PASS Tests\Unit\Services\Frontend\StaticPageServiceTest + ✓ load returns content 0.02s + ✓ load missing returns error 0.01s + + PASS Tests\Unit\Services\Grading\BelowSixtyEmailServiceTest + ✓ send requires student id 0.01s + ✓ send delivers to guardians 0.02s + + PASS Tests\Unit\Services\Grading\GradingBelowSixtyServiceTest + ✓ list rows returns students below sixty 0.01s + + PASS Tests\Unit\Services\Grading\GradingLockServiceTest + ✓ toggle creates lock 0.01s + ✓ lock all locks sections 0.02s + + PASS Tests\Unit\Services\Grading\HomeworkTrackingServiceTest + ✓ report returns teacher rows 0.02s + + PASS Tests\Unit\Services\Incidents\IncidentAnalysisServiceTest + ✓ analyze groups incidents by student 0.01s + + PASS Tests\Unit\Services\Incidents\IncidentHistoryServiceTest + ✓ processed enriches grade and updater names 0.02s + + PASS Tests\Unit\Services\Incidents\IncidentLookupServiceTest + ✓ grade options with active students 0.01s + ✓ updater name map 0.01s + + PASS Tests\Unit\Services\Inventory\InventoryCategoryServiceTest + ✓ create category 0.02s + ✓ update category 0.01s + + PASS Tests\Unit\Services\Inventory\InventoryItemServiceTest + ✓ create creates item and movement 0.02s + ✓ update updates item 0.02s + + PASS Tests\Unit\Services\Inventory\InventoryMovementServiceTest + ✓ create movement 0.01s + + PASS Tests\Unit\Services\Inventory\InventorySummaryServiceTest + ✓ summary returns items 0.01s + + PASS Tests\Unit\Services\Inventory\InventoryTeacherDistributionServiceTest + ✓ form data requires teacher role 0.02s + ✓ distribute success 0.02s + + PASS Tests\Unit\Services\Inventory\SupplierServiceTest + ✓ create supplier 0.01s + ✓ update supplier 0.02s + + PASS Tests\Unit\Services\Inventory\SupplyCategoryServiceTest + ✓ create category 0.01s + ✓ update category 0.01s + + PASS Tests\Unit\Services\Invoices\InvoiceConfigServiceTest + ✓ config service reads values 0.02s + + PASS Tests\Unit\Services\Invoices\InvoiceGenerationServiceTest + ✓ generate invoice creates new invoice 0.02s + + PASS Tests\Unit\Services\Invoices\InvoiceGradeServiceTest + ✓ grade parsing handles common cases 0.01s + ✓ compare grades orders numeric then suffix 0.02s + + PASS Tests\Unit\Services\Invoices\InvoiceManagementServiceTest + ✓ management data returns parent invoice summary 0.02s + + PASS Tests\Unit\Services\Invoices\InvoicePaymentServiceTest + ✓ parent invoice summary includes refunds and last payment 0.01s + + PASS Tests\Unit\Services\Invoices\InvoicePdfServiceTest + ✓ build pdf returns bytes 0.02s + + PASS Tests\Unit\Services\Invoices\InvoiceServiceTest + ✓ has class assignment returns true 0.02s + + PASS Tests\Unit\Services\Invoices\InvoiceTuitionServiceTest + ✓ calculate tuition fee counts regular and youth 0.01s + ✓ refund deadline includes withdrawn when passed 0.02s + + PASS Tests\Unit\Services\Messaging\MessageCommandServiceTest + ✓ create sends message 0.02s + ✓ create rejects invalid role 0.01s + + PASS Tests\Unit\Services\Messaging\MessageQueryServiceTest + ✓ inbox filters messages 0.02s + + PASS Tests\Unit\Services\Messaging\MessageRecipientServiceTest + ✓ teachers returns list 0.01s + ✓ parents returns list 0.02s + + FAIL Tests\Unit\Services\Navigation\NavBuilderServiceTest + ✓ save creates nav item and roles 0.02s + ⨯ reorder updates sort order 0.01s + + PASS Tests\Unit\Services\Navigation\NavbarServiceTest + ✓ get menu for roles builds tree 0.01s + + PASS Tests\Unit\Services\Notifications\NotificationActiveServiceTest + ✓ list filters by target group 0.02s + + PASS Tests\Unit\Services\Notifications\NotificationCleanupServiceTest + ✓ cleanup expired soft deletes rows 0.01s + + PASS Tests\Unit\Services\Notifications\NotificationDeletedServiceTest + ✓ list returns deleted notifications 0.01s + + PASS Tests\Unit\Services\Notifications\NotificationDispatchServiceTest + ✓ dispatch logs email and sms 0.02s + + PASS Tests\Unit\Services\Notifications\NotificationManagementServiceTest + ✓ update modifies notification 0.01s + ✓ update returns false when missing 0.01s + ✓ delete and restore notification 0.02s + + PASS Tests\Unit\Services\Notifications\NotificationReadServiceTest + ✓ mark read updates row 0.01s + ✓ mark read returns false when missing 0.01s + + PASS Tests\Unit\Services\Notifications\NotificationRecipientServiceTest + ✓ get recipients by role 0.02s + + FAIL Tests\Unit\Services\Notifications\NotificationSendServiceTest + ⨯ send creates notification and user notifications 0.02s + + PASS Tests\Unit\Services\Notifications\NotificationShowServiceTest + ✓ get for user returns notification 0.01s + ✓ get for user returns null when missing 0.02s + + PASS Tests\Unit\Services\Notifications\NotificationTriggerServiceTest + ✓ trigger dispatches event 0.01s + ✓ to user dispatches event 0.01s + + PASS Tests\Unit\Services\Notifications\NotificationUserListServiceTest + ✓ list filters by read status 0.02s + + PASS Tests\Unit\Services\Notifications\UserNotificationDispatchServiceTest + ✓ notify user creates notification 0.02s + ✓ notify user rejects invalid user 0.01s + + PASS Tests\Unit\Services\Parents\ParentAttendanceReportServiceTest + ✓ form data returns students 0.02s + + PASS Tests\Unit\Services\Parents\ParentAttendanceServiceTest + ✓ list attendance returns rows 0.02s + + PASS Tests\Unit\Services\Parents\ParentConfigServiceTest + ✓ context returns config values 0.01s + + PASS Tests\Unit\Services\Parents\ParentEmergencyContactServiceTest + ✓ store creates contact 0.02s + + PASS Tests\Unit\Services\Parents\ParentEnrollmentServiceTest + ✓ overview returns students 0.02s + + PASS Tests\Unit\Services\Parents\ParentInvoiceServiceTest + ✓ list invoices filters by parent 0.02s + + PASS Tests\Unit\Services\Parents\ParentRegistrationServiceTest + ✓ register creates student and contact 0.02s + + PASS Tests\Unit\Services\Payments\PaymentBalanceServiceTest + ✓ update balance adjusts payment totals 0.01s + + PASS Tests\Unit\Services\Payments\PaymentEnrollmentEventServiceTest + ✓ build event data requires parent 0.02s + ✓ build event data returns parent payload when no students 0.02s + + PASS Tests\Unit\Services\Payments\PaymentEventChargesServiceTest + ✓ get enrolled students returns grade 0.01s + + PASS Tests\Unit\Services\Payments\PaymentLookupServiceTest + ✓ get by parent filters school year 0.01s + + PASS Tests\Unit\Services\Payments\PaymentManualServiceTest + ✓ record payment rejects invalid method 0.02s + ✓ suggest returns matches 0.01s + + PASS Tests\Unit\Services\Payments\PaymentMissedCheckServiceTest + ✓ find users with missed payments 0.01s + ✓ send reminders sends email and notification 0.01s + + PASS Tests\Unit\Services\Payments\PaymentNotificationDispatchServiceTest + ✓ notify user creates notification records 0.01s + + PASS Tests\Unit\Services\Payments\PaymentNotificationServiceTest + ✓ send records log and returns sent count 0.02s + ✓ list logs filters by type 0.02s + + PASS Tests\Unit\Services\Payments\PaymentPlanServiceTest + ✓ create plan uses defaults when missing 0.02s + + PASS Tests\Unit\Services\Payments\PaymentTestNotificationServiceTest + ✓ send logs and sends email 0.02s + + PASS Tests\Unit\Services\Payments\PaymentTransactionServiceTest + ✓ create and update transaction 0.02s + + PASS Tests\Unit\Services\Payments\PaypalPaymentServiceTest + ✓ create payment falls back to hosted when sdk missing 0.01s + ✓ execute payment throws when sdk missing 0.01s + + PASS Tests\Unit\Services\Payments\PaypalPaymentSyncServiceTest + ✓ sync applies payment and marks synced 0.02s + + PASS Tests\Unit\Services\Payments\PaypalTransactionsServiceTest + ✓ list all filters by keyword 0.01s + + PASS Tests\Unit\Services\Phone\PhoneFormatterServiceTest + ✓ format returns null for invalid 0.01s + ✓ format formats digits 0.01s + + PASS Tests\Unit\Services\Policy\PolicyContentServiceTest + ✓ get policy returns content 0.01s + + PASS Tests\Unit\Services\Preferences\PreferencesCommandServiceTest + ✓ upsert creates record 0.01s + + PASS Tests\Unit\Services\Preferences\PreferencesOptionsServiceTest + ✓ defaults include expected keys 0.02s + + PASS Tests\Unit\Services\Preferences\PreferencesQueryServiceTest + ✓ get for user returns defaults when missing 0.01s + ✓ paginate filters by user id 0.01s + + PASS Tests\Unit\Services\Promotions\LevelProgressionServiceTest + ✓ seed defaults creates baseline levels 0.02s + ✓ resolve by class id uses mapping when present 0.02s + ✓ resolve falls back to class id plus one when no mapping 0.01s + ✓ upsert mapping updates existing row 0.01s + + FAIL Tests\Unit\Services\Promotions\PromotionEligibilityServiceTest + ✓ passing student becomes awaiting parent enrollment 0.02s + ✓ failing student becomes repeated 0.01s + ✓ missing scores marks on hold 0.01s + ⨯ terminal level is graduated 0.02s + ✓ audit log records status changes 0.01s + + PASS Tests\Unit\Services\Promotions\PromotionEnrollmentServiceTest + ✓ completing checklist finalises promotion and creates enrollment 0.02s + ✓ partial checklist keeps status in progress 0.02s + ✓ submit requires complete checklist 0.01s + ✓ other parent cannot act on record 0.01s + ✓ expired records become not enrolled 0.02s + + PASS Tests\Unit\Services\Promotions\PromotionStatusServiceTest + ✓ allowed transition updates status and audit log 0.02s + ✓ disallowed transition throws 0.01s + ✓ force status bypasses transition map 0.02s + ✓ no op transition returns record unchanged 0.02s + + PASS Tests\Unit\Services\PurchaseOrders\PurchaseOrderCreateServiceTest + ✓ create persists purchase order and items 0.01s + + FAIL Tests\Unit\Services\PurchaseOrders\PurchaseOrderReceiveServiceTest + ⨯ receive updates items and inventory 0.01s + + PASS Tests\Unit\Services\PurchaseOrders\PurchaseOrderStatusServiceTest + ✓ cancel marks purchase order canceled 0.02s + + PASS Tests\Unit\Services\Refunds\RefundDecisionServiceTest + ✓ approve updates refund status 0.01s + + PASS Tests\Unit\Services\Refunds\RefundInvoiceAdjustmentServiceTest + ✓ apply book charge inserts additional charge 0.01s + + PASS Tests\Unit\Services\Refunds\RefundNotificationServiceTest + ✓ notify pending logs event 0.02s + + FAIL Tests\Unit\Services\Refunds\RefundOverpaymentServiceTest + ⨯ recalculate creates overpayment refund 0.01s + + PASS Tests\Unit\Services\Refunds\RefundPayoutServiceTest + ✓ record payment marks partial 0.01s + + FAIL Tests\Unit\Services\Refunds\RefundPolicyServiceTest + ⨯ process withdrawal refund creates refund 0.02s + + PASS Tests\Unit\Services\Refunds\RefundQueryServiceTest + ✓ list filters by status 0.01s + + FAIL Tests\Unit\Services\Refunds\RefundRequestServiceTest + ⨯ request overpayment creates refund 0.01s + + FAIL Tests\Unit\Services\Refunds\RefundSummaryServiceTest + ⨯ summary calculates unapplied balance 0.02s + + PASS Tests\Unit\Services\Reimbursements\ReimbursementBatchAssignmentServiceTest + ✓ assign and unassign batch item 0.02s + + PASS Tests\Unit\Services\Reimbursements\ReimbursementBatchServiceTest + ✓ create batch assigns sequence and title 0.01s + + PASS Tests\Unit\Services\Reimbursements\ReimbursementDonationServiceTest + ✓ mark donation updates expense and unassigns 0.02s + + PASS Tests\Unit\Services\Reimbursements\ReimbursementRecipientServiceTest + ✓ recipient options include staff and specials 0.02s + + PASS Tests\Unit\Services\Reports\ReportCards\ReportCardServiceTest + ✓ meta returns data sets 0.01s + ✓ completeness returns summary 0.02s + ✓ acknowledgement returns signed data 0.01s + ✓ generate single report returns pdf 0.02s + ✓ generate single report handles missing scores 0.01s + + PASS Tests\Unit\Services\Reports\SlipPrinterFormatterServiceTest + ✓ to db date parses us format 0.02s + ✓ to db time parses string 0.01s + + PASS Tests\Unit\Services\Reports\Stickers\StickerPresetServiceTest + ✓ presets include alias fields 0.01s + + PASS Tests\Unit\Services\Reports\Stickers\StickerPrintServiceTest + ✓ generate returns pdf content 0.02s + ✓ generate returns error when no students 0.01s + + PASS Tests\Unit\Services\Reports\Stickers\StickerQueryServiceTest + ✓ list students by class returns rows 0.01s + ✓ list students for print all excludes youth and kg 0.02s + + PASS Tests\Unit\Services\Roles\PermissionCrudServiceTest + ✓ create and update permission 0.01s + + FAIL Tests\Unit\Services\Roles\RoleAssignmentServiceTest + ⨯ assign roles creates user roles and staff 0.01s + + PASS Tests\Unit\Services\Roles\RoleCrudServiceTest + ✓ create and update role 0.02s + + PASS Tests\Unit\Services\Roles\RoleDashboardServiceTest + ✓ best dashboard route for returns route 0.01s + + PASS Tests\Unit\Services\Roles\RolePermissionServiceTest + ✓ save role permissions persists rows 0.01s + + PASS Tests\Unit\Services\Roles\RoleQueryServiceTest + ✓ list roles returns paginator 0.02s + ✓ list users with roles returns roles 0.01s + + PASS Tests\Unit\Services\Roles\RoleSwitchServiceTest + ✓ get user role names returns roles 0.02s + + PASS Tests\Unit\Services\School\AccountEventServiceTest + ✓ new account added creates family links 0.02s + ✓ delete unverified user handles missing admin emails 0.01s + + FAIL Tests\Unit\Services\School\EnrollmentEventServiceTest + ⨯ admission under review sends email 0.01s + ⨯ admission under review requires email 0.02s + + FAIL Tests\Unit\Services\School\PaymentEventServiceTest + ⨯ payment received sends email 0.01s + ⨯ extra charge requires email 0.01s + + PASS Tests\Unit\Services\School\SemesterSelectionServiceTest + ✓ selected teacher semester prefers session value 0.02s + ✓ selected teacher semester falls back to config 0.01s + + FAIL Tests\Unit\Services\SchoolIds\SchoolIdAssignmentServiceTest + ⨯ assigns school id when missing 0.01s + ✓ assign returns existing school id 0.02s + + PASS Tests\Unit\Services\SchoolIds\SchoolIdGenerationServiceTest + ✓ generates student school id with prefix 0.01s + ✓ generates user school id with prefix 0.01s + + PASS Tests\Unit\Services\Scores\AttendanceCalculatorTest + ✓ calculate uses configured days 0.02s + + PASS Tests\Unit\Services\Scores\ExamScoreServiceTest + ✓ list returns latest exam score 0.01s + ✓ update creates exam score and missing override 0.01s + + PASS Tests\Unit\Services\Scores\HomeworkCalculatorTest + ✓ calculate returns average score 0.02s + + PASS Tests\Unit\Services\Scores\HomeworkScoreServiceTest + ✓ list includes semester variants 0.02s + ✓ add column inserts next index 0.01s + + PASS Tests\Unit\Services\Scores\ParticipationScoreServiceTest + ✓ list returns participation scores 0.02s + ✓ update updates existing scores 0.01s + + FAIL Tests\Unit\Services\Scores\ProjectCalculatorTest + ⨯ calculate returns average score 0.01s + + PASS Tests\Unit\Services\Scores\ProjectScoreServiceTest + ✓ list returns headers and scores 0.02s + ✓ update creates scores and missing overrides 0.01s + ✓ add column inserts next index 0.01s + + PASS Tests\Unit\Services\Scores\QuizCalculatorTest + ✓ calculate returns average score 0.02s + + PASS Tests\Unit\Services\Scores\QuizScoreServiceTest + ✓ list returns headers and scores 0.02s + ✓ update creates scores and missing overrides 0.01s + ✓ add column inserts next index 0.02s + + PASS Tests\Unit\Services\Scores\ScoreCommentServiceTest + ✓ list returns comments for students 0.01s + ✓ save returns validation errors for short comment 0.01s + + PASS Tests\Unit\Services\Scores\ScoreDashboardServiceTest + ✓ overview returns students and scores 0.02s + ✓ view student scores groups by year and semester 0.01s + + PASS Tests\Unit\Services\Scores\ScorePredictorServiceTest + ✓ report builds predictions 0.01s + + PASS Tests\Unit\Services\Scores\ScoreTermServiceTest + ✓ semester and school year fallback to configuration 0.02s + ✓ normalize and variants 0.01s + + PASS Tests\Unit\Services\Scores\SemesterScoreServiceTest + ✓ update student scores upserts semester scores 0.03s + + FAIL Tests\Unit\Services\Security\IpBanCommandServiceTest + ⨯ ban now updates blocked until 0.02s + ⨯ unban all resets active 0.01s + + FAIL Tests\Unit\Services\Security\IpBanQueryServiceTest + ⨯ paginate filters active 0.01s + + PASS Tests\Unit\Services\Security\Pbkdf2HasherTest + ✓ hash and verify 0.95s + + PASS Tests\Unit\Services\Semesters\SemesterConfigServiceTest + ✓ reads dates from configuration 0.01s + + PASS Tests\Unit\Services\Semesters\SemesterRangeServiceTest + ✓ get school year range falls back when config missing 0.01s + ✓ get semester for date uses config dates 0.02s + ✓ normalize semester 0.01s + + PASS Tests\Unit\Services\Settings\ConfigurationServiceTest + ✓ store creates config 0.01s + + PASS Tests\Unit\Services\Settings\SchoolCalendar\SchoolCalendarContextServiceTest + ✓ event types returns list 0.02s + + PASS Tests\Unit\Services\Settings\SchoolCalendar\SchoolCalendarFormatterServiceTest + ✓ format event sets background for no school 0.01s + ✓ format event normalizes iso dates to plain calendar date 0.01s + + PASS Tests\Unit\Services\Settings\SchoolCalendar\SchoolCalendarMeetingServiceTest + ✓ list meetings filters for parent 0.02s + + FAIL Tests\Unit\Services\Settings\SchoolCalendar\SchoolCalendarMutationServiceTest + ✓ create persists event 0.02s + ⨯ update persists changes 0.01s + + FAIL Tests\Unit\Services\Settings\SchoolCalendar\SchoolCalendarNotificationServiceTest + ⨯ notify returns empty when no targets 0.02s + + PASS Tests\Unit\Services\Settings\SchoolCalendar\SchoolCalendarQueryServiceTest + ✓ list events filters by school year 0.01s + ✓ filter events for audience limits visibility 0.01s + + PASS Tests\Unit\Services\Settings\SettingsServiceTest + ✓ update persists settings 0.02s + + PASS Tests\Unit\Services\Staff\StaffCommandServiceTest + ✓ create requires user 0.01s + ✓ create with user id 0.01s + + PASS Tests\Unit\Services\Staff\StaffQueryServiceTest + ✓ paginate returns staff 0.02s + + PASS Tests\Unit\Services\Staff\StaffTimeOffLinkServiceTest + ✓ token round trip 0.01s + ✓ token invalid on expiry 2.02s + + PASS Tests\Unit\Services\Students\StudentAssignmentServiceTest + ✓ assign creates student class rows 0.04s + ✓ remove deletes assignment 0.01s + + FAIL Tests\Unit\Services\Students\StudentProfileServiceTest + ⨯ update student saves allergies 0.01s + + FAIL Tests\Unit\Services\Students\StudentScoreCardServiceTest + ⨯ score card returns rows and comments 0.02s + + PASS Tests\Unit\Services\Subjects\SubjectCurriculumServiceTest + ✓ store creates entry 0.01s + ✓ update changes title 0.01s + + PASS Tests\Unit\Services\Support\ContactMessageServiceTest + ✓ send returns payload 0.02s + + PASS Tests\Unit\Services\Support\SupportRequestServiceTest + ✓ create persists request 0.02s + + PASS Tests\Unit\Services\System\CleanupSchedulerServiceTest + ✓ should run when no cache 0.01s + ✓ mark run sets cache 0.02s + ✓ run unverified cleanup calls artisan 0.01s + + PASS Tests\Unit\Services\System\ConfigUpdateServiceTest + ✓ run task rejects unknown task 0.01s + ✓ run task sets config when forced 0.02s + + PASS Tests\Unit\Services\System\GlobalConfigServiceTest + ✓ get semester and school year 0.01s + + PASS Tests\Unit\Services\System\HealthCheckServiceTest + ✓ check returns payload 0.01s + + PASS Tests\Unit\Services\System\TimeServiceTest + ✓ to utc and to local round trip 0.02s + + FAIL Tests\Unit\Services\Teachers\TeacherAbsenceServiceTest + ⨯ form data returns available dates 0.02s + ⨯ submit creates staff attendance 0.01s + + PASS Tests\Unit\Services\Teachers\TeacherAssignmentServiceTest + ✓ assign creates teacher class row 0.02s + ✓ delete removes assignment 0.01s + + PASS Tests\Unit\Services\Teachers\TeacherDashboardServiceTest + ✓ class view returns students 0.02s + + PASS Tests\Unit\Services\TrophyReportServiceTest + ✓ calculate threshold enforces minimum of three winners 0.02s + ✓ projection marks students without fall scores as not projected 0.02s + ✓ final report classifies confirmed surprise and missed winners 0.02s + + PASS Tests\Unit\Services\Ui\UiStyleServiceTest + ✓ update creates preferences 0.02s + + PASS Tests\Unit\Services\Users\DeleteUnverifiedUserServiceTest + ✓ delete after timeout deletes user 0.02s + ✓ delete after timeout skips recent user 0.01s + + PASS Tests\Unit\Services\Users\InactiveUserCleanupServiceTest + ✓ cleanup removes inactive users and roles 0.02s + + PASS Tests\Unit\Services\Users\LoginActivityServiceTest + ✓ list returns paginated payload 0.01s + + PASS Tests\Unit\Services\Users\UserEventServiceTest + ✓ handle new account sends email 0.01s + ✓ handle new account requires email 0.02s + + PASS Tests\Unit\Services\Users\UserListServiceTest + ✓ list includes roles and second parent flag 0.02s + + PASS Tests\Unit\Services\Users\UserManagementServiceTest + ✓ create persists user and role and sends welcome 0.02s + ✓ update changes user fields 0.02s + ✓ delete removes user and roles 0.01s + + PASS Tests\Unit\Services\Whatsapp\WhatsappContactServiceTest + ✓ list parent contacts returns primary and second 0.02s + + PASS Tests\Unit\Services\Whatsapp\WhatsappContextServiceTest + ✓ school year aliases generate expected values 0.02s + ✓ has roster for year 0.01s + + PASS Tests\Unit\Services\Whatsapp\WhatsappInviteBundleServiceTest + ✓ bundle for parent returns links and emails 0.02s + ✓ consolidate bundles merges by parent 0.02s + + PASS Tests\Unit\Services\Whatsapp\WhatsappInviteEmailServiceTest + ✓ send requires recipients 0.01s + ✓ send dispatches email 0.01s + + FAIL Tests\Unit\Services\Whatsapp\WhatsappInviteNotificationServiceTest + ⨯ dispatch returns error when no listeners 0.02s + ✓ dispatch triggers event when listener registered 0.03s + + PASS Tests\Unit\Services\Whatsapp\WhatsappInviteServiceTest + ✓ send returns success for parent mode 0.02s + + PASS Tests\Unit\Services\Whatsapp\WhatsappLinkServiceTest + ✓ upsert creates link 0.02s + ✓ paginate filters by active 0.01s + + PASS Tests\Unit\Services\Whatsapp\WhatsappMembershipServiceTest + ✓ update membership saves primary 0.01s + ✓ update membership returns error when table missing 0.02s + + PASS Tests\Feature\Api\ApiAttendanceTemplateFeatureTest + ✓ attendance comment templates can be managed through current api 0.03s + ✓ attendance comment template validation blocks bad ranges 0.02s + ✓ legacy attendance template aliases still work 0.03s + + FAIL Tests\Feature\Api\ApiAuthenticationAndAuthorizationTest + ✓ api login returns token and user object 0.06s + ✓ session login also returns token and user object for spa clients 0.04s + ✓ auth me requires authentication 0.02s + ✓ auth me returns the current authenticated user 0.02s + ⨯ admin only routes reject non admin users 0.03s + ✓ protected api routes reject anonymous requests before business logi… 0.14s + + PASS Tests\Feature\Api\ApiPreferencesFeatureTest + ✓ authenticated user can create read update and delete preferences 0.03s + ✓ non admin cannot list or manage another users preferences 0.03s + ✓ admin can list and delete any users preferences 0.03s + ✓ preferences validation rejects invalid options 0.02s + + PASS Tests\Feature\Api\ApiPublicEndpointsTest + ✓ health endpoint is available 0.01s + ✓ public policy endpoints are available 0.02s + ✓ public static pages are available 0.01s + ✓ public frontend content endpoints do not server error 0.01s + ✓ registration captcha endpoint returns captcha payload 0.02s + ✓ invalid login payload is rejected cleanly 0.01s + + PASS Tests\Feature\Api\ApiRolePermissionFeatureTest + ✓ admin can manage roles permissions and assign roles 0.04s + ✓ role permission validation rejects bad payloads 0.02s + + FAIL Tests\Feature\Api\ApiRouteContractTest + ⨯ every api route points to an existing controller method 0.01s + ✓ api routes do not duplicate method and uri pairs 0.02s + ✓ mutating api routes are protected unless explicitly public 0.05s + + PASS Tests\Feature\Api\ApiUseCaseCoverageMatrixTest + ✓ every api route is mapped to an explicit use case domain 0.01s + ✓ required use case domains have route coverage 0.01s + ✓ every protected api route rejects anonymous requests 0.21s + + PASS Tests\Feature\Api\ApiUserManagementFeatureTest + ✓ admin can create list update and delete a user through api 0.04s + ✓ user creation validates required payload and unique email 0.02s + ✓ user creation rejects nonexistent role id 0.02s + + PASS Tests\Feature\Api\V1\Admin\AdministratorAbsenceControllerTest + ✓ guest cannot access absence index 0.01s + ✓ authenticated user can get absence index 0.02s + ✓ absence store requires reason 0.01s + ✓ absence store requires valid date format 0.01s + ✓ absence store calls service and returns success 0.02s + + PASS Tests\Feature\Api\V1\Administrator\AdministratorDashboardControllerTest + ✓ metrics require authentication 0.02s + ✓ metrics are forbidden for non admin users 0.02s + ✓ metrics return payload for admin 0.03s + ✓ user search passes query to service 0.02s + + PASS Tests\Feature\Api\Administrator\AdministratorEnrollmentControllerTest + ✓ guest cannot update enrollment statuses 0.03s + ✓ can fetch enrollment withdrawal data 0.02s + ✓ can fetch new students 0.02s + ✓ update statuses requires valid status values 0.02s + ✓ update statuses calls service 0.02s + + PASS Tests\Feature\Api\V1\Admin\AdministratorEnrollmentQueryApiTest + ✓ enrollment withdrawal endpoint returns students classes and years 0.02s + ✓ new students endpoint returns transformed rows 0.02s + + PASS Tests\Feature\Api\Administrator\AdministratorEnrollmentUpdateStatusesApiTest + ✓ update statuses requires enrollment status payload 0.02s + ✓ update statuses rejects invalid status value 0.02s + ✓ update statuses creates new enrollment row 0.02s + ✓ update statuses updates existing enrollment row 0.02s + ✓ update statuses creates or updates refund when status is refund pen… 0.02s + ✓ update statuses returns partial success when some students are inva… 0.02s + + PASS Tests\Feature\Api\Administrator\AdministratorNotificationControllerTest + ✓ can get alerts data 0.02s + ✓ save alerts requires subjects payload 0.02s + ✓ save alerts calls subject service 0.01s + ✓ can get print recipients data 0.02s + ✓ save print recipients requires notify payload 0.01s + ✓ save print recipients calls service 0.01s + + PASS Tests\Feature\Api\Administrator\AdministratorTeacherSubmissionControllerTest + ✓ can get teacher submission report 0.02s + ✓ notify requires notify payload 0.02s + ✓ notify calls service 0.01s + + PASS Tests\Feature\Api\Administrator\AdministratorTeacherSubmissionNotifyApiTest + ✓ notify endpoint requires notify payload 0.02s + ✓ notify endpoint sends email and creates history row 0.02s + ✓ notify endpoint marks failed when teacher email is invalid 0.02s + ✓ notify endpoint accepts flat teacher ids from spa payload 0.02s + ✓ notify endpoint accepts flat teacher ids when teacher class has no… 0.02s + + PASS Tests\Feature\Api\Administrator\AdministratorTeacherSubmissionReportApiTest + ✓ teacher submission report endpoint returns rows summary and history 0.03s + ✓ teacher submission report returns no students status for empty sect… 0.02s + ✓ teacher submission report handles teacher class without semester co… 0.02s + ✓ teacher submission report limits history to three entries 0.02s + ✓ teacher submission report honors school year and semester query fil… 0.02s + + PASS Tests\Feature\Api\V1\Administrator\EmergencyContactControllerTest + ✓ index returns grouped contacts 0.03s + ✓ update changes emergency contact 0.02s + ✓ destroy deletes emergency contact 0.02s + ✓ show returns single contact for parent 0.02s + ✓ update requires matching parent id 0.02s + ✓ destroy requires matching parent id 0.02s + + PASS Tests\Feature\Api\V1\Administrator\TeacherClassAssignmentControllerTest + ✓ index returns teachers and classes 0.02s + ✓ store and delete assignment 0.02s + + PASS Tests\Feature\Api\V1\Administrator\TrophyControllerTest + ✓ index requires authentication 0.02s + ✓ index is forbidden for non admin users 0.02s + ✓ index returns projection for admin 0.02s + ✓ winners returns data for admin 0.03s + ✓ final returns data for admin 0.02s + ✓ index validates percentile range 0.02s + + PASS Tests\Feature\Api\AssignmentApiControllerTest + ✓ index returns assignment overview 0.02s + ✓ index filters by school year 0.02s + ✓ index sorts sections by name 0.02s + ✓ index excludes inactive students 0.02s + ✓ store creates new assignment 0.02s + ✓ store updates existing assignment for same unique keys 0.02s + ✓ store validates required fields 0.02s + ✓ store validates foreign keys 0.02s + ✓ class assignment data returns expected structure 0.02s + ✓ class assignment data deduplicates teacher names 0.02s + + PASS Tests\Feature\Api\AssignmentApiTest + ✓ it returns assignment sections json 0.02s + ✓ it filters assignments by school year 0.02s + ✓ it creates or updates student assignment 0.02s + ✓ it validates required fields when storing assignment 0.01s + ✓ store is idempotent for same student semester and year 0.02s + ✓ guest cannot access assignment api when auth is required 0.02s + + PASS Tests\Feature\Api\V1\Attendance\LateSlipLogsControllerTest + ✓ index requires admin 0.02s + ✓ index returns logs 0.02s + ✓ show returns log 0.02s + ✓ destroy deletes log 0.02s + ✓ index validation rejects bad dates 0.02s + + PASS Tests\Feature\Api\AttendanceCommentTemplateApiTest + ✓ can list templates 0.02s + ✓ can list templates active only 0.02s + ✓ can create template 0.01s + ✓ store validation fails when max less than min 0.01s + ✓ can show template 0.02s + ✓ can update template 0.01s + ✓ update validation fails if both scores invalid relation 0.01s + ✓ can delete template 0.02s + ✓ legacy list data endpoint returns templates key 0.01s + + PASS Tests\Feature\Api\V1\AttendanceTracking\AttendanceTrackingControllerTest + ✓ pending violations returns json response 0.02s + ✓ notified violations returns json response 0.02s + ✓ student case returns service payload 0.01s + ✓ student case returns service status code when not found 0.01s + ✓ record validates and returns service response 0.02s + ✓ record returns validation errors for bad payload 0.01s + ✓ send auto emails returns service response 0.01s + ✓ compose returns service response 0.02s + ✓ send manual email returns service response 0.01s + ✓ send manual email validates payload 0.01s + ✓ parents info returns service response 0.02s + ✓ save notification note returns service response 0.01s + ✓ save notification note validates payload 0.01s + + PASS Tests\Feature\Api\V1\Auth\IpBanControllerTest + ✓ index requires admin 0.03s + ✓ index returns bans 0.02s + ✓ show returns ban 0.02s + ✓ ban creates block 0.02s + ✓ unban single 0.02s + ✓ unban all 0.02s + ✓ ban validation requires ip or id 0.02s + + PASS Tests\Feature\Api\V1\Auth\RegisterControllerTest + ✓ captcha endpoint returns value 0.01s + ✓ register creates user 0.33s + + PASS Tests\Feature\Api\V1\Auth\RegisterPayloadDebugTest + ✓ debug payload shows json body 0.01s + + PASS Tests\Feature\Api\BadgeControllerTest + ✓ form data returns success response 0.02s + ✓ print status returns success response 0.02s + ✓ print status returns 500 when service throws 0.02s + ✓ log print returns success response 0.02s + ✓ log print returns 500 when service throws 0.01s + ✓ generate pdf returns pdf response 0.02s + ✓ generate pdf validates required user ids 0.01s + ✓ log print validates required user ids 0.02s + ✓ endpoints require authentication 0.02s + + PASS Tests\Feature\Api\V1\BadgeScan\BadgeScanControllerTest + ✓ scan is public but validates badge value 0.02s + ✓ scan returns 404 for unrecognized badge 0.02s + ✓ logs require authentication 0.01s + ✓ logs are forbidden for non staff roles 0.02s + ✓ logs return data for staff 0.02s + + PASS Tests\Feature\Api\V1\BroadcastEmail\BroadcastEmailControllerTest + ✓ options returns parents and senders 0.02s + ✓ send test only dispatches email 0.02s diff --git a/storage/uploads/exams/drafts/exam_6a4abcff285845.51919952.docx b/storage/uploads/exams/drafts/exam_6a4abcff285845.51919952.docx new file mode 100644 index 00000000..e69de29b diff --git a/storage/uploads/exams/drafts/exam_6a4ac0eb362bc6.28143006.docx b/storage/uploads/exams/drafts/exam_6a4ac0eb362bc6.28143006.docx new file mode 100644 index 00000000..e69de29b diff --git a/storage/uploads/exams/drafts/exam_6a4ac116b2e363.41805786.docx b/storage/uploads/exams/drafts/exam_6a4ac116b2e363.41805786.docx new file mode 100644 index 00000000..e69de29b diff --git a/storage/uploads/exams/drafts/exam_6a4ac23fcf7fb1.82462443.docx b/storage/uploads/exams/drafts/exam_6a4ac23fcf7fb1.82462443.docx new file mode 100644 index 00000000..e69de29b diff --git a/storage/uploads/exams/drafts/exam_6a4ac27bf2fa37.62621938.docx b/storage/uploads/exams/drafts/exam_6a4ac27bf2fa37.62621938.docx new file mode 100644 index 00000000..e69de29b diff --git a/storage/uploads/exams/drafts/exam_6a4ac288490c23.94142736.docx b/storage/uploads/exams/drafts/exam_6a4ac288490c23.94142736.docx new file mode 100644 index 00000000..e69de29b diff --git a/storage/uploads/exams/drafts/exam_6a4ad610776194.16519083.docx b/storage/uploads/exams/drafts/exam_6a4ad610776194.16519083.docx new file mode 100644 index 00000000..e69de29b diff --git a/storage/uploads/exams/drafts/exam_6a4ad61cd5aed9.45472025.docx b/storage/uploads/exams/drafts/exam_6a4ad61cd5aed9.45472025.docx new file mode 100644 index 00000000..e69de29b diff --git a/test-output.txt b/test-output.txt deleted file mode 100644 index cf3464ce543765ed2311208d3a8eabb0e9b5b8b8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 117880 zcmeI5+mahcww@6&caHEo^bY+TyEPwn~(`}cRl#aqL~2gA-w`+i7& zg8Q2Ux5Iw2cxXIwW`E4rIbw{5?i*yUjn3}}E_!abI=6417MClz>OU6$$HqRl=igrO z%Ll{b-|h2rdtTfGSADd5z^!;xSoWt*2JC~`L*ggVSlInGVVCRw{FC5*W|(?oki#Qy zzu*vj0Lw?a@_vB%WWeonyXUjrD>y&dzfZ5^?A)H`*Qa(jIDpgM8~$D{{ur>he|~GZ zYFBUz<~IiSr$OG}nrU3X+w1Z7XB+pIfseuMn*p<{bfu_!G0X=!c(eG2(L!{6Vc(#y z_?u7AjeCBx&ptQjke)GKnpXK}BV2Yq?a~FOAXjK`YydK-Io31sS@mdyA8fQwHtv(f z>3}ON10y5f=Y~PIJN(O?=*|}drm#Ca^KQ_R@Gm+C*fbyg%Jn=V_dt7}qhk(jgsl8= z1=FWNDz*?;Lkq!-9Cw;wO$%i$*GK+m6CQT^!% z?6st$>wh);fTzR#YvFcV)?;tKHx77eIKke%HtTveSaP`HuXY`e(LcSp!W`P-v0WXr zn#6WQEx#JRF20N;E+ewzEnxM%jf+k9nYz`@&%CpHM6qY~Hu`*4;9tD9=bjJL{y5z2SRrbAY4+ji5Z?kn@AUWfVEMky16Y`Y z`!Toe6K~}zQ8oS>anCFJ4}JTyJ;9aw*(uyRhx;c|36vt=CK zlc#tw@Hf5-UK(6|I#Ba`;GY(s%2kLL;RNW94!|E0AE8H}+qroLCj-UaUVRsyGY5JU z58uGMc(G_9X!86E7kP#RDLEhHhkOXWtGMCB_&F@r^jqL}Xs$er^Qe#RJVI_k`G{A8 z^)I2(Z@lA~-S>Q$4PL^DVS%Vo{127Z8<$vBSku_x6dq?pGCn7Ze>W(>kYW*^{mG(_ z%I^&7_lqBGrqCKWdTwJo-Op_7$PGNOyP(0_5nU$wqZKux^p{69imHFH(a9{-_7klG z1U`4i5VKH@0p7r$1P9_LVF8{}6p{Td#__TG@UU)Fv>Fp=S!P#808ldf#lQp3GmXc1 ze-4Ol4|IJxNxPVFiw&3N9Oe5wmp$iHaEg95UW5ANSnsHYHbub*}3R@ zxstlzooo&Bc2E9=eS2zr2*2iEzyQ)k)DHfHEuNIbUVM=2&n) z&fX;5!aJE`>+iUYK_{VQm@jW28_uV=4oAUR%m;n-!hWr3sJWuIJy(Rk0i0YRiib1N z;CbYFl*rB#4d?lkzpS1Qc>Q3KfiIHBDX(XUf+qM$?!VPDET89F&PK`h31%?1Y$V~Q z#+xMg+^`RqxNRJRUUV(J#&)!IWg&F2GF`3qx?|jeA1%9;_3vYwGZ5D}b4^m~>(+LW z?UIg%8adnZn|;SOMQ-5K-;F;+TYO^8$1529?|)@a;)TGSwWopn@H=rr`9`QNKS3Tf zG^^)_L@D1&jL<)$H+DC=j(0FCII6@%#!>xN*D9`2YAlv8_0NjgVuKZLAHlM<0jDjCD$Az*;QhySN2BU zaDWXRtD5L>!*yzKVIlFNupfs7&FYx4)Oe=`i|Qdz3BUiA!S(mSfBa-t88}sQ8neP# zI{NkAww$;u+tTtX-L(Bu3i+zUzSP!U>R*BPJIHA2M1<{d;Od(Ji@5VkxJO*mmXW$n&Y-J zcMK-)?48cWT&GvMT8hg|#hrl*urIk^Wy~MgCjWByne`J}S;Oj@e>JVmY+VBOm3a<2 z9J_>2-+O2F&uip|1<(5OA$VFSwvmVZbJrhNm2&F;EiBimvDWpm?hgD#by~KCwHV5l zzq&z?eQ!Q7z9jvj_y#wJW@m$kL!BC{b93N2EJ)VXb9ar;)VF$P=+JmKLYZUIcmdB% z$sd+o^klZFx*s>!{a{ewNB?gB(vjRkb4)yU&m@So|*$ZPt~k`&XL%%%UpRoJ`ftk4X;-hBs!vZkbi4ZqBMS_8@3^@0j3v zFvNpIhi@(JeQNOB488uqEEN6JhgjoUSJyo-PJ3azMkf5-;$}otz!d%N5mo&(_!d-O z<@p}Bbp2@j_nYlX1?`UA6P#M5c-$01=Xs_7meC1Hsry$euWnA)VTKg#s17hzn;?DE z%U@WQknZQ3L(!Yhvxh~ibuF8C5^su3$48Sz??`Onx=xRN6S%N$%0#_bphdJ+l25S~ z?509_{BT_k-tcOl_&T|A-M9>C3;+I(**&@sj=f8&glbCTA7Tu;iB<{v9hQu3$BSC` z$4)!y>(Ra^EriDuS&J{RX{>yvf8nOVr+C!kI99+OJH=Qp$9@Z*17V$`_V&GLkli;Z z$>NXgCUaa;R?{qU3CB(|;?i;_u(3|Mcf|PJ&vF2sG@849CZ5s zu&e-k&K!SUfK?r2I#?6^a`BUWqqcs2L-KPEjYi|}9TrEf>-EBa?4HmOu5FH3t3Aiyc=wb!Gj3b9E5|YU9l%0118N{cL9xT) zymj-3z(utdAA@t1jvX3S&%d(2u^RMY!M47RaM)Tnj!Tk&gWXPBIF8AGFS|i+nSI5= zvc~qw3Z&nq~jgBn-Kv!G%ZcGk&%6`=>OYL6@e>th6}4hbq)iog*Y9lh3}YnZW=!P zDRSA!8)pd6g?O`Iy=U~(T9ubax)LW&*d#k0-IG%%4z#(byi*bg`fvAezU+4g$7nHs4@zXh{f_Kqb2w4cwWaB~6%=dxayzl?v#SsmgJ_yV5Lj$NvmmG@mQ z7TS}{n2+ycw2IytUhE0yVtg=~vo{$Kv#;0n!Z-EymfmiYdv-CKTVwrfTEtK98Ospv zLuaAKI5mnLWRU9P(P1qur+7H)YCkXLnQ^SNc5pLNo8h10qU*iBo$OA*jX#)SN1M@u z=NYK$g_*ba(>rVwc{D$NGHf$APz6%@`TAj7HiMSlp|e(J0Pt)$6=+hfn~ojlJC@CkJ@@nij&}?{PvT~s>UuNZe4)VRZ*WT^0gk0pOW30<69Xf)+X0*sQ#bm{}Q{P9*`N94!t?Opf2_}La~U`e9Y2NXxV~GQJO01oJ}@4i_JjMcJic2zyI$ukA95+q z^A}r0RbREsC)3z9=c2{y-bk*{r=eU%ea2<%d03D2)!W(L-yfqz*}3`^>(V{nj7C|T z<*lgjsh?KWK7C$|>6;$U&adU^kostURJG7Yp109H4msNG$tUz?&~9QhwJE2U_%G=J z$49;VEC0{W|38~YL)`ji=qk7zs=BN3{FTq|4;eN0FckZ9-YPl-n|W?ECVFL+Gl=!1 z>ao<>iRhds*2CdzO{cO3>f-#njYSQi9NlN&dA)!BNj88Q5VN2sD)(rRvwLp8eYUqU zw-d87{{Ffmv09?bxqyX$W)n!=&o0NEf|0!?w7W@$f|J6u`k&qm`pl!U_t_v;rXZEoJal@|R|H+veJ`06CBYs%OLTNy(B3gjQ(I*n4)cVQBPQ#kDl0%PhPtB5GiSuB zgHttA?e-(d%$;a-KeFTarC}+a*`M^*JUxaDc7Q%-V zpDu0so3I(w#9tm1hdi?R_vVDae3D?O6Kf<9*2hY2DE?bSr*VA16=K8Tegu2bHJ1`0K($j!oR>>VrJ{ zC|Ot6vJAxXVB!3?#vQws>D9E|PPQ+Mvhq}cwe-}{+BzBe5a4{2c(9MECD+!pgo2#K z35=IJ_Pkb85vh$VXCHh(phydUOFP<@)|NE@PwgI}7I7+dPtQQGzZUB!SS1nqLhB;P zlOPrI@VDmo+BnVQk3I-p1GA!;y`&Yp$fht7o&^?6GFe;Q_rux`R(YtK7#|j>><-q*CFeFqjE3IhOT9z#b@>}r#7D0 z|FI+FYf5}_cbs=GUkDEl&-SVPR`S&p_WS2ZUcSr;;b*88z==t8`@t2;o<*K$jOP7s zC0pT{x*G2%h9&%ZW&!-$!w9amX9o0DbTGz^{DRG9)qu1(xOm;n0DSnGpfQ-CF0vIl zjraCVJov%>tsz=HUiSZ)B~()!t{KAJV z873cXexA8hM1vj*A1t_GSNfAYZi^SMje+mpJapi^)Und6?~Hn(J@*R@Svs@`JL{uU z(DZ$F!{bP@b0uAZ+M*l$Sn8Adi7B~`ca-`DX>#t>JJ6c=ip(Ers5KVyjiGv zezEITFIrw0=a2_B3vk+pN9PSRjCXfLyaO!LHp3xuZ)5dXwInO&NNoTb5sA4TMhffk z!7}*eKKyi6+ho7K9zEY59KKIlK!eaw>rx~?oAnJgm%jHoAZbsl(rJELUE=-=oYr?| zAB=b%FU*d~mQx>smUQw%U)d3OZ=5S5KD`*|j|@uo@N2MxS`W+Uk+XJ-(%Nr)89KqD zRv@cOh68_tnV|Wlq40N}+ZFjsycbOzZ}#fJ^TB7371Rh``5_9xx{T?L-OyBLN8snl zI*-$nt}ZaTZmztRJ7o=o5$#r-J;+*@w*I5b{id3-<;`{O z7x^&YRNj6Web<;^Ex*HF>r~~YusTsm_53T`<$Pa`d7a#JXV6mEMSPaPM6ZR1tB@E) zf5=(hfkF60j*v`A5OK zkylXlyu34FLzmNi>v~p7pj~7S|7!mdk%xBe!!x+dIVt25*ziCiXM!Y-=Pa%Z`r01$ zK??_j{!x^Jy^$tGqoSqfi6A$%;bWA{xuQqI452li-8#02$V5+N$r+29q+>E)lva6v z7;3Tc$g~I^>K)^Lt=WCqsZ*wWarU@)`^9&6j&}cr{fdw?v^6rpnX$hbj|2{}XQk}P zx5o1KY2dqdC%mT)3w&Fw{kV_IRqwUCWzWE|%nu&MkI=JtEO-aVvhQs>Wp8;FFNX}F zJTkJPwPqlb|9p4@aeN(q9D@SZ;r|wxan%guqw4xRI6o~j<4cvh)7mxV9 zLr|GJ4*5@A%6}dtt=(g58QgBU>28w8B(8?ahyT~Y?HXx54`W=;&>2LJ@JerH7T$|z z(1~aqGO}n}{0Oif8920683noTK9$4ld&4r%jkR{@jM{_Qrw#+RM0LIrVZClumtJCI zw7F~%-t@ZB0Q~QkjoDy1WXbAr<#Wr@VMmBkJ^K>*s~n^4&T|^)*V{HH*)6ggQ71n$ zxWdb8HK%&p1A3~@`UZE(DxgVY#4;Au9XTG@Cnr4|c!2CqZzm{F<+=~Cv@*}yGaaiB zeX$mwm% z_X=d^HlBPJq})egF4;>fA=xLz*3CwiGgU{jcFAmgGOT~((}@4PlOkl4s=R0B9ILyw zC6A1{(*Ja_T^hxnclv5MhXV|)7ghRd-1EZDoy5kd5{<7&OgGj~!o6rbuO9b|Uss-Y z8T*fGIy4$~83@sBj|@8P8`-DpJez`+%j1AaAIUkxB|mrGlzyc=a59fAKZgHV`_P-! z3|s0?V`#O`@8PYiU)&c`HAZwtr$lB1TZ~;CtM+aFHuj_Py3KWPTef{ja_~YQzrh#r zjOSV4T<;ahZ-9^RXm-aj_YI#&&e>pjK3?qrjZY>Uj~CPj88JQC2SyYBb4sk!N}20j z*_LrA*0nD9Ey|k+CwPBl?O(k@9y9F<8t|QUQNK=8H);cZp;8fPD z)rNXo=H_v2*oUX}GCgO;XIiy?%Ra$#+huy-Rbo4K-xhuQGCetJ2tN)@xXvg}jX8af z0Yd4Ukljb6?_SBaJfV61&q-vIK~NoGf7Z4?56o(Jd1dTqW9>gk@uNn`+T?4 z)jbEdUSyldJ(YGae*=qc-<{+2;>vI2E-Z@sle>_#$2NY%NMkr&Kd*|s#+ccUmmE`B zCmx#eq{?h-mce>t)y~PftUI#PNZm!y8LQxZ+S1S39kVx=y?)MjHSUS;>n`#>*+y3{ zTj>k5U^DC0&}x00wj5$|*S}aU|Dj=)%=zzwRJ^#_vj|V(bnqzPdSs&yF8cT2E*UF3C-=y>Si2bIPWbz8lod88vyO_}VWFPql?9M?;5#h1iV(%wjEs zp>o{d9Ict-UUcxBvOdK(eX@0Kl>x?P5H{HXn)D9(wmERs37ryGWu*AHj-9ZavtI9ff zokjyM;gzaV6`ZHM2AmbErulZgf6KXSHQeM1eAf>wJUR~^b9{uQQ2$f-$fbNDyUKg+ z2Olk$@m`OOvQ%fW9mCVw?|QLZzP-gczt?cLalSA}Oi4UR zT;OX79Ddj4^7`Z*Q!~GQ`wfJxPS0>>uQ>cxor*+kM+^ZRKu*Nxr?PpDB}*EZ0SE6b zdS=gn694=Dwh7$K`MJ&fH~TkZhU=bb%vjntOg-;g2ksovw2}|hzZx~sv-Ffi-sHMz zJBA0r{p}Us)p`x9n7gw*LX*FZkAQUmuDl|Y8nHT{==wkw- z_#?+9%DTBXbe&MF|L*1VhKhLB_&i#BS^Gt-A*GLsOego!!3dYL!c(!vA#%Cv^W3%T zyuMl0?>mD#d}8HX$aAQFl058N(}`pcB4bs0`mHaa{y%x!@hrF|6G0AIz8n@Kd!yuh z^SW31jAJgLlQkQM+v76dJp~($1ya^g7M-`ysSHi)x2pR{eRlPjNJy^Qp*QHGP!=U} zqSyzr$Er0cYpq?A=E;iHG|Jx}+nl@`tB*2yuI|OCZwpC~4-MwA`&4&U_j|2+F8UDh zj2uslE>9s--ZPBcNzB(~r}O;V8Tz|w+Qr^E;sT;SB%KNYba&d%BS)u0B&BRIWlz^R+EZjLOZpqu%l;Bo?~5YsqGJTMtvgX8`&cl zU%TeXO;*T!XLHxCDc~4+xMT7rj|NRY{p+bcx6XQOWh#i&wI0cBD^Me6-oM3~1#&;c z>Jg&{&B5~_{w?=5ur7fuS)6j+xv#y*byf9bB!>s`8b*;GqT^W1Wdd}N%o z$*$|Uk_UIWw};fbEO5QfZbYSAmAkmxG2r?Y9xrFcc2WEuZ_&xb8;GZm>#vn}r}}1me>&h8-wHlM8xxt_GTg&w{d=>b z#mil2O0TB$dEi60jjDHY1ucy}#?ONG@UHJ1sV8(7-VuA&<8yqlc@s_19fH+zY`6?C z0(PEzd4g%lD?5kc|j@V`oe z6{CgMQe((9SmcPnnd5C!Deww<%>HcP6m|HY5BtE#Ctr8|stJh4a*iX%F7os|YICl; zG^~wtbzsMRy1<6kSRuXYFoM!Zz+C$Q2UQ(cc%l)5XS$Eyfp+m#J01=9VKw{4#D(=J z$a39f8gcw?_I1Id;8YDTRgYN9(3a`JG zG9cfb$W0#4g~1vt=3HO6oxt+tx1+y5UTHFNDvl}7^&n+rT+nFh?}ZL+bTp4HU6;p* zlE@z@e(b}d_gdixyRHss!Jc}8rNwulbJvCP-r&J0X9KtNu8PfFNM$CS>=m>o_6~ml zZ~PCt5_N_{fd0PGX?2H!tf|vBI9jp2Rua0u1!a*CbOk=gEBkBZ1bZScQ8J+JLG@d@ zBq}G1G|bUmxxK}~4q;V$_cj1ex<6}y+TW8uR%2-VStyX}mhQ`ucZTb<|H~op)%w1g zQ$6e7QrqI0mig-1DiejdF81-JpDFcHsnwkxb9sX6YNbAH8y;N9WbN0NIFtpKoMqq9 z;dShJW>B0fE|$F?=im9QKYB@CC%ucM^yc4g8Bb6jKo_m&2f`U>e5^FOs2&Aewf+zH z!*{B;l(M!-7IPZ1Wl%q`Suo#KeBzl)>Kxv=jT~h!1~@a<5aVL`iT7S#=@hhkST3G8 zjKBFa899c_e72k#L|75MtfGon5W%`zK|a$v>ua1_&SPIz;xF>cs@AJIO&$l8rv@4hi8(-R#TLuMCGdnyia(t^WDH(Pz1IejJ zzhtWL;d~^WqB?+TE?7_TSo_;! zn`z$Dtq;P`+4z1~MY8_tiOQn^A>Qmq(=PICh?Cw88fp$osy2#kM2iaAGnc=Q#WfIyx-g~$Y!XW0aLFAW!Q*;NK9$n(F_)cIhHJhy$iW%qGlU1Vr zNd9IuzstX>d6MWq#>n~(zNf1l8Aksd`k&&t-2W*p6@DevcJ|96yBc-)8Uu$8XFb2R z6D7lqc5XY5B;Qy(d}r^us7F5R?=9RRW1IMj$Qb$wJBJ^CIrtsqY^5F0m84>pM}?+l&>vk)%uJNQQB z42%2P-qlkDkwnVJ^QZhoAK=UuBQ)({b7P*}+?l0mypz=z$8H|A)ELKx)B6d?q!@3kknGW zncf?x#RGdQmH~aZUUt0A9cGEfYetXJIf55D$9eWs5^^@^65?3tso;=xDFPKstsDK4 z^GnAchIjfRusHgB+vHsPBop((5Aw15;9&NOD&hT7F3KI4x0UNZ%m)VB$feIet~|1< zWXRO#y#Cyoc|7077w!v(N297IStj;s2D;rs2*+vP#6IXk=An_E^xD7H-O)o4-T>Ob zqYPQ%d0^6tic{k%w&&1EQOz|n6c%Ry4MB~-aPOrJ_KJ{;jew?c;~M9Yh8bqDhXWU8B3s{ zX9|mvy^r87akW#;ISgDucQh3o_SvY5&Vgfn4M00;^yk&%#rxnSVji6fQ_lx0xcR+Gg1~ z;Tn6XPv0A!)Qx#&_*$kFg=wOH-A_lGynFgarSYk3DjRxz7~AyCEv6aC_ZF#hrhx}^ z58Q(k%L`(+QCW5@44Mi57imXE=@eA`chi~9``p~QshYzc8SE~HWM68jTg7+YMN&T5 zN;nd&>K8Ua_5iEz+{r2~mmSxjwN_v+0dmYa{ma7r@`$AgaL|^!Whq z8^aG;tc8sGLz|7ik(wCZ2X#kAzc4HlEfPcG<@r;B8Z3hc-sSJx)c=ASp~D~9H^=F1 z`wZ9P_0J_)Xf_`cIBTxXR&##n&I-g}ea=VL?=CA@|1memEH+bgnUljF7kaL?PJJHea{C0G&JA;n`_)T zctaIx&nThWBArHrs-e;&+xp6ulib@5i@-S^@1JZ5j@MKxdW=-vnMKe4)2 zBh{EB8lfvl-BDOLWeDcUFa|W^&^@%7#Xe4ba#DKL*hlgjz?JhorFNrlpL0T>BNhqV zc&2tARMcM6k8FjvOaG`mSP z5KZQ?G|qizCS{(*|DQHXq@<57XeRjR#Bi_Yu;4XiWVP@ak!SA4$43&S!Q6m0q=^i`=BE0=g)g?%13Ca2=$~h(32j` z6Gfs$WW~1SRAc}Mn8gdT1E*KtRV{~dbDZ2$*C$kQ00wajTg1R{qfXeqr5UnL=kg%4K;U-;iA;xyMVUrF~2uh zy53#6vLC*h3(&I4kCS_@eWH16>Dl0W;9EZbqR&@xw(O{9Ct5q|{(yX;eOSJE-?6+# z7jTz)ti=O-k1j#NkKu1_|KWRs9L*zdfjt|^p^@7%e3-j71zmcxUeyz*8cBi zU({djdGM%Yk%?$)aq&F$2I4RBM5?F~f3R~<*%MRC-6kGKjfwL67+(6Y5%D8@rroA% zEs1>$tbiv@x)B|SB%Ko5>&g|;kN{>X8R(-b6r9d<5Z#4cmFF|hiqm^0S>y|m48_4u z7WK7T_6xY>jAgvIK8T1K^py6|e{FbCwg$R@oASNzD0SSDcem%z8XEHN^|c=cxZuB@ zl^fDZS}{eRAAYT}GT@NvH@P9@H-Or^S`{d3p}@B|0V!JRc^W6&a%AB;cAob}N% zLs9SL>h(3`Pm-oAd`U;ahDCI*HuuM8EcoiXc_{B){i3WWUtXg&hkSWWv=1X$JGFJy zT1RDA$M5zhHj7`NdI{ASr1u6m-*wWwh7b)UOi6yh88tlTYTv`evs@0*7`;mw$m8vc z>JLl;z?jc=6RM9v>`?ELj=PAf%HGX=KvBkux34rX+LMUMEp{JW6j#BG#D`H!EPcf> zE9&`!teHIb9&;gcNLHsj5q^FwLD}dU>8&V~lFB^u7(UB!IUKv&pO}w_11{E+-V}XH zRZ#ZdwXI)Kc2t?nJ`OH(pBJW?qGMK3CSC-Za^AeCEQinAy#-Y~f$e+yFHWyrr*DNU zaXjgD`4|~HSlSfs{@oyaGgvd96WlllNBVeUFuIS{N2}}&DVH1leALT{RnaR@3%XJ{ zQ;!qE878%du9UN1c27P!{kxxdNrLWENDhct6kCwC9` zL!0>~odR5VYUr{?1sL_ zBEU&-jK8n#4bS#a62GjcjBJW~ua5Q2Jhlw+I2P7jhsG$Za%AlpUJ$!(dd9WH!5le{ z)$@O3ZztRI(f*ST?vs=kt< z_$Sy_c$RL*sN)92Pi-`+ZHzwv=U+LA%}+5B5jH>ez3$jL*4FZljOh&cUsu zDj!QUtvye`L}YR2pwc)D%iud5bRKqxD7Ozn>@1Gy!x{S0{Ua0iEhY&|Ka- zRGuf#K1Hu(u->*=Fmq$0%CG@79s6S(RBPl-YR;QMOKkzYsSfN_v{gk~ zxte&&PeVWw^SW;LR4z=G`R(xksLcM`;xAXTy&h@XJi;q8-o(F93SU5yHN}0dG2M=q z_1aQ$*LC zN*Z~i*6vEPIV6tlu_rghxsSbHEN$ZDxs?af@_96ctf1R_pxQrV(482fkN(Jm`XyQq zZk+c*4x&G8N&;&8ut{&kCidZM=(nejBpbi@P~_Udzo z*R|o)cv!q;IVOMe_Bebv_$11`5cA~kw~SK6IM^)wbm~rcJl+r0hqI{~aE^h-dQu!$ zoB1gjjvl!BU!WrnKX*)Ko$EbgshNtj`}jb`?#I>m~_!@DT5ZH zvH%vTF_Ukh65IzFwD70#*xHJDNuBWGcfoy8TXa1aSH3gYs0m4T_d!=i_GD#a1R#m? zbfF|Pi}#UbC6ZC}KMxIK^cKD`35(r!`{0c%F_|gv)~l=DWyey@srasL)BDEDRw9q) z7^PPlT<81=-a_4nJBJ_ju%O`>mK`g;a{-Y`Z@;leeE1Qr4L!dL7RdYLI%dX9bad>V zmp19XRTV;BZb`*j!;S9!Pt; zrd6$?V()Od&fq?c2KITDZ`c+_^{g|Aj4iJ#bR3mAsO8X?A>$u9#Jp z+yF77dGwfkm(5Pun9D^ZB*5Zx);?6a7C?08A~i8 zQGq<4$Uk2g4|7+`t=V!Cr(>P`?6vyMSX|FFWRG!rbk`R1TGnyQUK;N_?~JW3%-i5@ zbYFDKgV7ph=OwR=agRR@mUqoR<5JP<6^C|)7ul<8TsP}PFs)&n2PQa?j&5>&{`sz5 zJ2xKmtk&u(gesbz+vB;`pNoCSyxOBo01%I@2QEj;-=Hm-exh#opSI;-y7cguE(c7+ zx6=VX%I)=Lz&*wxGwP$Z_`p^Z=_uZrgFo>L*h7?m730gx9lH)(>vl|{r|~t|->S`W z@D^Zd_ZHeDo6lYj{m}emGxMxXugtaH0{j?VuHJzJRIaHdfAjc~>%g~eXQy+ZOPWU| zEf=;}2y3+53Za43kBhw1jWMpX;@vLg+sZ1ojb4?YIQsQ{)@;XF(+q5( zIkI<9ziF8t(!L+RnmK6CVP+cqKxA3Z%W3JcYpEk@7_z6wJMd(bcXcS`x6GprTP_iA zWZt`kr-n=Rw1aQ;1S3E%tvBIc&xv_< zpvEuMq>I%@SoKauCz_Ltwpo}`#_^e?!!_gVO(8`(UxpsqdR}M%dGkyJ6X}FN%2DXc&ljUR=r=etbXWAos~PEv?Q59IT4-#SzFEQM}Vpdl3*L zKwDsxJ{2~(B8njUC0|Egpw>`5{3H%!9-`XVJg|Cj5i~5Z&+PHVnNw)onyO^_w7a4E zg=PM{#0Wa4okcw++Mn2-dP^xqnBTMkAS<$mLQFOX+x_Rd2z zSn$DIaYjvH_u@*rpBY>(2YsBU*n(bZ*|><+?r~NtsWpX=V{!zv-+*lhK;;t!rvRZGS_lL$;^jGHC9ZhKNpwTgG93H%>#J zx_8$ntDgI!%S@*dk|UJvQFja+i}pf_wFZ=Gu{%xEVn zVD2kLE<7sqyM^YbfwRtSCb|CEM?L8p@K45;cu&!C*1+f-@A4_%AuHtEyIUw94$x6S z>dkZswyElHsb%0h_cM15N95i5Xe197?MOTqm0MrkEa@rrNKL=|>u%v&Hycz&6nT}e zDt_6++wIIB8HVxw!Sgyi7SBw}$@S5LeRE=Gi$0DcCW>d!=Cy`^5AiWw`?DsC3{lyG zH4nWwL6%M>{7n2g^euKo)_MF_y2;d^am((+V&~l!`mo^n6P^rDOHjv{f?4kh-|P?| z?}IXPW(iA%A9{m*@w)Q&ffF?6C$k=N)a8-FahfitIHw=Mj~*fQLGM<8noaq9>vt;# zhx@=pKwopj9P!4cSm3#G{aGI#&YS1ZWw~x4FD_Rgq?tJ}G;qP{Tg?ECF&8Ghi{ClG zzn>bti9x5X_rZ=vAzRVL)UgvB6!&Ug&S%%zA#&}q(qOdggULD-{gB5|1s>1x_d$+c z3^_yBb?wYtqe<)fJnK=(J2E5n4J$_>KNVTksE*6_9ol7QyD^o4h`p?qWpqoOxyhPw zxZmM{C(aC)?ASqO9k`VTzH3-suY&CB*r+hPFk8g`-BZRRmSvJnb z;6}T`m7do`E@T_XZg~uJ=_;o zi3R)#@D9eaPDbmJEf*K!mHD0`4)dY@D_VRzN{dZu^sO$)n3s0QS3*auqJ;WMTHOj| zvc~sa%CHe-F9kI4n&j$n;2rWuR1@lYCpI|urI$K%A9&k5-mB-1_en-2*L`c8f(PGC zC1Ww7$aYlkGeCA^1@KqY$%IcA@`KdGK4jt5{A$*C4$KnyBfVtHp=ww|IONo>K+8V< zEB$t_eB|t+XU@yF%nQdOqX#g}6=gwR;Rrr}`m(c7M%@QULB7i&hwhxR{c2`PIfV05 z$D!B_MQ#sP;1`oAR_EX)_wf~#L~tn|r#^#-IeTZP%hi~S>Ym*|HYPiLu*JS)j{9*L zf!l~<@av-L#51mYfJ~NjGac((P7Xt#H`k*M3$w0ifp;2xP}mTkx!a%6oGxFC6RSg( zjUK=4hSFzO^Prm0M`5ffyz8)puF&3d_^xAkniGE_Rvs)i&#{G6mD@p-oOAM&UbEJ7pYd z+f3&dyv7MHbVuQ5{c61FP`S3@dF;EYOk~ceisF}nVT~OaT$MdwM!c2$Y^*k$BkNS+ z^Nzhi8X{K5uZvZmt1`#AgOGr+t~}sQr<#5h9;cdc{$-#}C0C&yBAij1S;>Ki_X#y4ToaPi^q8(=ckR zIp*e|d=1Iw98hMi<(Jo*0m+9Z$jeyuO&+PZpOqo+?7p_!41ZR8NAXVRD^Gq-ykM=> zL8R(yu0y*P*j7fc>ErLn6mNa*Qd06ad6)Gnmy4vg=9UDq>>s}D7k9jJP{Ogf6x5Q8 zm4vI^7Djf{xo8!AYfYG`*{=cHw;YbFktut#_{Y}Pv&Q}Yw5UVym2bQwcpo}Cuzfn% zV~?%2)yqgG-E#PLSShdnqm^@}sg=RRly|xSM?O77nMEH{*;4VIV{HykFn9rPpIT<$%rETjGX4v!M~<92ES3BJH}`^H L*Qzb9YZ?0gVn9Q8 diff --git a/tests/.DS_Store b/tests/.DS_Store index e4a10600c07e57d25b10def02959c298c52cf0df..8f6a9c8cfea627512df7ad78fa4e91be530e145d 100644 GIT binary patch delta 71 zcmZoMXfc@JFUrKgz`)4BAi%(o%233R$55P7oSZXpqxxh65f&*924{wRpkOkxWKw>9 P4#UQtIQGr#9Dn%%K$j9R delta 45 zcmZoMXfc@JFUrWkzyQPo3=E|VMGUDa#mPBI`4cayGcs;m8OJ{Hf$U~>j=%f>_<9W3 diff --git a/tests/Concerns/CreatesApiTestUsers.php b/tests/Concerns/CreatesApiTestUsers.php index 46ea100d..0029dc00 100644 --- a/tests/Concerns/CreatesApiTestUsers.php +++ b/tests/Concerns/CreatesApiTestUsers.php @@ -6,6 +6,8 @@ use App\Models\Configuration; use App\Models\Role; use App\Models\SchoolYear; use App\Models\User; +use Illuminate\Support\Facades\DB; +use Illuminate\Support\Facades\Schema; use Laravel\Sanctum\Sanctum; trait CreatesApiTestUsers @@ -64,6 +66,7 @@ trait CreatesApiTestUsers { $roles = $this->seedApiRoles(); $this->seedApiTestConfig(); + $this->seedSchoolYearClosurePermissionsForTests($roles); $user = User::factory()->create(array_merge([ 'status' => 'Active', @@ -91,6 +94,81 @@ trait CreatesApiTestUsers return $user; } + + /** + * Keep test fixtures aligned with explicit permission middleware. + * Production receives these through the closure permission migration. + * + * @param array $roles + */ + protected function seedSchoolYearClosurePermissionsForTests(array $roles): void + { + if (! Schema::hasTable('permissions') || ! Schema::hasTable('role_permissions')) { + return; + } + + $permissions = [ + 'school_year.view', + 'school_year.view_closed', + 'school_year.create', + 'school_year.close', + 'school_year.reopen', + 'school_year.archive', + 'school_year.manage', + 'school_year.select', + 'student_enrollment.view', + 'student_enrollment.promote', + 'finance.view', + 'finance.balance_transfer.view', + 'reports.view', + ]; + + foreach ($permissions as $permission) { + DB::table('permissions')->updateOrInsert( + ['name' => $permission], + ['description' => 'Test permission '.$permission, 'created_at' => now(), 'updated_at' => now()] + ); + } + + $adminRoleIds = collect([$roles['administrator'] ?? null, $roles['admin'] ?? null])->filter()->map(fn (Role $role) => (int) $role->id)->all(); + $teacherRoleId = isset($roles['teacher']) ? (int) $roles['teacher']->id : null; + $parentRoleId = isset($roles['parent']) ? (int) $roles['parent']->id : null; + + $this->grantTestPermissions($adminRoleIds, $permissions); + if ($teacherRoleId) { + $this->grantTestPermissions([$teacherRoleId], ['school_year.view', 'school_year.view_closed', 'school_year.select', 'student_enrollment.view']); + } + if ($parentRoleId) { + $this->grantTestPermissions([$parentRoleId], ['school_year.view', 'school_year.select', 'finance.view']); + } + } + + /** @param list $roleIds */ + private function grantTestPermissions(array $roleIds, array $permissions): void + { + foreach ($roleIds as $roleId) { + foreach ($permissions as $permission) { + $permissionId = (int) DB::table('permissions')->where('name', $permission)->value('id'); + if ($permissionId <= 0) { + continue; + } + + DB::table('role_permissions')->updateOrInsert( + ['role_id' => $roleId, 'permission_id' => $permissionId], + [ + 'can_create' => true, + 'can_read' => true, + 'can_update' => true, + 'can_delete' => true, + 'can_manage' => true, + 'created_at' => now(), + 'updated_at' => now(), + ] + ); + } + } + } + /** * @return array */ diff --git a/tests/Feature/Api/V1/.DS_Store b/tests/Feature/Api/V1/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..0ca200e5c02fe5aef9413e54f7e2e53691c293c3 GIT binary patch literal 6148 zcmeHKyG{c!5S)b+kI>PqM77%3nHZbt$CJ~X;xFPswN)4?HH0OEq- zFwUcwAT|#Wd*PJG2+fj8OsZ9jVM%AaRbDTg5|a+A=ELe{s}9BDcAnoN9o7>yN&zWw zsla_M*Ixf0>3{V9mn5yEfE2hX1#Gd~@3wqW)z;bLyw*1QGu?B(=x&?`g+r8MVw7Vp gyc|D7QsyassertJsonPath('data.promotion_preview.summary.promote', 1) ->assertJsonPath('data.parent_balances.summary.total_old_unpaid_balance', 200); - $this->assertSame(200.0, (float) $response->json('data.parent_balances.rows.0.amount_to_transfer')); + $balanceRows = collect($response->json('data.parent_balances.rows')); + $parentRow = $balanceRows->first(fn (array $row): bool => (int) $row['parent_id'] === 10); + + $this->assertCount(1, $balanceRows); + $this->assertNotNull($parentRow); + $this->assertSame(200.0, (float) $parentRow['amount_to_transfer']); $this->assertSame('promote', $response->json('data.promotion_preview.rows.0.promotion_action')); } + public function test_preview_close_excludes_zero_invoice_balance_parent_even_when_parent_account_is_stale(): void + { + $this->seedClosureData(); + $this->seedZeroBalanceParentWithStaleAccount(); + + $this->actingAs(User::query()->findOrFail(1), 'api'); + + $response = $this->postJson('/api/v1/school-years/1/preview-close', [ + 'new_school_year' => [ + 'name' => '2026-2027', + 'start_date' => '2026-09-01', + 'end_date' => '2027-06-30', + ], + 'transfer_unpaid_balances' => true, + ]); + + $response->assertOk() + ->assertJsonPath('data.validation.can_close', true) + ->assertJsonPath('data.parent_balances.summary.total_old_unpaid_balance', 200) + ->assertJsonPath('data.parent_balances.summary.net_balance_to_transfer', 200); + + $balanceRows = collect($response->json('data.parent_balances.rows')); + + $this->assertTrue( + $balanceRows->contains(fn (array $row): bool => (int) $row['parent_id'] === 10 && (float) $row['amount_to_transfer'] === 200.0) + ); + $this->assertFalse( + $balanceRows->contains(fn (array $row): bool => (int) $row['parent_id'] === 11), + 'Parent with invoice balance 0 must not appear in closure balance preview, even when parent_accounts.current_balance is stale.' + ); + } + + public function test_close_school_year_does_not_transfer_zero_invoice_balance_parent_even_when_parent_account_is_stale(): void + { + $this->seedClosureData(); + $this->seedZeroBalanceParentWithStaleAccount(); + + $this->actingAs(User::query()->findOrFail(1), 'api'); + + $this->postJson('/api/v1/school-years/1/close', [ + 'new_school_year' => [ + 'name' => '2026-2027', + 'start_date' => '2026-09-01', + 'end_date' => '2027-06-30', + ], + 'transfer_unpaid_balances' => true, + 'confirmation' => 'CLOSE 2025-2026', + ])->assertOk(); + + $this->assertDatabaseHas('parent_balance_transfers', [ + 'parent_id' => 10, + 'from_school_year' => '2025-2026', + 'to_school_year' => '2026-2027', + 'amount' => 200.00, + 'status' => 'transferred', + ]); + + $this->assertDatabaseMissing('parent_balance_transfers', [ + 'parent_id' => 11, + 'from_school_year' => '2025-2026', + 'to_school_year' => '2026-2027', + ]); + + $this->assertDatabaseMissing('invoices', [ + 'parent_id' => 11, + 'school_year' => '2026-2027', + 'description' => 'Opening balance transferred from 2025-2026', + ]); + } + + public function test_parent_cannot_close_school_year(): void + { + $this->seedClosureData(); + + $this->actingAs(User::query()->findOrFail(10), 'api'); + + $this->postJson('/api/v1/school-years/1/close', [ + 'new_school_year' => [ + 'name' => '2026-2027', + 'start_date' => '2026-09-01', + 'end_date' => '2027-06-30', + ], + 'transfer_unpaid_balances' => true, + 'confirmation' => 'CLOSE 2025-2026', + ])->assertForbidden(); + } + + public function test_school_year_closure_routes_have_explicit_permission_middleware(): void + { + $routes = collect(app('router')->getRoutes()->getRoutes()) + ->filter(fn ($route) => str_starts_with($route->uri(), 'api/v1/school-years')); + + $missing = []; + foreach ($routes as $route) { + $middleware = $route->gatherMiddleware(); + $hasPermission = collect($middleware)->contains(fn (string $middleware): bool => str_starts_with($middleware, 'perm:')); + $hasAuth = collect($middleware)->contains(fn (string $middleware): bool => str_contains($middleware, 'multi.auth') || str_contains($middleware, 'auth')); + $hasAccountGuard = in_array('account.active', $middleware, true); + + if (! $hasPermission || ! $hasAuth || ! $hasAccountGuard) { + $missing[] = implode('|', $route->methods()).' '.$route->uri(); + } + } + + $this->assertSame([], $missing, 'School-year routes missing auth/account/permission middleware: '.implode(', ', $missing)); + } + public function test_admin_can_create_draft_school_year_via_api(): void { $this->seedClosureData(); @@ -178,6 +291,68 @@ class SchoolYearControllerTest extends TestCase ->assertJsonPath('message', 'School year 2025-2026 is closed and read-only.'); } + private function seedZeroBalanceParentWithStaleAccount(): void + { + DB::table('users')->insert([ + 'id' => 11, + 'school_id' => 1, + 'firstname' => 'Zero', + 'lastname' => 'Balance', + 'cellphone' => '5555555556', + 'email' => 'zero@example.com', + 'address_street' => '123 Main', + 'city' => 'City', + 'state' => 'ST', + 'zip' => '12345', + 'accept_school_policy' => 1, + 'is_verified' => 1, + 'status' => 'Active', + 'is_suspended' => 0, + 'failed_attempts' => 0, + 'password' => bcrypt('secret'), + 'semester' => 'Fall', + 'school_year' => '2025-2026', + ]); + + DB::table('user_roles')->insert([ + 'user_id' => 11, + 'role_id' => 2, + ]); + + $parentAccount = [ + 'parent_id' => 11, + 'school_year' => '2025-2026', + 'opening_balance' => 999, + 'current_balance' => 999, + ]; + if (Schema::hasColumn('parent_accounts', 'created_at')) { + $parentAccount['created_at'] = now(); + } + if (Schema::hasColumn('parent_accounts', 'updated_at')) { + $parentAccount['updated_at'] = now(); + } + DB::table('parent_accounts')->insert($parentAccount); + + DB::table('invoices')->insert([ + 'id' => 501, + 'parent_id' => 11, + 'invoice_number' => 'INV-501', + 'total_amount' => 500, + 'balance' => 0, + 'paid_amount' => 500, + 'has_discount' => 0, + 'issue_date' => '2026-05-10', + 'due_date' => '2026-06-10', + 'status' => 'overdue', + 'description' => 'Paid invoice with stale overdue status', + 'school_year' => '2025-2026', + 'created_at' => now(), + 'updated_at' => now(), + 'updated_by' => 1, + 'semester' => 'Fall', + ]); + } + private function seedClosureData(): void { DB::table('configuration')->insert([ @@ -238,6 +413,38 @@ class SchoolYearControllerTest extends TestCase ['user_id' => 10, 'role_id' => 2], ]); + $permissions = [ + 'school_year.view', + 'school_year.create', + 'school_year.manage', + 'school_year.close', + 'school_year.reopen', + 'school_year.archive', + 'school_year.select', + 'student_enrollment.promote', + 'finance.balance_transfer.view', + ]; + + foreach ($permissions as $permission) { + $permissionId = DB::table('permissions')->insertGetId([ + 'name' => $permission, + 'description' => 'Test permission '.$permission, + 'created_at' => now(), + 'updated_at' => now(), + ]); + DB::table('role_permissions')->insert([ + 'role_id' => 1, + 'permission_id' => $permissionId, + 'can_create' => 1, + 'can_read' => 1, + 'can_update' => 1, + 'can_delete' => 1, + 'can_manage' => 1, + 'created_at' => now(), + 'updated_at' => now(), + ]); + } + DB::table('school_years')->insert([ 'id' => 1, 'name' => '2025-2026',