new funcionality

This commit is contained in:
2026-07-27 17:20:02 +02:00
parent c2b5291a74
commit c5ce8a7a36
101 changed files with 6889 additions and 176 deletions

View File

@@ -0,0 +1,150 @@
<?php
namespace Tests\Feature;
use App\Models\User;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Laravel\Passport\Token;
use Tests\TestCase;
class ClientCrudTest extends TestCase
{
use RefreshDatabase;
private User $owner;
protected function setUp(): void
{
parent::setUp();
$this->owner = User::factory()->approved()->create();
}
public function test_owner_can_list_only_their_own_non_revoked_clients(): void
{
$this->actingAs($this->owner)->postJson('/web-api/clients', [
'name' => 'My Client',
'grant_type' => 'client_credentials',
])->assertCreated();
$stranger = User::factory()->approved()->create();
$this->actingAs($stranger)->postJson('/web-api/clients', [
'name' => 'Someone Elses Client',
'grant_type' => 'client_credentials',
])->assertCreated();
$response = $this->actingAs($this->owner)->getJson('/web-api/clients');
$response->assertOk();
$names = collect($response->json())->pluck('name');
$this->assertTrue($names->contains('My Client'));
$this->assertFalse($names->contains('Someone Elses Client'));
}
public function test_creating_a_client_credentials_client_is_always_confidential(): void
{
$response = $this->actingAs($this->owner)->postJson('/web-api/clients', [
'name' => 'CC Client',
'grant_type' => 'client_credentials',
'confidential' => false,
]);
$response->assertCreated();
$this->assertNotNull($response->json('plain_secret'));
$this->assertDatabaseHas('audit_logs', ['action' => 'client.created']);
}
public function test_creating_a_public_authorization_code_client_has_no_secret(): void
{
$response = $this->actingAs($this->owner)->postJson('/web-api/clients', [
'name' => 'Public SPA',
'grant_type' => 'authorization_code',
'redirect_uris' => ['https://example.test/callback'],
'confidential' => false,
]);
$response->assertCreated();
$this->assertNull($response->json('plain_secret'));
}
public function test_authorization_code_requires_redirect_uris(): void
{
$this->actingAs($this->owner)->postJson('/web-api/clients', [
'name' => 'No Redirect',
'grant_type' => 'authorization_code',
])->assertUnprocessable()->assertJsonValidationErrors('redirect_uris');
}
public function test_invalid_grant_type_is_rejected(): void
{
$this->actingAs($this->owner)->postJson('/web-api/clients', [
'name' => 'Bad Grant',
'grant_type' => 'not-a-real-grant',
])->assertUnprocessable()->assertJsonValidationErrors('grant_type');
}
public function test_owner_can_update_name_and_redirect_uris(): void
{
$created = $this->actingAs($this->owner)->postJson('/web-api/clients', [
'name' => 'Original Name',
'grant_type' => 'authorization_code',
'redirect_uris' => ['https://example.test/callback'],
])->json('client');
$response = $this->actingAs($this->owner)->putJson("/web-api/clients/{$created['id']}", [
'name' => 'Updated Name',
'redirect_uris' => ['https://example.test/new-callback'],
]);
$response->assertOk();
$response->assertJsonPath('name', 'Updated Name');
$response->assertJsonPath('redirect_uris.0', 'https://example.test/new-callback');
}
public function test_non_owner_cannot_update_or_revoke_another_users_client(): void
{
$created = $this->actingAs($this->owner)->postJson('/web-api/clients', [
'name' => 'Owned Client',
'grant_type' => 'client_credentials',
])->json('client');
$stranger = User::factory()->approved()->create();
$this->actingAs($stranger)
->putJson("/web-api/clients/{$created['id']}", ['name' => 'Hijacked'])
->assertNotFound();
$this->actingAs($stranger)
->deleteJson("/web-api/clients/{$created['id']}")
->assertNotFound();
}
public function test_revoking_a_client_also_revokes_its_active_tokens(): void
{
$response = $this->actingAs($this->owner)->postJson('/web-api/clients', [
'name' => 'To Revoke',
'grant_type' => 'client_credentials',
]);
$clientId = $response->json('client.id');
$token = Token::create([
'id' => \Illuminate\Support\Str::random(80),
'user_id' => $this->owner->id,
'client_id' => $clientId,
'name' => null,
'scopes' => ['users:read'],
'revoked' => false,
'created_at' => now(),
'updated_at' => now(),
'expires_at' => now()->addDays(15),
]);
$this->actingAs($this->owner)
->deleteJson("/web-api/clients/{$clientId}")
->assertNoContent();
$this->assertDatabaseHas('oauth_clients', ['id' => $clientId, 'revoked' => true]);
$this->assertDatabaseHas('oauth_access_tokens', ['id' => $token->id, 'revoked' => true]);
$this->assertDatabaseHas('audit_logs', ['action' => 'client.revoked', 'subject_id' => $clientId]);
}
}