How to test the token revocation for Laravel Passport with PestPHP?

54 Views Asked by At

I have followed this answer for logging out from a Laravel Passport API. I would like to test the method I have written, but I keep bumping into this SQL error when running sail pest tests/Feature/Http/Controllers/AuthenticationControllerTest.php:

SQLSTATE[HY000]: General error: 1364 Field \'id\' doesn\'t have a default value (Connection: mysql, SQL: insert into `oauth_access_tokens` (`scopes`, `revoked`, `updated_at`, `created_at`) values (["*"], 1, 2024-03-25 09:08:38, 2024-03-25 09:08:38))

I expected to receive:

Logged out succesfully.

This is the test I have written (in Pest):

// AuthenticationControllerTest.php

it('can logout', function () {
    $this->seed();
    $this->user    = User::first();
    Passport::actingAs($this->user, ['*']);

    $response = $this->postJson('api/v1/logout');

    $response
        ->assertJson([
            'message' => 'Logged out successfully.',
        ])->assertStatus(200);
});

the api definition:

// api.php

Route::post('logout', [AuthenticationController::class, 'logout']);

and here is the controller method itself:

// AuthenticationController.php

public function logout(Request $request): ?\Illuminate\Http\JsonResponse
{
    if (Auth::user() && $request->user() instanceof User && $request->user()->token() instanceof \Laravel\Passport\Token) {
        $token = Auth::user()->token();
        $token->revoke();
        return response()->json([
            'message' => 'Logged out successfully.',
        ], 200);
    }
    return null;
}

I suspect it has something to do with the Token class using forceFill to revoke the token, while it doesn't exist yet in the test, and the migration hasn't set a default id for the token. Why does it not exist in the test? It works perfectly outside of the testing environment...

Thanks for helping!

Edit 1: This is the migration used for oauth_access_tokens. It's one of the published migrations supplied by Laravel Passport itself. I feel discouraged from editing it as the developers of this file probably had a good reason to create it like this.

public function up(): void
{
    Schema::create('oauth_access_tokens', function (Blueprint $table) {
        $table->string('id', 100)->primary();
        $table->uuid('user_id')->nullable()->index();
        $table->uuid('client_id');
        $table->string('name')->nullable();
        $table->text('scopes')->nullable();
        $table->boolean('revoked');
        $table->timestamps();
        $table->dateTime('expires_at')->nullable();
    });
}
0

There are 0 best solutions below