Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
70.97% covered (warning)
70.97%
22 / 31
58.33% covered (warning)
58.33%
7 / 12
CRAP
0.00% covered (danger)
0.00%
0 / 1
User
70.97% covered (warning)
70.97%
22 / 31
58.33% covered (warning)
58.33%
7 / 12
27.83
0.00% covered (danger)
0.00%
0 / 1
 __construct
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getId
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 isBlocked
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getBlockedReason
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 block
66.67% covered (warning)
66.67%
2 / 3
0.00% covered (danger)
0.00%
0 / 1
2.15
 unblock
0.00% covered (danger)
0.00%
0 / 3
0.00% covered (danger)
0.00%
0 / 1
6
 setPhoneNumber
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
1
 getPhoneNumber
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 activate
57.14% covered (warning)
57.14%
4 / 7
0.00% covered (danger)
0.00%
0 / 1
5.26
 verify
85.71% covered (warning)
85.71%
6 / 7
0.00% covered (danger)
0.00%
0 / 1
3.03
 indexProvider
100.00% covered (success)
100.00%
3 / 3
100.00% covered (success)
100.00%
1 / 1
1
 getPermissionIdentifiers
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
1<?php
2namespace Apie\IntegrationTests\Apie\TypeDemo\Resources;
3
4use Apie\Core\Attributes\Internal;
5use Apie\Core\Attributes\ProvideIndex;
6use Apie\Core\Entities\EntityInterface;
7use Apie\Core\Identifiers\UuidV4;
8use Apie\Core\Lists\PermissionList;
9use Apie\Core\Permissions\PermissionInterface;
10use Apie\Core\ValueObjects\DatabaseText;
11use Apie\CountryAndPhoneNumber\DutchPhoneNumber;
12use Apie\Fixtures\ValueObjects\EncryptedPassword;
13use Apie\IntegrationTests\Apie\TypeDemo\Identifiers\UserIdentifier;
14use Apie\TextValueObjects\StrongPassword;
15use LogicException;
16
17#[ProvideIndex('indexProvider')]
18final class User implements EntityInterface, PermissionInterface
19{
20    private ?EncryptedPassword $password = null;
21
22    private UuidV4 $activationToken;
23
24    private ?DutchPhoneNumber $phoneNumber = null;
25
26    private ?DatabaseText $blockedReason = null;
27
28    public function __construct(
29        private UserIdentifier $id
30    ) {
31        $this->activationToken = UuidV4::createRandom();
32    }
33
34    public function getId(): UserIdentifier
35    {
36        return $this->id;
37    }
38
39    public function isBlocked(): bool
40    {
41        return $this->blockedReason !== null;
42    }
43
44    public function getBlockedReason(): ?DatabaseText
45    {
46        return $this->blockedReason;
47    }
48
49    public function block(DatabaseText $blockedReason): void
50    {
51        if ($this->blockedReason !== null) {
52            throw new LogicException("User is already blocked!");
53        }
54        $this->blockedReason = $blockedReason;
55    }
56
57    public function unblock(): void
58    {
59        if ($this->blockedReason === null) {
60            throw new LogicException("User is not blocked!");
61        }
62        $this->blockedReason = null;
63    }
64
65    public function setPhoneNumber(?DutchPhoneNumber $phoneNumber): self
66    {
67        $this->phoneNumber = $phoneNumber;
68
69        return $this;
70    }
71
72    public function getPhoneNumber(): ?DutchPhoneNumber
73    {
74        return $this->phoneNumber;
75    }
76
77    public function activate(string $activationToken, StrongPassword $newPassword, StrongPassword $repeat): void
78    {
79        if ($newPassword->toNative() !== $repeat->toNative()) {
80            throw new LogicException('Type the same password twice!');
81        }
82        if ($activationToken !== $this->activationToken->toNative()) {
83            throw new LogicException('Activation token is incorrect');
84        }
85        if ($this->isBlocked()) {
86            throw new LogicException('User is blocked and can not be activated');
87        }
88        $this->password = EncryptedPassword::fromUnencryptedPassword($newPassword);
89    }
90
91    public function verify(string $password): bool
92    {
93        if (null === $this->password) {
94            throw new LogicException(
95                'User is not activated yet'
96            );
97        }
98        if ($this->isBlocked()) {
99            throw new LogicException('User is blocked');
100        }
101        return $this->password->verifyUnencryptedPassword($password);
102    }
103
104    /**
105     * @return array<string, int>
106     */
107    #[Internal]
108    public function indexProvider(): array
109    {
110        return [
111            $this->id->toNative() => 1,
112        ];
113    }
114
115    #[Internal]
116    public function getPermissionIdentifiers(): PermissionList
117    {
118        return new PermissionList([$this->id->toPermission()]);
119    }
120}