Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
100.00% covered (success)
100.00%
13 / 13
100.00% covered (success)
100.00%
2 / 2
CRAP
100.00% covered (success)
100.00%
1 / 1
ChangePasswordController
100.00% covered (success)
100.00%
13 / 13
100.00% covered (success)
100.00%
2 / 2
4
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
 changePassword
100.00% covered (success)
100.00%
12 / 12
100.00% covered (success)
100.00%
1 / 1
3
1<?php
2
3declare(strict_types=1);
4
5namespace App\Identity\Infrastructure\Controllers;
6
7use App\Identity\Application\Command\ChangePasswordCommand;
8use App\Identity\Application\Command\ChangePasswordHandler;
9use App\Identity\Domain\Exceptions\InvalidCurrentPassword;
10use App\Identity\Domain\Exceptions\UserNotFound;
11use App\Identity\Infrastructure\Http\ResolvesAuthenticatedUser;
12use App\Shared\Infrastructure\Http\ReadsJsonPayload;
13use InvalidArgumentException;
14use OpenApi\Attributes as OA;
15use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
16use Symfony\Component\HttpFoundation\JsonResponse;
17use Symfony\Component\HttpFoundation\Request;
18use Symfony\Component\HttpFoundation\Response;
19use Symfony\Component\Routing\Attribute\Route;
20
21#[OA\Tag(name: 'Users')]
22class ChangePasswordController extends AbstractController
23{
24    use ReadsJsonPayload;
25    use ResolvesAuthenticatedUser;
26
27    public function __construct(
28        private readonly ChangePasswordHandler $handler,
29    ) {
30    }
31
32    #[Route('/users/me/password', name: 'users_change_password', methods: ['PUT'])]
33    public function changePassword(Request $request): Response
34    {
35        $securityUser = $this->securityUser();
36
37        try {
38            $payload = $this->decodeJsonBody($request);
39
40            $this->handler->handle(new ChangePasswordCommand(
41                userId: $securityUser->userId(),
42                currentPassword: $this->stringField($payload, 'currentPassword'),
43                newPassword: $this->stringField($payload, 'newPassword'),
44            ));
45        } catch (UserNotFound $e) {
46            return new JsonResponse(['error' => $e->getMessage()], 404);
47        } catch (InvalidCurrentPassword|InvalidArgumentException $e) {
48            return new JsonResponse(['error' => $e->getMessage()], 400);
49        }
50
51        return new Response(null, Response::HTTP_NO_CONTENT);
52    }
53}