refactor(repository): make entity deletion idempotent
This commit is contained in:
parent
3582a3928c
commit
0766e9dc8f
10 changed files with 26 additions and 43 deletions
|
|
@ -31,8 +31,5 @@ interface ClientRepository extends Repository
|
|||
|
||||
public function persist(Client $client): void;
|
||||
|
||||
/**
|
||||
* @throws \Application\Security\Exceptions\ClientNotFoundException
|
||||
*/
|
||||
public function delete(Client $client): void;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -24,8 +24,5 @@ interface BrandRepository extends Repository
|
|||
|
||||
public function persist(Brand $entity): void;
|
||||
|
||||
/**
|
||||
* @throws \Domain\Exceptions\BrandNotFoundException
|
||||
*/
|
||||
public function delete(Brand $entity): void;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,7 +4,6 @@ declare(strict_types=1);
|
|||
|
||||
namespace Infra\Adapters\Repositories;
|
||||
|
||||
use Application\Security\Exceptions\ClientNotFoundException;
|
||||
use Application\Security\Models\Entities\Client;
|
||||
use Application\Security\Models\ValueObjects\ClientIdentifier;
|
||||
use Application\Security\Models\ValueObjects\ClientName;
|
||||
|
|
@ -113,10 +112,7 @@ final class ApiClientRepository implements ClientRepository
|
|||
#[\Override]
|
||||
public function delete(Client $client): void
|
||||
{
|
||||
$deleted = ApiClient::query()->where('id', $client->id->value)->delete();
|
||||
if ($deleted === 0) {
|
||||
throw ClientNotFoundException::forClient($client->id);
|
||||
}
|
||||
ApiClient::query()->where('id', $client->id->value)->delete();
|
||||
}
|
||||
|
||||
private function toDomain(ApiClient $apiClient): Client
|
||||
|
|
|
|||
|
|
@ -4,7 +4,6 @@ declare(strict_types=1);
|
|||
|
||||
namespace Infra\Adapters\Repositories;
|
||||
|
||||
use Domain\Exceptions\BrandNotFoundException;
|
||||
use Domain\Models\Entities\Brand;
|
||||
use Domain\Models\ValueObjects\Brand\ArcadiaId;
|
||||
use Domain\Models\ValueObjects\Brand\BrandCode;
|
||||
|
|
@ -124,14 +123,10 @@ final readonly class EloquentBrandRepository implements BrandRepository
|
|||
#[\Override]
|
||||
public function delete(Brand $entity): void
|
||||
{
|
||||
$deleted = BrandModel::query()
|
||||
BrandModel::query()
|
||||
->where('id', $entity->id()->value)
|
||||
->delete();
|
||||
|
||||
if ($deleted === 0) {
|
||||
throw BrandNotFoundException::forBrand($entity->id());
|
||||
}
|
||||
|
||||
$this->brandCache->invalidate($entity);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -4,7 +4,6 @@ declare(strict_types=1);
|
|||
|
||||
namespace Infra\Adapters\Repositories;
|
||||
|
||||
use Domain\Exceptions\BrandNotFoundException;
|
||||
use Domain\Models\Entities\Brand;
|
||||
use Domain\Models\ValueObjects\Brand\ArcadiaId;
|
||||
use Domain\Models\ValueObjects\Brand\BrandCode;
|
||||
|
|
@ -75,10 +74,6 @@ final class InMemoryBrandRepository implements BrandRepository
|
|||
#[\Override]
|
||||
public function delete(Brand $entity): void
|
||||
{
|
||||
if (! isset($this->brands[$entity->id()->value])) {
|
||||
throw BrandNotFoundException::forBrand($entity->id());
|
||||
}
|
||||
|
||||
unset($this->brands[$entity->id()->value]);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,7 +4,6 @@ declare(strict_types=1);
|
|||
|
||||
namespace Infra\Adapters\Repositories;
|
||||
|
||||
use Application\Security\Exceptions\ClientNotFoundException;
|
||||
use Application\Security\Models\Entities\Client;
|
||||
use Application\Security\Models\ValueObjects\ClientIdentifier;
|
||||
use Application\Security\Models\ValueObjects\ClientName;
|
||||
|
|
@ -48,10 +47,6 @@ final class InMemoryClientRepository implements ClientRepository
|
|||
#[\Override]
|
||||
public function delete(Client $client): void
|
||||
{
|
||||
if (! isset($this->clients[$client->id->value])) {
|
||||
throw ClientNotFoundException::forClient($client->id);
|
||||
}
|
||||
|
||||
unset($this->clients[$client->id->value]);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -183,7 +183,7 @@ describe('ApiClientRepository Integration Tests', function (): void {
|
|||
]);
|
||||
});
|
||||
|
||||
it('throws ClientNotFoundException when deleting non-existent client', function (): void {
|
||||
it('is idempotent when deleting non-existent client', function (): void {
|
||||
// GIVEN
|
||||
$repository = new ApiClientRepository();
|
||||
$client = Client::hydrate(
|
||||
|
|
@ -195,9 +195,11 @@ describe('ApiClientRepository Integration Tests', function (): void {
|
|||
updatedAt: new DateTimeImmutable(),
|
||||
);
|
||||
|
||||
// WHEN & THEN
|
||||
expect(fn () => $repository->delete($client))
|
||||
->toThrow(ClientNotFoundException::class);
|
||||
// WHEN
|
||||
$repository->delete($client);
|
||||
|
||||
// THEN
|
||||
expect($repository->find($client->id))->toBeNull();
|
||||
});
|
||||
|
||||
it('finds all clients with pagination', function (): void {
|
||||
|
|
|
|||
|
|
@ -246,7 +246,7 @@ describe('EloquentBrandRepository Integration Tests', function (): void {
|
|||
->and(Cache::has('brand:all'))->toBeFalse();
|
||||
});
|
||||
|
||||
it('throws BrandNotFoundException when deleting non-existent brand', function (): void {
|
||||
it('is idempotent when deleting non-existent brand', function (): void {
|
||||
// GIVEN
|
||||
$brandCache = resolve(BrandCache::class);
|
||||
$repository = new EloquentBrandRepository($brandCache);
|
||||
|
|
@ -257,8 +257,10 @@ describe('EloquentBrandRepository Integration Tests', function (): void {
|
|||
arcadiaId: new ArcadiaId('999'),
|
||||
);
|
||||
|
||||
// WHEN & THEN
|
||||
expect(fn () => $repository->delete($brand))
|
||||
->toThrow(BrandNotFoundException::class);
|
||||
// WHEN
|
||||
$repository->delete($brand);
|
||||
|
||||
// THEN
|
||||
expect($repository->find($brand->id()))->toBeNull();
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -63,14 +63,16 @@ describe('InMemoryBrandRepository Unit Tests', function (): void {
|
|||
expect($repository->find($brand->id()))->toBeNull();
|
||||
});
|
||||
|
||||
it('throws BrandNotFoundException when deleting non-existent brand', function (): void {
|
||||
it('is idempotent when deleting non-existent brand', function (): void {
|
||||
// GIVEN
|
||||
$repository = new InMemoryBrandRepository();
|
||||
$brand = createBrand('MCQ02', 'Maître CoQ', '2');
|
||||
|
||||
// WHEN & THEN
|
||||
expect(fn () => $repository->delete($brand))
|
||||
->toThrow(BrandNotFoundException::class);
|
||||
// WHEN
|
||||
$repository->delete($brand);
|
||||
|
||||
// THEN
|
||||
expect($repository->find($brand->id()))->toBeNull();
|
||||
});
|
||||
|
||||
it('clears all brands', function (): void {
|
||||
|
|
|
|||
|
|
@ -63,14 +63,16 @@ describe('InMemoryClientRepository Unit Tests', function (): void {
|
|||
->and($foundAfterDelete)->toBeNull();
|
||||
});
|
||||
|
||||
it('throws ClientNotFoundException when deleting non-existent client', function (): void {
|
||||
it('is idempotent when deleting non-existent client', function (): void {
|
||||
// GIVEN
|
||||
$repository = new InMemoryClientRepository();
|
||||
$client = createClient('arcadia_id_' . str_repeat('9', 32));
|
||||
|
||||
// WHEN & THEN
|
||||
expect(fn () => $repository->delete($client))
|
||||
->toThrow(ClientNotFoundException::class);
|
||||
// WHEN
|
||||
$repository->delete($client);
|
||||
|
||||
// THEN
|
||||
expect($repository->find($client->id))->toBeNull();
|
||||
});
|
||||
|
||||
it('finds all clients with pagination', function (): void {
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue