['GET', '/api/v1/tickets', 'tickets:read'], 'GET categories' => ['GET', '/api/v1/categories', 'dictionaries:read'], 'GET users' => ['GET', '/api/v1/users', 'users:read'], ]; }); test('a request with no token is unauthenticated', function (string $method, string $uri) { $this->json($method, $uri)->assertUnauthorized(); })->with('protected_endpoints'); test('a token missing the required ability is forbidden', function (string $method, string $uri, string $requiredAbility) { $client = ApiClient::factory()->create(); Sanctum::actingAs($client, ['some:other-ability']); $this->json($method, $uri)->assertForbidden(); })->with('protected_endpoints'); test('a token with the required ability is allowed', function (string $method, string $uri, string $requiredAbility) { seedStatusesAndPriorities(); $client = ApiClient::factory()->create(); Sanctum::actingAs($client, [$requiredAbility]); $this->json($method, $uri)->assertOk(); })->with('protected_endpoints'); test('a token whose underlying access token has been deleted is rejected', function () { $client = ApiClient::factory()->create(); $token = $client->createToken('test', ['tickets:read']); $plaintext = $token->plainTextToken; $client->tokens()->delete(); $this->withHeader('Authorization', 'Bearer '.$plaintext) ->getJson('/api/v1/tickets') ->assertUnauthorized(); });