From 08605cf64091e4c847da8f7997bacb2dbc11fe0c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=94=D0=BC=D0=B8=D1=82=D1=80=D0=B8=D0=B9?= Date: Thu, 14 May 2026 05:35:06 +0300 Subject: [PATCH] =?UTF-8?q?fix(tests):=20Bus::fake=20partial=20+=20session?= =?UTF-8?q?=20mock=20=E2=80=94=20close=20quirk=20#72?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit CsvReconcileJobTest used Bus::fake() (all jobs), silencing dispatch_sync of RefreshSupplierSessionJob when a parallel afterEach wiped supplier:session. Now: Bus::fake([RouteSupplierLeadJob::class]) + anonymous mock that re-puts the session in handle(), making race-window recovery deterministic. Co-Authored-By: Claude Sonnet 4.6 --- app/tests/Feature/Supplier/CsvReconcileJobTest.php | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/app/tests/Feature/Supplier/CsvReconcileJobTest.php b/app/tests/Feature/Supplier/CsvReconcileJobTest.php index 4b07d775..d5c3c964 100644 --- a/app/tests/Feature/Supplier/CsvReconcileJobTest.php +++ b/app/tests/Feature/Supplier/CsvReconcileJobTest.php @@ -5,6 +5,7 @@ declare(strict_types=1); use App\Exceptions\Supplier\SupplierTransientException; use App\Jobs\RouteSupplierLeadJob; use App\Jobs\Supplier\CsvReconcileJob; +use App\Jobs\Supplier\RefreshSupplierSessionJob; use App\Mail\CsvDriftAlertMail; use App\Models\SupplierLead; use App\Models\SupplierProject; @@ -47,7 +48,18 @@ function putSupplierSession(): void beforeEach(function () { Mail::fake(); - Bus::fake(); + // Partial fake: only RouteSupplierLeadJob is intercepted (what we assert on). + // RefreshSupplierSessionJob must NOT be faked — it must run our mock below + // so that loadSession() can recover if a concurrent afterEach wipes the session. + Bus::fake([RouteSupplierLeadJob::class]); + // Bind a mock that re-puts the session when dispatch_sync triggers it during a race. + app()->bind(RefreshSupplierSessionJob::class, fn () => new class + { + public function handle(): void + { + putSupplierSession(); + } + }); // NB: NOT Cache::store('redis')->flush() — flush wipes session keys belonging to // OTHER parallel tests (cross-pollution). Just forget our reserved keys + re-put. Cache::store('redis')->forget('supplier:csv_reconcile');