7 Notes, 0 Own notes, 0 Own private notes, 0 Own public notes

Prevent "Page Expired" errors in Laravel PEST testing with "actingAs"

If you want to test a POST route without loading a page first it will not work:

actingAs($user) ...
 1test('users can logout', function () {
 2    $user = User::factory()->create();
 3
 4    $response = $this->actingAs($user)
 5        ->post(route('logout-user'));
 6
 7    $response->assertRedirect(route('filament.user.pages..'));
 8
 9    $this->assertGuest();
10});

It will return a 419 status ("Page expired"), because the "CSRF" token will not be set.
(no session is started at the post request)

You MUST initialize the CSRF token before the post call:

Start session -or - Regenerate CSRF token (starts the session as well) ...
1test('users can logout', function () {
2    ...
3    session()->start(); // OR session()->regenerateToken();
4
5    $response = $this->actingAs($user)->post(route('logout-user'));
6    ...
7});

And it still will not work, the csrf_token must be passed with the post request:

Sample code... ...
1test('users can logout', function () {
2    ...
3    $response = $this
4        ->actingAs($user)
5        ->post(route('logout-user'), [
6            '_token' => csrf_token(),
7        ]);
8    ...
9});

-OR- add an empty array to the (non jet existing) session:

Sample code... ...
 1test('users can logout', function () {
 2    $user = User::factory()->create();
 3
 4    $response = $this
 5        ->actingAs($user)
 6        ->session([])
 7        ->post(route('logout-user'), [
 8            '_token' => csrf_token(),
 9        ]);
10
11    $response->assertRedirect(route('filament.user.pages..'));
12
13    $this->assertGuest();
14});

So a new session will be created and a "CSRF Token" will be generated.

2025-10-06 12:51:04
Powered by: Scriptum Version: v0.7.0-dev