trevorpan's avatar

CSRF token mismatch. ($this->withoutExceptionHandling() not doing its job)

Hey there,

The test suite passes sometimes but not others. I'm at a loss as to why this occurs randomly.

Using sqlite, :memory: local env.

/** @test
     *
     * @throws Illuminate\Session\TokenMismatchException
     */
    public function registering_with_a_valid_invitation_code()
    {
        $this->withoutExceptionHandling();
//        dd(env('APP_ENV'));
        $shelley = factory(User::class)->create([
                    'firstname' => 'Shelley',
                    'email' => '[email protected]',
        ]);
        $this->assertEquals(1, User::count());
        $invitation = factory(Invitation::class)->create([
            'inviter_user_id' => $shelley->id,
            'invitation_code' => 'TESTCODE1234',
        ]);

        $this->assertDatabaseHas('users', [
            'email' => '[email protected]',
        ]);

        $response = $this->from('/invitations/TESTCODE1234')->post('/invitations/register', [
            'firstname' => 'John',
            'lastname' => 'Smith',
            'email' => '[email protected]',
            'password' => 'secretsecret',
            'password_confirmation' => 'secretsecret',
            'invitation_code' => 'TESTCODE1234',
        ]);

        $response->assertRedirect('/email/verify');

        $this->assertEquals(2, User::count());
        $inviterShelley = User::first();
        $john = User::find(2);

        $this->actingAs($john);
        $this->assertEquals('[email protected]', $inviterShelley->email);
        $this->assertEquals('[email protected]', $john->email);
        $this->assertTrue(Hash::check('secretsecret', $john->password));

//        dd($invitation);
//        dd($invitation->fresh()->invitedUser);
        $this->assertTrue($invitation->fresh()->invitedUser->is($john));

        $this->assertDatabaseHas('users', [
            'email' => '[email protected]',
        ]);

        $this->assertDatabaseHas('invitations', [
            'user_id' => $john->id,
        ]);

    }
0 likes
3 replies
trevorpan's avatar

Looking at this more closely I may have found the issue - but not certain.

The InvitationsController posts the invitation in an email form on the dashboard. The dashboard displays the form. The dashboard has auth, verified middleware applied.

I'm thinking the show method needs to be broken off the InvitationsController to the InvitationsShowController (or something like that).

Have you faced a similar situation?

trevorpan's avatar

\Session\TokenMismatchException: CSRF token mismatch.

Does anyone know why this would trigger in a phpunit test?

trevorpan's avatar

https://medium.com/p/d9c00fbef263/responses/show

This article really helped. What started as the csrf token mismatch exception became expected 200 but got 419 errors.

It's still confusing how the docs in laravel https://laravel.com/docs/7.x/configuration#environment-configuration advocate for a .env.testing file.

https://laravel.com/docs/7.x/testing#environment advocates for .env.testing file.

Dusk https://laravel.com/docs/7.x/dusk#environment-handling has .env.dusk.local It also uses another config file: phpunit.dusk.local

    /**
     * Determine if the application is running unit tests.
     *
     * @return bool
     */
    public function runningUnitTests()
    {
        return $this['env'] === 'testing';
    }

Yet, the .env that ships with laravel uses the local ENV.

Here the appserviceprovider:

    /**
     * Register any application services.
     *
     * @return void
     */
    public function register()
    {
        //
        if ($this->app->isLocal()) {
            $this->app->register(TelescopeServiceProvider::class);
            $this->app->register(DuskServiceProvider::class);
        }

requires local env.

I'm still having a hard time understanding what takes precedence. It seems like one .env file should be able to configure everything instead we have about 4 or 5 if you include production.

Please or to participate in this conversation.