Passed
Push — master ( 80fed1...32ef61 )
by Peter
09:46
created

UserSqlDataMapperTest::testFindByEmail()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 35
Code Lines 26

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 1 Features 0
Metric Value
eloc 26
c 2
b 1
f 0
dl 0
loc 35
rs 9.504
cc 1
nc 1
nop 0
1
<?php
2
3
declare(strict_types=1);
4
5
namespace AbterPhp\Admin\Orm\DataMapper;
6
7
use AbterPhp\Admin\Domain\Entities\User;
8
use AbterPhp\Admin\Domain\Entities\UserGroup;
9
use AbterPhp\Admin\Domain\Entities\UserLanguage;
10
use AbterPhp\Admin\Orm\DataMappers\UserSqlDataMapper;
11
use AbterPhp\Admin\TestCase\Orm\DataMapperTestCase;
12
use AbterPhp\Admin\TestDouble\Orm\MockIdGeneratorFactory;
13
use AbterPhp\Framework\Domain\Entities\IStringerEntity;
14
use AbterPhp\Framework\TestDouble\Database\MockStatementFactory;
15
use PHPUnit\Framework\MockObject\MockObject;
16
17
class UserSqlDataMapperTest extends DataMapperTestCase
18
{
19
    /** @var UserSqlDataMapper */
20
    protected $sut;
21
22
    public function setUp(): void
23
    {
24
        parent::setUp();
25
26
        $this->sut = new UserSqlDataMapper($this->readConnectionMock, $this->writeConnectionMock);
27
    }
28
29
    public function testAddWithoutRelated()
30
    {
31
        $nextId            = '041532f6-d84c-4827-9404-b426609b99b1';
32
        $username          = 'foo';
33
        $email             = '[email protected]';
34
        $password          = '';
35
        $userLanguage      = new UserLanguage('c486784f-a067-402b-94f0-fe85c838c71c', 'baz', 'Baz');
36
        $canLogin          = true;
37
        $isGravatarAllowed = true;
38
39
        $sql0       = 'INSERT INTO users (id, username, email, password, user_language_id, can_login, is_gravatar_allowed) VALUES (?, ?, ?, ?, ?, ?, ?)'; // phpcs:ignore
40
        $values    = [
41
            [$nextId, \PDO::PARAM_STR],
42
            [$username, \PDO::PARAM_STR],
43
            [$email, \PDO::PARAM_STR],
44
            [$password, \PDO::PARAM_STR],
45
            [$userLanguage->getId(), \PDO::PARAM_STR],
46
            [$canLogin, \PDO::PARAM_INT],
47
            [$isGravatarAllowed, \PDO::PARAM_INT],
48
        ];
49
        $statement0 = MockStatementFactory::createWriteStatement($this, $values);
50
51
        $this->writeConnectionMock
52
            ->expects($this->once())
53
            ->method('prepare')
54
            ->with($sql0)
55
            ->willReturn($statement0);
56
57
        $entity = new User($nextId, $username, $email, $password, $canLogin, $isGravatarAllowed, $userLanguage);
58
        $this->sut->add($entity);
59
60
        $this->assertSame($nextId, $entity->getId());
61
    }
62
63
    public function testAddWithRelated()
64
    {
65
        $nextId            = '92c633eb-70f0-4300-930c-6a797f213014';
66
        $username          = 'foo';
67
        $email             = '[email protected]';
68
        $password          = '';
69
        $userLanguage      = new UserLanguage('5dbea768-0dc9-426e-b434-d225535d440f', 'baz', 'Baz');
70
        $canLogin          = true;
71
        $isGravatarAllowed = true;
72
        $uugId0            = '76036dfa-5978-434e-96a6-9c5d5e8831c7';
73
        $uugId1            = '81c6f4a6-583a-41ff-b5bb-9015d9f97bd3';
74
        $userGroups        = [
75
            new UserGroup('feaf4cc1-fc70-4468-b34b-738ea17ab94e', 'ug-38', 'UG 38'),
76
            new UserGroup('47123e47-067e-4542-80b7-a5aa78916a30', 'ug-51', 'UG 51'),
77
        ];
78
79
        $this->sut->setIdGenerator(MockIdGeneratorFactory::create($this, $uugId0, $uugId1));
80
81
        $sql0      = 'INSERT INTO users (id, username, email, password, user_language_id, can_login, is_gravatar_allowed) VALUES (?, ?, ?, ?, ?, ?, ?)'; // phpcs:ignore
82
        $values    = [
83
            [$nextId, \PDO::PARAM_STR],
84
            [$username, \PDO::PARAM_STR],
85
            [$email, \PDO::PARAM_STR],
86
            [$password, \PDO::PARAM_STR],
87
            [$userLanguage->getId(), \PDO::PARAM_STR],
88
            [$canLogin, \PDO::PARAM_INT],
89
            [$isGravatarAllowed, \PDO::PARAM_INT],
90
        ];
91
        $statement0 = MockStatementFactory::createWriteStatement($this, $values);
92
93
        $sql1       = 'INSERT INTO users_user_groups (id, user_id, user_group_id) VALUES (?, ?, ?)'; // phpcs:ignore
94
        $values1    = [
95
            [$uugId0, \PDO::PARAM_STR],
96
            [$nextId, \PDO::PARAM_STR],
97
            [$userGroups[0]->getId(), \PDO::PARAM_STR],
98
        ];
99
        $statement1 = MockStatementFactory::createWriteStatement($this, $values1);
100
101
        $sql2       = 'INSERT INTO users_user_groups (id, user_id, user_group_id) VALUES (?, ?, ?)'; // phpcs:ignore
102
        $values2    = [
103
            [$uugId1, \PDO::PARAM_STR],
104
            [$nextId, \PDO::PARAM_STR],
105
            [$userGroups[1]->getId(), \PDO::PARAM_STR],
106
        ];
107
        $statement2 = MockStatementFactory::createWriteStatement($this, $values2);
108
109
        $this->writeConnectionMock
110
            ->expects($this->exactly(3))
111
            ->method('prepare')
112
            ->withConsecutive([$sql0], [$sql1], [$sql2])
113
            ->willReturnOnConsecutiveCalls($statement0, $statement1, $statement2);
114
115
        $entity = new User(
116
            $nextId,
117
            $username,
118
            $email,
119
            $password,
120
            $canLogin,
121
            $isGravatarAllowed,
122
            $userLanguage,
123
            $userGroups
124
        );
125
        $this->sut->add($entity);
126
127
        $this->assertSame($nextId, $entity->getId());
128
    }
129
130
    public function testDelete()
131
    {
132
        $id                = '1c36adc9-47e7-4d64-884d-f3c0ef0c89a3';
133
        $username          = 'foo';
134
        $email             = '[email protected]';
135
        $password          = 'somePassword';
136
        $storedPassword    = '';
137
        $userLanguage      = new UserLanguage('5c66b4ac-5d92-434f-85ee-040f3d1572dc', 'baz', 'Baz');
138
        $canLogin          = true;
139
        $isGravatarAllowed = true;
140
141
        $sql0       = 'DELETE FROM users_user_groups WHERE (user_id = ?)'; // phpcs:ignore
142
        $values0    = [[$id, \PDO::PARAM_STR]];
143
        $statement0 = MockStatementFactory::createWriteStatement($this, $values0);
144
145
        $sql1       = 'UPDATE users AS users SET deleted_at = NOW(), username = LEFT(MD5(RAND()), 8), email = CONCAT(username, "@example.com"), password = ? WHERE (id = ?)'; // phpcs:ignore
146
        $values1    = [
147
            [$storedPassword, \PDO::PARAM_STR],
148
            [$id, \PDO::PARAM_STR],
149
        ];
150
        $statement1 = MockStatementFactory::createWriteStatement($this, $values1);
151
152
        $this->writeConnectionMock
153
            ->expects($this->exactly(2))
154
            ->method('prepare')
155
            ->withConsecutive([$sql0], [$sql1])
156
            ->willReturnOnConsecutiveCalls($statement0, $statement1);
157
158
        $entity = new User($id, $username, $email, $password, $canLogin, $isGravatarAllowed, $userLanguage);
159
        $this->sut->delete($entity);
160
    }
161
162
    public function testGetAll()
163
    {
164
        $id                = '85cc9880-4d86-4ffb-8289-98843c0e97eb';
165
        $username          = 'foo';
166
        $email             = '[email protected]';
167
        $password          = '';
168
        $userLanguage      = new UserLanguage('a6fe61fd-4e03-4ec2-b066-e7d26fbdade3', 'baz', 'Baz');
169
        $canLogin          = true;
170
        $isGravatarAllowed = true;
171
172
        $sql0          = 'SELECT users.id, users.username, users.email, users.password, users.user_language_id, ul.identifier AS user_language_identifier, users.can_login, users.is_gravatar_allowed, GROUP_CONCAT(ug.id) AS user_group_ids, GROUP_CONCAT(ug.identifier) AS user_group_identifiers, GROUP_CONCAT(ug.name) AS user_group_names FROM users INNER JOIN user_languages AS ul ON ul.id = users.user_language_id AND ul.deleted_at IS NULL LEFT JOIN users_user_groups AS uug ON uug.user_id = users.id AND uug.deleted_at IS NULL LEFT JOIN user_groups AS ug ON ug.id = uug.user_group_id AND ug.deleted_at IS NULL WHERE (users.deleted_at IS NULL) GROUP BY users.id'; // phpcs:ignore
173
        $values       = [];
174
        $expectedData = [
175
            [
176
                'id'                       => $id,
177
                'username'                 => $username,
178
                'email'                    => $email,
179
                'password'                 => $password,
180
                'user_language_id'         => $userLanguage->getId(),
181
                'user_language_identifier' => $userLanguage->getIdentifier(),
182
                'can_login'                => $canLogin,
183
                'is_gravatar_allowed'      => $isGravatarAllowed,
184
            ],
185
        ];
186
        $statement0 = MockStatementFactory::createReadStatement($this, $values, $expectedData);
187
188
        $this->readConnectionMock
189
            ->expects($this->once())
190
            ->method('prepare')
191
            ->with($sql0)
192
            ->willReturn($statement0);
193
194
        $actualResult = $this->sut->getAll();
195
196
        $this->assertCollection($expectedData, $actualResult);
197
    }
198
199
    public function testGetAllWithRelated()
200
    {
201
        $id                   = '85cc9880-4d86-4ffb-8289-98843c0e97eb';
202
        $username             = 'foo';
203
        $email                = '[email protected]';
204
        $password             = '';
205
        $userLanguage         = new UserLanguage('a6fe61fd-4e03-4ec2-b066-e7d26fbdade3', 'baz', 'Baz');
206
        $canLogin             = true;
207
        $isGravatarAllowed    = true;
208
        $userGroupIds         = 'd6aae5b8-b34d-409b-9085-e02947e32b8e,aaad5aa6-7044-432d-ae28-2017376a1a55';
209
        $userGroupIdentifiers = 'ug-1,ug-2';
210
        $userGroupNames       = 'UG #1,UG #2';
211
212
        $sql0          = 'SELECT users.id, users.username, users.email, users.password, users.user_language_id, ul.identifier AS user_language_identifier, users.can_login, users.is_gravatar_allowed, GROUP_CONCAT(ug.id) AS user_group_ids, GROUP_CONCAT(ug.identifier) AS user_group_identifiers, GROUP_CONCAT(ug.name) AS user_group_names FROM users INNER JOIN user_languages AS ul ON ul.id = users.user_language_id AND ul.deleted_at IS NULL LEFT JOIN users_user_groups AS uug ON uug.user_id = users.id AND uug.deleted_at IS NULL LEFT JOIN user_groups AS ug ON ug.id = uug.user_group_id AND ug.deleted_at IS NULL WHERE (users.deleted_at IS NULL) GROUP BY users.id'; // phpcs:ignore
213
        $values       = [];
214
        $expectedData = [
215
            [
216
                'id'                       => $id,
217
                'username'                 => $username,
218
                'email'                    => $email,
219
                'password'                 => $password,
220
                'user_language_id'         => $userLanguage->getId(),
221
                'user_language_identifier' => $userLanguage->getIdentifier(),
222
                'can_login'                => $canLogin,
223
                'is_gravatar_allowed'      => $isGravatarAllowed,
224
                'user_group_ids'           => $userGroupIds,
225
                'user_group_identifiers'   => $userGroupIdentifiers,
226
                'user_group_names'         => $userGroupNames,
227
            ],
228
        ];
229
        $statement0 = MockStatementFactory::createReadStatement($this, $values, $expectedData);
230
231
        $this->readConnectionMock
232
            ->expects($this->once())
233
            ->method('prepare')
234
            ->with($sql0)
235
            ->willReturn($statement0);
236
237
        $actualResult = $this->sut->getAll();
238
239
        $this->assertCollection($expectedData, $actualResult);
240
    }
241
242
    public function testGetPage()
243
    {
244
        $id                = '85cc9880-4d86-4ffb-8289-98843c0e97eb';
245
        $username          = 'foo';
246
        $email             = '[email protected]';
247
        $password          = '';
248
        $userLanguage      = new UserLanguage('a6fe61fd-4e03-4ec2-b066-e7d26fbdade3', 'baz', 'Baz');
249
        $canLogin          = true;
250
        $isGravatarAllowed = true;
251
252
        $sql0          = 'SELECT SQL_CALC_FOUND_ROWS users.id, users.username, users.email, users.password, users.user_language_id, ul.identifier AS user_language_identifier, users.can_login, users.is_gravatar_allowed, GROUP_CONCAT(ug.id) AS user_group_ids, GROUP_CONCAT(ug.identifier) AS user_group_identifiers, GROUP_CONCAT(ug.name) AS user_group_names FROM users INNER JOIN user_languages AS ul ON ul.id = users.user_language_id AND ul.deleted_at IS NULL LEFT JOIN users_user_groups AS uug ON uug.user_id = users.id AND uug.deleted_at IS NULL LEFT JOIN user_groups AS ug ON ug.id = uug.user_group_id AND ug.deleted_at IS NULL WHERE (users.deleted_at IS NULL) GROUP BY users.id ORDER BY username ASC LIMIT 10 OFFSET 0'; // phpcs:ignore
253
        $values       = [];
254
        $expectedData = [
255
            [
256
                'id'                       => $id,
257
                'username'                 => $username,
258
                'email'                    => $email,
259
                'password'                 => $password,
260
                'user_language_id'         => $userLanguage->getId(),
261
                'user_language_identifier' => $userLanguage->getIdentifier(),
262
                'can_login'                => $canLogin,
263
                'is_gravatar_allowed'      => $isGravatarAllowed,
264
            ],
265
        ];
266
        $statement0 = MockStatementFactory::createReadStatement($this, $values, $expectedData);
267
268
        $this->readConnectionMock
269
            ->expects($this->once())
270
            ->method('prepare')
271
            ->with($sql0)
272
            ->willReturn($statement0);
273
274
        $actualResult = $this->sut->getPage(0, 10, [], [], []);
275
276
        $this->assertCollection($expectedData, $actualResult);
277
    }
278
279
    public function testGetPageWithOrdersAndConditions()
280
    {
281
        $id                = '85cc9880-4d86-4ffb-8289-98843c0e97eb';
282
        $username          = 'foo';
283
        $email             = '[email protected]';
284
        $password          = '';
285
        $userLanguage      = new UserLanguage('a6fe61fd-4e03-4ec2-b066-e7d26fbdade3', 'baz', 'Baz');
286
        $canLogin          = true;
287
        $isGravatarAllowed = true;
288
289
        $orders     = ['ac.description ASC'];
290
        $conditions = ['ac.description LIKE \'abc%\'', 'abc.description LIKE \'%bca\''];
291
292
        $sql0          = 'SELECT SQL_CALC_FOUND_ROWS users.id, users.username, users.email, users.password, users.user_language_id, ul.identifier AS user_language_identifier, users.can_login, users.is_gravatar_allowed, GROUP_CONCAT(ug.id) AS user_group_ids, GROUP_CONCAT(ug.identifier) AS user_group_identifiers, GROUP_CONCAT(ug.name) AS user_group_names FROM users INNER JOIN user_languages AS ul ON ul.id = users.user_language_id AND ul.deleted_at IS NULL LEFT JOIN users_user_groups AS uug ON uug.user_id = users.id AND uug.deleted_at IS NULL LEFT JOIN user_groups AS ug ON ug.id = uug.user_group_id AND ug.deleted_at IS NULL WHERE (users.deleted_at IS NULL) AND (ac.description LIKE \'abc%\') AND (abc.description LIKE \'%bca\') GROUP BY users.id ORDER BY ac.description ASC LIMIT 10 OFFSET 0'; // phpcs:ignore
293
        $values       = [];
294
        $expectedData = [
295
            [
296
                'id'                       => $id,
297
                'username'                 => $username,
298
                'email'                    => $email,
299
                'password'                 => $password,
300
                'user_language_id'         => $userLanguage->getId(),
301
                'user_language_identifier' => $userLanguage->getIdentifier(),
302
                'can_login'                => $canLogin,
303
                'is_gravatar_allowed'      => $isGravatarAllowed,
304
            ],
305
        ];
306
        $statement0 = MockStatementFactory::createReadStatement($this, $values, $expectedData);
307
308
        $this->readConnectionMock
309
            ->expects($this->once())
310
            ->method('prepare')
311
            ->with($sql0)
312
            ->willReturn($statement0);
313
314
        $actualResult = $this->sut->getPage(0, 10, $orders, $conditions, []);
315
316
        $this->assertCollection($expectedData, $actualResult);
317
    }
318
319
    public function testGetById()
320
    {
321
        $id                = 'a83be8c1-fb9a-471f-9284-133487837c46';
322
        $username          = 'foo';
323
        $email             = '[email protected]';
324
        $password          = '';
325
        $userLanguage      = new UserLanguage('0133699c-7826-4b19-b69a-61b894b924d7', 'baz', 'Baz');
326
        $canLogin          = true;
327
        $isGravatarAllowed = true;
328
329
        $sql0          = 'SELECT users.id, users.username, users.email, users.password, users.user_language_id, ul.identifier AS user_language_identifier, users.can_login, users.is_gravatar_allowed, GROUP_CONCAT(ug.id) AS user_group_ids, GROUP_CONCAT(ug.identifier) AS user_group_identifiers, GROUP_CONCAT(ug.name) AS user_group_names FROM users INNER JOIN user_languages AS ul ON ul.id = users.user_language_id AND ul.deleted_at IS NULL LEFT JOIN users_user_groups AS uug ON uug.user_id = users.id AND uug.deleted_at IS NULL LEFT JOIN user_groups AS ug ON ug.id = uug.user_group_id AND ug.deleted_at IS NULL WHERE (users.deleted_at IS NULL) AND (users.id = :user_id) GROUP BY users.id'; // phpcs:ignore
330
        $values       = ['user_id' => [$id, \PDO::PARAM_STR]];
331
        $expectedData = [
332
            [
333
                'id'                       => $id,
334
                'username'                 => $username,
335
                'email'                    => $email,
336
                'password'                 => $password,
337
                'user_language_id'         => $userLanguage->getId(),
338
                'user_language_identifier' => $userLanguage->getIdentifier(),
339
                'can_login'                => $canLogin,
340
                'is_gravatar_allowed'      => $isGravatarAllowed,
341
            ],
342
        ];
343
        $statement0 = MockStatementFactory::createReadStatement($this, $values, $expectedData);
344
345
        $this->readConnectionMock
346
            ->expects($this->once())
347
            ->method('prepare')
348
            ->with($sql0)
349
            ->willReturn($statement0);
350
351
        $actualResult = $this->sut->getById($id);
352
353
        $this->assertEntity($expectedData[0], $actualResult);
354
    }
355
356
    public function testGetByUsername()
357
    {
358
        $id                = '792de058-0d5b-4ae3-8e80-6b4470626530';
359
        $username          = 'foo';
360
        $email             = '[email protected]';
361
        $password          = '';
362
        $userLanguage      = new UserLanguage('e3d2689c-5284-43b4-a847-b84053623b30', 'baz', 'Baz');
363
        $canLogin          = true;
364
        $isGravatarAllowed = true;
365
366
        $sql0          = 'SELECT users.id, users.username, users.email, users.password, users.user_language_id, ul.identifier AS user_language_identifier, users.can_login, users.is_gravatar_allowed, GROUP_CONCAT(ug.id) AS user_group_ids, GROUP_CONCAT(ug.identifier) AS user_group_identifiers, GROUP_CONCAT(ug.name) AS user_group_names FROM users INNER JOIN user_languages AS ul ON ul.id = users.user_language_id AND ul.deleted_at IS NULL LEFT JOIN users_user_groups AS uug ON uug.user_id = users.id AND uug.deleted_at IS NULL LEFT JOIN user_groups AS ug ON ug.id = uug.user_group_id AND ug.deleted_at IS NULL WHERE (users.deleted_at IS NULL) AND (`username` = :username) GROUP BY users.id'; // phpcs:ignore
367
        $values       = ['username' => [$username, \PDO::PARAM_STR]];
368
        $expectedData = [
369
            [
370
                'id'                       => $id,
371
                'username'                 => $username,
372
                'email'                    => $email,
373
                'password'                 => $password,
374
                'user_language_id'         => $userLanguage->getId(),
375
                'user_language_identifier' => $userLanguage->getIdentifier(),
376
                'can_login'                => $canLogin,
377
                'is_gravatar_allowed'      => $isGravatarAllowed,
378
            ],
379
        ];
380
        $statement0 = MockStatementFactory::createReadStatement($this, $values, $expectedData);
381
382
        $this->readConnectionMock
383
            ->expects($this->once())
384
            ->method('prepare')
385
            ->with($sql0)
386
            ->willReturn($statement0);
387
388
        $actualResult = $this->sut->getByUsername($username);
389
390
        $this->assertEntity($expectedData[0], $actualResult);
391
    }
392
393
    public function testGetByEmail()
394
    {
395
        $id                = 'd26ae765-e801-4444-9bed-af1b825414b3';
396
        $username          = 'foo';
397
        $email             = '[email protected]';
398
        $password          = '';
399
        $userLanguage      = new UserLanguage('8eb0a9eb-fd6e-4036-a6f6-4da7d99baa65', 'baz', 'Baz');
400
        $canLogin          = true;
401
        $isGravatarAllowed = true;
402
403
        $sql0          = 'SELECT users.id, users.username, users.email, users.password, users.user_language_id, ul.identifier AS user_language_identifier, users.can_login, users.is_gravatar_allowed, GROUP_CONCAT(ug.id) AS user_group_ids, GROUP_CONCAT(ug.identifier) AS user_group_identifiers, GROUP_CONCAT(ug.name) AS user_group_names FROM users INNER JOIN user_languages AS ul ON ul.id = users.user_language_id AND ul.deleted_at IS NULL LEFT JOIN users_user_groups AS uug ON uug.user_id = users.id AND uug.deleted_at IS NULL LEFT JOIN user_groups AS ug ON ug.id = uug.user_group_id AND ug.deleted_at IS NULL WHERE (users.deleted_at IS NULL) AND (email = :email) GROUP BY users.id'; // phpcs:ignore
404
        $values       = ['email' => [$email, \PDO::PARAM_STR]];
405
        $expectedData = [
406
            [
407
                'id'                       => $id,
408
                'username'                 => $username,
409
                'email'                    => $email,
410
                'password'                 => $password,
411
                'user_language_id'         => $userLanguage->getId(),
412
                'user_language_identifier' => $userLanguage->getIdentifier(),
413
                'can_login'                => $canLogin,
414
                'is_gravatar_allowed'      => $isGravatarAllowed,
415
            ],
416
        ];
417
        $statement0 = MockStatementFactory::createReadStatement($this, $values, $expectedData);
418
419
        $this->readConnectionMock
420
            ->expects($this->once())
421
            ->method('prepare')
422
            ->with($sql0)
423
            ->willReturn($statement0);
424
425
        $actualResult = $this->sut->getByEmail($email);
426
427
        $this->assertEntity($expectedData[0], $actualResult);
428
    }
429
430
    public function testFindByUsername()
431
    {
432
        $id                = 'd9954f10-1ee9-462e-a1e5-6065c032adaa';
433
        $username          = 'foo';
434
        $email             = '[email protected]';
435
        $password          = '';
436
        $userLanguage      = new UserLanguage('d1284a66-6fad-4e40-a7f6-4c144aa5de5e', 'baz', 'Baz');
437
        $canLogin          = true;
438
        $isGravatarAllowed = true;
439
440
        $sql0          = 'SELECT users.id, users.username, users.email, users.password, users.user_language_id, ul.identifier AS user_language_identifier, users.can_login, users.is_gravatar_allowed, GROUP_CONCAT(ug.id) AS user_group_ids, GROUP_CONCAT(ug.identifier) AS user_group_identifiers, GROUP_CONCAT(ug.name) AS user_group_names FROM users INNER JOIN user_languages AS ul ON ul.id = users.user_language_id AND ul.deleted_at IS NULL LEFT JOIN users_user_groups AS uug ON uug.user_id = users.id AND uug.deleted_at IS NULL LEFT JOIN user_groups AS ug ON ug.id = uug.user_group_id AND ug.deleted_at IS NULL WHERE (users.deleted_at IS NULL) AND ((username = :identifier OR email = :identifier)) GROUP BY users.id'; // phpcs:ignore
441
        $values       = ['identifier' => [$username, \PDO::PARAM_STR]];
442
        $expectedData = [
443
            [
444
                'id'                       => $id,
445
                'username'                 => $username,
446
                'email'                    => $email,
447
                'password'                 => $password,
448
                'user_language_id'         => $userLanguage->getId(),
449
                'user_language_identifier' => $userLanguage->getIdentifier(),
450
                'can_login'                => $canLogin,
451
                'is_gravatar_allowed'      => $isGravatarAllowed,
452
            ],
453
        ];
454
        $statement0 = MockStatementFactory::createReadStatement($this, $values, $expectedData);
455
456
        $this->readConnectionMock
457
            ->expects($this->once())
458
            ->method('prepare')
459
            ->with($sql0)
460
            ->willReturn($statement0);
461
462
        $actualResult = $this->sut->find($username);
463
464
        $this->assertEntity($expectedData[0], $actualResult);
465
    }
466
467
    public function testFindByEmail()
468
    {
469
        $id                = '0496d1d1-a750-4c91-822e-03a0fd6718b7';
470
        $username          = 'foo';
471
        $email             = '[email protected]';
472
        $password          = '';
473
        $userLanguage      = new UserLanguage('8b9543ad-17e8-4e54-af17-e8a8b271a70e', 'baz', 'Baz');
474
        $canLogin          = true;
475
        $isGravatarAllowed = true;
476
477
        $sql0          = 'SELECT users.id, users.username, users.email, users.password, users.user_language_id, ul.identifier AS user_language_identifier, users.can_login, users.is_gravatar_allowed, GROUP_CONCAT(ug.id) AS user_group_ids, GROUP_CONCAT(ug.identifier) AS user_group_identifiers, GROUP_CONCAT(ug.name) AS user_group_names FROM users INNER JOIN user_languages AS ul ON ul.id = users.user_language_id AND ul.deleted_at IS NULL LEFT JOIN users_user_groups AS uug ON uug.user_id = users.id AND uug.deleted_at IS NULL LEFT JOIN user_groups AS ug ON ug.id = uug.user_group_id AND ug.deleted_at IS NULL WHERE (users.deleted_at IS NULL) AND ((username = :identifier OR email = :identifier)) GROUP BY users.id'; // phpcs:ignore
478
        $values       = ['identifier' => [$email, \PDO::PARAM_STR]];
479
        $expectedData = [
480
            [
481
                'id'                       => $id,
482
                'username'                 => $username,
483
                'email'                    => $email,
484
                'password'                 => $password,
485
                'user_language_id'         => $userLanguage->getId(),
486
                'user_language_identifier' => $userLanguage->getIdentifier(),
487
                'can_login'                => $canLogin,
488
                'is_gravatar_allowed'      => $isGravatarAllowed,
489
            ],
490
        ];
491
        $statement0 = MockStatementFactory::createReadStatement($this, $values, $expectedData);
492
493
        $this->readConnectionMock
494
            ->expects($this->once())
495
            ->method('prepare')
496
            ->with($sql0)
497
            ->willReturn($statement0);
498
499
        $actualResult = $this->sut->find($email);
500
501
        $this->assertEntity($expectedData[0], $actualResult);
502
    }
503
504
    public function testGetByClientId()
505
    {
506
        $id                = '0496d1d1-a750-4c91-822e-03a0fd6718b7';
507
        $username          = 'foo';
508
        $email             = '[email protected]';
509
        $password          = '';
510
        $userLanguage      = new UserLanguage('8b9543ad-17e8-4e54-af17-e8a8b271a70e', 'baz', 'Baz');
511
        $canLogin          = true;
512
        $isGravatarAllowed = true;
513
        $clientId          = '063b730f-3458-49dc-b60e-8171cefacabf';
514
515
        $sql0          = 'SELECT users.id, users.username, users.email, users.password, users.user_language_id, ul.identifier AS user_language_identifier, users.can_login, users.is_gravatar_allowed, GROUP_CONCAT(ug.id) AS user_group_ids, GROUP_CONCAT(ug.identifier) AS user_group_identifiers, GROUP_CONCAT(ug.name) AS user_group_names FROM users INNER JOIN user_languages AS ul ON ul.id = users.user_language_id AND ul.deleted_at IS NULL INNER JOIN api_clients AS ac ON ac.user_id = users.id AND ac.deleted_at IS NULL LEFT JOIN users_user_groups AS uug ON uug.user_id = users.id AND uug.deleted_at IS NULL LEFT JOIN user_groups AS ug ON ug.id = uug.user_group_id AND ug.deleted_at IS NULL WHERE (users.deleted_at IS NULL) AND (ac.id = :client_id) GROUP BY users.id'; // phpcs:ignore
516
        $values       = ['client_id' => [$clientId, \PDO::PARAM_STR]];
517
        $expectedData = [
518
            [
519
                'id'                       => $id,
520
                'username'                 => $username,
521
                'email'                    => $email,
522
                'password'                 => $password,
523
                'user_language_id'         => $userLanguage->getId(),
524
                'user_language_identifier' => $userLanguage->getIdentifier(),
525
                'can_login'                => $canLogin,
526
                'is_gravatar_allowed'      => $isGravatarAllowed,
527
            ],
528
        ];
529
        $statement0 = MockStatementFactory::createReadStatement($this, $values, $expectedData);
530
531
        $this->readConnectionMock
532
            ->expects($this->once())
533
            ->method('prepare')
534
            ->with($sql0)
535
            ->willReturn($statement0);
536
537
        $actualResult = $this->sut->getByClientId($clientId);
538
539
        $this->assertEntity($expectedData[0], $actualResult);
540
    }
541
542
    public function testUpdateWithoutRelated()
543
    {
544
        $id                = '76b408bc-d061-4bc7-8e03-8892317e4c78';
545
        $username          = 'foo';
546
        $email             = '[email protected]';
547
        $password          = '';
548
        $userLanguage      = new UserLanguage('eae6da9c-16fc-4929-8bc6-1a81e2982702', 'baz', 'Baz');
549
        $canLogin          = true;
550
        $isGravatarAllowed = true;
551
552
        $sql0       = 'UPDATE users AS users SET username = ?, email = ?, password = ?, user_language_id = ?, can_login = ?, is_gravatar_allowed = ? WHERE (id = ?)'; // phpcs:ignore
553
        $values0    = [
554
            [$username, \PDO::PARAM_STR],
555
            [$email, \PDO::PARAM_STR],
556
            [$password, \PDO::PARAM_STR],
557
            [$userLanguage->getId(), \PDO::PARAM_STR],
558
            [$canLogin, \PDO::PARAM_INT],
559
            [$isGravatarAllowed, \PDO::PARAM_INT],
560
            [$id, \PDO::PARAM_STR],
561
        ];
562
        $statement0 = MockStatementFactory::createWriteStatement($this, $values0);
563
564
        $sql1       = 'DELETE FROM users_user_groups WHERE (user_id = ?)'; // phpcs:ignore
565
        $values1    = [[$id, \PDO::PARAM_STR]];
566
        $statement1 = MockStatementFactory::createWriteStatement($this, $values1);
567
568
        $this->writeConnectionMock
569
            ->expects($this->exactly(2))
570
            ->method('prepare')
571
            ->withConsecutive([$sql0], [$sql1])
572
            ->willReturnOnConsecutiveCalls($statement0, $statement1);
573
574
        $entity = new User($id, $username, $email, $password, $canLogin, $isGravatarAllowed, $userLanguage);
575
        $this->sut->update($entity);
576
    }
577
578
    public function testUpdateWithRelated()
579
    {
580
        $id                = '2410891a-5e7f-4b39-ad00-5d0379b54b25';
581
        $username          = 'foo';
582
        $email             = '[email protected]';
583
        $password          = '';
584
        $userLanguage      = new UserLanguage('aa489d5d-c3bd-4039-b431-4aaa2d33418a', 'baz', 'Baz');
585
        $canLogin          = true;
586
        $isGravatarAllowed = true;
587
        $uugId0            = '76036dfa-5978-434e-96a6-9c5d5e8831c7';
588
        $uugId1            = '81c6f4a6-583a-41ff-b5bb-9015d9f97bd3';
589
        $userGroups        = [
590
            new UserGroup('7858a040-5b45-4989-b0ea-941a668e9db8', 'ug-38', 'UG 38'),
591
            new UserGroup('e4ecde09-2b7a-4445-be68-abd5be948d28', 'ug-51', 'UG 51'),
592
        ];
593
594
        $this->sut->setIdGenerator(MockIdGeneratorFactory::create($this, $uugId0, $uugId1));
595
596
        $sql0       = 'UPDATE users AS users SET username = ?, email = ?, password = ?, user_language_id = ?, can_login = ?, is_gravatar_allowed = ? WHERE (id = ?)'; // phpcs:ignore
597
        $values0    = [
598
            [$username, \PDO::PARAM_STR],
599
            [$email, \PDO::PARAM_STR],
600
            [$password, \PDO::PARAM_STR],
601
            [$userLanguage->getId(), \PDO::PARAM_STR],
602
            [$canLogin, \PDO::PARAM_INT],
603
            [$isGravatarAllowed, \PDO::PARAM_INT],
604
            [$id, \PDO::PARAM_STR],
605
        ];
606
        $statement0 = MockStatementFactory::createWriteStatement($this, $values0);
607
608
        $sql1       = 'DELETE FROM users_user_groups WHERE (user_id = ?)'; // phpcs:ignore
609
        $values1    = [[$id, \PDO::PARAM_STR]];
610
        $statement1 = MockStatementFactory::createWriteStatement($this, $values1);
611
612
        $sql2       = 'INSERT INTO users_user_groups (id, user_id, user_group_id) VALUES (?, ?, ?)'; // phpcs:ignore
613
        $values2    = [[$uugId0, \PDO::PARAM_STR], [$id, \PDO::PARAM_STR], [$userGroups[0]->getId(), \PDO::PARAM_STR]];
614
        $statement2 = MockStatementFactory::createWriteStatement($this, $values2);
615
616
        $sql3       = 'INSERT INTO users_user_groups (id, user_id, user_group_id) VALUES (?, ?, ?)'; // phpcs:ignore
617
        $values3    = [[$uugId1, \PDO::PARAM_STR], [$id, \PDO::PARAM_STR], [$userGroups[1]->getId(), \PDO::PARAM_STR]];
618
        $statement3 = MockStatementFactory::createWriteStatement($this, $values3);
619
620
        $this->writeConnectionMock
621
            ->expects($this->exactly(4))
622
            ->method('prepare')
623
            ->withConsecutive([$sql0], [$sql1], [$sql2], [$sql3])
624
            ->willReturnOnConsecutiveCalls($statement0, $statement1, $statement2, $statement3);
625
626
        $entity = new User(
627
            $id,
628
            $username,
629
            $email,
630
            $password,
631
            $canLogin,
632
            $isGravatarAllowed,
633
            $userLanguage,
634
            $userGroups
635
        );
636
        $this->sut->update($entity);
637
    }
638
639
    public function testAddThrowsExceptionIfCalledWithInvalidEntity()
640
    {
641
        $this->expectException(\InvalidArgumentException::class);
642
643
        /** @var IStringerEntity|MockObject $entity */
644
        $entity = $this->createMock(IStringerEntity::class);
645
646
        $this->sut->add($entity);
647
    }
648
649
    public function testDeleteThrowsExceptionIfCalledWithInvalidEntity()
650
    {
651
        $this->expectException(\InvalidArgumentException::class);
652
653
        /** @var IStringerEntity|MockObject $entity */
654
        $entity = $this->createMock(IStringerEntity::class);
655
656
        $this->sut->delete($entity);
657
    }
658
659
    public function testUpdateThrowsExceptionIfCalledWithInvalidEntity()
660
    {
661
        $this->expectException(\InvalidArgumentException::class);
662
663
        /** @var IStringerEntity|MockObject $entity */
664
        $entity = $this->createMock(IStringerEntity::class);
665
666
        $this->sut->update($entity);
667
    }
668
669
    /**
670
     * @param array $expectedData
671
     * @param User  $entity
672
     */
673
    protected function assertEntity(array $expectedData, $entity)
674
    {
675
        $this->assertInstanceOf(User::class, $entity);
676
        $this->assertSame($expectedData['id'], $entity->getId());
677
        $this->assertSame($expectedData['username'], $entity->getUsername());
678
        $this->assertSame($expectedData['email'], $entity->getEmail());
679
        $this->assertSame($expectedData['password'], $entity->getPassword());
680
        $this->assertSame($expectedData['user_language_id'], $entity->getUserLanguage()->getId());
681
        $this->assertSame($expectedData['user_language_identifier'], $entity->getUserLanguage()->getIdentifier());
682
        $this->assertSame($expectedData['can_login'], $entity->canLogin());
683
        $this->assertSame($expectedData['is_gravatar_allowed'], $entity->isGravatarAllowed());
684
685
        $this->assertUserGroups($expectedData, $entity);
686
    }
687
688
    /**
689
     * @param array $expectedData
690
     * @param User  $entity
691
     */
692
    protected function assertUserGroups(array $expectedData, $entity)
693
    {
694
        if (empty($expectedData['user_group_ids'])) {
695
            return;
696
        }
697
698
        $ugIds         = explode(',', $expectedData['user_group_ids']);
699
        $ugIdentifiers = explode(',', $expectedData['user_group_identifiers']);
700
        $ugNames       = explode(',', $expectedData['user_group_names']);
701
702
        foreach ($entity->getUserGroups() as $idx => $ug) {
703
            $this->assertSame($ugIds[$idx], $ug->getId());
704
            $this->assertSame($ugIdentifiers[$idx], $ug->getIdentifier());
705
            $this->assertSame($ugNames[$idx], $ug->getName());
706
        }
707
    }
708
}
709