delete(); }); describe('ApiClientRepository Integration Tests', function (): void { it('persists a new client into database', function (): void { // GIVEN $repository = new ApiClientRepository(); $clientId = new ClientId(Uuid::uuid7()); $identifier = new ClientIdentifier('arcadia_id_' . str_repeat('a', 32)); $secret = new ClientSecret('arcadia_sec_' . str_repeat('b', 86)); $client = Client::hydrate( id: $clientId, name: new ClientName('New API Client'), identifier: $identifier, secret: $secret, isActive: true, createdAt: new DateTimeImmutable(), updatedAt: new DateTimeImmutable(), ); // WHEN $repository->persist($client); // THEN $found = $repository->find($clientId); expect($found)->not->toBeNull() ->and($found->id->value)->toBe($clientId->value) ->and($found->name->value)->toBe('New API Client') ->and($found->identifier->value)->toBe($identifier->value) ->and($found->secret->value)->toBe($secret->value) ->and($found->isActive)->toBeTrue(); }); it('updates an existing client in database on persist', function (): void { // GIVEN $repository = new ApiClientRepository(); $rawId = Uuid::uuid7()->toString(); $identifier = 'arcadia_id_' . str_repeat('a', 32); $oldSecret = 'arcadia_sec_' . str_repeat('1', 86); $newSecret = 'arcadia_sec_' . str_repeat('2', 86); ApiClient::query()->create([ 'id' => $rawId, 'name' => 'Initial Client', 'slug' => 'initial-client', 'identifier' => $identifier, 'secret' => $oldSecret, 'is_active' => true, ]); $clientId = new ClientId(Uuid::fromString($rawId)); $client = Client::hydrate( id: $clientId, name: new ClientName('Initial Client'), identifier: new ClientIdentifier($identifier), secret: new ClientSecret($oldSecret), isActive: true, createdAt: new DateTimeImmutable(), updatedAt: new DateTimeImmutable(), ); $client->regenerateSecret(new ClientSecret($newSecret)); // WHEN $repository->persist($client); // THEN $found = $repository->find($clientId); expect($found)->not->toBeNull() ->and($found->secret->value)->toBe($newSecret); }); it('finds a client by its ClientId', function (): void { // GIVEN $repository = new ApiClientRepository(); $rawId = Uuid::uuid7()->toString(); $identifier = 'arcadia_id_' . str_repeat('a', 32); $secret = 'arcadia_sec_' . str_repeat('b', 86); ApiClient::query()->create([ 'id' => $rawId, 'name' => 'Existing Client', 'slug' => 'existing-client', 'identifier' => $identifier, 'secret' => $secret, 'is_active' => true, ]); $clientId = new ClientId(Uuid::fromString($rawId)); // WHEN $client = $repository->find($clientId); // THEN expect($client)->not->toBeNull() ->and($client->id->value)->toBe($rawId) ->and($client->name->value)->toBe('Existing Client') ->and($client->identifier->value)->toBe($identifier); }); it('finds a client by its ClientIdentifier', function (): void { // GIVEN $repository = new ApiClientRepository(); $rawId = Uuid::uuid7()->toString(); $identifier = 'arcadia_id_' . str_repeat('a', 32); $secret = 'arcadia_sec_' . str_repeat('b', 86); ApiClient::query()->create([ 'id' => $rawId, 'name' => 'Searchable Client', 'slug' => 'searchable-client', 'identifier' => $identifier, 'secret' => $secret, 'is_active' => true, ]); $clientIdentifier = new ClientIdentifier($identifier); // WHEN $client = $repository->findByIdentifier($clientIdentifier); // THEN expect($client)->not->toBeNull() ->and($client->identifier->value)->toBe($identifier) ->and($client->name->value)->toBe('Searchable Client'); }); it('deletes an existing client from database', function (): void { // GIVEN /** @var \Tests\TestCase $this */ $repository = new ApiClientRepository(); $rawId = Uuid::uuid7()->toString(); $identifier = 'arcadia_id_' . str_repeat('a', 32); $secret = 'arcadia_sec_' . str_repeat('b', 86); ApiClient::query()->create([ 'id' => $rawId, 'name' => 'Client to Delete', 'slug' => 'client-to-delete', 'identifier' => $identifier, 'secret' => $secret, 'is_active' => true, ]); $client = Client::hydrate( id: new ClientId(Uuid::fromString($rawId)), name: new ClientName('Client to Delete'), identifier: new ClientIdentifier($identifier), secret: new ClientSecret($secret), isActive: true, createdAt: new DateTimeImmutable(), updatedAt: new DateTimeImmutable(), ); // WHEN $repository->delete($client); // THEN $this->assertDatabaseMissing('api_clients', [ 'id' => $rawId, ]); }); it('finds all clients with pagination', function (): void { // GIVEN $repository = new ApiClientRepository(); for ($i = 1; $i <= 5; $i++) { ApiClient::query()->create([ 'id' => Uuid::uuid7()->toString(), 'name' => "Client $i", 'slug' => "client-$i", 'identifier' => 'arcadia_id_' . str_pad((string) $i, 32, '0', STR_PAD_LEFT), 'secret' => 'arcadia_sec_' . str_pad((string) $i, 86, '0', STR_PAD_LEFT), 'is_active' => true, ]); } $pagination = Pagination::ofPage(pageNumber: 1, pageSize: 2); // WHEN $paginated = $repository->findAll($pagination); // THEN expect($paginated->getTotal())->toBe(5) ->and(count($paginated->getItems()))->toBe(2) ->and($paginated->getPagination()->pageNumber())->toBe(1); }); });