getJson(route('api.projects.index')) ->assertUnauthorized() ->assertJsonPath('message', 'Unauthenticated.'); } public function test_invalid_bearer_token_returns_unauthorized(): void { $this->withHeader('Authorization', 'Bearer wrong-key') ->getJson(route('api.projects.index')) ->assertUnauthorized() ->assertJsonPath('message', 'Unauthenticated.'); } public function test_valid_bearer_token_authenticates_as_owner(): void { $user = User::factory()->create(); $project = Project::factory()->create([ 'name' => 'Visible project', ]); $this->syncProjectPermissions($project, $user, ['view']); $this->withApplicationKey($user) ->getJson(route('api.projects.index')) ->assertOk() ->assertJsonPath('data.0.name', 'Visible project') ->assertJsonCount(1, 'data'); } public function test_application_key_owner_permissions_still_apply(): void { $user = User::factory()->create(); $visibleProject = Project::factory()->create([ 'name' => 'Visible project', ]); Project::factory()->create([ 'name' => 'Hidden project', ]); $this->syncProjectPermissions($visibleProject, $user, ['view']); $this->withApplicationKey($user) ->getJson(route('api.projects.index')) ->assertOk() ->assertJsonPath('data.0.name', 'Visible project') ->assertJsonCount(1, 'data'); } public function test_application_last_used_at_updates_after_use(): void { $user = User::factory()->create(); $project = Project::factory()->create(); $plainTextKey = UserApplication::generatePlainTextKey(); $application = UserApplication::query()->create([ 'key_hash' => UserApplication::hashKey($plainTextKey), 'name' => 'Claude Desktop', 'user_id' => $user->id, ]); $this->syncProjectPermissions($project, $user, ['view']); $this->withHeader('Authorization', "Bearer {$plainTextKey}") ->getJson(route('api.projects.index')) ->assertOk(); $this->assertNotNull($application->fresh()->last_used_at); } }