Completed
Push — ezp-30928-as_a_developer_i_wan... ( 4d81da...f06b29 )
by
unknown
14:36
created

UserServiceTest::testLoadUsersOfUserGroup()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 21

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
nc 2
nop 0
dl 0
loc 21
rs 9.584
c 0
b 0
f 0
1
<?php
2
3
/**
4
 * File containing the UserServiceTest class.
5
 *
6
 * @copyright Copyright (C) eZ Systems AS. All rights reserved.
7
 * @license For full copyright and license information view LICENSE file distributed with this source code.
8
 */
9
namespace eZ\Publish\API\Repository\Tests;
10
11
use DateInterval;
12
use DateTime;
13
use DateTimeImmutable;
14
use eZ\Publish\API\Repository\Exceptions\InvalidArgumentException;
15
use eZ\Publish\API\Repository\Exceptions\NotFoundException;
16
use eZ\Publish\API\Repository\Values\Content\ContentInfo;
17
use eZ\Publish\API\Repository\Values\Content\VersionInfo as APIVersionInfo;
18
use eZ\Publish\API\Repository\Values\ContentType\ContentType;
19
use eZ\Publish\API\Repository\Values\User\Limitation\SubtreeLimitation;
20
use eZ\Publish\API\Repository\Values\User\PasswordInfo;
21
use eZ\Publish\API\Repository\Values\User\PasswordValidationContext;
22
use eZ\Publish\API\Repository\Values\User\UserGroupUpdateStruct;
23
use eZ\Publish\API\Repository\Values\User\UserTokenUpdateStruct;
24
use eZ\Publish\API\Repository\Values\User\UserUpdateStruct;
25
use eZ\Publish\API\Repository\Values\User\User;
26
use eZ\Publish\Core\FieldType\ValidationError;
27
use eZ\Publish\Core\Repository\Values\Content\Content;
28
use eZ\Publish\Core\Repository\Values\Content\VersionInfo;
29
use eZ\Publish\Core\Repository\Values\User\UserGroup;
30
use Exception;
31
use ReflectionClass;
32
33
/**
34
 * Test case for operations in the UserService using in memory storage.
35
 *
36
 * @see eZ\Publish\API\Repository\UserService
37
 * @group integration
38
 * @group user
39
 */
40
class UserServiceTest extends BaseTest
41
{
42
    // Example password matching default rules
43
    private const EXAMPLE_PASSWORD = 'P@ssword123!';
44
45
    private const EXAMPLE_PASSWORD_TTL = 30;
46
    private const EXAMPLE_PASSWORD_TTL_WARNING = 14;
47
48
    /**
49
     * Test for the loadUserGroup() method.
50
     *
51
     * @see \eZ\Publish\API\Repository\UserService::loadUserGroup()
52
     */
53
    public function testLoadUserGroup()
54
    {
55
        $repository = $this->getRepository();
56
57
        $mainGroupId = $this->generateId('group', 4);
58
        /* BEGIN: Use Case */
59
        // $mainGroupId is the ID of the main "Users" group
60
61
        $userService = $repository->getUserService();
62
63
        $userGroup = $userService->loadUserGroup($mainGroupId);
64
        /* END: Use Case */
65
66
        $this->assertInstanceOf(UserGroup::class, $userGroup);
67
68
        // User group happens to also be a Content; isUserGroup() should be true and isUser() should be false
69
        $this->assertTrue($userService->isUserGroup($userGroup), 'isUserGroup() => false on a user group');
70
        $this->assertFalse($userService->isUser($userGroup), 'isUser() => true on a user group');
71
        $this->assertSame(0, $userGroup->parentId, 'parentId should be equal `0` because it is top level node');
72
    }
73
74
    /**
75
     * Test for the loadUserGroup() method to ensure that DomainUserGroupObject is created properly even if a user
76
     * has no access to parent of UserGroup.
77
     *
78
     * @see \eZ\Publish\API\Repository\UserService::loadUserGroup()
79
     */
80
    public function testLoadUserGroupWithNoAccessToParent()
81
    {
82
        $repository = $this->getRepository();
83
84
        $mainGroupId = $this->generateId('group', 4);
85
        /* BEGIN: Use Case */
86
        // $mainGroupId is the ID of the main "Users" group
87
88
        $userService = $repository->getUserService();
89
90
        $user = $this->createUserWithPolicies(
91
            'user',
92
            [
93
                ['module' => 'content', 'function' => 'read'],
94
            ],
95
            new SubtreeLimitation(['limitationValues' => ['/1/5']])
96
        );
97
        $repository->getPermissionResolver()->setCurrentUserReference($user);
98
99
        $userGroup = $userService->loadUserGroup($mainGroupId);
100
        /* END: Use Case */
101
102
        $this->assertInstanceOf(UserGroup::class, $userGroup);
103
104
        // User group happens to also be a Content; isUserGroup() should be true and isUser() should be false
105
        $this->assertTrue($userService->isUserGroup($userGroup), 'isUserGroup() => false on a user group');
106
        $this->assertFalse($userService->isUser($userGroup), 'isUser() => true on a user group');
107
        $this->assertSame(0, $userGroup->parentId, 'parentId should be equal `0` because it is top level node');
108
    }
109
110
    /**
111
     * Test for the loadUserGroup() method.
112
     *
113
     * @see \eZ\Publish\API\Repository\UserService::loadUserGroup()
114
     * @depends eZ\Publish\API\Repository\Tests\UserServiceTest::testLoadUserGroup
115
     */
116
    public function testLoadUserGroupThrowsNotFoundException()
117
    {
118
        $this->expectException(\eZ\Publish\API\Repository\Exceptions\NotFoundException::class);
119
120
        $repository = $this->getRepository();
121
122
        $nonExistingGroupId = $this->generateId('group', self::DB_INT_MAX);
123
        /* BEGIN: Use Case */
124
        $userService = $repository->getUserService();
125
126
        // This call will fail with a NotFoundException
127
        $userService->loadUserGroup($nonExistingGroupId);
128
        /* END: Use Case */
129
    }
130
131
    /**
132
     * Test for the loadSubUserGroups() method.
133
     *
134
     * @see \eZ\Publish\API\Repository\UserService::loadSubUserGroups()
135
     * @depends eZ\Publish\API\Repository\Tests\UserServiceTest::testLoadUserGroup
136
     */
137
    public function testLoadSubUserGroups()
138
    {
139
        $repository = $this->getRepository();
140
141
        $mainGroupId = $this->generateId('group', 4);
142
        /* BEGIN: Use Case */
143
        // $mainGroupId is the ID of the main "Users" group
144
145
        $userService = $repository->getUserService();
146
147
        $userGroup = $userService->loadUserGroup($mainGroupId);
148
149
        $subUserGroups = $userService->loadSubUserGroups($userGroup);
150
        foreach ($subUserGroups as $subUserGroup) {
151
            // Do something with the $subUserGroup
152
            $this->assertInstanceOf(UserGroup::class, $subUserGroup);
153
        }
154
        /* END: Use Case */
155
    }
156
157
    /**
158
     * Test loading sub groups throwing NotFoundException.
159
     *
160
     * @covers \eZ\Publish\API\Repository\UserService::loadSubUserGroups
161
     */
162
    public function testLoadSubUserGroupsThrowsNotFoundException()
163
    {
164
        $this->expectException(\eZ\Publish\API\Repository\Exceptions\NotFoundException::class);
165
166
        $repository = $this->getRepository();
167
        $userService = $repository->getUserService();
168
169
        $parentGroup = new UserGroup(
170
            [
171
                'content' => new Content(
172
                    [
173
                        'versionInfo' => new VersionInfo(
174
                            [
175
                                'contentInfo' => new ContentInfo(
176
                                    ['id' => 123456]
177
                                ),
178
                            ]
179
                        ),
180
                        'internalFields' => [],
181
                    ]
182
                ),
183
            ]
184
        );
185
        $userService->loadSubUserGroups($parentGroup);
186
    }
187
188
    /**
189
     * Test for the newUserGroupCreateStruct() method.
190
     *
191
     * @return \eZ\Publish\API\Repository\Values\User\UserGroupCreateStruct
192
     *
193
     * @see \eZ\Publish\API\Repository\UserService::newUserGroupCreateStruct()
194
     * @depends eZ\Publish\API\Repository\Tests\ContentTypeServiceTest::testLoadContentTypeByIdentifier
195
     */
196
    public function testNewUserGroupCreateStruct()
197
    {
198
        $repository = $this->getRepository();
199
200
        /* BEGIN: Use Case */
201
        $userService = $repository->getUserService();
202
203
        $groupCreate = $userService->newUserGroupCreateStruct('eng-US');
204
        /* END: Use Case */
205
206
        $this->assertInstanceOf(
207
            '\\eZ\\Publish\\API\\Repository\\Values\\User\\UserGroupCreateStruct',
208
            $groupCreate
209
        );
210
211
        return $groupCreate;
212
    }
213
214
    /**
215
     * Test for the newUserGroupCreateStruct() method.
216
     *
217
     * @param \eZ\Publish\API\Repository\Values\User\UserGroupCreateStruct $groupCreate
218
     *
219
     * @see \eZ\Publish\API\Repository\UserService::newUserGroupCreateStruct()
220
     * @depends eZ\Publish\API\Repository\Tests\UserServiceTest::testNewUserGroupCreateStruct
221
     */
222
    public function testNewUserGroupCreateStructSetsMainLanguageCode($groupCreate)
223
    {
224
        $this->assertEquals('eng-US', $groupCreate->mainLanguageCode);
225
    }
226
227
    /**
228
     * Test for the newUserGroupCreateStruct() method.
229
     *
230
     * @param \eZ\Publish\API\Repository\Values\User\UserGroupCreateStruct $groupCreate
231
     *
232
     * @see \eZ\Publish\API\Repository\UserService::newUserGroupCreateStruct()
233
     * @depends eZ\Publish\API\Repository\Tests\UserServiceTest::testNewUserGroupCreateStruct
234
     */
235
    public function testNewUserGroupCreateStructSetsContentType($groupCreate)
236
    {
237
        $this->assertInstanceOf(
238
            '\\eZ\\Publish\\API\\Repository\\Values\\ContentType\\ContentType',
239
            $groupCreate->contentType
240
        );
241
    }
242
243
    /**
244
     * Test for the newUserGroupCreateStruct() method.
245
     *
246
     * @see \eZ\Publish\API\Repository\UserService::newUserGroupCreateStruct($mainLanguageCode, $contentType)
247
     * @depends eZ\Publish\API\Repository\Tests\UserServiceTest::testNewUserGroupCreateStruct
248
     * @depends eZ\Publish\API\Repository\Tests\ContentTypeServiceTest::testLoadContentTypeByIdentifier
249
     */
250
    public function testNewUserGroupCreateStructWithSecondParameter()
251
    {
252
        if ($this->isVersion4()) {
253
            $this->markTestSkipped('This test is only relevant for eZ Publish versions > 4');
254
        }
255
256
        $repository = $this->getRepository();
257
258
        /* BEGIN: Use Case */
259
        $contentTypeService = $repository->getContentTypeService();
260
        $userService = $repository->getUserService();
261
262
        // Load the default ContentType for user groups
263
        $groupType = $contentTypeService->loadContentTypeByIdentifier('user_group');
264
265
        // Instantiate a new group create struct
266
        $groupCreate = $userService->newUserGroupCreateStruct(
267
            'eng-US',
268
            $groupType
269
        );
270
        /* END: Use Case */
271
272
        $this->assertSame($groupType, $groupCreate->contentType);
273
    }
274
275
    /**
276
     * Test for the createUserGroup() method.
277
     *
278
     * @return \eZ\Publish\API\Repository\Values\User\UserGroup
279
     *
280
     * @see \eZ\Publish\API\Repository\UserService::createUserGroup()
281
     * @depends eZ\Publish\API\Repository\Tests\UserServiceTest::testNewUserGroupCreateStruct
282
     * @depends eZ\Publish\API\Repository\Tests\UserServiceTest::testLoadUserGroup
283
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testCreateContent
284
     */
285
    public function testCreateUserGroup()
286
    {
287
        /* BEGIN: Use Case */
288
        $userGroup = $this->createUserGroupVersion1();
289
        /* END: Use Case */
290
291
        $this->assertInstanceOf(
292
            UserGroup::class,
293
            $userGroup
294
        );
295
296
        $versionInfo = $userGroup->getVersionInfo();
297
298
        $this->assertEquals(APIVersionInfo::STATUS_PUBLISHED, $versionInfo->status);
299
        $this->assertEquals(1, $versionInfo->versionNo);
300
301
        return $userGroup;
302
    }
303
304
    /**
305
     * Test for the createUserGroup() method.
306
     *
307
     * @param \eZ\Publish\API\Repository\Values\User\UserGroup $userGroup
308
     *
309
     * @see \eZ\Publish\API\Repository\UserService::createUserGroup()
310
     * @depends eZ\Publish\API\Repository\Tests\UserServiceTest::testCreateUserGroup
311
     */
312
    public function testCreateUserGroupSetsExpectedProperties($userGroup)
313
    {
314
        $this->assertEquals(
315
            [
316
                'parentId' => $this->generateId('group', 4),
317
            ],
318
            [
319
                'parentId' => $userGroup->parentId,
320
            ]
321
        );
322
    }
323
324
    /**
325
     * Test for the createUserGroup() method.
326
     *
327
     * @see \eZ\Publish\API\Repository\UserService::createUserGroup()
328
     * @depends eZ\Publish\API\Repository\Tests\UserServiceTest::testCreateUserGroup
329
     */
330
    public function testCreateUserGroupThrowsInvalidArgumentException()
331
    {
332
        $this->expectException(\eZ\Publish\API\Repository\Exceptions\InvalidArgumentException::class);
333
334
        $repository = $this->getRepository();
335
336
        $mainGroupId = $this->generateId('group', 4);
337
        /* BEGIN: Use Case */
338
        // $mainGroupId is the ID of the main "Users" group
339
340
        $userService = $repository->getUserService();
341
342
        // Load main group
343
        $parentUserGroup = $userService->loadUserGroup($mainGroupId);
344
345
        // Instantiate a new create struct
346
        $userGroupCreate = $userService->newUserGroupCreateStruct('eng-US');
347
        $userGroupCreate->setField('name', 'Example Group');
348
        $userGroupCreate->remoteId = '5f7f0bdb3381d6a461d8c29ff53d908f';
349
350
        // This call will fail with an "InvalidArgumentException", because the
351
        // specified remoteId is already used for the "Members" user group.
352
        $userService->createUserGroup(
353
            $userGroupCreate,
354
            $parentUserGroup
355
        );
356
        /* END: Use Case */
357
    }
358
359
    /**
360
     * Test for the createUserGroup() method.
361
     *
362
     * @see \eZ\Publish\API\Repository\UserService::createUserGroup()
363
     * @depends eZ\Publish\API\Repository\Tests\UserServiceTest::testCreateUserGroup
364
     */
365
    public function testCreateUserGroupThrowsInvalidArgumentExceptionFieldTypeNotAccept()
366
    {
367
        $this->expectException(\eZ\Publish\API\Repository\Exceptions\InvalidArgumentException::class);
368
369
        $repository = $this->getRepository();
370
371
        $mainGroupId = $this->generateId('group', 4);
372
        /* BEGIN: Use Case */
373
        // $mainGroupId is the ID of the main "Users" group
374
375
        $userService = $repository->getUserService();
376
377
        // Load main group
378
        $parentUserGroup = $userService->loadUserGroup($mainGroupId);
379
380
        // Instantiate a new create struct
381
        $userGroupCreate = $userService->newUserGroupCreateStruct('eng-US');
382
        $userGroupCreate->setField('name', new \stdClass());
383
384
        // This call will fail with an "InvalidArgumentException", because the
385
        // specified remoteId is already used for the "Members" user group.
386
        $userService->createUserGroup(
387
            $userGroupCreate,
388
            $parentUserGroup
389
        );
390
        /* END: Use Case */
391
    }
392
393
    /**
394
     * Test for the createUserGroup() method.
395
     *
396
     * @see \eZ\Publish\API\Repository\UserService::createUserGroup()
397
     * @depends eZ\Publish\API\Repository\Tests\UserServiceTest::testCreateUserGroup
398
     */
399
    public function testCreateUserGroupWhenMissingField()
400
    {
401
        $this->expectException(\eZ\Publish\API\Repository\Exceptions\ContentFieldValidationException::class);
402
403
        $repository = $this->getRepository();
404
405
        $mainGroupId = $this->generateId('group', 4);
406
        /* BEGIN: Use Case */
407
        // $mainGroupId is the ID of the main "Users" group
408
409
        $userService = $repository->getUserService();
410
411
        // Load main group
412
        $parentUserGroup = $userService->loadUserGroup($mainGroupId);
413
414
        // Instantiate a new create struct
415
        $userGroupCreate = $userService->newUserGroupCreateStruct('eng-US');
416
417
        // This call will fail with a "ContentFieldValidationException", because the
418
        // only mandatory field "name" is not set.
419
        $userService->createUserGroup($userGroupCreate, $parentUserGroup);
420
        /* END: Use Case */
421
    }
422
423
    /**
424
     * Test for the createUserGroup() method.
425
     *
426
     * @return \eZ\Publish\API\Repository\Values\User\UserGroup
427
     *
428
     * @see \eZ\Publish\API\Repository\UserService::createUserGroup()
429
     * @depends eZ\Publish\API\Repository\Tests\UserServiceTest::testNewUserGroupCreateStruct
430
     * @depends eZ\Publish\API\Repository\Tests\UserServiceTest::testLoadUserGroup
431
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testCreateContent
432
     */
433
    public function testCreateUserGroupInTransactionWithRollback()
434
    {
435
        $repository = $this->getRepository();
436
437
        $mainGroupId = $this->generateId('group', 4);
438
        /* BEGIN: Use Case */
439
        // $mainGroupId is the ID of the main "Users" group
440
441
        $userService = $repository->getUserService();
442
443
        $repository->beginTransaction();
444
445
        try {
446
            // Load main group
447
            $parentUserGroup = $userService->loadUserGroup($mainGroupId);
448
449
            // Instantiate a new create struct
450
            $userGroupCreate = $userService->newUserGroupCreateStruct('eng-US');
451
            $userGroupCreate->setField('name', 'Example Group');
452
453
            // Create the new user group
454
            $createdUserGroupId = $userService->createUserGroup(
455
                $userGroupCreate,
456
                $parentUserGroup
457
            )->id;
458
        } catch (Exception $e) {
459
            // Cleanup hanging transaction on error
460
            $repository->rollback();
461
            throw $e;
462
        }
463
464
        $repository->rollback();
465
466
        try {
467
            // Throws exception since creation of user group was rolled back
468
            $loadedGroup = $userService->loadUserGroup($createdUserGroupId);
0 ignored issues
show
Unused Code introduced by
$loadedGroup is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
469
        } catch (NotFoundException $e) {
470
            return;
471
        }
472
        /* END: Use Case */
473
474
        $this->fail('User group object still exists after rollback.');
475
    }
476
477
    /**
478
     * Test for the deleteUserGroup() method.
479
     *
480
     * @see \eZ\Publish\API\Repository\UserService::deleteUserGroup()
481
     * @depends eZ\Publish\API\Repository\Tests\UserServiceTest::testCreateUserGroup
482
     */
483
    public function testDeleteUserGroup()
484
    {
485
        $this->expectException(\eZ\Publish\API\Repository\Exceptions\NotFoundException::class);
486
487
        $repository = $this->getRepository();
488
        $userService = $repository->getUserService();
489
490
        /* BEGIN: Use Case */
491
        $userGroup = $this->createUserGroupVersion1();
492
493
        // Delete the currently created user group again
494
        $userService->deleteUserGroup($userGroup);
495
        /* END: Use Case */
496
497
        // We use the NotFoundException here for verification
498
        $userService->loadUserGroup($userGroup->id);
499
    }
500
501
    /**
502
     * Test deleting user group throwing NotFoundException.
503
     *
504
     * @covers \eZ\Publish\API\Repository\UserService::deleteUserGroup
505
     */
506
    public function testDeleteUserGroupThrowsNotFoundException()
507
    {
508
        $this->expectException(\eZ\Publish\API\Repository\Exceptions\NotFoundException::class);
509
510
        $repository = $this->getRepository();
511
        $userService = $repository->getUserService();
512
513
        $userGroup = new UserGroup(
514
            [
515
                'content' => new Content(
516
                    [
517
                        'versionInfo' => new VersionInfo(
518
                            ['contentInfo' => new ContentInfo(['id' => 123456])]
519
                        ),
520
                        'internalFields' => [],
521
                    ]
522
                ),
523
            ]
524
        );
525
        $userService->deleteUserGroup($userGroup);
526
    }
527
528
    /**
529
     * Test for the moveUserGroup() method.
530
     *
531
     * @see \eZ\Publish\API\Repository\UserService::moveUserGroup()
532
     * @depends eZ\Publish\API\Repository\Tests\UserServiceTest::testCreateUserGroup
533
     * @depends eZ\Publish\API\Repository\Tests\UserServiceTest::testLoadSubUserGroups
534
     */
535
    public function testMoveUserGroup()
536
    {
537
        $repository = $this->getRepository();
538
        $userService = $repository->getUserService();
539
540
        $membersGroupId = $this->generateId('group', 13);
541
        /* BEGIN: Use Case */
542
        // $membersGroupId is the ID of the "Members" user group in an eZ
543
        // Publish demo installation
544
545
        $userGroup = $this->createUserGroupVersion1();
546
547
        // Load the new parent group
548
        $membersUserGroup = $userService->loadUserGroup($membersGroupId);
549
550
        // Move user group from "Users" to "Members"
551
        $userService->moveUserGroup($userGroup, $membersUserGroup);
552
553
        // Reload the user group to get an updated $parentId
554
        $userGroup = $userService->loadUserGroup($userGroup->id);
555
556
        $this->refreshSearch($repository);
557
558
        // The returned array will no contain $userGroup
559
        $subUserGroups = $userService->loadSubUserGroups(
560
            $membersUserGroup
561
        );
562
        /* END: Use Case */
563
564
        $subUserGroupIds = array_map(
565
            function ($content) {
566
                return $content->id;
567
            },
568
            $subUserGroups
569
        );
570
571
        $this->assertEquals($membersGroupId, $userGroup->parentId);
572
        $this->assertEquals([$userGroup->id], $subUserGroupIds);
573
    }
574
575
    /**
576
     * Test moving a user group below another group throws NotFoundException.
577
     *
578
     * @covers \eZ\Publish\API\Repository\UserService::moveUserGroup
579
     */
580
    public function testMoveUserGroupThrowsNotFoundException()
581
    {
582
        $this->expectException(\eZ\Publish\API\Repository\Exceptions\NotFoundException::class);
583
584
        $repository = $this->getRepository();
585
        $userService = $repository->getUserService();
586
587
        $userGroupToMove = new UserGroup(
588
            [
589
                'content' => new Content(
590
                    [
591
                        'versionInfo' => new VersionInfo(
592
                            ['contentInfo' => new ContentInfo(['id' => 123456])]
593
                        ),
594
                        'internalFields' => [],
595
                    ]
596
                ),
597
            ]
598
        );
599
        $parentUserGroup = new UserGroup(
600
            [
601
                'content' => new Content(
602
                    [
603
                        'versionInfo' => new VersionInfo(
604
                            ['contentInfo' => new ContentInfo(['id' => 123455])]
605
                        ),
606
                        'internalFields' => [],
607
                    ]
608
                ),
609
            ]
610
        );
611
        $userService->moveUserGroup($userGroupToMove, $parentUserGroup);
612
    }
613
614
    /**
615
     * Test for the newUserGroupUpdateStruct() method.
616
     *
617
     * @covers \eZ\Publish\API\Repository\UserService::newUserGroupUpdateStruct
618
     */
619
    public function testNewUserGroupUpdateStruct()
620
    {
621
        $repository = $this->getRepository();
622
623
        /* BEGIN: Use Case */
624
        $userService = $repository->getUserService();
625
626
        $groupUpdate = $userService->newUserGroupUpdateStruct();
627
        /* END: Use Case */
628
629
        $this->assertInstanceOf(
630
            UserGroupUpdateStruct::class,
631
            $groupUpdate
632
        );
633
634
        $this->assertNull($groupUpdate->contentUpdateStruct);
635
        $this->assertNull($groupUpdate->contentMetadataUpdateStruct);
636
    }
637
638
    /**
639
     * Test for the updateUserGroup() method.
640
     *
641
     * @see \eZ\Publish\API\Repository\UserService::updateUserGroup()
642
     * @depends eZ\Publish\API\Repository\Tests\UserServiceTest::testCreateUserGroup
643
     * @depends eZ\Publish\API\Repository\Tests\UserServiceTest::testNewUserGroupUpdateStruct
644
     */
645
    public function testUpdateUserGroup()
646
    {
647
        $repository = $this->getRepository();
648
        $userService = $repository->getUserService();
649
650
        /* BEGIN: Use Case */
651
        $userGroup = $this->createUserGroupVersion1();
652
653
        // Create a group update struct and change nothing
654
        $groupUpdate = $userService->newUserGroupUpdateStruct();
655
656
        // This update will do nothing
657
        $userGroup = $userService->updateUserGroup(
658
            $userGroup,
659
            $groupUpdate
660
        );
661
        /* END: Use Case */
662
663
        $this->assertInstanceOf(
664
            UserGroup::class,
665
            $userGroup
666
        );
667
668
        $this->assertEquals(1, $userGroup->getVersionInfo()->versionNo);
669
    }
670
671
    /**
672
     * Test for the updateUserGroup() method.
673
     *
674
     * @see \eZ\Publish\API\Repository\UserService::updateUserGroup()
675
     * @depends eZ\Publish\API\Repository\Tests\UserServiceTest::testUpdateUserGroup
676
     */
677
    public function testUpdateUserGroupWithSubContentUpdateStruct()
678
    {
679
        $repository = $this->getRepository();
680
        $userService = $repository->getUserService();
681
682
        /* BEGIN: Use Case */
683
        $userGroup = $this->createUserGroupVersion1();
684
685
        // Load the content service
686
        $contentService = $repository->getContentService();
687
688
        // Create a content update struct and update the group name
689
        $contentUpdate = $contentService->newContentUpdateStruct();
690
        $contentUpdate->setField('name', 'Sindelfingen', 'eng-US');
691
692
        // Create a group update struct and set content update struct
693
        $groupUpdate = $userService->newUserGroupUpdateStruct();
694
        $groupUpdate->contentUpdateStruct = $contentUpdate;
695
696
        // This will update the name and the increment the group version number
697
        $userGroup = $userService->updateUserGroup(
698
            $userGroup,
699
            $groupUpdate
700
        );
701
        /* END: Use Case */
702
703
        $this->assertEquals('Sindelfingen', $userGroup->getFieldValue('name', 'eng-US'));
704
705
        $versionInfo = $userGroup->getVersionInfo();
706
707
        $this->assertEquals(APIVersionInfo::STATUS_PUBLISHED, $versionInfo->status);
708
        $this->assertEquals(2, $versionInfo->versionNo);
709
    }
710
711
    /**
712
     * Test for the updateUserGroup() method.
713
     *
714
     * @see \eZ\Publish\API\Repository\UserService::updateUserGroup()
715
     * @depends eZ\Publish\API\Repository\Tests\UserServiceTest::testUpdateUserGroup
716
     */
717
    public function testUpdateUserGroupWithSubContentMetadataUpdateStruct()
718
    {
719
        $repository = $this->getRepository();
720
        $userService = $repository->getUserService();
721
722
        /* BEGIN: Use Case */
723
        $userGroup = $this->createUserGroupVersion1();
724
725
        // Load the content service
726
        $contentService = $repository->getContentService();
727
728
        // Create a metadata update struct and change the remoteId
729
        $metadataUpdate = $contentService->newContentMetadataUpdateStruct();
730
        $metadataUpdate->remoteId = '3c61299780663bafa3af2101e52125da';
731
732
        // Create a group update struct and set content update struct
733
        $groupUpdate = $userService->newUserGroupUpdateStruct();
734
        $groupUpdate->contentMetadataUpdateStruct = $metadataUpdate;
735
736
        // This will update the name and the increment the group version number
737
        $userGroup = $userService->updateUserGroup(
738
            $userGroup,
739
            $groupUpdate
740
        );
741
        /* END: Use Case */
742
743
        $this->assertEquals(
744
            '3c61299780663bafa3af2101e52125da',
745
            $userGroup->contentInfo->remoteId
746
        );
747
748
        $versionInfo = $userGroup->getVersionInfo();
749
750
        $this->assertEquals(APIVersionInfo::STATUS_PUBLISHED, $versionInfo->status);
751
        $this->assertEquals(1, $versionInfo->versionNo);
752
    }
753
754
    /**
755
     * Test for the updateUserGroup() method.
756
     *
757
     * @see \eZ\Publish\API\Repository\UserService::updateUserGroup()
758
     * @depends eZ\Publish\API\Repository\Tests\UserServiceTest::testUpdateUserGroup
759
     */
760
    public function testUpdateUserGroupThrowsInvalidArgumentExceptionOnFieldTypeNotAccept()
761
    {
762
        $this->expectException(\eZ\Publish\API\Repository\Exceptions\InvalidArgumentException::class);
763
764
        $repository = $this->getRepository();
765
        $userService = $repository->getUserService();
766
767
        /* BEGIN: Use Case */
768
        $userGroup = $this->createUserGroupVersion1();
769
770
        // Load the content service
771
        $contentService = $repository->getContentService();
772
773
        // Create a content update struct and update the group name
774
        $contentUpdate = $contentService->newContentUpdateStruct();
775
        // An object of stdClass is not accepted as a value by the field "name"
776
        $contentUpdate->setField('name', new \stdClass(), 'eng-US');
777
778
        // Create a group update struct and set content update struct
779
        $groupUpdate = $userService->newUserGroupUpdateStruct();
780
        $groupUpdate->contentUpdateStruct = $contentUpdate;
781
782
        // This call will fail with an InvalidArgumentException, because the
783
        // field "name" does not accept the given value
784
        $userService->updateUserGroup($userGroup, $groupUpdate);
785
        /* END: Use Case */
786
    }
787
788
    /**
789
     * Test for the newUserCreateStruct() method.
790
     *
791
     * @see \eZ\Publish\API\Repository\UserService::newUserCreateStruct()
792
     */
793
    public function testNewUserCreateStruct()
794
    {
795
        $repository = $this->getRepository();
796
797
        /* BEGIN: Use Case */
798
        $userService = $repository->getUserService();
799
800
        $userCreate = $userService->newUserCreateStruct(
801
            'user',
802
            '[email protected]',
803
            'secret',
804
            'eng-US'
805
        );
806
        /* END: Use Case */
807
808
        $this->assertInstanceOf(
809
            '\\eZ\\Publish\\API\\Repository\\Values\\User\\UserCreateStruct',
810
            $userCreate
811
        );
812
813
        return $userCreate;
814
    }
815
816
    /**
817
     * Test updating a user group throws ContentFieldValidationException.
818
     *
819
     * @covers \eZ\Publish\API\Repository\UserService::updateUserGroup
820
     */
821
    public function testUpdateUserGroupThrowsContentFieldValidationExceptionOnRequiredFieldEmpty()
822
    {
823
        $this->expectException(\eZ\Publish\API\Repository\Exceptions\ContentFieldValidationException::class);
824
825
        $repository = $this->getRepository();
826
        $userService = $repository->getUserService();
827
        $contentService = $repository->getContentService();
828
829
        $userGroup = $userService->loadUserGroup(42);
830
        $userGroupUpdateStruct = $userService->newUserGroupUpdateStruct();
831
        $userGroupUpdateStruct->contentUpdateStruct = $contentService->newContentUpdateStruct();
832
        $userGroupUpdateStruct->contentUpdateStruct->setField('name', '', 'eng-US');
833
834
        $userService->updateUserGroup($userGroup, $userGroupUpdateStruct);
835
    }
836
837
    /**
838
     * Test for the newUserCreateStruct() method.
839
     *
840
     * @param \eZ\Publish\API\Repository\Values\User\UserCreateStruct $userCreate
841
     *
842
     * @see \eZ\Publish\API\Repository\UserService::newUserCreateStruct()
843
     * @depends eZ\Publish\API\Repository\Tests\UserServiceTest::testNewUserCreateStruct
844
     */
845
    public function testNewUserCreateStructSetsExpectedProperties($userCreate)
846
    {
847
        $this->assertEquals(
848
            [
849
                'login' => 'user',
850
                'email' => '[email protected]',
851
                'password' => 'secret',
852
                'mainLanguageCode' => 'eng-US',
853
            ],
854
            [
855
                'login' => $userCreate->login,
856
                'email' => $userCreate->email,
857
                'password' => $userCreate->password,
858
                'mainLanguageCode' => $userCreate->mainLanguageCode,
859
            ]
860
        );
861
    }
862
863
    /**
864
     * Test for the newUserCreateStruct() method.
865
     *
866
     * @see \eZ\Publish\API\Repository\UserService::newUserCreateStruct($login, $email, $password, $mainLanguageCode, $contentType)
867
     * @depends eZ\Publish\API\Repository\Tests\UserServiceTest::testNewUserCreateStruct
868
     * @depends eZ\Publish\API\Repository\Tests\ContentTypeServiceTest::testLoadContentTypeByIdentifier
869
     */
870
    public function testNewUserCreateStructWithFifthParameter()
871
    {
872
        if ($this->isVersion4()) {
873
            $this->markTestSkipped('This test is only relevant for eZ Publish versions > 4');
874
        }
875
876
        $repository = $this->getRepository();
877
878
        /* BEGIN: Use Case */
879
        $contentTypeService = $repository->getContentTypeService();
880
        $userService = $repository->getUserService();
881
882
        $userType = $contentTypeService->loadContentTypeByIdentifier('user');
883
884
        $userCreate = $userService->newUserCreateStruct(
885
            'user',
886
            '[email protected]',
887
            'secret',
888
            'eng-US',
889
            $userType
890
        );
891
        /* END: Use Case */
892
893
        $this->assertSame($userType, $userCreate->contentType);
894
    }
895
896
    /**
897
     * Test for creating user with Active Directory login name.
898
     */
899
    public function testNewUserWithDomainName()
900
    {
901
        $repository = $this->getRepository();
902
        $userService = $repository->getUserService();
903
        $createdUser = $this->createUserVersion1('ez-user-Domain\username-by-login');
904
        $loadedUser = $userService->loadUserByLogin('ez-user-Domain\username-by-login');
905
906
        $this->assertEquals($createdUser, $loadedUser);
907
    }
908
909
    /**
910
     * Test for the createUser() method.
911
     *
912
     * @return \eZ\Publish\API\Repository\Values\User\User
913
     *
914
     * @see \eZ\Publish\API\Repository\UserService::createUser()
915
     * @depends eZ\Publish\API\Repository\Tests\UserServiceTest::testLoadUserGroup
916
     * @depends eZ\Publish\API\Repository\Tests\UserServiceTest::testNewUserCreateStruct
917
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testCreateContent
918
     */
919
    public function testCreateUser()
920
    {
921
        /* BEGIN: Use Case */
922
        $user = $this->createUserVersion1();
923
        /* END: Use Case */
924
925
        $this->assertInstanceOf(
926
            '\\eZ\\Publish\\API\\Repository\\Values\\User\\User',
927
            $user
928
        );
929
930
        return $user;
931
    }
932
933
    /**
934
     * Test for the createUser() method.
935
     *
936
     * @param \eZ\Publish\API\Repository\Values\User\User $user
937
     *
938
     * @see \eZ\Publish\API\Repository\UserService::createUser()
939
     * @depends eZ\Publish\API\Repository\Tests\UserServiceTest::testCreateUser
940
     */
941
    public function testCreateUserSetsExpectedProperties(User $user)
942
    {
943
        $this->assertEquals(
944
            [
945
                'login' => 'user',
946
                'email' => '[email protected]',
947
                'mainLanguageCode' => 'eng-US',
948
            ],
949
            [
950
                'login' => $user->login,
951
                'email' => $user->email,
952
                'mainLanguageCode' => $user->contentInfo->mainLanguageCode,
953
            ]
954
        );
955
    }
956
957
    /**
958
     * Test for the createUser() method.
959
     *
960
     * @see \eZ\Publish\API\Repository\UserService::createUser()
961
     * @depends eZ\Publish\API\Repository\Tests\UserServiceTest::testCreateUser
962
     */
963
    public function testCreateUserWhenMissingField()
964
    {
965
        $this->expectException(\eZ\Publish\API\Repository\Exceptions\ContentFieldValidationException::class);
966
967
        $repository = $this->getRepository();
968
969
        $editorsGroupId = $this->generateId('group', 13);
970
        /* BEGIN: Use Case */
971
        // $editorsGroupId is the ID of the "Editors" user group in an eZ
972
        // Publish demo installation
973
974
        $userService = $repository->getUserService();
975
976
        // Instantiate a create struct with mandatory properties
977
        $userCreate = $userService->newUserCreateStruct(
978
            'user',
979
            '[email protected]',
980
            'secret',
981
            'eng-US'
982
        );
983
984
        // Do not set the mandatory fields "first_name" and "last_name"
985
        //$userCreate->setField( 'first_name', 'Example' );
986
        //$userCreate->setField( 'last_name', 'User' );
987
988
        // Load parent group for the user
989
        $group = $userService->loadUserGroup($editorsGroupId);
990
991
        // This call will fail with a "ContentFieldValidationException", because the
992
        // mandatory fields "first_name" and "last_name" are not set.
993
        $userService->createUser($userCreate, [$group]);
994
        /* END: Use Case */
995
    }
996
997
    /**
998
     * Test for the createUser() method.
999
     *
1000
     * @see \eZ\Publish\API\Repository\UserService::createUser()
1001
     * @depends eZ\Publish\API\Repository\Tests\UserServiceTest::testCreateUser
1002
     */
1003
    public function testCreateUserThrowsInvalidArgumentExceptionOnFieldTypeNotAccept()
1004
    {
1005
        $this->expectException(\eZ\Publish\API\Repository\Exceptions\InvalidArgumentException::class);
1006
1007
        $repository = $this->getRepository();
1008
1009
        $editorsGroupId = $this->generateId('group', 13);
1010
        /* BEGIN: Use Case */
1011
        // $editorsGroupId is the ID of the "Editors" user group in an eZ
1012
        // Publish demo installation
1013
1014
        $userService = $repository->getUserService();
1015
1016
        // Instantiate a create struct with mandatory properties
1017
        $userCreate = $userService->newUserCreateStruct(
1018
            'user',
1019
            '[email protected]',
1020
            'secret',
1021
            'eng-US'
1022
        );
1023
1024
        // An object of stdClass is not a valid value for the field first_name
1025
        $userCreate->setField('first_name', new \stdClass());
1026
        $userCreate->setField('last_name', 'User');
1027
1028
        // Load parent group for the user
1029
        $group = $userService->loadUserGroup($editorsGroupId);
1030
1031
        // This call will fail with an "InvalidArgumentException", because the
1032
        // value for the firled "first_name" is not accepted by the field type.
1033
        $userService->createUser($userCreate, [$group]);
1034
        /* END: Use Case */
1035
    }
1036
1037
    /**
1038
     * Test for the createUser() method.
1039
     *
1040
     * @covers \eZ\Publish\API\Repository\UserService::createUser
1041
     * @depends eZ\Publish\API\Repository\Tests\UserServiceTest::testCreateUser
1042
     */
1043
    public function testCreateUserThrowsInvalidArgumentException()
1044
    {
1045
        $this->expectException(\eZ\Publish\API\Repository\Exceptions\InvalidArgumentException::class);
1046
        $this->expectExceptionMessage('Argument \'userCreateStruct\' is invalid: User with provided login already exists');
1047
1048
        $repository = $this->getRepository();
1049
1050
        $editorsGroupId = $this->generateId('group', 13);
1051
        /* BEGIN: Use Case */
1052
        // $editorsGroupId is the ID of the "Editors" user group in an eZ
1053
        // Publish demo installation
1054
1055
        $userService = $repository->getUserService();
1056
1057
        // Instantiate a create struct with mandatory properties
1058
        $userCreate = $userService->newUserCreateStruct(
1059
            // admin is an existing login
1060
            'admin',
1061
            '[email protected]',
1062
            'secret',
1063
            'eng-US'
1064
        );
1065
1066
        $userCreate->setField('first_name', 'Example');
1067
        $userCreate->setField('last_name', 'User');
1068
1069
        // Load parent group for the user
1070
        $group = $userService->loadUserGroup($editorsGroupId);
1071
1072
        // This call will fail with a "InvalidArgumentException", because the
1073
        // user with "admin" login already exists.
1074
        $userService->createUser($userCreate, [$group]);
1075
        /* END: Use Case */
1076
    }
1077
1078
    /**
1079
     * Test for the createUser() method.
1080
     *
1081
     * @return \eZ\Publish\API\Repository\Values\User\User
1082
     *
1083
     * @see \eZ\Publish\API\Repository\UserService::createUser()
1084
     * @depends eZ\Publish\API\Repository\Tests\UserServiceTest::testLoadUserGroup
1085
     * @depends eZ\Publish\API\Repository\Tests\UserServiceTest::testNewUserCreateStruct
1086
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testCreateContent
1087
     */
1088
    public function testCreateUserInTransactionWithRollback()
1089
    {
1090
        $repository = $this->getRepository();
1091
        $userService = $repository->getUserService();
1092
1093
        /* BEGIN: Use Case */
1094
        $repository->beginTransaction();
1095
1096
        try {
1097
            $user = $this->createUserVersion1();
1098
        } catch (Exception $e) {
1099
            // Cleanup hanging transaction on error
1100
            $repository->rollback();
1101
            throw $e;
1102
        }
1103
1104
        $repository->rollback();
1105
1106
        try {
1107
            // Throws exception since creation of user was rolled back
1108
            $loadedUser = $userService->loadUser($user->id);
0 ignored issues
show
Unused Code introduced by
$loadedUser is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
1109
        } catch (NotFoundException $e) {
1110
            return;
1111
        }
1112
        /* END: Use Case */
1113
1114
        $this->fail('User object still exists after rollback.');
1115
    }
1116
1117
    /**
1118
     * Test creating a user throwing NotFoundException.
1119
     *
1120
     * @covers \eZ\Publish\API\Repository\UserService::createUser
1121
     */
1122
    public function testCreateUserThrowsNotFoundException()
1123
    {
1124
        $this->expectException(\eZ\Publish\API\Repository\Exceptions\NotFoundException::class);
1125
1126
        $repository = $this->getRepository();
1127
        $userService = $repository->getUserService();
1128
1129
        $userCreateStruct = $userService->newUserCreateStruct('new_user', '[email protected]', 'password', 'eng-GB');
1130
        $userCreateStruct->setField('first_name', 'New');
1131
        $userCreateStruct->setField('last_name', 'User');
1132
1133
        $parentGroup = new UserGroup(
1134
            [
1135
                'content' => new Content(
1136
                    [
1137
                        'versionInfo' => new VersionInfo(
1138
                            [
1139
                                'contentInfo' => new ContentInfo(['id' => 123456]),
1140
                            ]
1141
                        ),
1142
                        'internalFields' => [],
1143
                    ]
1144
                ),
1145
            ]
1146
        );
1147
        $userService->createUser($userCreateStruct, [$parentGroup]);
1148
    }
1149
1150
    /**
1151
     * Test creating a user throwing UserPasswordValidationException when password doesn't follow specific rules.
1152
     *
1153
     * @covers \eZ\Publish\API\Repository\UserService::createUser
1154
     */
1155
    public function testCreateUserWithWeakPasswordThrowsUserPasswordValidationException()
1156
    {
1157
        $this->expectException(\eZ\Publish\Core\Base\Exceptions\UserPasswordValidationException::class);
1158
        $this->expectExceptionMessage('Argument \'password\' is invalid: Password doesn\'t match the following rules: User password must be at least 8 characters long, User password must include at least one upper case letter, User password must include at least one number, User password must include at least one special character');
1159
1160
        $userContentType = $this->createUserContentTypeWithStrongPassword();
1161
1162
        /* BEGIN: Use Case */
1163
        // This call will fail with a "UserPasswordValidationException" because the
1164
        // the password does not follow specified rules.
1165
        $this->createTestUserWithPassword('pass', $userContentType);
1166
        /* END: Use Case */
1167
    }
1168
1169
    /**
1170
     * Opposite test case for testCreateUserWithWeakPasswordThrowsUserPasswordValidationException.
1171
     *
1172
     * @covers \eZ\Publish\API\Repository\UserService::createUser
1173
     */
1174
    public function testCreateUserWithStrongPassword()
1175
    {
1176
        $userContentType = $this->createUserContentTypeWithStrongPassword();
1177
1178
        /* BEGIN: Use Case */
1179
        $user = $this->createTestUserWithPassword('H@xxi0r!', $userContentType);
1180
        /* END: Use Case */
1181
1182
        $this->assertInstanceOf(User::class, $user);
1183
    }
1184
1185
    /**
1186
     * Test for the loadUser() method.
1187
     *
1188
     * @see \eZ\Publish\API\Repository\UserService::loadUser()
1189
     * @depends eZ\Publish\API\Repository\Tests\UserServiceTest::testCreateUser
1190
     */
1191
    public function testLoadUser()
1192
    {
1193
        $repository = $this->getRepository();
1194
1195
        $userService = $repository->getUserService();
1196
1197
        /* BEGIN: Use Case */
1198
        $user = $this->createUserVersion1();
1199
1200
        // Load the newly created user
1201
        $userReloaded = $userService->loadUser($user->id);
1202
        /* END: Use Case */
1203
1204
        $this->assertEquals($user, $userReloaded);
1205
1206
        // User happens to also be a Content; isUser() should be true and isUserGroup() should be false
1207
        $this->assertTrue($userService->isUser($user), 'isUser() => false on a user');
1208
        $this->assertFalse($userService->isUserGroup($user), 'isUserGroup() => true on a user group');
1209
    }
1210
1211
    /**
1212
     * Test for the loadUser() method.
1213
     *
1214
     * @see \eZ\Publish\API\Repository\UserService::loadUser()
1215
     * @depends eZ\Publish\API\Repository\Tests\UserServiceTest::testLoadUser
1216
     */
1217
    public function testLoadUserThrowsNotFoundException()
1218
    {
1219
        $this->expectException(\eZ\Publish\API\Repository\Exceptions\NotFoundException::class);
1220
1221
        $repository = $this->getRepository();
1222
1223
        $nonExistingUserId = $this->generateId('user', self::DB_INT_MAX);
1224
        /* BEGIN: Use Case */
1225
        $userService = $repository->getUserService();
1226
1227
        // This call will fail with a "NotFoundException", because no user with
1228
        // an id equal to self::DB_INT_MAX should exist.
1229
        $userService->loadUser($nonExistingUserId);
1230
        /* END: Use Case */
1231
    }
1232
1233
    /**
1234
     * Test for the loadUserByCredentials() method.
1235
     *
1236
     * @see \eZ\Publish\API\Repository\UserService::loadUserByCredentials()
1237
     * @depends eZ\Publish\API\Repository\Tests\UserServiceTest::testCreateUser
1238
     */
1239
    public function testLoadUserByCredentials()
1240
    {
1241
        $repository = $this->getRepository();
1242
1243
        $userService = $repository->getUserService();
1244
1245
        /* BEGIN: Use Case */
1246
        $user = $this->createUserVersion1();
1247
1248
        // Load the newly created user
1249
        $userReloaded = $userService->loadUserByCredentials('user', 'secret');
1250
        /* END: Use Case */
1251
1252
        $this->assertEquals($user, $userReloaded);
1253
    }
1254
1255
    /**
1256
     * Test for the loadUserByCredentials() method.
1257
     *
1258
     * @see \eZ\Publish\API\Repository\UserService::loadUserByCredentials()
1259
     * @depends eZ\Publish\API\Repository\Tests\UserServiceTest::testLoadUserByCredentials
1260
     */
1261
    public function testLoadUserByCredentialsThrowsNotFoundExceptionForUnknownPassword()
1262
    {
1263
        $this->expectException(\eZ\Publish\API\Repository\Exceptions\NotFoundException::class);
1264
1265
        $repository = $this->getRepository();
1266
1267
        $userService = $repository->getUserService();
1268
1269
        /* BEGIN: Use Case */
1270
        $this->createUserVersion1();
1271
1272
        // This call will fail with a "NotFoundException", because the given
1273
        // login/password combination does not exist.
1274
        $userService->loadUserByCredentials('user', 'SeCrEt');
1275
        /* END: Use Case */
1276
    }
1277
1278
    /**
1279
     * Test for the loadUserByCredentials() method.
1280
     *
1281
     * @see \eZ\Publish\API\Repository\UserService::loadUserByCredentials()
1282
     * @depends eZ\Publish\API\Repository\Tests\UserServiceTest::testLoadUserByCredentials
1283
     */
1284
    public function testLoadUserByCredentialsThrowsNotFoundExceptionForUnknownPasswordEmtpy()
1285
    {
1286
        $this->expectException(\eZ\Publish\API\Repository\Exceptions\NotFoundException::class);
1287
1288
        $repository = $this->getRepository();
1289
1290
        $userService = $repository->getUserService();
1291
1292
        /* BEGIN: Use Case */
1293
        $this->createUserVersion1();
1294
1295
        // This call will fail with a "NotFoundException", because the given
1296
        // login/password combination does not exist.
1297
        $userService->loadUserByCredentials('user', '');
1298
        /* END: Use Case */
1299
    }
1300
1301
    /**
1302
     * Test for the loadUserByCredentials() method.
1303
     *
1304
     * @see \eZ\Publish\API\Repository\UserService::loadUserByCredentials()
1305
     * @depends eZ\Publish\API\Repository\Tests\UserServiceTest::testLoadUserByCredentials
1306
     */
1307
    public function testLoadUserByCredentialsThrowsNotFoundExceptionForUnknownLogin()
1308
    {
1309
        $this->expectException(\eZ\Publish\API\Repository\Exceptions\NotFoundException::class);
1310
1311
        $repository = $this->getRepository();
1312
1313
        $userService = $repository->getUserService();
1314
1315
        /* BEGIN: Use Case */
1316
        $this->createUserVersion1();
1317
1318
        // This call will fail with a "NotFoundException", because the given
1319
        // login/password combination does not exist.
1320
        $userService->loadUserByCredentials('üser', 'secret');
1321
        /* END: Use Case */
1322
    }
1323
1324
    /**
1325
     * Test for the loadUserByCredentials() method.
1326
     *
1327
     * @see \eZ\Publish\API\Repository\UserService::loadUserByCredentials()
1328
     * @depends eZ\Publish\API\Repository\Tests\UserServiceTest::testLoadUserByCredentials
1329
     */
1330
    public function testLoadUserByCredentialsThrowsInvalidArgumentValueForEmptyLogin()
1331
    {
1332
        $this->expectException(\eZ\Publish\Core\Base\Exceptions\InvalidArgumentValue::class);
1333
1334
        $repository = $this->getRepository();
1335
1336
        $userService = $repository->getUserService();
1337
1338
        /* BEGIN: Use Case */
1339
        $this->createUserVersion1();
1340
1341
        // This call will fail with a "InvalidArgumentValue", because the given
1342
        // login is empty.
1343
        $userService->loadUserByCredentials('', 'secret');
1344
        /* END: Use Case */
1345
    }
1346
1347
    /**
1348
     * Test for the loadUserByLogin() method.
1349
     *
1350
     * @see \eZ\Publish\API\Repository\UserService::loadUserByLogin()
1351
     * @depends eZ\Publish\API\Repository\Tests\UserServiceTest::testCreateUser
1352
     */
1353
    public function testLoadUserByLogin()
1354
    {
1355
        $repository = $this->getRepository();
1356
1357
        $userService = $repository->getUserService();
1358
1359
        /* BEGIN: Use Case */
1360
        $user = $this->createUserVersion1('User');
1361
1362
        // Load the newly created user
1363
        $userReloaded = $userService->loadUserByLogin('User');
1364
        /* END: Use Case */
1365
1366
        $this->assertPropertiesCorrect(
1367
            [
1368
                'login' => $user->login,
1369
                'email' => $user->email,
1370
                'passwordHash' => $user->passwordHash,
1371
                'hashAlgorithm' => $user->hashAlgorithm,
1372
                'enabled' => $user->enabled,
1373
                'maxLogin' => $user->maxLogin,
1374
                'id' => $user->id,
1375
                'contentInfo' => $user->contentInfo,
1376
                'versionInfo' => $user->versionInfo,
1377
                'fields' => $user->fields,
1378
            ],
1379
            $userReloaded
1380
        );
1381
    }
1382
1383
    /**
1384
     * Test for the loadUserByLogin() method.
1385
     *
1386
     * @see \eZ\Publish\API\Repository\UserService::loadUserByLogin()
1387
     * @depends eZ\Publish\API\Repository\Tests\UserServiceTest::testLoadUserByLogin
1388
     */
1389
    public function testLoadUserByLoginThrowsNotFoundExceptionForUnknownLogin()
1390
    {
1391
        $this->expectException(\eZ\Publish\API\Repository\Exceptions\NotFoundException::class);
1392
1393
        $repository = $this->getRepository();
1394
1395
        $userService = $repository->getUserService();
1396
1397
        /* BEGIN: Use Case */
1398
        $this->createUserVersion1();
1399
1400
        // This call will fail with a "NotFoundException", because the given
1401
        // login/password combination does not exist.
1402
        $userService->loadUserByLogin('user42');
1403
        /* END: Use Case */
1404
    }
1405
1406
    /**
1407
     * Test for the loadUserByLogin() method.
1408
     *
1409
     * @see \eZ\Publish\API\Repository\UserService::loadUserByLogin()
1410
     * @depends eZ\Publish\API\Repository\Tests\UserServiceTest::testLoadUserByLogin
1411
     */
1412
    public function testLoadUserByLoginWorksForLoginWithWrongCase()
1413
    {
1414
        $repository = $this->getRepository();
1415
1416
        $userService = $repository->getUserService();
1417
1418
        /* BEGIN: Use Case */
1419
        $user = $this->createUserVersion1();
1420
1421
        // Lookup by user login should ignore casing
1422
        $userReloaded = $userService->loadUserByLogin('USER');
1423
        /* END: Use Case */
1424
1425
        $this->assertPropertiesCorrect(
1426
            [
1427
                'login' => $user->login,
1428
                'email' => $user->email,
1429
                'passwordHash' => $user->passwordHash,
1430
                'hashAlgorithm' => $user->hashAlgorithm,
1431
                'enabled' => $user->enabled,
1432
                'maxLogin' => $user->maxLogin,
1433
                'id' => $user->id,
1434
                'contentInfo' => $user->contentInfo,
1435
                'versionInfo' => $user->versionInfo,
1436
                'fields' => $user->fields,
1437
            ],
1438
            $userReloaded
1439
        );
1440
    }
1441
1442
    /**
1443
     * Test for the loadUserByLogin() method.
1444
     *
1445
     * In some cases people use email as login name, make sure system works as exepcted when asking for user by email.
1446
     *
1447
     * @see \eZ\Publish\API\Repository\UserService::loadUserByLogin()
1448
     * @depends eZ\Publish\API\Repository\Tests\UserServiceTest::testLoadUserByLogin
1449
     */
1450
    public function testLoadUserByLoginThrowsNotFoundExceptionForUnknownLoginByEmail()
1451
    {
1452
        $this->expectException(\eZ\Publish\API\Repository\Exceptions\NotFoundException::class);
1453
1454
        $repository = $this->getRepository();
1455
1456
        $userService = $repository->getUserService();
1457
1458
        /* BEGIN: Use Case */
1459
        $user = $this->createUserVersion1();
0 ignored issues
show
Unused Code introduced by
$user is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
1460
1461
        // Lookup by user login by email should behave as normal
1462
        $userService->loadUserByLogin('[email protected]');
1463
        /* END: Use Case */
1464
    }
1465
1466
    /**
1467
     * Test for the loadUsersByEmail() method.
1468
     *
1469
     * @see \eZ\Publish\API\Repository\UserService::loadUsersByEmail()
1470
     * @depends eZ\Publish\API\Repository\Tests\UserServiceTest::testCreateUser
1471
     */
1472
    public function testLoadUserByEmail()
1473
    {
1474
        $repository = $this->getRepository();
1475
1476
        $userService = $repository->getUserService();
1477
1478
        /* BEGIN: Use Case */
1479
        $user = $this->createUserVersion1();
1480
1481
        // Load the newly created user
1482
        $usersReloaded = $userService->loadUsersByEmail('[email protected]');
1483
        /* END: Use Case */
1484
1485
        $this->assertEquals([$user], $usersReloaded);
1486
    }
1487
1488
    /**
1489
     * Test for the loadUsersByEmail() method.
1490
     *
1491
     * @see \eZ\Publish\API\Repository\UserService::loadUsersByEmail()
1492
     * @depends eZ\Publish\API\Repository\Tests\UserServiceTest::testLoadUserByEmail
1493
     */
1494
    public function testLoadUserByEmailReturnsEmptyInUnknownEmail()
1495
    {
1496
        $repository = $this->getRepository();
1497
1498
        $userService = $repository->getUserService();
1499
1500
        /* BEGIN: Use Case */
1501
        $this->createUserVersion1();
1502
1503
        // This call will return empty array, because the given
1504
        // login/password combination does not exist.
1505
        $emptyUserList = $userService->loadUsersByEmail('[email protected]');
1506
        /* END: Use Case */
1507
1508
        $this->assertEquals([], $emptyUserList);
1509
    }
1510
1511
    /**
1512
     * Test for the deleteUser() method.
1513
     *
1514
     * @see \eZ\Publish\API\Repository\UserService::deleteUser()
1515
     * @depends eZ\Publish\API\Repository\Tests\UserServiceTest::testCreateUser
1516
     * @depends eZ\Publish\API\Repository\Tests\UserServiceTest::testLoadUser
1517
     */
1518
    public function testDeleteUser()
1519
    {
1520
        $this->expectException(\eZ\Publish\API\Repository\Exceptions\NotFoundException::class);
1521
1522
        $repository = $this->getRepository();
1523
1524
        $userService = $repository->getUserService();
1525
1526
        /* BEGIN: Use Case */
1527
        $user = $this->createUserVersion1();
1528
1529
        // Delete the currently created user
1530
        $userService->deleteUser($user);
1531
        /* END: Use Case */
1532
1533
        // We use the NotFoundException here to verify that the user not exists
1534
        $userService->loadUser($user->id);
1535
    }
1536
1537
    /**
1538
     * Test for the deleteUser() method.
1539
     *
1540
     * @covers \eZ\Publish\API\Repository\UserService::deleteUser()
1541
     * @depends eZ\Publish\API\Repository\Tests\UserServiceTest::testCreateUser
1542
     * @depends eZ\Publish\API\Repository\Tests\UserServiceTest::testLoadUser
1543
     */
1544
    public function testDeleteUserDeletesRelatedBookmarks()
1545
    {
1546
        $repository = $this->getRepository();
1547
1548
        $userService = $repository->getUserService();
1549
        $locationService = $repository->getLocationService();
1550
        $bookmarkService = $repository->getBookmarkService();
1551
        /* BEGIN: Use Case */
1552
        $admin = $repository->getPermissionResolver()->getCurrentUserReference();
1553
1554
        $user = $this->createUserVersion1();
1555
1556
        $repository->getPermissionResolver()->setCurrentUserReference($user);
1557
1558
        $bookmarkService->createBookmark(
1559
            $locationService->loadLocation($this->generateId('location', 43))
1560
        );
1561
1562
        $repository->getPermissionResolver()->setCurrentUserReference($admin);
1563
        // Delete the currently created user
1564
        $userService->deleteUser($user);
1565
1566
        $repository->getPermissionResolver()->setCurrentUserReference($user);
1567
        /* END: Use Case */
1568
1569
        $this->assertEquals(0, $bookmarkService->loadBookmarks(0, 9999)->totalCount);
1570
    }
1571
1572
    /**
1573
     * Test for the newUserUpdateStruct() method.
1574
     *
1575
     * @see \eZ\Publish\API\Repository\UserService::newUserUpdateStruct()
1576
     */
1577
    public function testNewUserUpdateStruct()
1578
    {
1579
        $repository = $this->getRepository();
1580
1581
        /* BEGIN: Use Case */
1582
        $userService = $repository->getUserService();
1583
1584
        // Create a new update struct instance
1585
        $userUpdate = $userService->newUserUpdateStruct();
1586
        /* END: Use Case */
1587
1588
        $this->assertInstanceOf(
1589
            UserUpdateStruct::class,
1590
            $userUpdate
1591
        );
1592
1593
        $this->assertNull($userUpdate->contentUpdateStruct);
1594
        $this->assertNull($userUpdate->contentMetadataUpdateStruct);
1595
1596
        $this->assertPropertiesCorrect(
1597
            [
1598
                'email' => null,
1599
                'password' => null,
1600
                'enabled' => null,
1601
                'maxLogin' => null,
1602
            ],
1603
            $userUpdate
1604
        );
1605
    }
1606
1607
    /**
1608
     * Test for the updateUser() method.
1609
     *
1610
     * @return \eZ\Publish\API\Repository\Values\User\User
1611
     *
1612
     * @see \eZ\Publish\API\Repository\UserService::updateUser()
1613
     * @depends eZ\Publish\API\Repository\Tests\UserServiceTest::testCreateUser
1614
     * @depends eZ\Publish\API\Repository\Tests\UserServiceTest::testNewUserUpdateStruct
1615
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testUpdateContent
1616
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testUpdateContentMetadata
1617
     */
1618
    public function testUpdateUser()
1619
    {
1620
        $repository = $this->getRepository();
1621
1622
        $userService = $repository->getUserService();
1623
1624
        /* BEGIN: Use Case */
1625
        $user = $this->createUserVersion1();
1626
1627
        // Create a new update struct instance
1628
        $userUpdate = $userService->newUserUpdateStruct();
1629
1630
        // Set new values for password and maxLogin
1631
        $userUpdate->password = 'my-new-password';
1632
        $userUpdate->maxLogin = 42;
1633
        $userUpdate->enabled = false;
1634
1635
        // Updated the user record.
1636
        $userVersion2 = $userService->updateUser($user, $userUpdate);
1637
        /* END: Use Case */
1638
1639
        $this->assertInstanceOf(User::class, $userVersion2);
1640
1641
        return $userVersion2;
1642
    }
1643
1644
    /**
1645
     * Test for the updateUser() and loadUsersByEmail() method on change to email.
1646
     */
1647
    public function testUpdateUserEmail(): void
1648
    {
1649
        $repository = $this->getRepository();
1650
        $userService = $repository->getUserService();
1651
1652
        // Create a user
1653
        $user = $this->createUserVersion1();
1654
1655
        // Check we get what we expect (and implicit warmup any kind of cache)
1656
        $users = $userService->loadUsersByEmail('[email protected]');
1657
        $this->assertCount(0, $users);
1658
1659
        // Update user with the given email address
1660
        $userUpdate = $userService->newUserUpdateStruct();
1661
        $userUpdate->email = '[email protected]';
1662
        $updatedUser = $userService->updateUser($user, $userUpdate);
1663
        $this->assertInstanceOf(User::class, $updatedUser);
1664
1665
        // Check that we can load user by email
1666
        $users = $userService->loadUsersByEmail('[email protected]');
1667
        $this->assertCount(1, $users);
1668
        $this->assertInstanceOf(User::class, $users[0]);
1669
    }
1670
1671
    /**
1672
     * Test for the updateUser() method.
1673
     *
1674
     * @return \eZ\Publish\API\Repository\Values\User\User
1675
     *
1676
     * @see \eZ\Publish\API\Repository\UserService::updateUser()
1677
     * @depends eZ\Publish\API\Repository\Tests\UserServiceTest::testCreateUser
1678
     * @depends eZ\Publish\API\Repository\Tests\UserServiceTest::testNewUserUpdateStruct
1679
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testUpdateContent
1680
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testUpdateContentMetadata
1681
     */
1682
    public function testUpdateUserNoPassword()
1683
    {
1684
        $repository = $this->getRepository();
1685
        $eventUserService = $repository->getUserService();
1686
1687
        $eventUserServiceReflection = new ReflectionClass($eventUserService);
1688
        $userServiceProperty = $eventUserServiceReflection->getProperty('innerService');
1689
        $userServiceProperty->setAccessible(true);
1690
        $userService = $userServiceProperty->getValue($eventUserService);
1691
1692
        $userServiceReflection = new ReflectionClass($userService);
1693
        $settingsProperty = $userServiceReflection->getProperty('settings');
1694
        $settingsProperty->setAccessible(true);
1695
        $settingsProperty->setValue(
1696
            $userService,
1697
            [
1698
                'hashType' => User::PASSWORD_HASH_MD5_USER,
0 ignored issues
show
Deprecated Code introduced by
The constant eZ\Publish\API\Repositor...:PASSWORD_HASH_MD5_USER has been deprecated with message: since 6.13

This class constant has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the constant will be removed from the class and what other constant to use instead.

Loading history...
1699
            ] + $settingsProperty->getValue($userService)
1700
        );
1701
1702
        /* BEGIN: Use Case */
1703
        $user = $this->createUserVersion1();
1704
1705
        $settingsProperty->setValue(
1706
            $userService,
1707
            [
1708
                'hashType' => User::PASSWORD_HASH_PHP_DEFAULT,
1709
            ] + $settingsProperty->getValue($userService)
1710
        );
1711
1712
        // Create a new update struct instance
1713
        $userUpdate = $userService->newUserUpdateStruct();
1714
1715
        // Set new values for maxLogin, don't change password
1716
        $userUpdate->maxLogin = 43;
1717
        $userUpdate->enabled = false;
1718
1719
        // Updated the user record.
1720
        $userVersion2 = $userService->updateUser($user, $userUpdate);
1721
        /* END: Use Case */
1722
1723
        $this->assertInstanceOf(User::class, $user);
1724
1725
        $this->assertEquals(
1726
            [
1727
                'login' => $user->login,
1728
                'email' => $user->email,
1729
                'passwordHash' => $user->passwordHash,
1730
                'hashAlgorithm' => $user->hashAlgorithm,
1731
                'maxLogin' => 43,
1732
                'enabled' => false,
1733
            ],
1734
            [
1735
                'login' => $userVersion2->login,
1736
                'email' => $userVersion2->email,
1737
                'passwordHash' => $userVersion2->passwordHash,
1738
                'hashAlgorithm' => $userVersion2->hashAlgorithm,
1739
                'maxLogin' => $userVersion2->maxLogin,
1740
                'enabled' => $userVersion2->enabled,
1741
            ]
1742
        );
1743
    }
1744
1745
    /**
1746
     * Test for the updateUser() method.
1747
     *
1748
     * @param \eZ\Publish\API\Repository\Values\User\User $user
1749
     *
1750
     * @see \eZ\Publish\API\Repository\UserService::updateUser()
1751
     * @depends eZ\Publish\API\Repository\Tests\UserServiceTest::testUpdateUser
1752
     */
1753
    public function testUpdateUserUpdatesExpectedProperties(User $user)
1754
    {
1755
        $this->assertEquals(
1756
            [
1757
                'login' => 'user',
1758
                'email' => '[email protected]',
1759
                'maxLogin' => 42,
1760
                'enabled' => false,
1761
            ],
1762
            [
1763
                'login' => $user->login,
1764
                'email' => $user->email,
1765
                'maxLogin' => $user->maxLogin,
1766
                'enabled' => $user->enabled,
1767
            ]
1768
        );
1769
    }
1770
1771
    /**
1772
     * Test for the updateUser() method.
1773
     *
1774
     * @param \eZ\Publish\API\Repository\Values\User\User $user
1775
     *
1776
     * @see \eZ\Publish\API\Repository\UserService::updateUser()
1777
     * @depends eZ\Publish\API\Repository\Tests\UserServiceTest::testUpdateUser
1778
     */
1779
    public function testUpdateUserReturnsPublishedVersion(User $user)
1780
    {
1781
        $this->assertEquals(
1782
            APIVersionInfo::STATUS_PUBLISHED,
1783
            $user->getVersionInfo()->status
1784
        );
1785
    }
1786
1787
    /**
1788
     * Test for the updateUser() method.
1789
     *
1790
     * @see \eZ\Publish\API\Repository\UserService::updateUser()
1791
     * @depends eZ\Publish\API\Repository\Tests\UserServiceTest::testUpdateUser
1792
     */
1793
    public function testUpdateUserWithContentMetadataUpdateStruct()
1794
    {
1795
        $repository = $this->getRepository();
1796
1797
        $userService = $repository->getUserService();
1798
1799
        /* BEGIN: Use Case */
1800
        $user = $this->createUserVersion1();
1801
1802
        // Get the ContentService implementation
1803
        $contentService = $repository->getContentService();
1804
1805
        // Create a metadata update struct and change the remote id.
1806
        $metadataUpdate = $contentService->newContentMetadataUpdateStruct();
1807
        $metadataUpdate->remoteId = '85e10037d1ac0a00aa75443ced483e08';
1808
1809
        // Create a new update struct instance
1810
        $userUpdate = $userService->newUserUpdateStruct();
1811
1812
        // Set the metadata update struct.
1813
        $userUpdate->contentMetadataUpdateStruct = $metadataUpdate;
1814
1815
        // Updated the user record.
1816
        $userVersion2 = $userService->updateUser($user, $userUpdate);
1817
1818
        // The contentInfo->remoteId will be changed now.
1819
        $remoteId = $userVersion2->contentInfo->remoteId;
1820
        /* END: Use Case */
1821
1822
        $this->assertEquals('85e10037d1ac0a00aa75443ced483e08', $remoteId);
1823
    }
1824
1825
    /**
1826
     * Test for the updateUser() method.
1827
     *
1828
     * @see \eZ\Publish\API\Repository\UserService::updateUser()
1829
     * @depends eZ\Publish\API\Repository\Tests\UserServiceTest::testUpdateUser
1830
     */
1831
    public function testUpdateUserWithContentUpdateStruct()
1832
    {
1833
        $repository = $this->getRepository();
1834
1835
        $userService = $repository->getUserService();
1836
1837
        /* BEGIN: Use Case */
1838
        $user = $this->createUserVersion1();
1839
1840
        // Get the ContentService implementation
1841
        $contentService = $repository->getContentService();
1842
1843
        // Create a content update struct and change the remote id.
1844
        $contentUpdate = $contentService->newContentUpdateStruct();
1845
        $contentUpdate->setField('first_name', 'Hello', 'eng-US');
1846
        $contentUpdate->setField('last_name', 'World', 'eng-US');
1847
1848
        // Create a new update struct instance
1849
        $userUpdate = $userService->newUserUpdateStruct();
1850
1851
        // Set the content update struct.
1852
        $userUpdate->contentUpdateStruct = $contentUpdate;
1853
1854
        // Updated the user record.
1855
        $userVersion2 = $userService->updateUser($user, $userUpdate);
1856
1857
        $name = sprintf(
1858
            '%s %s',
1859
            $userVersion2->getFieldValue('first_name'),
1860
            $userVersion2->getFieldValue('last_name')
1861
        );
1862
        /* END: Use Case */
1863
1864
        $this->assertEquals('Hello World', $name);
1865
    }
1866
1867
    /**
1868
     * Test for the updateUser() method.
1869
     *
1870
     * @see \eZ\Publish\API\Repository\UserService::updateUser()
1871
     * @depends eZ\Publish\API\Repository\Tests\UserServiceTest::testUpdateUser
1872
     */
1873
    public function testUpdateUserWhenMissingField()
1874
    {
1875
        $this->expectException(\eZ\Publish\API\Repository\Exceptions\ContentFieldValidationException::class);
1876
1877
        $repository = $this->getRepository();
1878
1879
        $userService = $repository->getUserService();
1880
1881
        /* BEGIN: Use Case */
1882
        $user = $this->createUserVersion1();
1883
1884
        // Get the ContentService implementation
1885
        $contentService = $repository->getContentService();
1886
1887
        // Create a content update struct and change the remote id.
1888
        $contentUpdate = $contentService->newContentUpdateStruct();
1889
        $contentUpdate->setField('first_name', null, 'eng-US');
1890
1891
        // Create a new update struct instance
1892
        $userUpdate = $userService->newUserUpdateStruct();
1893
1894
        // Set the content update struct.
1895
        $userUpdate->contentUpdateStruct = $contentUpdate;
1896
1897
        // This call will fail with a "ContentFieldValidationException" because the
1898
        // mandatory field "first_name" is set to an empty value.
1899
        $userService->updateUser($user, $userUpdate);
1900
1901
        /* END: Use Case */
1902
    }
1903
1904
    /**
1905
     * Test for the updateUser() method.
1906
     *
1907
     * @see \eZ\Publish\API\Repository\UserService::updateUser()
1908
     * @depends eZ\Publish\API\Repository\Tests\UserServiceTest::testUpdateUser
1909
     */
1910
    public function testUpdateUserThrowsInvalidArgumentExceptionOnFieldTypeNotAccept()
1911
    {
1912
        $this->expectException(\eZ\Publish\API\Repository\Exceptions\InvalidArgumentException::class);
1913
1914
        $repository = $this->getRepository();
1915
1916
        $userService = $repository->getUserService();
1917
1918
        /* BEGIN: Use Case */
1919
        $user = $this->createUserVersion1();
1920
1921
        // Get the ContentService implementation
1922
        $contentService = $repository->getContentService();
1923
1924
        $contentUpdate = $contentService->newContentUpdateStruct();
1925
        // An object of stdClass is not valid for the field first_name
1926
        $contentUpdate->setField('first_name', new \stdClass(), 'eng-US');
1927
1928
        // Create a new update struct instance
1929
        $userUpdate = $userService->newUserUpdateStruct();
1930
1931
        // Set the content update struct.
1932
        $userUpdate->contentUpdateStruct = $contentUpdate;
1933
1934
        // This call will fail with a "InvalidArgumentException" because the
1935
        // the field "first_name" does not accept the given value.
1936
        $userService->updateUser($user, $userUpdate);
1937
1938
        /* END: Use Case */
1939
    }
1940
1941
    /**
1942
     * Test updating a user throwing UserPasswordValidationException when password doesn't follow specified rules.
1943
     *
1944
     * @covers \eZ\Publish\API\Repository\UserService::updateUser
1945
     */
1946
    public function testUpdateUserWithWeakPasswordThrowsUserPasswordValidationException()
1947
    {
1948
        $this->expectException(\eZ\Publish\Core\Base\Exceptions\UserPasswordValidationException::class);
1949
        $this->expectExceptionMessage('Argument \'password\' is invalid: Password doesn\'t match the following rules: User password must be at least 8 characters long, User password must include at least one upper case letter, User password must include at least one number, User password must include at least one special character');
1950
1951
        $userService = $this->getRepository()->getUserService();
1952
1953
        $user = $this->createTestUserWithPassword('H@xxxiR!_1', $this->createUserContentTypeWithStrongPassword());
1954
1955
        /* BEGIN: Use Case */
1956
        // Create a new update struct instance
1957
        $userUpdate = $userService->newUserUpdateStruct();
1958
        $userUpdate->password = 'pass';
1959
1960
        // This call will fail with a "UserPasswordValidationException" because the
1961
        // the password does not follow specified rules
1962
        $userService->updateUser($user, $userUpdate);
1963
        /* END: Use Case */
1964
    }
1965
1966
    /**
1967
     * Opposite test case for testUpdateUserWithWeakPasswordThrowsUserPasswordValidationException.
1968
     *
1969
     * @covers \eZ\Publish\API\Repository\UserService::updateUser
1970
     */
1971
    public function testUpdateUserWithStrongPassword()
1972
    {
1973
        $userService = $this->getRepository()->getUserService();
1974
1975
        $user = $this->createTestUserWithPassword('H@xxxiR!_1', $this->createUserContentTypeWithStrongPassword());
1976
1977
        /* BEGIN: Use Case */
1978
        // Create a new update struct instance
1979
        $userUpdate = $userService->newUserUpdateStruct();
1980
        $userUpdate->password = 'H@xxxiR!_2';
1981
1982
        $user = $userService->updateUser($user, $userUpdate);
1983
        /* END: Use Case */
1984
1985
        $this->assertInstanceOf(User::class, $user);
1986
    }
1987
1988
    /**
1989
     * Test for the loadUserGroupsOfUser() method.
1990
     *
1991
     * @covers \eZ\Publish\API\Repository\UserService::loadUserGroupsOfUser
1992
     * @depends eZ\Publish\API\Repository\Tests\UserServiceTest::testCreateUser
1993
     */
1994
    public function testLoadUserGroupsOfUser()
1995
    {
1996
        $repository = $this->getRepository();
1997
1998
        $userService = $repository->getUserService();
1999
2000
        /* BEGIN: Use Case */
2001
        $user = $this->createUserVersion1();
2002
2003
        // This array will contain the "Editors" user group name
2004
        $userGroupNames = [];
2005
        foreach ($userService->loadUserGroupsOfUser($user) as $userGroup) {
2006
            $this->assertInstanceOf(UserGroup::class, $userGroup);
2007
            $userGroupNames[] = $userGroup->getFieldValue('name');
2008
        }
2009
        /* END: Use Case */
2010
2011
        $this->assertEquals(['Editors'], $userGroupNames);
2012
    }
2013
2014
    /**
2015
     * Test for the loadUsersOfUserGroup() method.
2016
     *
2017
     * @covers \eZ\Publish\API\Repository\UserService::loadUsersOfUserGroup
2018
     * @depends eZ\Publish\API\Repository\Tests\UserServiceTest::testCreateUser
2019
     */
2020
    public function testLoadUsersOfUserGroup()
2021
    {
2022
        $repository = $this->getRepository();
2023
        $userService = $repository->getUserService();
2024
2025
        $group = $userService->loadUserGroup($this->generateId('group', 13));
2026
2027
        /* BEGIN: Use Case */
2028
        $this->createUserVersion1();
2029
2030
        $this->refreshSearch($repository);
2031
2032
        // This array will contain the email of the newly created "Editor" user
2033
        $email = [];
2034
        foreach ($userService->loadUsersOfUserGroup($group) as $user) {
2035
            $this->assertInstanceOf(User::class, $user);
2036
            $email[] = $user->email;
2037
        }
2038
        /* END: Use Case */
2039
        $this->assertEquals(['[email protected]'], $email);
2040
    }
2041
2042
    /**
2043
     * Test for the assignUserToUserGroup() method.
2044
     *
2045
     * @see \eZ\Publish\API\Repository\UserService::assignUserToUserGroup()
2046
     * @depends eZ\Publish\API\Repository\Tests\UserServiceTest::testLoadUserGroupsOfUser
2047
     */
2048
    public function testAssignUserToUserGroup()
2049
    {
2050
        $repository = $this->getRepository();
2051
        $userService = $repository->getUserService();
2052
2053
        $administratorGroupId = $this->generateId('group', 12);
2054
        /* BEGIN: Use Case */
2055
        // $administratorGroupId is the ID of the "Administrator" group in an
2056
        // eZ Publish demo installation
2057
2058
        $user = $this->createUserVersion1();
2059
2060
        // Assign group to newly created user
2061
        $userService->assignUserToUserGroup(
2062
            $user,
2063
            $userService->loadUserGroup($administratorGroupId)
2064
        );
2065
2066
        // This array will contain "Editors" and "Administrator users"
2067
        $userGroupNames = [];
2068
        foreach ($userService->loadUserGroupsOfUser($user) as $userGroup) {
2069
            $userGroupNames[] = $userGroup->getFieldValue('name');
2070
        }
2071
        /* END: Use Case */
2072
2073
        sort($userGroupNames, SORT_STRING);
2074
2075
        $this->assertEquals(
2076
            [
2077
                'Administrator users',
2078
                'Editors',
2079
            ],
2080
            $userGroupNames
2081
        );
2082
    }
2083
2084
    /**
2085
     * Test for the assignUserToUserGroup() method.
2086
     *
2087
     * @covers \eZ\Publish\API\Repository\UserService::assignUserToUserGroup
2088
     * @depends eZ\Publish\API\Repository\Tests\UserServiceTest::testAssignUserToUserGroup
2089
     */
2090
    public function testAssignUserToUserGroupThrowsInvalidArgumentException()
2091
    {
2092
        $this->expectException(\eZ\Publish\API\Repository\Exceptions\InvalidArgumentException::class);
2093
        $this->expectExceptionMessage('Argument \'user\' is invalid: user is already in the given user group');
2094
2095
        $repository = $this->getRepository();
2096
        $userService = $repository->getUserService();
2097
2098
        $editorsGroupId = $this->generateId('group', 13);
2099
        /* BEGIN: Use Case */
2100
        $user = $this->createUserVersion1();
2101
        // $editorsGroupId is the ID of the "Editors" group in an
2102
        // eZ Publish demo installation
2103
2104
        // This call will fail with an "InvalidArgumentException", because the
2105
        // user is already assigned to the "Editors" group
2106
        $userService->assignUserToUserGroup(
2107
            $user,
2108
            $userService->loadUserGroup($editorsGroupId)
2109
        );
2110
        /* END: Use Case */
2111
    }
2112
2113
    /**
2114
     * Test for the unAssignUssrFromUserGroup() method.
2115
     *
2116
     * @see \eZ\Publish\API\Repository\UserService::unAssignUssrFromUserGroup()
2117
     * @depends eZ\Publish\API\Repository\Tests\UserServiceTest::testLoadUserGroupsOfUser
2118
     */
2119
    public function testUnAssignUserFromUserGroup()
2120
    {
2121
        $repository = $this->getRepository();
2122
        $userService = $repository->getUserService();
2123
2124
        $editorsGroupId = $this->generateId('group', 13);
2125
        $anonymousGroupId = $this->generateId('group', 42);
2126
2127
        /* BEGIN: Use Case */
2128
        // $anonymousGroupId is the ID of the "Anonymous Users" group in an eZ
2129
        // Publish demo installation
2130
2131
        $user = $this->createUserVersion1();
2132
2133
        // Assign group to newly created user
2134
        $userService->assignUserToUserGroup(
2135
            $user,
2136
            $userService->loadUserGroup($anonymousGroupId)
2137
        );
2138
2139
        // Unassign user from "Editors" group
2140
        $userService->unAssignUserFromUserGroup(
2141
            $user,
2142
            $userService->loadUserGroup($editorsGroupId)
2143
        );
2144
2145
        // This array will contain "Anonymous Users"
2146
        $userGroupNames = [];
2147
        foreach ($userService->loadUserGroupsOfUser($user) as $userGroup) {
2148
            $userGroupNames[] = $userGroup->getFieldValue('name');
2149
        }
2150
        /* END: Use Case */
2151
2152
        $this->assertEquals(['Anonymous Users'], $userGroupNames);
2153
    }
2154
2155
    /**
2156
     * Test for the unAssignUserFromUserGroup() method.
2157
     *
2158
     * @see \eZ\Publish\API\Repository\UserService::unAssignUserFromUserGroup()
2159
     * @depends eZ\Publish\API\Repository\Tests\UserServiceTest::testUnAssignUserFromUserGroup
2160
     */
2161
    public function testUnAssignUserFromUserGroupThrowsInvalidArgumentException()
2162
    {
2163
        $this->expectException(\eZ\Publish\API\Repository\Exceptions\InvalidArgumentException::class);
2164
2165
        $repository = $this->getRepository();
2166
        $userService = $repository->getUserService();
2167
2168
        $administratorGroupId = $this->generateId('group', 12);
2169
        /* BEGIN: Use Case */
2170
        $user = $this->createUserVersion1();
2171
        // $administratorGroupId is the ID of the "Administrator" group in an
2172
        // eZ Publish demo installation
2173
2174
        // This call will fail with an "InvalidArgumentException", because the
2175
        // user is not assigned to the "Administrator" group
2176
        $userService->unAssignUserFromUserGroup(
2177
            $user,
2178
            $userService->loadUserGroup($administratorGroupId)
2179
        );
2180
        /* END: Use Case */
2181
    }
2182
2183
    /**
2184
     * Test for the unAssignUserFromUserGroup() method removing user from the last group.
2185
     *
2186
     * @covers \eZ\Publish\API\Repository\UserService::unAssignUserFromUserGroup
2187
     * @depends eZ\Publish\API\Repository\Tests\UserServiceTest::testUnAssignUserFromUserGroup
2188
     */
2189
    public function testUnAssignUserFromUserGroupThrowsBadStateArgumentException()
2190
    {
2191
        $this->expectException(\eZ\Publish\API\Repository\Exceptions\BadStateException::class);
2192
        $this->expectExceptionMessage('Argument \'user\' has a bad state: user only has one user group, cannot unassign from last group');
2193
2194
        $repository = $this->getRepository();
2195
        $userService = $repository->getUserService();
2196
2197
        $editorsGroupId = $this->generateId('group', 13);
2198
        /* BEGIN: Use Case */
2199
        $user = $this->createUserVersion1();
2200
2201
        // This call will fail with an "BadStateException", because the
2202
        // user has to be assigned to at least one group
2203
        $userService->unAssignUserFromUserGroup(
2204
            $user,
2205
            $userService->loadUserGroup($editorsGroupId)
2206
        );
2207
        /* END: Use Case */
2208
    }
2209
2210
    /**
2211
     * Test that multi-language logic for the loadUserGroup method respects prioritized language list.
2212
     *
2213
     * @covers \eZ\Publish\API\Repository\UserService::loadUserGroup
2214
     * @dataProvider getPrioritizedLanguageList
2215
     * @param string[] $prioritizedLanguages
2216
     * @param string|null $expectedLanguageCode language code of expected translation
2217
     */
2218
    public function testLoadUserGroupWithPrioritizedLanguagesList(
2219
        array $prioritizedLanguages,
2220
        $expectedLanguageCode
2221
    ) {
2222
        $repository = $this->getRepository();
2223
        $userService = $repository->getUserService();
2224
2225
        $userGroup = $this->createMultiLanguageUserGroup();
2226
        if ($expectedLanguageCode === null) {
2227
            $expectedLanguageCode = $userGroup->contentInfo->mainLanguageCode;
2228
        }
2229
2230
        $loadedUserGroup = $userService->loadUserGroup($userGroup->id, $prioritizedLanguages);
2231
2232
        self::assertEquals(
2233
            $loadedUserGroup->getName($expectedLanguageCode),
2234
            $loadedUserGroup->getName()
2235
        );
2236
        self::assertEquals(
2237
            $loadedUserGroup->getFieldValue('description', $expectedLanguageCode),
2238
            $loadedUserGroup->getFieldValue('description')
2239
        );
2240
    }
2241
2242
    /**
2243
     * Test that multi-language logic works correctly after updating user group main language.
2244
     *
2245
     * @covers \eZ\Publish\API\Repository\UserService::loadUserGroup
2246
     * @dataProvider getPrioritizedLanguageList
2247
     * @param string[] $prioritizedLanguages
2248
     * @param string|null $expectedLanguageCode language code of expected translation
2249
     */
2250
    public function testLoadUserGroupWithPrioritizedLanguagesListAfterMainLanguageUpdate(
2251
        array $prioritizedLanguages,
2252
        $expectedLanguageCode
2253
    ) {
2254
        $repository = $this->getRepository();
2255
        $userService = $repository->getUserService();
2256
        $contentService = $repository->getContentService();
2257
2258
        $userGroup = $this->createMultiLanguageUserGroup();
2259
2260
        $userGroupUpdateStruct = $userService->newUserGroupUpdateStruct();
2261
        $userGroupUpdateStruct->contentMetadataUpdateStruct = $contentService->newContentMetadataUpdateStruct();
2262
        $userGroupUpdateStruct->contentMetadataUpdateStruct->mainLanguageCode = 'eng-GB';
2263
        $userService->updateUserGroup($userGroup, $userGroupUpdateStruct);
2264
2265
        if ($expectedLanguageCode === null) {
2266
            $expectedLanguageCode = 'eng-GB';
2267
        }
2268
2269
        $loadedUserGroup = $userService->loadUserGroup($userGroup->id, $prioritizedLanguages);
2270
2271
        self::assertEquals(
2272
            $loadedUserGroup->getName($expectedLanguageCode),
2273
            $loadedUserGroup->getName()
2274
        );
2275
        self::assertEquals(
2276
            $loadedUserGroup->getFieldValue('description', $expectedLanguageCode),
2277
            $loadedUserGroup->getFieldValue('description')
2278
        );
2279
    }
2280
2281
    /**
2282
     * Test that multi-language logic for the loadSubUserGroups method respects prioritized language list.
2283
     *
2284
     * @covers \eZ\Publish\API\Repository\UserService::loadSubUserGroups
2285
     * @dataProvider getPrioritizedLanguageList
2286
     * @param string[] $prioritizedLanguages
2287
     * @param string|null $expectedLanguageCode language code of expected translation
2288
     */
2289
    public function testLoadSubUserGroupsWithPrioritizedLanguagesList(
2290
        array $prioritizedLanguages,
2291
        $expectedLanguageCode
2292
    ) {
2293
        $repository = $this->getRepository();
2294
        $userService = $repository->getUserService();
2295
2296
        // create main group for subgroups
2297
        $userGroup = $this->createMultiLanguageUserGroup(4);
2298
        if ($expectedLanguageCode === null) {
2299
            $expectedLanguageCode = $userGroup->contentInfo->mainLanguageCode;
2300
        }
2301
2302
        // create subgroups
2303
        $this->createMultiLanguageUserGroup($userGroup->id);
2304
        $this->createMultiLanguageUserGroup($userGroup->id);
2305
2306
        $userGroup = $userService->loadUserGroup($userGroup->id, $prioritizedLanguages);
2307
2308
        $subUserGroups = $userService->loadSubUserGroups($userGroup, 0, 2, $prioritizedLanguages);
2309
        foreach ($subUserGroups as $subUserGroup) {
2310
            self::assertEquals(
2311
                $subUserGroup->getName($expectedLanguageCode),
2312
                $subUserGroup->getName()
2313
            );
2314
            self::assertEquals(
2315
                $subUserGroup->getFieldValue('description', $expectedLanguageCode),
2316
                $subUserGroup->getFieldValue('description')
2317
            );
2318
        }
2319
    }
2320
2321
    /**
2322
     * Test that multi-language logic for the loadUser method respects prioritized language list.
2323
     *
2324
     * @covers \eZ\Publish\API\Repository\UserService::loadUser
2325
     * @dataProvider getPrioritizedLanguageList
2326
     * @param string[] $prioritizedLanguages
2327
     * @param string|null $expectedLanguageCode language code of expected translation
2328
     */
2329
    public function testLoadUserWithPrioritizedLanguagesList(
2330
        array $prioritizedLanguages,
2331
        $expectedLanguageCode
2332
    ) {
2333
        $repository = $this->getRepository();
2334
        $userService = $repository->getUserService();
2335
2336
        $user = $this->createMultiLanguageUser();
2337
        if ($expectedLanguageCode === null) {
2338
            $expectedLanguageCode = $user->contentInfo->mainLanguageCode;
2339
        }
2340
2341
        $loadedUser = $userService->loadUser($user->id, $prioritizedLanguages);
2342
2343
        self::assertEquals(
2344
            $loadedUser->getName($expectedLanguageCode),
2345
            $loadedUser->getName()
2346
        );
2347
2348
        foreach (['fist_name', 'last_name', 'signature'] as $fieldIdentifier) {
2349
            self::assertEquals(
2350
                $loadedUser->getFieldValue($fieldIdentifier, $expectedLanguageCode),
2351
                $loadedUser->getFieldValue($fieldIdentifier)
2352
            );
2353
        }
2354
    }
2355
2356
    /**
2357
     * Test that multi-language logic for the loadUser method works correctly after updating
2358
     * user content main language.
2359
     *
2360
     * @covers \eZ\Publish\API\Repository\UserService::loadUserGroup
2361
     * @dataProvider getPrioritizedLanguageList
2362
     * @param string[] $prioritizedLanguages
2363
     * @param string|null $expectedLanguageCode language code of expected translation
2364
     */
2365
    public function testLoadUserWithPrioritizedLanguagesListAfterMainLanguageUpdate(
2366
        array $prioritizedLanguages,
2367
        $expectedLanguageCode
2368
    ) {
2369
        $repository = $this->getRepository();
2370
        $userService = $repository->getUserService();
2371
        $contentService = $repository->getContentService();
2372
2373
        $user = $this->createMultiLanguageUser();
2374
        // sanity check
2375
        self::assertEquals($user->contentInfo->mainLanguageCode, 'eng-US');
2376
2377
        $userUpdateStruct = $userService->newUserUpdateStruct();
2378
        $userUpdateStruct->contentMetadataUpdateStruct = $contentService->newContentMetadataUpdateStruct();
2379
        $userUpdateStruct->contentMetadataUpdateStruct->mainLanguageCode = 'eng-GB';
2380
        $userService->updateUser($user, $userUpdateStruct);
2381
        if ($expectedLanguageCode === null) {
2382
            $expectedLanguageCode = 'eng-GB';
2383
        }
2384
2385
        $loadedUser = $userService->loadUser($user->id, $prioritizedLanguages);
2386
2387
        self::assertEquals(
2388
            $loadedUser->getName($expectedLanguageCode),
2389
            $loadedUser->getName()
2390
        );
2391
2392
        foreach (['fist_name', 'last_name', 'signature'] as $fieldIdentifier) {
2393
            self::assertEquals(
2394
                $loadedUser->getFieldValue($fieldIdentifier, $expectedLanguageCode),
2395
                $loadedUser->getFieldValue($fieldIdentifier)
2396
            );
2397
        }
2398
    }
2399
2400
    /**
2401
     * Test that multi-language logic for the loadUserByLogin method respects prioritized language list.
2402
     *
2403
     * @covers \eZ\Publish\API\Repository\UserService::loadUserByLogin
2404
     * @dataProvider getPrioritizedLanguageList
2405
     * @param string[] $prioritizedLanguages
2406
     * @param string|null $expectedLanguageCode language code of expected translation
2407
     */
2408
    public function testLoadUserByLoginWithPrioritizedLanguagesList(
2409
        array $prioritizedLanguages,
2410
        $expectedLanguageCode
2411
    ) {
2412
        $repository = $this->getRepository();
2413
        $userService = $repository->getUserService();
2414
        $user = $this->createMultiLanguageUser();
2415
2416
        // load, with prioritized languages, the newly created user
2417
        $loadedUser = $userService->loadUserByLogin($user->login, $prioritizedLanguages);
2418
        if ($expectedLanguageCode === null) {
2419
            $expectedLanguageCode = $loadedUser->contentInfo->mainLanguageCode;
2420
        }
2421
2422
        self::assertEquals(
2423
            $loadedUser->getName($expectedLanguageCode),
2424
            $loadedUser->getName()
2425
        );
2426
2427
        foreach (['first_name', 'last_name', 'signature'] as $fieldIdentifier) {
2428
            self::assertEquals(
2429
                $loadedUser->getFieldValue($fieldIdentifier, $expectedLanguageCode),
2430
                $loadedUser->getFieldValue($fieldIdentifier)
2431
            );
2432
        }
2433
    }
2434
2435
    /**
2436
     * Test that multi-language logic for the loadUserByCredentials method respects
2437
     * prioritized language list.
2438
     *
2439
     * @covers \eZ\Publish\API\Repository\UserService::loadUserByCredentials
2440
     * @dataProvider getPrioritizedLanguageList
2441
     * @param string[] $prioritizedLanguages
2442
     * @param string|null $expectedLanguageCode language code of expected translation
2443
     */
2444
    public function testLoadUserByCredentialsWithPrioritizedLanguagesList(
2445
        array $prioritizedLanguages,
2446
        $expectedLanguageCode
2447
    ) {
2448
        $repository = $this->getRepository();
2449
        $userService = $repository->getUserService();
2450
        $user = $this->createMultiLanguageUser();
2451
2452
        // load, with prioritized languages, the newly created user
2453
        $loadedUser = $userService->loadUserByCredentials(
2454
            $user->login,
2455
            'secret',
2456
            $prioritizedLanguages
2457
        );
2458
        if ($expectedLanguageCode === null) {
2459
            $expectedLanguageCode = $loadedUser->contentInfo->mainLanguageCode;
2460
        }
2461
2462
        self::assertEquals(
2463
            $loadedUser->getName($expectedLanguageCode),
2464
            $loadedUser->getName()
2465
        );
2466
2467
        foreach (['first_name', 'last_name', 'signature'] as $fieldIdentifier) {
2468
            self::assertEquals(
2469
                $loadedUser->getFieldValue($fieldIdentifier, $expectedLanguageCode),
2470
                $loadedUser->getFieldValue($fieldIdentifier)
2471
            );
2472
        }
2473
    }
2474
2475
    /**
2476
     * Test that multi-language logic for the loadUsersByEmail method respects
2477
     * prioritized language list.
2478
     *
2479
     * @covers \eZ\Publish\API\Repository\UserService::loadUsersByEmail
2480
     * @dataProvider getPrioritizedLanguageList
2481
     * @param string[] $prioritizedLanguages
2482
     * @param string|null $expectedLanguageCode language code of expected translation
2483
     */
2484
    public function testLoadUsersByEmailWithPrioritizedLanguagesList(
2485
        array $prioritizedLanguages,
2486
        $expectedLanguageCode
2487
    ) {
2488
        $repository = $this->getRepository();
2489
        $userService = $repository->getUserService();
2490
        $user = $this->createMultiLanguageUser();
2491
2492
        // load, with prioritized languages, users by email
2493
        $loadedUsers = $userService->loadUsersByEmail($user->email, $prioritizedLanguages);
2494
2495
        foreach ($loadedUsers as $loadedUser) {
2496
            if ($expectedLanguageCode === null) {
2497
                $expectedLanguageCode = $loadedUser->contentInfo->mainLanguageCode;
2498
            }
2499
            self::assertEquals(
2500
                $loadedUser->getName($expectedLanguageCode),
2501
                $loadedUser->getName()
2502
            );
2503
2504
            foreach (['first_name', 'last_name', 'signature'] as $fieldIdentifier) {
2505
                self::assertEquals(
2506
                    $loadedUser->getFieldValue($fieldIdentifier, $expectedLanguageCode),
2507
                    $loadedUser->getFieldValue($fieldIdentifier)
2508
                );
2509
            }
2510
        }
2511
    }
2512
2513
    /**
2514
     * Test that multi-language logic for the loadUserGroupsOfUser method respects
2515
     * prioritized language list.
2516
     *
2517
     * @covers \eZ\Publish\API\Repository\UserService::loadUserGroupsOfUser
2518
     * @dataProvider getPrioritizedLanguageList
2519
     * @param string[] $prioritizedLanguages
2520
     * @param string|null $expectedLanguageCode language code of expected translation
2521
     */
2522
    public function testLoadUserGroupsOfUserWithPrioritizedLanguagesList(
2523
        array $prioritizedLanguages,
2524
        $expectedLanguageCode
2525
    ) {
2526
        $repository = $this->getRepository();
2527
        $userService = $repository->getUserService();
2528
        $userGroup = $this->createMultiLanguageUserGroup();
2529
        $user = $this->createMultiLanguageUser($userGroup->id);
2530
2531
        $userGroups = $userService->loadUserGroupsOfUser($user, 0, 25, $prioritizedLanguages);
2532
        foreach ($userGroups as $userGroup) {
2533
            self::assertEquals(
2534
                $userGroup->getName($expectedLanguageCode),
2535
                $userGroup->getName()
2536
            );
2537
            self::assertEquals(
2538
                $userGroup->getFieldValue('description', $expectedLanguageCode),
2539
                $userGroup->getFieldValue('description')
2540
            );
2541
        }
2542
    }
2543
2544
    /**
2545
     * Test that multi-language logic for the loadUsersOfUserGroup method respects
2546
     * prioritized language list.
2547
     *
2548
     * @covers \eZ\Publish\API\Repository\UserService::loadUsersOfUserGroup
2549
     * @dataProvider getPrioritizedLanguageList
2550
     * @param string[] $prioritizedLanguages
2551
     * @param string|null $expectedLanguageCode language code of expected translation
2552
     */
2553
    public function testLoadUsersOfUserGroupWithPrioritizedLanguagesList(
2554
        array $prioritizedLanguages,
2555
        $expectedLanguageCode
2556
    ) {
2557
        $repository = $this->getRepository();
2558
        $userService = $repository->getUserService();
2559
2560
        // create parent user group
2561
        $userGroup = $this->createMultiLanguageUserGroup();
2562
        // add two users to the created parent user group
2563
        $this->createMultiLanguageUser($userGroup->id);
2564
        $this->createMultiLanguageUser($userGroup->id);
2565
2566
        // test loading of users via user group with prioritized languages list
2567
        $users = $userService->loadUsersOfUserGroup($userGroup, 0, 25, $prioritizedLanguages);
2568
        foreach ($users as $user) {
2569
            if ($expectedLanguageCode === null) {
2570
                $expectedLanguageCode = $user->contentInfo->mainLanguageCode;
2571
            }
2572
            self::assertEquals(
2573
                $user->getName($expectedLanguageCode),
2574
                $user->getName()
2575
            );
2576
2577
            foreach (['first_name', 'last_name', 'signature'] as $fieldIdentifier) {
2578
                self::assertEquals(
2579
                    $user->getFieldValue($fieldIdentifier, $expectedLanguageCode),
2580
                    $user->getFieldValue($fieldIdentifier)
2581
                );
2582
            }
2583
        }
2584
    }
2585
2586
    /**
2587
     * Get prioritized languages list data.
2588
     *
2589
     * Test cases using this data provider should expect the following arguments:
2590
     * <code>
2591
     *   array $prioritizedLanguagesList
2592
     *   string $expectedLanguage (if null - use main language)
2593
     * </code>
2594
     *
2595
     * @return array
2596
     */
2597
    public function getPrioritizedLanguageList()
2598
    {
2599
        return [
2600
            [[], null],
2601
            [['eng-US'], 'eng-US'],
2602
            [['eng-GB'], 'eng-GB'],
2603
            [['eng-US', 'eng-GB'], 'eng-US'],
2604
            [['eng-GB', 'eng-US'], 'eng-GB'],
2605
            // use non-existent group as the first one
2606
            [['ger-DE'], null],
2607
            [['ger-DE', 'eng-GB'], 'eng-GB'],
2608
        ];
2609
    }
2610
2611
    /**
2612
     * @param int $parentGroupId
2613
     * @return \eZ\Publish\API\Repository\Values\User\UserGroup
2614
     */
2615
    private function createMultiLanguageUserGroup($parentGroupId = 4)
2616
    {
2617
        $repository = $this->getRepository();
2618
        $userService = $repository->getUserService();
2619
2620
        // create user group with multiple translations
2621
        $parentGroupId = $this->generateId('group', $parentGroupId);
2622
        $parentGroup = $userService->loadUserGroup($parentGroupId);
2623
2624
        $userGroupCreateStruct = $userService->newUserGroupCreateStruct('eng-US');
2625
        $userGroupCreateStruct->setField('name', 'US user group', 'eng-US');
2626
        $userGroupCreateStruct->setField('name', 'GB user group', 'eng-GB');
2627
        $userGroupCreateStruct->setField('description', 'US user group description', 'eng-US');
2628
        $userGroupCreateStruct->setField('description', 'GB user group description', 'eng-GB');
2629
        $userGroupCreateStruct->alwaysAvailable = true;
2630
2631
        return $userService->createUserGroup($userGroupCreateStruct, $parentGroup);
2632
    }
2633
2634
    /**
2635
     * Create a user group fixture in a variable named <b>$userGroup</b>,.
2636
     *
2637
     * @return \eZ\Publish\API\Repository\Values\User\UserGroup
2638
     */
2639
    private function createUserGroupVersion1()
2640
    {
2641
        $repository = $this->getRepository();
2642
2643
        $mainGroupId = $this->generateId('group', 4);
2644
        /* BEGIN: Inline */
2645
        // $mainGroupId is the ID of the main "Users" group
2646
2647
        $userService = $repository->getUserService();
2648
2649
        // Load main group
2650
        $parentUserGroup = $userService->loadUserGroup($mainGroupId);
2651
2652
        // Instantiate a new create struct
2653
        $userGroupCreate = $userService->newUserGroupCreateStruct('eng-US');
2654
        $userGroupCreate->setField('name', 'Example Group');
2655
2656
        // Create the new user group
2657
        $userGroup = $userService->createUserGroup(
2658
            $userGroupCreate,
2659
            $parentUserGroup
2660
        );
2661
        /* END: Inline */
2662
2663
        return $userGroup;
2664
    }
2665
2666
    /**
2667
     * Create user with multiple translations of User Content fields.
2668
     *
2669
     * @param int $userGroupId User group ID (default 13 - Editors)
2670
     *
2671
     * @return \eZ\Publish\API\Repository\Values\User\User
2672
     */
2673
    private function createMultiLanguageUser($userGroupId = 13)
2674
    {
2675
        $repository = $this->getRepository();
2676
        $userService = $repository->getUserService();
2677
2678
        // Instantiate a create struct with mandatory properties
2679
        $randomLogin = md5(mt_rand() . time());
2680
        $userCreateStruct = $userService->newUserCreateStruct(
2681
            $randomLogin,
2682
            "{$randomLogin}@example.com",
2683
            'secret',
2684
            'eng-US'
2685
        );
2686
        $userCreateStruct->enabled = true;
2687
        $userCreateStruct->alwaysAvailable = true;
2688
2689
        // set field for each language
2690
        foreach (['eng-US', 'eng-GB'] as $languageCode) {
2691
            $userCreateStruct->setField('first_name', "{$languageCode} Example", $languageCode);
2692
            $userCreateStruct->setField('last_name', "{$languageCode} User", $languageCode);
2693
            $userCreateStruct->setField('signature', "{$languageCode} signature", $languageCode);
2694
        }
2695
2696
        // Load parent group for the user
2697
        $group = $userService->loadUserGroup($userGroupId);
2698
2699
        // Create a new user
2700
        return $userService->createUser($userCreateStruct, [$group]);
2701
    }
2702
2703
    /**
2704
     * Test for the createUser() method.
2705
     *
2706
     * @see \eZ\Publish\API\Repository\UserService::createUser()
2707
     */
2708
    public function testCreateUserInvalidPasswordHashTypeThrowsException()
2709
    {
2710
        $this->expectException(InvalidArgumentException::class);
2711
        $this->expectExceptionMessage("Argument 'type' is invalid: Password hash type '42424242' is not recognized");
2712
2713
        $repository = $this->getRepository();
2714
        $eventUserService = $repository->getUserService();
2715
2716
        $eventUserServiceReflection = new ReflectionClass($eventUserService);
2717
        $userServiceProperty = $eventUserServiceReflection->getProperty('innerService');
2718
        $userServiceProperty->setAccessible(true);
2719
        $userService = $userServiceProperty->getValue($eventUserService);
2720
2721
        $userServiceReflection = new ReflectionClass($userService);
2722
        $settingsProperty = $userServiceReflection->getProperty('settings');
2723
        $settingsProperty->setAccessible(true);
2724
2725
        $defaultUserServiceSettings = $settingsProperty->getValue($userService);
2726
2727
        /* BEGIN: Use Case */
2728
        $settingsProperty->setValue(
2729
            $userService,
2730
            [
2731
                'hashType' => 42424242, // Non-existing hash type
2732
            ] + $settingsProperty->getValue($userService)
2733
        );
2734
2735
        try {
2736
            $this->createUserVersion1();
2737
        } catch (InvalidArgumentException $e) {
2738
            // Reset to default settings, so we don't break other tests
2739
            $settingsProperty->setValue($userService, $defaultUserServiceSettings);
2740
2741
            throw $e;
2742
        }
2743
        /* END: Use Case */
2744
2745
        // Reset to default settings, so we don't break other tests
2746
        $settingsProperty->setValue($userService, $defaultUserServiceSettings);
2747
    }
2748
2749
    /**
2750
     * Test loading User by Token.
2751
     *
2752
     * @covers \eZ\Publish\API\Repository\UserService::loadUserByToken
2753
     */
2754
    public function testLoadUserByToken()
2755
    {
2756
        $repository = $this->getRepository();
2757
        $userService = $repository->getUserService();
2758
2759
        $user = $this->createUserVersion1();
2760
2761
        $userTokenUpdateStruct = new UserTokenUpdateStruct();
2762
        $userTokenUpdateStruct->hashKey = md5('hash');
2763
        $userTokenUpdateStruct->time = new DateTime();
2764
2765
        $userService->updateUserToken($user, $userTokenUpdateStruct);
2766
2767
        $loadedUser = $userService->loadUserByToken($userTokenUpdateStruct->hashKey);
2768
        self::assertEquals($user, $loadedUser);
2769
2770
        return $userTokenUpdateStruct->hashKey;
2771
    }
2772
2773
    /**
2774
     * Test trying to load User by invalid Token.
2775
     *
2776
     * @covers \eZ\Publish\API\Repository\UserService::loadUserByToken
2777
     */
2778
    public function testLoadUserByTokenThrowsNotFoundException()
2779
    {
2780
        $this->expectException(NotFoundException::class);
2781
2782
        $repository = $this->getRepository();
2783
        $userService = $repository->getUserService();
2784
2785
        $user = $this->createUserVersion1();
2786
2787
        $userTokenUpdateStruct = new UserTokenUpdateStruct();
2788
        $userTokenUpdateStruct->hashKey = md5('hash');
2789
        $userTokenUpdateStruct->time = new DateTime();
2790
2791
        $userService->updateUserToken($user, $userTokenUpdateStruct);
2792
2793
        $userService->loadUserByToken('not_existing_token');
2794
    }
2795
2796
    /**
2797
     * Test updating User Token.
2798
     *
2799
     * @covers \eZ\Publish\API\Repository\UserService::updateUserToken()
2800
     *
2801
     * @depends testLoadUserByToken
2802
     *
2803
     * @param string $originalUserToken
2804
     */
2805
    public function testUpdateUserToken($originalUserToken)
2806
    {
2807
        $repository = $this->getRepository(false);
2808
        $userService = $repository->getUserService();
2809
2810
        $user = $userService->loadUserByToken($originalUserToken);
2811
2812
        $userTokenUpdateStruct = new UserTokenUpdateStruct();
2813
        $userTokenUpdateStruct->hashKey = md5('my_updated_hash');
2814
        $userTokenUpdateStruct->time = new DateTime();
2815
2816
        $userService->updateUserToken($user, $userTokenUpdateStruct);
2817
2818
        $loadedUser = $userService->loadUserByToken($userTokenUpdateStruct->hashKey);
2819
        self::assertEquals($user, $loadedUser);
2820
    }
2821
2822
    /**
2823
     * Test invalidating (expiring) User Token.
2824
     *
2825
     * @covers \eZ\Publish\API\Repository\UserService::expireUserToken()
2826
     *
2827
     * @depends testLoadUserByToken
2828
     *
2829
     * @param string $userToken
2830
     */
2831
    public function testExpireUserToken($userToken)
2832
    {
2833
        $this->expectException(NotFoundException::class);
2834
2835
        $repository = $this->getRepository(false);
2836
        $userService = $repository->getUserService();
2837
2838
        // sanity check
2839
        $userService->loadUserByToken($userToken);
2840
2841
        $userService->expireUserToken($userToken);
2842
2843
        // should throw NotFoundException now
2844
        $userService->loadUserByToken($userToken);
2845
    }
2846
2847
    /**
2848
     * @covers \eZ\Publish\API\Repository\UserService::validatePassword()
2849
     */
2850
    public function testValidatePasswordWithDefaultContext()
2851
    {
2852
        $userService = $this->getRepository()->getUserService();
2853
2854
        /* BEGIN: Use Case */
2855
        $errors = $userService->validatePassword('pass');
2856
        /* END: Use Case */
2857
2858
        $this->assertEmpty($errors);
2859
    }
2860
2861
    /**
2862
     * @covers \eZ\Publish\API\Repository\UserService::validatePassword()
2863
     * @dataProvider dataProviderForValidatePassword
2864
     */
2865
    public function testValidatePassword(string $password, array $expectedErrorr)
2866
    {
2867
        $userService = $this->getRepository()->getUserService();
2868
        $contentType = $this->createUserContentTypeWithStrongPassword();
2869
2870
        /* BEGIN: Use Case */
2871
        $context = new PasswordValidationContext([
2872
            'contentType' => $contentType,
2873
        ]);
2874
2875
        $actualErrors = $userService->validatePassword($password, $context);
2876
        /* END: Use Case */
2877
2878
        $this->assertEquals($expectedErrorr, $actualErrors);
2879
    }
2880
2881
    /**
2882
     * Data provider for testValidatePassword.
2883
     *
2884
     * @return array
2885
     */
2886
    public function dataProviderForValidatePassword(): array
2887
    {
2888
        return [
2889
            [
2890
                'pass',
2891
                [
2892
                    new ValidationError('User password must be at least %length% characters long', null, [
2893
                        '%length%' => 8,
2894
                    ], 'password'),
2895
                    new ValidationError('User password must include at least one upper case letter', null, [], 'password'),
2896
                    new ValidationError('User password must include at least one number', null, [], 'password'),
2897
                    new ValidationError('User password must include at least one special character', null, [], 'password'),
2898
                ],
2899
            ],
2900
            [
2901
                'H@xxxi0R!!!',
2902
                [],
2903
            ],
2904
        ];
2905
    }
2906
2907
    public function testGetPasswordInfo(): void
2908
    {
2909
        $userService = $this->getRepository()->getUserService();
2910
        $contentType = $this->createUserContentTypeWithPasswordExpirationDate(
2911
            self::EXAMPLE_PASSWORD_TTL,
2912
            self::EXAMPLE_PASSWORD_TTL_WARNING
2913
        );
2914
2915
        $user = $this->createTestUser($contentType);
2916
2917
        /* BEGIN: Use Case */
2918
        $passwordInfo = $userService->getPasswordInfo($user);
2919
        /* END: Use Case */
2920
2921
        $passwordUpdatedAt = $user->passwordUpdatedAt;
2922
        if ($passwordUpdatedAt instanceof DateTime) {
2923
            $passwordUpdatedAt = DateTimeImmutable::createFromFormat(DateTime::ATOM, $passwordUpdatedAt->format(DateTime::ATOM));
2924
        }
2925
2926
        $expectedPasswordExpirationDate = $passwordUpdatedAt->add(
2927
            new DateInterval(sprintf('P%dD', self::EXAMPLE_PASSWORD_TTL))
2928
        );
2929
2930
        $expectedPasswordExpirationWarningDate = $passwordUpdatedAt->add(
2931
            new DateInterval(sprintf('P%dD', self::EXAMPLE_PASSWORD_TTL - self::EXAMPLE_PASSWORD_TTL_WARNING))
2932
        );
2933
2934
        $this->assertEquals(new PasswordInfo(
2935
            $expectedPasswordExpirationDate,
2936
            $expectedPasswordExpirationWarningDate
2937
        ), $passwordInfo);
2938
    }
2939
2940
    public function testGetPasswordInfoIfExpirationIsDisabled(): void
2941
    {
2942
        $userService = $this->getRepository()->getUserService();
2943
        $contentType = $this->createUserContentTypeWithPasswordExpirationDate(null, null);
2944
2945
        $user = $this->createTestUser($contentType);
2946
2947
        /* BEGIN: Use Case */
2948
        $passwordInfo = $userService->getPasswordInfo($user);
2949
        /* END: Use Case */
2950
2951
        $this->assertEquals(new PasswordInfo(), $passwordInfo);
2952
    }
2953
2954
    public function testGetPasswordInfoIfExpirationWarningIsDisabled(): void
2955
    {
2956
        $userService = $this->getRepository()->getUserService();
2957
        $contentType = $this->createUserContentTypeWithPasswordExpirationDate(self::EXAMPLE_PASSWORD_TTL, null);
2958
2959
        $user = $this->createTestUser($contentType);
2960
2961
        /* BEGIN: Use Case */
2962
        $passwordInfo = $userService->getPasswordInfo($user);
2963
        /* END: Use Case */
2964
2965
        $passwordUpdatedAt = $user->passwordUpdatedAt;
2966
        if ($passwordUpdatedAt instanceof DateTime) {
2967
            $passwordUpdatedAt = DateTimeImmutable::createFromFormat(DateTime::ATOM, $passwordUpdatedAt->format(DateTime::ATOM));
2968
        }
2969
2970
        $expectedPasswordExpirationDate = $passwordUpdatedAt->add(
2971
            new DateInterval(sprintf('P%dD', self::EXAMPLE_PASSWORD_TTL))
2972
        );
2973
2974
        $this->assertEquals(new PasswordInfo($expectedPasswordExpirationDate, null), $passwordInfo);
2975
    }
2976
2977
    public function createTestUser(ContentType $contentType): User
2978
    {
2979
        return $this->createTestUserWithPassword(self::EXAMPLE_PASSWORD, $contentType);
2980
    }
2981
2982
    /**
2983
     * Creates a user with given password.
2984
     *
2985
     * @param string $password
2986
     * @param \eZ\Publish\API\Repository\Values\ContentType\ContentType $contentType
2987
     *
2988
     * @return \eZ\Publish\API\Repository\Values\User\User
2989
     */
2990
    private function createTestUserWithPassword(string $password, ContentType $contentType): User
2991
    {
2992
        $userService = $this->getRepository()->getUserService();
2993
        // ID of the "Editors" user group in an eZ Publish demo installation
2994
        $editorsGroupId = 13;
2995
2996
        // Instantiate a create struct with mandatory properties
2997
        $userCreate = $userService->newUserCreateStruct(
2998
            'johndoe',
2999
            '[email protected]',
3000
            $password,
3001
            'eng-US',
3002
            $contentType
3003
        );
3004
        $userCreate->enabled = true;
3005
        $userCreate->setField('first_name', 'John');
3006
        $userCreate->setField('last_name', 'Doe');
3007
3008
        return $userService->createUser($userCreate, [
3009
            $userService->loadUserGroup($editorsGroupId),
3010
        ]);
3011
    }
3012
3013
    /**
3014
     * Creates the User Content Type with password constraints.
3015
     *
3016
     * @return \eZ\Publish\API\Repository\Values\ContentType\ContentType
3017
     */
3018
    private function createUserContentTypeWithStrongPassword(): ContentType
3019
    {
3020
        return $this->createUserContentTypeWithAccountSettings('user-with-strong-password', null, [
3021
            'PasswordValueValidator' => [
3022
                'requireAtLeastOneUpperCaseCharacter' => 1,
3023
                'requireAtLeastOneLowerCaseCharacter' => 1,
3024
                'requireAtLeastOneNumericCharacter' => 1,
3025
                'requireAtLeastOneNonAlphanumericCharacter' => 1,
3026
                'minLength' => 8,
3027
            ],
3028
        ]);
3029
    }
3030
3031
    private function createUserContentTypeWithPasswordExpirationDate(
3032
        ?int $passwordTTL = self::EXAMPLE_PASSWORD_TTL,
3033
        ?int $passwordTTLWarning = self::EXAMPLE_PASSWORD_TTL_WARNING
3034
    ): ContentType {
3035
        return $this->createUserContentTypeWithAccountSettings('password-expiration', [
3036
            'PasswordTTL' => $passwordTTL,
3037
            'PasswordTTLWarning' => $passwordTTLWarning,
3038
        ]);
3039
    }
3040
3041
    private function createUserContentTypeWithAccountSettings(
3042
        string $identifier,
3043
        ?array $fieldSetting = null,
3044
        ?array $validatorConfiguration = null
3045
    ): ContentType {
3046
        $repository = $this->getRepository();
3047
3048
        $contentTypeService = $repository->getContentTypeService();
3049
        $permissionResolver = $repository->getPermissionResolver();
3050
3051
        $typeCreate = $contentTypeService->newContentTypeCreateStruct($identifier);
3052
        $typeCreate->mainLanguageCode = 'eng-GB';
3053
        $typeCreate->urlAliasSchema = 'url|scheme';
3054
        $typeCreate->nameSchema = 'name|scheme';
3055
        $typeCreate->names = [
3056
            'eng-GB' => 'User: ' . $identifier,
3057
        ];
3058
        $typeCreate->descriptions = [
3059
            'eng-GB' => '',
3060
        ];
3061
        $typeCreate->creatorId = $this->generateId('user', $permissionResolver->getCurrentUserReference()->getUserId());
3062
        $typeCreate->creationDate = $this->createDateTime();
3063
3064
        $firstNameFieldCreate = $contentTypeService->newFieldDefinitionCreateStruct('first_name', 'ezstring');
3065
        $firstNameFieldCreate->names = [
3066
            'eng-GB' => 'First name',
3067
        ];
3068
        $firstNameFieldCreate->descriptions = [
3069
            'eng-GB' => '',
3070
        ];
3071
        $firstNameFieldCreate->fieldGroup = 'default';
3072
        $firstNameFieldCreate->position = 1;
3073
        $firstNameFieldCreate->isTranslatable = false;
3074
        $firstNameFieldCreate->isRequired = true;
3075
        $firstNameFieldCreate->isInfoCollector = false;
3076
        $firstNameFieldCreate->validatorConfiguration = [
3077
            'StringLengthValidator' => [
3078
                'minStringLength' => 0,
3079
                'maxStringLength' => 0,
3080
            ],
3081
        ];
3082
        $firstNameFieldCreate->fieldSettings = [];
3083
        $firstNameFieldCreate->isSearchable = true;
3084
        $firstNameFieldCreate->defaultValue = '';
3085
3086
        $typeCreate->addFieldDefinition($firstNameFieldCreate);
3087
3088
        $lastNameFieldCreate = $contentTypeService->newFieldDefinitionCreateStruct('last_name', 'ezstring');
3089
        $lastNameFieldCreate->names = [
3090
            'eng-GB' => 'Last name',
3091
        ];
3092
        $lastNameFieldCreate->descriptions = [
3093
            'eng-GB' => '',
3094
        ];
3095
        $lastNameFieldCreate->fieldGroup = 'default';
3096
        $lastNameFieldCreate->position = 2;
3097
        $lastNameFieldCreate->isTranslatable = false;
3098
        $lastNameFieldCreate->isRequired = true;
3099
        $lastNameFieldCreate->isInfoCollector = false;
3100
        $lastNameFieldCreate->validatorConfiguration = [
3101
            'StringLengthValidator' => [
3102
                'minStringLength' => 0,
3103
                'maxStringLength' => 0,
3104
            ],
3105
        ];
3106
        $lastNameFieldCreate->fieldSettings = [];
3107
        $lastNameFieldCreate->isSearchable = true;
3108
        $lastNameFieldCreate->defaultValue = '';
3109
3110
        $typeCreate->addFieldDefinition($lastNameFieldCreate);
3111
3112
        $accountFieldCreateStruct = $contentTypeService->newFieldDefinitionCreateStruct('account', 'ezuser');
3113
        $accountFieldCreateStruct->names = [
3114
            'eng-GB' => 'User account',
3115
        ];
3116
        $accountFieldCreateStruct->descriptions = [
3117
            'eng-GB' => '',
3118
        ];
3119
        $accountFieldCreateStruct->fieldGroup = 'default';
3120
        $accountFieldCreateStruct->position = 3;
3121
        $accountFieldCreateStruct->isTranslatable = false;
3122
        $accountFieldCreateStruct->isRequired = true;
3123
        $accountFieldCreateStruct->isInfoCollector = false;
3124
        $accountFieldCreateStruct->validatorConfiguration = $validatorConfiguration;
3125
        $accountFieldCreateStruct->fieldSettings = $fieldSetting;
3126
        $accountFieldCreateStruct->isSearchable = false;
3127
        $accountFieldCreateStruct->defaultValue = null;
3128
3129
        $typeCreate->addFieldDefinition($accountFieldCreateStruct);
3130
3131
        $contentTypeDraft = $contentTypeService->createContentType($typeCreate, [
3132
            $contentTypeService->loadContentTypeGroupByIdentifier('Users'),
3133
        ]);
3134
        $contentTypeService->publishContentTypeDraft($contentTypeDraft);
3135
3136
        return $contentTypeService->loadContentTypeByIdentifier($identifier);
3137
    }
3138
}
3139