Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
100.00% covered (success)
100.00%
3 / 3
100.00% covered (success)
100.00%
2 / 2
CRAP
100.00% covered (success)
100.00%
1 / 1
AvatarCleanupOnUserDeletion
100.00% covered (success)
100.00%
3 / 3
100.00% covered (success)
100.00%
2 / 2
2
100.00% covered (success)
100.00%
1 / 1
 __construct
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 onUserDeletion
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
1
1<?php
2
3declare(strict_types=1);
4
5namespace App\Identity\Application;
6
7use App\Identity\Application\Port\PreUserDeletion;
8use App\Identity\Domain\UserRepository;
9use App\Identity\Domain\ValueObject\UserId;
10use App\Shared\Infrastructure\Storage\ImageStorage;
11
12/**
13 * Unlinks the avatar of a user about to be deleted. Identity implementing its own
14 * PreUserDeletion port is deliberate: both delete paths (`DELETE /users/me` and
15 * the admin one) already iterate the tagged reactors, so hooking in here covers
16 * them — and any future one — without the same two lines living in each handler.
17 */
18final readonly class AvatarCleanupOnUserDeletion implements PreUserDeletion
19{
20    public function __construct(
21        private UserRepository $users,
22        private ImageStorage $storage,
23    ) {
24    }
25
26    public function onUserDeletion(string $userId): void
27    {
28        $user = $this->users->ofId(new UserId($userId));
29
30        $this->storage->delete($user?->avatarName());
31    }
32}