mirror of
https://github.com/solidtime-io/solidtime.git
synced 2026-08-14 19:22:14 +01:00
Added API endpoints for user API tokens
This commit is contained in:
@@ -5,6 +5,7 @@ declare(strict_types=1);
|
||||
namespace Tests\Unit\Database;
|
||||
|
||||
use Illuminate\Foundation\Testing\RefreshDatabase;
|
||||
use Illuminate\Support\Facades\Config;
|
||||
use Tests\TestCase;
|
||||
|
||||
class SeederTest extends TestCase
|
||||
@@ -13,6 +14,7 @@ class SeederTest extends TestCase
|
||||
|
||||
public function test_running_the_seeder_multiple_times_runs_successfully(): void
|
||||
{
|
||||
$this->setupForSeeder();
|
||||
$this->artisan('db:seed')
|
||||
->assertSuccessful();
|
||||
$this->artisan('db:seed')
|
||||
@@ -21,9 +23,16 @@ class SeederTest extends TestCase
|
||||
|
||||
public function test_fresh_migration_with_seeder_and_rollback_runs_successfully(): void
|
||||
{
|
||||
$this->setupForSeeder();
|
||||
$this->artisan('db:seed')
|
||||
->assertSuccessful();
|
||||
$this->artisan('migrate:rollback')
|
||||
->assertSuccessful();
|
||||
}
|
||||
|
||||
private function setupForSeeder(): void
|
||||
{
|
||||
Config::set('passport.personal_access_client.id', '9e27f54d-5dfb-4dde-99d7-834518236c92');
|
||||
Config::set('passport.personal_access_client.secret', 'EL5mXp3aF8ITjcwoOXRpbSK7zGrWhW4zTDpQXTkf');
|
||||
}
|
||||
}
|
||||
|
||||
186
tests/Unit/Endpoint/Api/V1/ApiTokenEndpointTest.php
Normal file
186
tests/Unit/Endpoint/Api/V1/ApiTokenEndpointTest.php
Normal file
@@ -0,0 +1,186 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Tests\Unit\Endpoint\Api\V1;
|
||||
|
||||
use App\Http\Controllers\Api\V1\ApiTokenController;
|
||||
use App\Models\Passport\Client;
|
||||
use App\Models\Passport\Token;
|
||||
use Illuminate\Support\Facades\Config;
|
||||
use Laravel\Passport\ClientRepository;
|
||||
use Laravel\Passport\Passport;
|
||||
use PHPUnit\Framework\Attributes\UsesClass;
|
||||
|
||||
#[UsesClass(ApiTokenController::class)]
|
||||
class ApiTokenEndpointTest extends ApiEndpointTestAbstract
|
||||
{
|
||||
public function test_index_endpoint_returns_list_api_tokens(): void
|
||||
{
|
||||
// Arrange
|
||||
$data = $this->createUserWithPermission([]);
|
||||
$client = $this->createPersonalAccessClient();
|
||||
$token = Token::factory()->forUser($data->user)->forClient($client)->create();
|
||||
$otherData = $this->createUserWithPermission([]);
|
||||
$otherToken = Token::factory()->forUser($otherData->user)->forClient($client)->create();
|
||||
Passport::actingAs($data->user);
|
||||
|
||||
// Act
|
||||
$response = $this->getJson(route('api.v1.api-tokens.index'));
|
||||
|
||||
// Assert
|
||||
$this->assertResponseCode($response, 200);
|
||||
$response->assertExactJson([
|
||||
'data' => [
|
||||
[
|
||||
'id' => $token->id,
|
||||
'name' => $token->name,
|
||||
'scopes' => $token->scopes,
|
||||
'revoked' => $token->revoked,
|
||||
'created_at' => $token->created_at->toIso8601ZuluString(),
|
||||
'expires_at' => $token->expires_at->toIso8601ZuluString(),
|
||||
],
|
||||
],
|
||||
]);
|
||||
}
|
||||
|
||||
public function test_store_endpoint_creates_new_api_token(): void
|
||||
{
|
||||
// Arrange
|
||||
$data = $this->createUserWithPermission([]);
|
||||
$client = $this->createPersonalAccessClient();
|
||||
Config::set('passport.personal_access_client.id', $client->id);
|
||||
Config::set('passport.personal_access_client.secret', $client->secret);
|
||||
Passport::actingAs($data->user);
|
||||
|
||||
// Act
|
||||
$response = $this->withoutExceptionHandling()->postJson(route('api.v1.api-tokens.store'), [
|
||||
'name' => 'Test Token',
|
||||
]);
|
||||
|
||||
// Assert
|
||||
$this->assertResponseCode($response, 200);
|
||||
$response->assertJsonStructure([
|
||||
'data' => [
|
||||
'id',
|
||||
'name',
|
||||
'scopes',
|
||||
'revoked',
|
||||
'created_at',
|
||||
'expires_at',
|
||||
'access_token',
|
||||
],
|
||||
]);
|
||||
}
|
||||
|
||||
public function test_revoke_endpoint_revokes_api_token(): void
|
||||
{
|
||||
// Arrange
|
||||
$data = $this->createUserWithPermission([]);
|
||||
$client = $this->createPersonalAccessClient();
|
||||
$token = Token::factory()->forUser($data->user)->forClient($client)->create();
|
||||
Passport::actingAs($data->user);
|
||||
|
||||
// Act
|
||||
$response = $this->postJson(route('api.v1.api-tokens.revoke', $token->id));
|
||||
|
||||
// Assert
|
||||
$this->assertResponseCode($response, 204);
|
||||
$this->assertDatabaseHas(Token::class, [
|
||||
'id' => $token->id,
|
||||
'revoked' => true,
|
||||
]);
|
||||
}
|
||||
|
||||
public function test_revoke_fails_if_token_with_id_does_not_exist(): void
|
||||
{
|
||||
// Arrange
|
||||
$data = $this->createUserWithPermission([]);
|
||||
Passport::actingAs($data->user);
|
||||
|
||||
// Act
|
||||
$response = $this->postJson(route('api.v1.api-tokens.revoke', 'not-valid'));
|
||||
|
||||
// Assert
|
||||
$this->assertResponseCode($response, 404);
|
||||
}
|
||||
|
||||
public function test_revoke_fails_if_the_token_does_not_belong_to_the_user(): void
|
||||
{
|
||||
// Arrange
|
||||
$data = $this->createUserWithPermission([]);
|
||||
$otherData = $this->createUserWithPermission([]);
|
||||
$client = $this->createPersonalAccessClient();
|
||||
$token = Token::factory()->forUser($otherData->user)->forClient($client)->create();
|
||||
Passport::actingAs($data->user);
|
||||
|
||||
// Act
|
||||
$response = $this->postJson(route('api.v1.api-tokens.revoke', $token->id));
|
||||
|
||||
// Assert
|
||||
$this->assertResponseCode($response, 404);
|
||||
$this->assertDatabaseHas(Token::class, [
|
||||
'id' => $token->id,
|
||||
'revoked' => false,
|
||||
]);
|
||||
}
|
||||
|
||||
public function test_destroy_endpoint_deletes_api_token(): void
|
||||
{
|
||||
// Arrange
|
||||
$data = $this->createUserWithPermission([]);
|
||||
$client = $this->createPersonalAccessClient();
|
||||
$token = Token::factory()->forUser($data->user)->forClient($client)->create();
|
||||
Passport::actingAs($data->user);
|
||||
|
||||
// Act
|
||||
$response = $this->deleteJson(route('api.v1.api-tokens.destroy', $token->id));
|
||||
|
||||
// Assert
|
||||
$this->assertResponseCode($response, 204);
|
||||
$this->assertDatabaseMissing(Token::class, ['id' => $token->id]);
|
||||
}
|
||||
|
||||
public function test_destroy_fails_if_token_with_id_does_not_exist(): void
|
||||
{
|
||||
// Arrange
|
||||
$data = $this->createUserWithPermission([]);
|
||||
Passport::actingAs($data->user);
|
||||
|
||||
// Act
|
||||
$response = $this->deleteJson(route('api.v1.api-tokens.destroy', 'not-valid'));
|
||||
|
||||
// Assert
|
||||
$this->assertResponseCode($response, 404);
|
||||
}
|
||||
|
||||
public function test_destroy_fails_if_the_token_does_not_belong_to_the_user(): void
|
||||
{
|
||||
// Arrange
|
||||
$data = $this->createUserWithPermission([]);
|
||||
$otherData = $this->createUserWithPermission([]);
|
||||
$client = $this->createPersonalAccessClient();
|
||||
$token = Token::factory()->forUser($otherData->user)->forClient($client)->create();
|
||||
Passport::actingAs($data->user);
|
||||
|
||||
// Act
|
||||
$response = $this->deleteJson(route('api.v1.api-tokens.destroy', $token->id));
|
||||
|
||||
// Assert
|
||||
$this->assertResponseCode($response, 404);
|
||||
$this->assertDatabaseHas(Token::class, [
|
||||
'id' => $token->id,
|
||||
]);
|
||||
}
|
||||
|
||||
private function createPersonalAccessClient(): Client
|
||||
{
|
||||
$clientRepository = new ClientRepository;
|
||||
/** @var Client $client */
|
||||
$client = $clientRepository->createPersonalAccessClient(
|
||||
null, 'Test Personal Access Client', 'http://localhost'
|
||||
);
|
||||
|
||||
return $client;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user