diff --git a/app/.DS_Store b/app/.DS_Store
index 958caa95..f418beda 100644
Binary files a/app/.DS_Store and b/app/.DS_Store differ
diff --git a/app/Http/Controllers/Api/.DS_Store b/app/Http/Controllers/Api/.DS_Store
index bf2b2d0a..f95540af 100644
Binary files a/app/Http/Controllers/Api/.DS_Store and b/app/Http/Controllers/Api/.DS_Store differ
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 abf0a397..a2716819 100644
Binary files a/app/Services/.DS_Store and b/app/Services/.DS_Store differ
diff --git a/app/Services/SchoolYears/SchoolYearClosureService.php b/app/Services/SchoolYears/SchoolYearClosureService.php
index d494acbf..505a72c0 100644
--- a/app/Services/SchoolYears/SchoolYearClosureService.php
+++ b/app/Services/SchoolYears/SchoolYearClosureService.php
@@ -628,51 +628,16 @@ class SchoolYearClosureService
private function buildParentBalanceRows(string $fromSchoolYear, string $toSchoolYear): array
{
- $invoices = DB::table('invoices')
+ $invoiceBalances = DB::table('invoices')
->where('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 00000000..78057959
Binary files /dev/null and b/database/.DS_Store differ
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 00000000..b7111e7b
Binary files /dev/null and b/storage/.DS_Store differ
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
+
+ [2m+7 vendor frames [22m
+ 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
+
+ [2m+7 vendor frames [22m
+ 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,
+
+ [2m+16 vendor frames [22m
+ 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,
+
+ [2m+16 vendor frames [22m
+ 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,
+
+ [2m+16 vendor frames [22m
+ 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,
+
+ [2m+16 vendor frames [22m
+ 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,
+
+ [2m+16 vendor frames [22m
+ 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,
+
+ [2m+16 vendor frames [22m
+ 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,
+
+ [2m+16 vendor frames [22m
+ 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,
+
+ [2m+16 vendor frames [22m
+ 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,
+
+ [2m+19 vendor frames [22m
+ 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,
+
+ [2m+16 vendor frames [22m
+ 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,
+
+ [2m+8 vendor frames [22m
+ 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
+
+ [2m+17 vendor frames [22m
+ 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,
+
+ [2m+8 vendor frames [22m
+ 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,
+
+ [2m+16 vendor frames [22m
+ 17 app/Services/ClassPreparation/ClassPreparationAdjustmentWriterService.php:39
+ [2m+3 vendor frames [22m
+ 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,
+
+ [2m+8 vendor frames [22m
+ 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,
+
+ [2m+8 vendor frames [22m
+ 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,
+
+ [2m+8 vendor frames [22m
+ 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,
+
+ [2m+8 vendor frames [22m
+ 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,
+
+ [2m+8 vendor frames [22m
+ 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,
+
+ [2m+13 vendor frames [22m
+ 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,
+
+ [2m+8 vendor frames [22m
+ 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,
+
+ [2m+8 vendor frames [22m
+ 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,
+
+ [2m+8 vendor frames [22m
+ 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,
+
+ [2m+11 vendor frames [22m
+ 12 app/Services/Settings/SchoolCalendar/SchoolCalendarMutationService.php:44
+ [2m+3 vendor frames [22m
+ 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) {
+
+ [2m+3 vendor frames [22m
+ 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,
+
+ [2m+8 vendor frames [22m
+ 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: TimeOffSorry, 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: TimeOffSorry, 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 cf3464ce..00000000
Binary files a/test-output.txt and /dev/null differ
diff --git a/tests/.DS_Store b/tests/.DS_Store
index e4a10600..8f6a9c8c 100644
Binary files a/tests/.DS_Store and b/tests/.DS_Store differ
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 00000000..0ca200e5
Binary files /dev/null and b/tests/Feature/Api/V1/.DS_Store differ
diff --git a/tests/Feature/Api/V1/SchoolYears/SchoolYearControllerTest.php b/tests/Feature/Api/V1/SchoolYears/SchoolYearControllerTest.php
index 33e045d5..d98721e0 100644
--- a/tests/Feature/Api/V1/SchoolYears/SchoolYearControllerTest.php
+++ b/tests/Feature/Api/V1/SchoolYears/SchoolYearControllerTest.php
@@ -5,6 +5,7 @@ namespace Tests\Feature\Api\V1\SchoolYears;
use App\Models\User;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Support\Facades\DB;
+use Illuminate\Support\Facades\Schema;
use Tests\TestCase;
class SchoolYearControllerTest extends TestCase
@@ -31,10 +32,122 @@ class SchoolYearControllerTest extends TestCase
->assertJsonPath('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',