UserTest   A
last analyzed

Complexity

Total Complexity 16

Size/Duplication

Total Lines 213
Duplicated Lines 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
wmc 16
eloc 123
c 1
b 0
f 0
dl 0
loc 213
rs 10

11 Methods

Rating   Name   Duplication   Size   Complexity  
A testSetRole() 0 16 3
A tearDown() 0 3 1
A testGetRunningBookings() 0 20 1
A testCannotBeOwnedByAnotherOwned() 0 10 1
A testCannotBeOwnedBecauseIsOwner() 0 11 1
A testSetStatus() 0 30 2
A testGetAccount() 0 32 1
A testCannotOwnMyself() 0 5 1
A providerSetRole() 0 8 1
A providerCanOpenDoor() 0 37 1
A testCanOpenDoor() 0 11 3
1
<?php
2
3
declare(strict_types=1);
4
5
namespace ApplicationTest\Model;
6
7
use Application\Enum\BookingStatus;
8
use Application\Enum\Door;
9
use Application\Enum\UserStatus;
10
use Application\Model\Account;
11
use Application\Model\Booking;
12
use Application\Model\User;
13
use Cake\Chronos\Chronos;
14
use PHPUnit\Framework\TestCase;
15
16
class UserTest extends TestCase
17
{
18
    protected function tearDown(): void
19
    {
20
        User::setCurrent(null);
21
    }
22
23
    /**
24
     * @dataProvider providerSetRole
25
     */
26
    public function testSetRole(string $currentRole, string $oldRole, string $newRole, ?string $exception): void
27
    {
28
        User::setCurrent(null);
29
        if ($currentRole !== User::ROLE_ANONYMOUS) {
30
            $currentUser = new User($currentRole);
31
            User::setCurrent($currentUser);
32
        }
33
34
        $user2 = new User($oldRole);
35
36
        if ($exception) {
37
            $this->expectExceptionMessage($exception);
38
        }
39
40
        $user2->setRole($newRole);
41
        self::assertSame($newRole, $user2->getRole());
42
    }
43
44
    public static function providerSetRole(): iterable
45
    {
46
        yield [User::ROLE_ANONYMOUS, User::ROLE_ADMINISTRATOR, User::ROLE_MEMBER, 'anonymous is not allowed to change role from administrator to member'];
47
        yield [User::ROLE_ANONYMOUS, User::ROLE_MEMBER, User::ROLE_ADMINISTRATOR, 'anonymous is not allowed to change role from member to administrator'];
48
        yield [User::ROLE_MEMBER, User::ROLE_MEMBER, User::ROLE_MEMBER, null];
49
        yield [User::ROLE_MEMBER, User::ROLE_MEMBER, User::ROLE_ADMINISTRATOR, 'member is not allowed to change role from member to administrator'];
50
        yield [User::ROLE_ADMINISTRATOR, User::ROLE_MEMBER, User::ROLE_ADMINISTRATOR, null];
51
        yield [User::ROLE_ADMINISTRATOR, User::ROLE_ADMINISTRATOR, User::ROLE_MEMBER, null];
52
    }
53
54
    public function testCannotOwnMyself(): void
55
    {
56
        $user = new User();
57
        $this->expectExceptionMessage('This user cannot be owned by himself');
58
        $user->setOwner($user);
59
    }
60
61
    public function testCannotBeOwnedByAnotherOwned(): void
62
    {
63
        $user = new User();
64
        $owner1 = new User();
65
        $owner2 = new User();
66
        $owner1->setOwner($owner2);
67
        self::assertSame($owner2, $owner1->getOwner());
68
69
        $this->expectExceptionMessage('This user cannot be owned by a user who is himself owned by somebody else');
70
        $user->setOwner($owner1);
71
    }
72
73
    public function testCannotBeOwnedBecauseIsOwner(): void
74
    {
75
        $user = new User();
76
        $owned = new User();
77
        $owned->setOwner($user);
78
        self::assertSame($user, $owned->getOwner());
79
80
        $owner = new User();
81
82
        $this->expectExceptionMessage('This user owns other users, so he cannot himself be owned by somebody else');
83
        $user->setOwner($owner);
84
    }
85
86
    /**
87
     * @dataProvider providerCanOpenDoor
88
     */
89
    public function testCanOpenDoor(string $role, UserStatus $status, array $doors, array $result): void
90
    {
91
        $user = new User($role);
92
        $user->setStatus($status);
93
        foreach ($doors as $door => $value) {
94
            $setter = 'set' . ucfirst($door);
95
            $user->$setter($value);
96
        }
97
98
        foreach ($result as $door => $canOpen) {
99
            self::assertSame($canOpen, $user->getCanOpenDoor(Door::from($door)));
100
        }
101
    }
102
103
    public static function providerCanOpenDoor(): iterable
104
    {
105
        yield 'anonymous cannot open' => [
106
            User::ROLE_ANONYMOUS,
107
            UserStatus::Active,
108
            ['door1' => true, 'door2' => true, 'door3' => true, 'door4' => true],
109
            ['door1' => false, 'door2' => false, 'door3' => false, 'door4' => false],
110
        ];
111
        yield 'individual member can open' => [
112
            User::ROLE_INDIVIDUAL,
113
            UserStatus::Active,
114
            ['door1' => true, 'door2' => true, 'door3' => true, 'door4' => false],
115
            ['door1' => true, 'door2' => true, 'door3' => true, 'door4' => false],
116
        ];
117
        yield 'active member can open' => [
118
            User::ROLE_MEMBER,
119
            UserStatus::Active,
120
            ['door1' => true, 'door2' => true, 'door3' => true, 'door4' => false],
121
            ['door1' => true, 'door2' => true, 'door3' => true, 'door4' => false],
122
        ];
123
        yield 'inactive member cannot open' => [
124
            User::ROLE_MEMBER,
125
            UserStatus::Inactive,
126
            ['door1' => true, 'door2' => true, 'door3' => true, 'door4' => false],
127
            ['door1' => false, 'door2' => false, 'door3' => false, 'door4' => false],
128
        ];
129
        yield 'responsible can open' => [
130
            User::ROLE_RESPONSIBLE,
131
            UserStatus::Active,
132
            ['door1' => true, 'door2' => true, 'door3' => true, 'door4' => true],
133
            ['door1' => true, 'door2' => true, 'door3' => true, 'door4' => true],
134
        ];
135
        yield 'administrator can open' => [
136
            User::ROLE_ADMINISTRATOR,
137
            UserStatus::Active,
138
            ['door1' => true, 'door2' => true, 'door3' => true, 'door4' => true],
139
            ['door1' => true, 'door2' => true, 'door3' => true, 'door4' => true],
140
        ];
141
    }
142
143
    public function testGetAccount(): void
144
    {
145
        $user1 = new User();
146
        $user2 = new User();
147
148
        self::assertNull($user1->getAccount());
149
        self::assertNull($user2->getAccount());
150
151
        $account1 = new Account();
152
        $account2 = new Account();
153
        $account1->setOwner($user1);
154
        $account2->setOwner($user2);
155
156
        self::assertSame($account1, $user1->getAccount());
157
        self::assertSame($account2, $user2->getAccount());
158
159
        $user2->setOwner($user1);
160
161
        self::assertSame($account1, $user1->getAccount());
162
        self::assertSame($account1, $user2->getAccount(), 'user2 should now use user1 account');
163
164
        User::setCurrent($user1);
165
        $user2->setOwner(null);
166
167
        self::assertSame($account1, $user1->getAccount());
168
        self::assertSame($account2, $user2->getAccount(), 'user2 should be use his own account again');
169
170
        User::setCurrent($user2);
171
        $user2->setOwner(null);
172
173
        self::assertSame($account1, $user1->getAccount());
174
        self::assertSame($account2, $user2->getAccount(), 'user2 should be use his own account again');
175
    }
176
177
    public function testGetRunningBookings(): void
178
    {
179
        $user = new User();
180
181
        $unapproved = new Booking();
182
        $unapproved->setOwner($user);
183
        $unapproved->setStatus(BookingStatus::Application);
184
185
        $completed = new Booking();
186
        $completed->setOwner($user);
187
        $completed->setStatus(BookingStatus::Booked);
188
        $completed->setEndDate(Chronos::yesterday());
189
190
        $running = new Booking();
191
        $running->setOwner($user);
192
        $running->setStatus(BookingStatus::Booked);
193
194
        $runnings = $user->getRunningBookings();
195
196
        self::assertCount(1, $runnings);
197
    }
198
199
    public function testSetStatus(): void
200
    {
201
        $u1 = new User();
202
        $u2 = new User();
203
204
        // Initial status
205
        self::assertSame(UserStatus::New, $u1->getStatus());
206
        self::assertSame(UserStatus::New, $u2->getStatus());
207
208
        $u2->setOwner($u1);
209
        $u1->setStatus(UserStatus::Inactive);
210
211
        // Status is propagated to existing users
212
        self::assertSame(UserStatus::Inactive, $u1->getStatus());
213
        self::assertSame(UserStatus::Inactive, $u2->getStatus());
214
215
        $u1->setStatus(UserStatus::Active);
216
        self::assertSame(UserStatus::Active, $u1->getStatus());
217
        self::assertSame(UserStatus::Active, $u2->getStatus());
218
219
        // Status is propagated on new users too
220
        $u3 = new User();
221
        self::assertSame(UserStatus::New, $u3->getStatus());
222
        $u3->setOwner($u1);
223
        self::assertSame(UserStatus::Active, $u3->getStatus());
224
225
        // Status 'archived' sets resign date
226
        Chronos::setTestNow((new Chronos()));
227
        $u1->setStatus(UserStatus::Archived);
228
        self::assertTrue($u1->getResignDate() && $u1->getResignDate()->isToday());
229
    }
230
}
231