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();
});
}