From 43a09a94f3a26e807318746673b5a008a23f362a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vi=CC=81ctor=20Falco=CC=81n?= Date: Sat, 4 Jul 2026 20:23:29 +0200 Subject: [PATCH] Block stray HTTP requests in the Feature test suite Feature tests could silently make real outbound HTTP requests when a code path was not covered by an Http::fake(), which is slow, flaky and network-dependent in CI. Adds a Feature-scoped beforeEach that calls Http::preventStrayRequests() so any unfaked request fails loudly instead. Tests that legitimately talk to external services register their own fakes, which take precedence. Ran a representative HTTP-touching subset with the guard active (open banking, exchange-rate/currency conversion, AI categorization and AI/stats reports, analytics, Discord and Stripe webhooks, bank-logo commands): no test relied on an unfaked real request, so no fakes had to be added. Adds StrayHttpRequestGuardTest to lock the behavior: an unfaked request throws StrayRequestException while a matched fake still resolves. --- tests/Feature/StrayHttpRequestGuardTest.php | 16 ++++++++++++++++ tests/Pest.php | 15 +++++++++++++++ 2 files changed, 31 insertions(+) create mode 100644 tests/Feature/StrayHttpRequestGuardTest.php diff --git a/tests/Feature/StrayHttpRequestGuardTest.php b/tests/Feature/StrayHttpRequestGuardTest.php new file mode 100644 index 00000000..8b40470a --- /dev/null +++ b/tests/Feature/StrayHttpRequestGuardTest.php @@ -0,0 +1,16 @@ +throws(StrayRequestException::class); + +test('a faked request still goes through when a matching fake is registered', function () { + Http::fake(['example.com/*' => Http::response(['ok' => true])]); + + $response = Http::get('https://example.com/allowed'); + + expect($response->json('ok'))->toBeTrue(); +}); diff --git a/tests/Pest.php b/tests/Pest.php index d3d6531f..69540061 100644 --- a/tests/Pest.php +++ b/tests/Pest.php @@ -14,6 +14,7 @@ use App\Services\Banking\Sync\BankingConnectionSyncerFactory; use App\Services\Banking\TransactionSyncService; use Illuminate\Foundation\Testing\RefreshDatabase; use Illuminate\Support\Facades\DB; +use Illuminate\Support\Facades\Http; use Stripe\Collection as StripeCollection; use Stripe\Service\SubscriptionService; use Stripe\StripeClient; @@ -52,6 +53,20 @@ pest()->beforeEach(function () { $this->withoutVite(); })->in('Feature', 'Performance'); +/* +|-------------------------------------------------------------------------- +| Block stray HTTP requests in Feature tests +|-------------------------------------------------------------------------- +| +| Any Feature test whose code path hits the network without a matching +| Http::fake() should fail loudly instead of making a real request. Tests +| that legitimately talk to external services register their own fakes, +| which take precedence over this guard. +*/ +pest()->beforeEach(function () { + Http::preventStrayRequests(); +})->in('Feature'); + /* |-------------------------------------------------------------------------- | Expectations