From 1f9e5309d246287c3217864daf012e43c34555b2 Mon Sep 17 00:00:00 2001 From: BT Date: Sun, 3 May 2026 12:15:36 +0200 Subject: [PATCH] =?UTF-8?q?=E2=9C=A8=20**Middleware=20&=20Tests:**=20Impro?= =?UTF-8?q?ved=20exception=20handling=20for=20stale=20Livewire=20asset=20r?= =?UTF-8?q?equests=20to=20return=20404=20instead=20of=20500.=20Added=20fea?= =?UTF-8?q?ture=20tests=20to=20validate=20these=20scenarios.=20?= =?UTF-8?q?=F0=9F=9A=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- bootstrap/app.php | 35 +++++++++++-- tests/Feature/LivewireStaleAssetTest.php | 63 ++++++++++++++++++++++++ 2 files changed, 94 insertions(+), 4 deletions(-) create mode 100644 tests/Feature/LivewireStaleAssetTest.php diff --git a/bootstrap/app.php b/bootstrap/app.php index 55ba99d..dc34ac6 100644 --- a/bootstrap/app.php +++ b/bootstrap/app.php @@ -1,8 +1,12 @@ withRouting( @@ -13,11 +17,34 @@ return Application::configure(basePath: dirname(__DIR__)) ) ->withMiddleware(function (Middleware $middleware) { $middleware->web(append: [ - \App\Http\Middleware\DomainMiddleware::class, - \Stefro\LaravelLangCountry\Middleware\LangCountrySession::class, - \App\Http\Middleware\SetTimezone::class, + DomainMiddleware::class, + LangCountrySession::class, + SetTimezone::class, ]); }) ->withExceptions(function (Exceptions $exceptions) { - // + $exceptions->render(function (Throwable $e, Request $request) { + if (! preg_match('#^livewire-[a-f0-9]+/(?:css|js)/#', $request->path())) { + return null; + } + + $message = $e->getMessage(); + + $stalePatterns = [ + 'does not have a style source', + 'does not have a global style source', + 'does not have a script source', + 'Style file not found', + 'Global style file not found', + 'Script file not found', + ]; + + foreach ($stalePatterns as $pattern) { + if (str_contains($message, $pattern)) { + return response('', 404); + } + } + + return null; + }); })->create(); diff --git a/tests/Feature/LivewireStaleAssetTest.php b/tests/Feature/LivewireStaleAssetTest.php new file mode 100644 index 0000000..ddea720 --- /dev/null +++ b/tests/Feature/LivewireStaleAssetTest.php @@ -0,0 +1,63 @@ +get($prefix.'/css/meetups--landingpage.css?v=1502173559'); + + $response->assertNotFound(); +}); + +it('returns 404 for stale livewire global css module urls', function () { + $prefix = EndpointResolver::prefix(); + + $response = $this->get($prefix.'/css/meetups--landingpage.global.css?v=1'); + + $response->assertNotFound(); +}); + +it('returns 404 for stale livewire js module urls', function () { + $prefix = EndpointResolver::prefix(); + + $response = $this->get($prefix.'/js/meetups--landingpage.js?v=1'); + + $response->assertNotFound(); +}); + +it('still serves css for components that do have a style source', function () { + $componentName = '__staletest_with_style_'.bin2hex(random_bytes(4)); + $bladePath = resource_path('views/livewire/'.$componentName.'.blade.php'); + + file_put_contents($bladePath, <<<'BLADE' + test'; + } + }; ?> + +
test
+ + BLADE + ); + + try { + $prefix = EndpointResolver::prefix(); + + $response = $this->get($prefix.'/css/'.$componentName.'.css'); + + $response->assertSuccessful(); + $response->assertHeader('content-type', 'text/css; charset=utf-8'); + expect($response->getContent())->toContain('.foo')->toContain('color: red'); + } finally { + @unlink($bladePath); + } +});