From 7ebca031562b3131e3d0a305be1226cf4f39e3a2 Mon Sep 17 00:00:00 2001 From: Raj Siva-Rajah <5361908+binaryfire@users.noreply.github.com> Date: Thu, 14 May 2026 01:06:45 +0000 Subject: [PATCH 01/11] Add configureSessionCookieUsing extension point to StartSession Replaces the subclass-based getSessionCookieConfig() override with a static callback registry. Callbacks run in registration order, each receiving the previous callback's output. Threads Request through to the resolver so callbacks can vary cookie attributes per-request without mutating worker-global config. --- src/session/src/Middleware/StartSession.php | 51 +++++++++++++++++---- 1 file changed, 43 insertions(+), 8 deletions(-) diff --git a/src/session/src/Middleware/StartSession.php b/src/session/src/Middleware/StartSession.php index 9e15fa55a..c9db11919 100644 --- a/src/session/src/Middleware/StartSession.php +++ b/src/session/src/Middleware/StartSession.php @@ -23,6 +23,13 @@ class StartSession { + /** + * The callbacks used to configure the session cookie attributes. + * + * @var array + */ + protected static array $sessionCookieCallbacks = []; + /** * Create a new session middleware. */ @@ -106,7 +113,7 @@ protected function handleStatefulRequest(Request $request, Session $session, Clo $this->storeCurrentUrl($request, $session); - $this->addCookieToResponse($response, $session); + $this->addCookieToResponse($request, $response, $session); // Again, if the session has been configured we will need to close out the session // so that the attributes may be persisted to some storage medium. We will also @@ -189,10 +196,10 @@ protected function storeCurrentUrl(Request $request, Session $session): void /** * Add the session cookie to the application response. */ - protected function addCookieToResponse(Response $response, Session $session): void + protected function addCookieToResponse(Request $request, Response $response, Session $session): void { if ($this->sessionIsPersistent($config = $this->manager->getSessionConfig())) { - $cookieConfig = $this->getSessionCookieConfig($config); + $cookieConfig = $this->resolveSessionCookieConfig($request, $config); $response->headers->setCookie(new Cookie( $session->getName(), @@ -212,14 +219,11 @@ protected function addCookieToResponse(Response $response, Session $session): vo /** * Get the session cookie configuration. * - * Extracted as an extension point so subclasses can provide dynamic - * cookie settings without duplicating the rest of addCookieToResponse. - * * @return array{path: string, domain: string, secure: ?bool, http_only: bool, same_site: ?string, partitioned: bool} */ - protected function getSessionCookieConfig(array $config): array + protected function resolveSessionCookieConfig(Request $request, array $config): array { - return [ + $cookieConfig = [ 'path' => $config['path'] ?? '/', 'domain' => $config['domain'] ?? '', 'secure' => $config['secure'] ?? null, @@ -227,6 +231,27 @@ protected function getSessionCookieConfig(array $config): array 'same_site' => $config['same_site'] ?? null, 'partitioned' => $config['partitioned'] ?? false, ]; + + foreach (static::$sessionCookieCallbacks as $callback) { + $cookieConfig = $callback($request, $cookieConfig); + } + + return $cookieConfig; + } + + /** + * Register a callback to configure the session cookie attributes. + * + * Boot-only. The callback persists in a static property for the worker + * lifetime and runs on every session cookie write across all coroutines. + * Callbacks run in registration order; later callbacks receive the values + * returned by earlier callbacks and may overwrite them. + * + * @param Closure(Request, array): array $callback + */ + public static function configureSessionCookieUsing(Closure $callback): void + { + static::$sessionCookieCallbacks[] = $callback; } /** @@ -276,4 +301,14 @@ protected function sessionIsPersistent(?array $config = null): bool return ! is_null($config['driver'] ?? null); } + + /** + * Flush all static state back to defaults. + * + * Boot or tests only. Resets the registered cookie configuration callbacks. + */ + public static function flushState(): void + { + static::$sessionCookieCallbacks = []; + } } From ccbd634001b0d039f46f04781a09bab986409b5a Mon Sep 17 00:00:00 2001 From: Raj Siva-Rajah <5361908+binaryfire@users.noreply.github.com> Date: Thu, 14 May 2026 01:06:50 +0000 Subject: [PATCH 02/11] Update StartSessionTest for callback-based cookie config extension Replaces the subclass-override test with four callback tests covering single-callback registration, per-request behavior via Request, chained composition in registration order, and flushState clearing the registry. Switches base class to Hypervel\Tests\TestCase and the reflection helper to ClassInvoker. --- tests/Session/Middleware/StartSessionTest.php | 104 ++++++++++++------ 1 file changed, 73 insertions(+), 31 deletions(-) diff --git a/tests/Session/Middleware/StartSessionTest.php b/tests/Session/Middleware/StartSessionTest.php index aa8dff377..048ab229d 100644 --- a/tests/Session/Middleware/StartSessionTest.php +++ b/tests/Session/Middleware/StartSessionTest.php @@ -4,17 +4,18 @@ namespace Hypervel\Tests\Session\Middleware; +use Hypervel\Http\Request; use Hypervel\Session\Middleware\StartSession; -use PHPUnit\Framework\TestCase; -use ReflectionMethod; +use Hypervel\Support\ClassInvoker; +use Hypervel\Tests\TestCase; class StartSessionTest extends TestCase { - public function testGetSessionCookieConfigReturnsDefaults(): void + public function testResolveSessionCookieConfigReturnsDefaults(): void { $middleware = $this->createStartSessionMock(); - $config = $this->invokeGetSessionCookieConfig($middleware, []); + $config = $this->invokeResolveSessionCookieConfig($middleware, Request::create('/'), []); $this->assertSame('/', $config['path']); $this->assertSame('', $config['domain']); @@ -24,11 +25,11 @@ public function testGetSessionCookieConfigReturnsDefaults(): void $this->assertFalse($config['partitioned']); } - public function testGetSessionCookieConfigReturnsConfiguredValues(): void + public function testResolveSessionCookieConfigReturnsConfiguredValues(): void { $middleware = $this->createStartSessionMock(); - $config = $this->invokeGetSessionCookieConfig($middleware, [ + $config = $this->invokeResolveSessionCookieConfig($middleware, Request::create('/'), [ 'path' => '/app', 'domain' => '.example.com', 'secure' => true, @@ -45,53 +46,94 @@ public function testGetSessionCookieConfigReturnsConfiguredValues(): void $this->assertTrue($config['partitioned']); } - public function testGetSessionCookieConfigCanBeOverridden(): void + public function testSessionCookieConfigCanBeConfiguredUsingCallback(): void { - $middleware = new CustomStartSession; + $middleware = $this->createStartSessionMock(); + + StartSession::configureSessionCookieUsing(function (Request $request, array $cookie): array { + $cookie['domain'] = '.custom.example.com'; - $config = $this->invokeGetSessionCookieConfig($middleware, [ + return $cookie; + }); + + $config = $this->invokeResolveSessionCookieConfig($middleware, Request::create('/'), [ 'path' => '/', 'domain' => '.example.com', ]); - // Custom middleware overrides domain $this->assertSame('.custom.example.com', $config['domain']); - // Other values come from config $this->assertSame('/', $config['path']); } - private function createStartSessionMock(): StartSession + public function testSessionCookieConfigCallbacksReceiveRequest(): void { - return new TestStartSession; + $middleware = $this->createStartSessionMock(); + + StartSession::configureSessionCookieUsing(function (Request $request, array $cookie): array { + $cookie['domain'] = '.' . $request->getHost(); + + return $cookie; + }); + + $config = $this->invokeResolveSessionCookieConfig( + $middleware, + Request::create('https://tenant.example.com'), + [] + ); + + $this->assertSame('.tenant.example.com', $config['domain']); } - private function invokeGetSessionCookieConfig(StartSession $middleware, array $config): array + public function testSessionCookieConfigCallbacksComposeInRegistrationOrder(): void { - $method = new ReflectionMethod($middleware, 'getSessionCookieConfig'); - $method->setAccessible(true); + $middleware = $this->createStartSessionMock(); + + StartSession::configureSessionCookieUsing(function (Request $request, array $cookie): array { + $cookie['same_site'] = 'strict'; + $cookie['domain'] = '.first.example.com'; + + return $cookie; + }); + StartSession::configureSessionCookieUsing(function (Request $request, array $cookie): array { + $cookie['same_site'] = 'lax'; + + return $cookie; + }); + + $config = $this->invokeResolveSessionCookieConfig($middleware, Request::create('/'), []); - return $method->invoke($middleware, $config); + $this->assertSame('.first.example.com', $config['domain']); + $this->assertSame('lax', $config['same_site']); } -} -/** - * Custom middleware for testing getSessionCookieConfig override. - */ -class CustomStartSession extends StartSession -{ - public function __construct() + public function testFlushStateClearsSessionCookieCallbacks(): void { - // Skip parent constructor for testing + $middleware = $this->createStartSessionMock(); + + StartSession::configureSessionCookieUsing(function (Request $request, array $cookie): array { + $cookie['domain'] = '.custom.example.com'; + + return $cookie; + }); + + $this->assertSame( + '.custom.example.com', + $this->invokeResolveSessionCookieConfig($middleware, Request::create('/'), [])['domain'] + ); + + StartSession::flushState(); + + $this->assertSame('', $this->invokeResolveSessionCookieConfig($middleware, Request::create('/'), [])['domain']); } - protected function getSessionCookieConfig(array $config): array + private function createStartSessionMock(): StartSession { - $cookieConfig = parent::getSessionCookieConfig($config); - - // Override domain - $cookieConfig['domain'] = '.custom.example.com'; + return new TestStartSession; + } - return $cookieConfig; + private function invokeResolveSessionCookieConfig(StartSession $middleware, Request $request, array $config): array + { + return (new ClassInvoker($middleware))->resolveSessionCookieConfig($request, $config); } } From a4a4e43908593e2bdef4a61812721b71e11f2e95 Mon Sep 17 00:00:00 2001 From: Raj Siva-Rajah <5361908+binaryfire@users.noreply.github.com> Date: Thu, 14 May 2026 01:06:55 +0000 Subject: [PATCH 03/11] Register StartSession and SanctumGuard flushStates in test subscriber Prevents the new StartSession cookie callback registry and SanctumGuard Macroable state from leaking between tests. --- tests/AfterEachTestSubscriber.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/AfterEachTestSubscriber.php b/tests/AfterEachTestSubscriber.php index 97d4c8d8e..bf3caaa95 100644 --- a/tests/AfterEachTestSubscriber.php +++ b/tests/AfterEachTestSubscriber.php @@ -143,12 +143,14 @@ public function notify(Finished $event): void \Hypervel\Routing\SortedMiddleware::flushCache(); \Hypervel\Routing\UrlGenerator::flushState(); \Hypervel\Sanctum\Sanctum::flushState(); + \Hypervel\Sanctum\SanctumGuard::flushState(); \Hypervel\Scout\Builder::flushState(); \Hypervel\Scout\Scout::flushState(); \Hypervel\Server\ServerManager::flushState(); \Hypervel\ServerProcess\ProcessCollector::flushState(); \Hypervel\ServerProcess\ProcessManager::flushState(); \Hypervel\Session\Middleware\AuthenticateSession::flushState(); + \Hypervel\Session\Middleware\StartSession::flushState(); \Hypervel\Session\Store::flushState(); \Hypervel\Support\Arr::flushState(); \Hypervel\Support\BinaryCodec::flushState(); From 76f5ebd0e0976c147254df419f2e3645674dbf5d Mon Sep 17 00:00:00 2001 From: Raj Siva-Rajah <5361908+binaryfire@users.noreply.github.com> Date: Thu, 14 May 2026 01:07:00 +0000 Subject: [PATCH 04/11] Document configureSessionCookieUsing in session docs Adds a Configuring the Session Cookie section covering the new StartSession callback API, its boot-time registration pattern, and chained registration semantics. --- src/boost/docs/session.md | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/src/boost/docs/session.md b/src/boost/docs/session.md index 9bfd9a35b..29bfb98fc 100644 --- a/src/boost/docs/session.md +++ b/src/boost/docs/session.md @@ -11,6 +11,7 @@ - [Regenerating the Session ID](#regenerating-the-session-id) - [Session Cache](#session-cache) - [Session Blocking](#session-blocking) +- [Configuring the Session Cookie](#configuring-the-session-cookie) - [Adding Custom Session Drivers](#adding-custom-session-drivers) - [Implementing the Driver](#implementing-the-driver) - [Registering the Driver](#registering-the-driver) @@ -329,6 +330,42 @@ Route::post('/profile', function () { })->block(); ``` + +## Configuring the Session Cookie + +Session cookie attributes are normally configured using your application's `config/session.php` configuration file. If you need to determine session cookie attributes dynamically for each request, you may register a callback using the `configureSessionCookieUsing` method on the `StartSession` middleware. + +This method should typically be called from the `boot` method of a [service provider](/docs/{{version}}/providers): + +```php + tenant()->sessionCookieDomain(), + ]); + }); + } +} +``` + +The callback receives the current request and the session cookie configuration, and should return the modified cookie configuration. This is useful when cookie attributes, such as the cookie domain, depend on the current request. In this example, `tenant()` represents an application-specific helper that returns the current tenant. + +If multiple callbacks are registered, they will be executed in the order they were registered. Each callback receives the cookie configuration returned by the previous callback. + ## Adding Custom Session Drivers From 49ebd87c46a4f6c90f069afab9ea16b2587eb31e Mon Sep 17 00:00:00 2001 From: Raj Siva-Rajah <5361908+binaryfire@users.noreply.github.com> Date: Thu, 14 May 2026 01:07:04 +0000 Subject: [PATCH 05/11] Remove configureSecureCookieSessions from Sanctum middleware Drops the unconditional config([...]) mutation that fired on every request through this middleware. Under Swoole the mutation persisted on the worker-global config singleton and leaked across concurrent requests. Cookie hardening is now applied via a StartSession callback registered by SanctumServiceProvider. --- .../EnsureFrontendRequestsAreStateful.php | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/src/sanctum/src/Http/Middleware/EnsureFrontendRequestsAreStateful.php b/src/sanctum/src/Http/Middleware/EnsureFrontendRequestsAreStateful.php index 0b039bfb0..762044192 100644 --- a/src/sanctum/src/Http/Middleware/EnsureFrontendRequestsAreStateful.php +++ b/src/sanctum/src/Http/Middleware/EnsureFrontendRequestsAreStateful.php @@ -19,8 +19,6 @@ class EnsureFrontendRequestsAreStateful */ public function handle(Request $request, Closure $next): Response { - $this->configureSecureCookieSessions(); - return (new Pipeline(app()))->send($request)->through( static::fromFrontend($request) ? $this->frontendMiddleware() : [] )->then(function ($request) use ($next) { @@ -85,15 +83,4 @@ public static function statefulDomains(): array { return config('sanctum.stateful', []); } - - /** - * Configure secure cookie sessions. - */ - protected function configureSecureCookieSessions(): void - { - config([ - 'session.http_only' => true, - 'session.same_site' => 'lax', - ]); - } } From 82efd631461a087b0935cdb600551b0556dccb95 Mon Sep 17 00:00:00 2001 From: Raj Siva-Rajah <5361908+binaryfire@users.noreply.github.com> Date: Thu, 14 May 2026 01:07:09 +0000 Subject: [PATCH 06/11] Register Sanctum cookie hardening via StartSession callback Replaces the runtime config mutation with a boot-time configureSessionCookieUsing callback that forces http_only=true and same_site=lax only when the request has the sanctum attribute set by EnsureFrontendRequestsAreStateful's prepended inline middleware. --- src/sanctum/src/SanctumServiceProvider.php | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/src/sanctum/src/SanctumServiceProvider.php b/src/sanctum/src/SanctumServiceProvider.php index b84019158..35ade5137 100644 --- a/src/sanctum/src/SanctumServiceProvider.php +++ b/src/sanctum/src/SanctumServiceProvider.php @@ -5,7 +5,9 @@ namespace Hypervel\Sanctum; use Hypervel\Auth\AuthManager; +use Hypervel\Http\Request; use Hypervel\Sanctum\Console\Commands\PruneExpired; +use Hypervel\Session\Middleware\StartSession; use Hypervel\Support\Facades\Route; use Hypervel\Support\ServiceProvider; @@ -28,6 +30,8 @@ public function register(): void public function boot(): void { $this->registerSanctumGuard(); + $this->configureSessionCookies(); + if ($this->app->runningInConsole()) { $this->registerPublishing(); $this->registerCommands(); @@ -54,6 +58,23 @@ protected function registerSanctumGuard(): void }); } + /** + * Configure session cookies for stateful frontend requests. + */ + protected function configureSessionCookies(): void + { + StartSession::configureSessionCookieUsing(function (Request $request, array $cookie): array { + if (! $request->attributes->get('sanctum')) { + return $cookie; + } + + return array_replace($cookie, [ + 'http_only' => true, + 'same_site' => 'lax', + ]); + }); + } + /** * Register the package routes. */ From 0c12639fd55ef832e74a04fc7a769682a63c1ea3 Mon Sep 17 00:00:00 2001 From: Raj Siva-Rajah <5361908+binaryfire@users.noreply.github.com> Date: Thu, 14 May 2026 01:07:14 +0000 Subject: [PATCH 07/11] Add SanctumGuard::flushState for Macroable test isolation SanctumGuard is effectively a worker-lifetime singleton (cached in AuthManager's guards registry, and AuthManager is itself a singleton). Without flushState, macros registered on the Macroable trait persisted across tests and across coroutines for the worker lifetime. --- src/sanctum/src/SanctumGuard.php | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/sanctum/src/SanctumGuard.php b/src/sanctum/src/SanctumGuard.php index 68d156479..db3c5b59e 100644 --- a/src/sanctum/src/SanctumGuard.php +++ b/src/sanctum/src/SanctumGuard.php @@ -275,4 +275,14 @@ protected function getContextKeyForToken(?string $token): string return "__auth.guards.{$this->name}.user." . md5($token); } + + /** + * Flush all static state back to defaults. + * + * Boot or tests only. Resets registered macros on the guard class. + */ + public static function flushState(): void + { + static::flushMacros(); + } } From f1871384b7308c5058689c8c1f06e61477381e67 Mon Sep 17 00:00:00 2001 From: Raj Siva-Rajah <5361908+binaryfire@users.noreply.github.com> Date: Thu, 14 May 2026 01:07:19 +0000 Subject: [PATCH 08/11] Add regression test for Sanctum middleware session-config mutation Sets session.http_only=false and session.same_site=strict to non-default values, runs EnsureFrontendRequestsAreStateful, and asserts both values are still unchanged. Catches any regression that reintroduces the removed configureSecureCookieSessions config([...]) call. --- .../EnsureFrontendRequestsAreStatefulTest.php | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/tests/Sanctum/EnsureFrontendRequestsAreStatefulTest.php b/tests/Sanctum/EnsureFrontendRequestsAreStatefulTest.php index cc1a14e25..c0a3bf23e 100644 --- a/tests/Sanctum/EnsureFrontendRequestsAreStatefulTest.php +++ b/tests/Sanctum/EnsureFrontendRequestsAreStatefulTest.php @@ -5,6 +5,7 @@ namespace Hypervel\Tests\Sanctum; use Hypervel\Http\Request; +use Hypervel\Http\Response; use Hypervel\Sanctum\Http\Middleware\EnsureFrontendRequestsAreStateful; use Hypervel\Testbench\TestCase; @@ -71,6 +72,21 @@ public function testStatefulDomainsCanBeOverridden(): void // Custom middleware with overridden statefulDomains SHOULD match $this->assertTrue(CustomStatefulMiddleware::fromFrontend($request)); } + + public function testMiddlewareDoesNotMutateSessionConfig(): void + { + $this->app->make('config')->set([ + 'session.http_only' => false, + 'session.same_site' => 'strict', + ]); + + $request = Request::create('http://localhost', server: ['HTTP_ORIGIN' => 'https://wrong.com']); + + (new EnsureFrontendRequestsAreStateful())->handle($request, fn () => new Response('ok')); + + $this->assertFalse($this->app->make('config')->get('session.http_only')); + $this->assertSame('strict', $this->app->make('config')->get('session.same_site')); + } } /** From de28a976376e592e98a41c121c2c23e16379b5ce Mon Sep 17 00:00:00 2001 From: Raj Siva-Rajah <5361908+binaryfire@users.noreply.github.com> Date: Thu, 14 May 2026 01:07:24 +0000 Subject: [PATCH 09/11] Add Sanctum frontend cookie hardening tests Covers three contracts: stateful Sanctum frontend requests force http_only=true and same_site=lax on the session cookie; app-level StartSession callbacks compose with Sanctum's hardening; non-Sanctum requests bypass the hardening based on the sanctum request attribute. --- tests/Sanctum/FrontendCookieHardeningTest.php | 93 +++++++++++++++++++ 1 file changed, 93 insertions(+) create mode 100644 tests/Sanctum/FrontendCookieHardeningTest.php diff --git a/tests/Sanctum/FrontendCookieHardeningTest.php b/tests/Sanctum/FrontendCookieHardeningTest.php new file mode 100644 index 000000000..c92f8f7f9 --- /dev/null +++ b/tests/Sanctum/FrontendCookieHardeningTest.php @@ -0,0 +1,93 @@ +app->make('config')->set([ + 'session.driver' => 'array', + 'session.http_only' => false, + 'session.same_site' => 'strict', + 'sanctum.stateful' => ['test.com'], + ]); + + $provider = $this->app->make(SanctumServiceProvider::class); + $provider->register(); + $provider->boot(); + } + + public function testStatefulFrontendRequestForcesSecureSessionCookieAttributes(): void + { + $cookie = $this->sessionCookie($this->handleStatefulFrontendRequest()); + + $this->assertTrue($cookie->isHttpOnly()); + $this->assertSame('lax', $cookie->getSameSite()); + $this->assertFalse($this->app->make('config')->get('session.http_only')); + $this->assertSame('strict', $this->app->make('config')->get('session.same_site')); + } + + public function testSanctumSessionCookieHonorsApplicationCookieCallbacks(): void + { + StartSession::configureSessionCookieUsing(function (Request $request, array $cookie): array { + $cookie['domain'] = '.example.com'; + + return $cookie; + }); + + $cookie = $this->sessionCookie($this->handleStatefulFrontendRequest()); + + $this->assertSame('.example.com', $cookie->getDomain()); + $this->assertTrue($cookie->isHttpOnly()); + $this->assertSame('lax', $cookie->getSameSite()); + } + + public function testNonSanctumSessionCookieDoesNotReceiveSanctumHardening(): void + { + $request = Request::create('http://localhost/normal', 'GET'); + + $response = $this->app->make(StartSession::class) + ->handle($request, fn () => new Response('ok')); + + $cookie = $this->sessionCookie($response); + + $this->assertFalse($cookie->isHttpOnly()); + $this->assertSame('strict', $cookie->getSameSite()); + } + + protected function handleStatefulFrontendRequest(): Response + { + $request = Request::create('http://localhost/probe', 'GET', server: [ + 'HTTP_ORIGIN' => 'https://test.com', + ]); + + return (new EnsureFrontendRequestsAreStateful()) + ->handle($request, fn () => new Response('ok')); + } + + protected function sessionCookie(Response $response): Cookie + { + $sessionCookieName = $this->app->make('config')->get('session.cookie'); + + foreach ($response->headers->getCookies() as $cookie) { + if ($cookie->getName() === $sessionCookieName) { + return $cookie; + } + } + + $this->fail("Session cookie [{$sessionCookieName}] was not set."); + } +} From a3755de270cff84ab565d48e6a9d97e70386f21e Mon Sep 17 00:00:00 2001 From: Raj Siva-Rajah <5361908+binaryfire@users.noreply.github.com> Date: Thu, 14 May 2026 01:07:29 +0000 Subject: [PATCH 10/11] Add SanctumGuard macro flushState test Locks in that SanctumGuard::flushState() clears Macroable-registered macros, guarding the test-isolation contract for the worker-lifetime singleton guard. --- tests/Sanctum/SanctumGuardStaticStateTest.php | 22 +++++++++++++++++++ 1 file changed, 22 insertions(+) create mode 100644 tests/Sanctum/SanctumGuardStaticStateTest.php diff --git a/tests/Sanctum/SanctumGuardStaticStateTest.php b/tests/Sanctum/SanctumGuardStaticStateTest.php new file mode 100644 index 000000000..b1411f85d --- /dev/null +++ b/tests/Sanctum/SanctumGuardStaticStateTest.php @@ -0,0 +1,22 @@ + 'ok'); + + $this->assertTrue(SanctumGuard::hasMacro('staticStateProbe')); + + SanctumGuard::flushState(); + + $this->assertFalse(SanctumGuard::hasMacro('staticStateProbe')); + } +} From d49222855ae6f1665485d73260759e04c322231a Mon Sep 17 00:00:00 2001 From: Raj Siva-Rajah <5361908+binaryfire@users.noreply.github.com> Date: Thu, 14 May 2026 01:13:20 +0000 Subject: [PATCH 11/11] Fix code style --- tests/Routing/RoutingStaticStateTest.php | 30 +++++++++---------- .../EnsureFrontendRequestsAreStatefulTest.php | 2 +- tests/Sanctum/FrontendCookieHardeningTest.php | 2 +- 3 files changed, 17 insertions(+), 17 deletions(-) diff --git a/tests/Routing/RoutingStaticStateTest.php b/tests/Routing/RoutingStaticStateTest.php index 952bd7938..dcb6b339e 100644 --- a/tests/Routing/RoutingStaticStateTest.php +++ b/tests/Routing/RoutingStaticStateTest.php @@ -12,8 +12,8 @@ use Hypervel\Routing\ResponseFactory; use Hypervel\Routing\Route; use Hypervel\Routing\RouteCollection; -use Hypervel\Routing\RouteRegistrar; use Hypervel\Routing\Router; +use Hypervel\Routing\RouteRegistrar; use Hypervel\Routing\UrlGenerator; use Hypervel\Tests\Routing\RoutingTestCase; use PHPUnit\Framework\Attributes\DataProvider; @@ -36,12 +36,24 @@ public function testFlushStateClearsRoutingMacros(string $class): void $this->assertFalse($class::hasMacro('routingFlushProbe')); } + public static function macroableRoutingClasses(): array + { + return [ + [PendingResourceRegistration::class], + [PendingSingletonResourceRegistration::class], + [Redirector::class], + [ResponseFactory::class], + [RouteRegistrar::class], + [Router::class], + ]; + } + public function testRouteFlushStateClearsEnumCache(): void { $enumCache = new ReflectionProperty(Route::class, 'enumCache'); - $enumCache->setValue(null, ['Some\\Enum' => true]); + $enumCache->setValue(null, ['Some\Enum' => true]); - $this->assertSame(['Some\\Enum' => true], $enumCache->getValue()); + $this->assertSame(['Some\Enum' => true], $enumCache->getValue()); Route::flushState(); @@ -79,16 +91,4 @@ public function testThrottleRequestsFlushStateRestoresHashedKeys(): void $this->assertTrue($shouldHashKeys->getValue()); } - - public static function macroableRoutingClasses(): array - { - return [ - [PendingResourceRegistration::class], - [PendingSingletonResourceRegistration::class], - [Redirector::class], - [ResponseFactory::class], - [RouteRegistrar::class], - [Router::class], - ]; - } } diff --git a/tests/Sanctum/EnsureFrontendRequestsAreStatefulTest.php b/tests/Sanctum/EnsureFrontendRequestsAreStatefulTest.php index c0a3bf23e..bb06f8f5d 100644 --- a/tests/Sanctum/EnsureFrontendRequestsAreStatefulTest.php +++ b/tests/Sanctum/EnsureFrontendRequestsAreStatefulTest.php @@ -82,7 +82,7 @@ public function testMiddlewareDoesNotMutateSessionConfig(): void $request = Request::create('http://localhost', server: ['HTTP_ORIGIN' => 'https://wrong.com']); - (new EnsureFrontendRequestsAreStateful())->handle($request, fn () => new Response('ok')); + (new EnsureFrontendRequestsAreStateful)->handle($request, fn () => new Response('ok')); $this->assertFalse($this->app->make('config')->get('session.http_only')); $this->assertSame('strict', $this->app->make('config')->get('session.same_site')); diff --git a/tests/Sanctum/FrontendCookieHardeningTest.php b/tests/Sanctum/FrontendCookieHardeningTest.php index c92f8f7f9..ce09909a8 100644 --- a/tests/Sanctum/FrontendCookieHardeningTest.php +++ b/tests/Sanctum/FrontendCookieHardeningTest.php @@ -74,7 +74,7 @@ protected function handleStatefulFrontendRequest(): Response 'HTTP_ORIGIN' => 'https://test.com', ]); - return (new EnsureFrontendRequestsAreStateful()) + return (new EnsureFrontendRequestsAreStateful) ->handle($request, fn () => new Response('ok')); }