Completed
Push — ezp_30797 ( c7df27...995301 )
by
unknown
20:14
created

testIsPasswordExpiredIfExpirationIsDisabled()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 13

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
nc 1
nop 0
dl 0
loc 13
rs 9.8333
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\UserService;
17
use eZ\Publish\API\Repository\Values\Content\ContentInfo;
18
use eZ\Publish\API\Repository\Values\Content\VersionInfo as APIVersionInfo;
19
use eZ\Publish\API\Repository\Values\ContentType\ContentType;
20
use eZ\Publish\API\Repository\Values\User\Limitation\SubtreeLimitation;
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
    /**
46
     * Test for the loadUserGroup() method.
47
     *
48
     * @see \eZ\Publish\API\Repository\UserService::loadUserGroup()
49
     */
50
    public function testLoadUserGroup()
51
    {
52
        $repository = $this->getRepository();
53
54
        $mainGroupId = $this->generateId('group', 4);
55
        /* BEGIN: Use Case */
56
        // $mainGroupId is the ID of the main "Users" group
57
58
        $userService = $repository->getUserService();
59
60
        $userGroup = $userService->loadUserGroup($mainGroupId);
61
        /* END: Use Case */
62
63
        $this->assertInstanceOf(UserGroup::class, $userGroup);
64
65
        // User group happens to also be a Content; isUserGroup() should be true and isUser() should be false
66
        $this->assertTrue($userService->isUserGroup($userGroup), 'isUserGroup() => false on a user group');
67
        $this->assertFalse($userService->isUser($userGroup), 'isUser() => true on a user group');
68
        $this->assertSame(0, $userGroup->parentId, 'parentId should be equal `0` because it is top level node');
69
    }
70
71
    /**
72
     * Test for the loadUserGroup() method to ensure that DomainUserGroupObject is created properly even if a user
73
     * has no access to parent of UserGroup.
74
     *
75
     * @see \eZ\Publish\API\Repository\UserService::loadUserGroup()
76
     */
77
    public function testLoadUserGroupWithNoAccessToParent()
78
    {
79
        $repository = $this->getRepository();
80
81
        $mainGroupId = $this->generateId('group', 4);
82
        /* BEGIN: Use Case */
83
        // $mainGroupId is the ID of the main "Users" group
84
85
        $userService = $repository->getUserService();
86
87
        $user = $this->createUserWithPolicies(
88
            'user',
89
            [
90
                ['module' => 'content', 'function' => 'read'],
91
            ],
92
            new SubtreeLimitation(['limitationValues' => ['/1/5']])
93
        );
94
        $repository->getPermissionResolver()->setCurrentUserReference($user);
95
96
        $userGroup = $userService->loadUserGroup($mainGroupId);
97
        /* END: Use Case */
98
99
        $this->assertInstanceOf(UserGroup::class, $userGroup);
100
101
        // User group happens to also be a Content; isUserGroup() should be true and isUser() should be false
102
        $this->assertTrue($userService->isUserGroup($userGroup), 'isUserGroup() => false on a user group');
103
        $this->assertFalse($userService->isUser($userGroup), 'isUser() => true on a user group');
104
        $this->assertSame(0, $userGroup->parentId, 'parentId should be equal `0` because it is top level node');
105
    }
106
107
    /**
108
     * Test for the loadUserGroup() method.
109
     *
110
     * @see     \eZ\Publish\API\Repository\UserService::loadUserGroup()
111
     * @expectedException \eZ\Publish\API\Repository\Exceptions\NotFoundException
112
     * @depends eZ\Publish\API\Repository\Tests\UserServiceTest::testLoadUserGroup
113
     */
114
    public function testLoadUserGroupThrowsNotFoundException()
115
    {
116
        $repository = $this->getRepository();
117
118
        $nonExistingGroupId = $this->generateId('group', self::DB_INT_MAX);
119
        /* BEGIN: Use Case */
120
        $userService = $repository->getUserService();
121
122
        // This call will fail with a NotFoundException
123
        $userService->loadUserGroup($nonExistingGroupId);
124
        /* END: Use Case */
125
    }
126
127
    /**
128
     * Test for the loadSubUserGroups() method.
129
     *
130
     * @see     \eZ\Publish\API\Repository\UserService::loadSubUserGroups()
131
     * @depends eZ\Publish\API\Repository\Tests\UserServiceTest::testLoadUserGroup
132
     */
133
    public function testLoadSubUserGroups()
134
    {
135
        $repository = $this->getRepository();
136
137
        $mainGroupId = $this->generateId('group', 4);
138
        /* BEGIN: Use Case */
139
        // $mainGroupId is the ID of the main "Users" group
140
141
        $userService = $repository->getUserService();
142
143
        $userGroup = $userService->loadUserGroup($mainGroupId);
144
145
        $subUserGroups = $userService->loadSubUserGroups($userGroup);
146
        foreach ($subUserGroups as $subUserGroup) {
147
            // Do something with the $subUserGroup
148
            $this->assertInstanceOf(UserGroup::class, $subUserGroup);
149
        }
150
        /* END: Use Case */
151
    }
152
153
    /**
154
     * Test loading sub groups throwing NotFoundException.
155
     *
156
     * @covers \eZ\Publish\API\Repository\UserService::loadSubUserGroups
157
     * @expectedException \eZ\Publish\API\Repository\Exceptions\NotFoundException
158
     */
159
    public function testLoadSubUserGroupsThrowsNotFoundException()
160
    {
161
        $repository = $this->getRepository();
162
        $userService = $repository->getUserService();
163
164
        $parentGroup = new UserGroup(
165
            [
166
                'content' => new Content(
167
                    [
168
                        'versionInfo' => new VersionInfo(
169
                            [
170
                                'contentInfo' => new ContentInfo(
171
                                    ['id' => 123456]
172
                                ),
173
                            ]
174
                        ),
175
                        'internalFields' => [],
176
                    ]
177
                ),
178
            ]
179
        );
180
        $userService->loadSubUserGroups($parentGroup);
181
    }
182
183
    /**
184
     * Test for the newUserGroupCreateStruct() method.
185
     *
186
     * @return \eZ\Publish\API\Repository\Values\User\UserGroupCreateStruct
187
     *
188
     * @see     \eZ\Publish\API\Repository\UserService::newUserGroupCreateStruct()
189
     * @depends eZ\Publish\API\Repository\Tests\ContentTypeServiceTest::testLoadContentTypeByIdentifier
190
     */
191
    public function testNewUserGroupCreateStruct()
192
    {
193
        $repository = $this->getRepository();
194
195
        /* BEGIN: Use Case */
196
        $userService = $repository->getUserService();
197
198
        $groupCreate = $userService->newUserGroupCreateStruct('eng-US');
199
        /* END: Use Case */
200
201
        $this->assertInstanceOf(
202
            '\\eZ\\Publish\\API\\Repository\\Values\\User\\UserGroupCreateStruct',
203
            $groupCreate
204
        );
205
206
        return $groupCreate;
207
    }
208
209
    /**
210
     * Test for the newUserGroupCreateStruct() method.
211
     *
212
     * @param \eZ\Publish\API\Repository\Values\User\UserGroupCreateStruct $groupCreate
213
     *
214
     * @see     \eZ\Publish\API\Repository\UserService::newUserGroupCreateStruct()
215
     * @depends eZ\Publish\API\Repository\Tests\UserServiceTest::testNewUserGroupCreateStruct
216
     */
217
    public function testNewUserGroupCreateStructSetsMainLanguageCode($groupCreate)
218
    {
219
        $this->assertEquals('eng-US', $groupCreate->mainLanguageCode);
220
    }
221
222
    /**
223
     * Test for the newUserGroupCreateStruct() method.
224
     *
225
     * @param \eZ\Publish\API\Repository\Values\User\UserGroupCreateStruct $groupCreate
226
     *
227
     * @see     \eZ\Publish\API\Repository\UserService::newUserGroupCreateStruct()
228
     * @depends eZ\Publish\API\Repository\Tests\UserServiceTest::testNewUserGroupCreateStruct
229
     */
230
    public function testNewUserGroupCreateStructSetsContentType($groupCreate)
231
    {
232
        $this->assertInstanceOf(
233
            '\\eZ\\Publish\\API\\Repository\\Values\\ContentType\\ContentType',
234
            $groupCreate->contentType
235
        );
236
    }
237
238
    /**
239
     * Test for the newUserGroupCreateStruct() method.
240
     *
241
     * @see     \eZ\Publish\API\Repository\UserService::newUserGroupCreateStruct($mainLanguageCode, $contentType)
242
     * @depends eZ\Publish\API\Repository\Tests\UserServiceTest::testNewUserGroupCreateStruct
243
     * @depends eZ\Publish\API\Repository\Tests\ContentTypeServiceTest::testLoadContentTypeByIdentifier
244
     */
245
    public function testNewUserGroupCreateStructWithSecondParameter()
246
    {
247
        if ($this->isVersion4()) {
248
            $this->markTestSkipped('This test is only relevant for eZ Publish versions > 4');
249
        }
250
251
        $repository = $this->getRepository();
252
253
        /* BEGIN: Use Case */
254
        $contentTypeService = $repository->getContentTypeService();
255
        $userService = $repository->getUserService();
256
257
        // Load the default ContentType for user groups
258
        $groupType = $contentTypeService->loadContentTypeByIdentifier('user_group');
259
260
        // Instantiate a new group create struct
261
        $groupCreate = $userService->newUserGroupCreateStruct(
262
            'eng-US',
263
            $groupType
264
        );
265
        /* END: Use Case */
266
267
        $this->assertSame($groupType, $groupCreate->contentType);
268
    }
269
270
    /**
271
     * Test for the createUserGroup() method.
272
     *
273
     * @return \eZ\Publish\API\Repository\Values\User\UserGroup
274
     *
275
     * @see     \eZ\Publish\API\Repository\UserService::createUserGroup()
276
     * @depends eZ\Publish\API\Repository\Tests\UserServiceTest::testNewUserGroupCreateStruct
277
     * @depends eZ\Publish\API\Repository\Tests\UserServiceTest::testLoadUserGroup
278
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testCreateContent
279
     */
280
    public function testCreateUserGroup()
281
    {
282
        /* BEGIN: Use Case */
283
        $userGroup = $this->createUserGroupVersion1();
284
        /* END: Use Case */
285
286
        $this->assertInstanceOf(
287
            UserGroup::class,
288
            $userGroup
289
        );
290
291
        $versionInfo = $userGroup->getVersionInfo();
292
293
        $this->assertEquals(APIVersionInfo::STATUS_PUBLISHED, $versionInfo->status);
294
        $this->assertEquals(1, $versionInfo->versionNo);
295
296
        return $userGroup;
297
    }
298
299
    /**
300
     * Test for the createUserGroup() method.
301
     *
302
     * @param \eZ\Publish\API\Repository\Values\User\UserGroup $userGroup
303
     *
304
     * @see     \eZ\Publish\API\Repository\UserService::createUserGroup()
305
     * @depends eZ\Publish\API\Repository\Tests\UserServiceTest::testCreateUserGroup
306
     */
307
    public function testCreateUserGroupSetsExpectedProperties($userGroup)
308
    {
309
        $this->assertEquals(
310
            [
311
                'parentId' => $this->generateId('group', 4),
312
            ],
313
            [
314
                'parentId' => $userGroup->parentId,
315
            ]
316
        );
317
    }
318
319
    /**
320
     * Test for the createUserGroup() method.
321
     *
322
     * @see     \eZ\Publish\API\Repository\UserService::createUserGroup()
323
     * @expectedException \eZ\Publish\API\Repository\Exceptions\InvalidArgumentException
324
     * @depends eZ\Publish\API\Repository\Tests\UserServiceTest::testCreateUserGroup
325
     */
326
    public function testCreateUserGroupThrowsInvalidArgumentException()
327
    {
328
        $repository = $this->getRepository();
329
330
        $mainGroupId = $this->generateId('group', 4);
331
        /* BEGIN: Use Case */
332
        // $mainGroupId is the ID of the main "Users" group
333
334
        $userService = $repository->getUserService();
335
336
        // Load main group
337
        $parentUserGroup = $userService->loadUserGroup($mainGroupId);
338
339
        // Instantiate a new create struct
340
        $userGroupCreate = $userService->newUserGroupCreateStruct('eng-US');
341
        $userGroupCreate->setField('name', 'Example Group');
342
        $userGroupCreate->remoteId = '5f7f0bdb3381d6a461d8c29ff53d908f';
343
344
        // This call will fail with an "InvalidArgumentException", because the
345
        // specified remoteId is already used for the "Members" user group.
346
        $userService->createUserGroup(
347
            $userGroupCreate,
348
            $parentUserGroup
349
        );
350
        /* END: Use Case */
351
    }
352
353
    /**
354
     * Test for the createUserGroup() method.
355
     *
356
     * @see     \eZ\Publish\API\Repository\UserService::createUserGroup()
357
     * @expectedException \eZ\Publish\API\Repository\Exceptions\InvalidArgumentException
358
     * @depends eZ\Publish\API\Repository\Tests\UserServiceTest::testCreateUserGroup
359
     */
360
    public function testCreateUserGroupThrowsInvalidArgumentExceptionFieldTypeNotAccept()
361
    {
362
        $repository = $this->getRepository();
363
364
        $mainGroupId = $this->generateId('group', 4);
365
        /* BEGIN: Use Case */
366
        // $mainGroupId is the ID of the main "Users" group
367
368
        $userService = $repository->getUserService();
369
370
        // Load main group
371
        $parentUserGroup = $userService->loadUserGroup($mainGroupId);
372
373
        // Instantiate a new create struct
374
        $userGroupCreate = $userService->newUserGroupCreateStruct('eng-US');
375
        $userGroupCreate->setField('name', new \stdClass());
376
377
        // This call will fail with an "InvalidArgumentException", because the
378
        // specified remoteId is already used for the "Members" user group.
379
        $userService->createUserGroup(
380
            $userGroupCreate,
381
            $parentUserGroup
382
        );
383
        /* END: Use Case */
384
    }
385
386
    /**
387
     * Test for the createUserGroup() method.
388
     *
389
     * @see     \eZ\Publish\API\Repository\UserService::createUserGroup()
390
     * @expectedException \eZ\Publish\API\Repository\Exceptions\ContentFieldValidationException
391
     * @depends eZ\Publish\API\Repository\Tests\UserServiceTest::testCreateUserGroup
392
     */
393
    public function testCreateUserGroupWhenMissingField()
394
    {
395
        $repository = $this->getRepository();
396
397
        $mainGroupId = $this->generateId('group', 4);
398
        /* BEGIN: Use Case */
399
        // $mainGroupId is the ID of the main "Users" group
400
401
        $userService = $repository->getUserService();
402
403
        // Load main group
404
        $parentUserGroup = $userService->loadUserGroup($mainGroupId);
405
406
        // Instantiate a new create struct
407
        $userGroupCreate = $userService->newUserGroupCreateStruct('eng-US');
408
409
        // This call will fail with a "ContentFieldValidationException", because the
410
        // only mandatory field "name" is not set.
411
        $userService->createUserGroup($userGroupCreate, $parentUserGroup);
412
        /* END: Use Case */
413
    }
414
415
    /**
416
     * Test for the createUserGroup() method.
417
     *
418
     * @return \eZ\Publish\API\Repository\Values\User\UserGroup
419
     *
420
     * @see     \eZ\Publish\API\Repository\UserService::createUserGroup()
421
     * @depends eZ\Publish\API\Repository\Tests\UserServiceTest::testNewUserGroupCreateStruct
422
     * @depends eZ\Publish\API\Repository\Tests\UserServiceTest::testLoadUserGroup
423
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testCreateContent
424
     */
425
    public function testCreateUserGroupInTransactionWithRollback()
426
    {
427
        $repository = $this->getRepository();
428
429
        $mainGroupId = $this->generateId('group', 4);
430
        /* BEGIN: Use Case */
431
        // $mainGroupId is the ID of the main "Users" group
432
433
        $userService = $repository->getUserService();
434
435
        $repository->beginTransaction();
436
437
        try {
438
            // Load main group
439
            $parentUserGroup = $userService->loadUserGroup($mainGroupId);
440
441
            // Instantiate a new create struct
442
            $userGroupCreate = $userService->newUserGroupCreateStruct('eng-US');
443
            $userGroupCreate->setField('name', 'Example Group');
444
445
            // Create the new user group
446
            $createdUserGroupId = $userService->createUserGroup(
447
                $userGroupCreate,
448
                $parentUserGroup
449
            )->id;
450
        } catch (Exception $e) {
451
            // Cleanup hanging transaction on error
452
            $repository->rollback();
453
            throw $e;
454
        }
455
456
        $repository->rollback();
457
458
        try {
459
            // Throws exception since creation of user group was rolled back
460
            $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...
461
        } catch (NotFoundException $e) {
462
            return;
463
        }
464
        /* END: Use Case */
465
466
        $this->fail('User group object still exists after rollback.');
467
    }
468
469
    /**
470
     * Test for the deleteUserGroup() method.
471
     *
472
     * @see     \eZ\Publish\API\Repository\UserService::deleteUserGroup()
473
     * @expectedException \eZ\Publish\API\Repository\Exceptions\NotFoundException
474
     * @depends eZ\Publish\API\Repository\Tests\UserServiceTest::testCreateUserGroup
475
     */
476
    public function testDeleteUserGroup()
477
    {
478
        $repository = $this->getRepository();
479
        $userService = $repository->getUserService();
480
481
        /* BEGIN: Use Case */
482
        $userGroup = $this->createUserGroupVersion1();
483
484
        // Delete the currently created user group again
485
        $userService->deleteUserGroup($userGroup);
486
        /* END: Use Case */
487
488
        // We use the NotFoundException here for verification
489
        $userService->loadUserGroup($userGroup->id);
490
    }
491
492
    /**
493
     * Test deleting user group throwing NotFoundException.
494
     *
495
     * @covers \eZ\Publish\API\Repository\UserService::deleteUserGroup
496
     * @expectedException \eZ\Publish\API\Repository\Exceptions\NotFoundException
497
     */
498
    public function testDeleteUserGroupThrowsNotFoundException()
499
    {
500
        $repository = $this->getRepository();
501
        $userService = $repository->getUserService();
502
503
        $userGroup = new UserGroup(
504
            [
505
                'content' => new Content(
506
                    [
507
                        'versionInfo' => new VersionInfo(
508
                            ['contentInfo' => new ContentInfo(['id' => 123456])]
509
                        ),
510
                        'internalFields' => [],
511
                    ]
512
                ),
513
            ]
514
        );
515
        $userService->deleteUserGroup($userGroup);
516
    }
517
518
    /**
519
     * Test for the moveUserGroup() method.
520
     *
521
     * @see     \eZ\Publish\API\Repository\UserService::moveUserGroup()
522
     * @depends eZ\Publish\API\Repository\Tests\UserServiceTest::testCreateUserGroup
523
     * @depends eZ\Publish\API\Repository\Tests\UserServiceTest::testLoadSubUserGroups
524
     */
525
    public function testMoveUserGroup()
526
    {
527
        $repository = $this->getRepository();
528
        $userService = $repository->getUserService();
529
530
        $membersGroupId = $this->generateId('group', 13);
531
        /* BEGIN: Use Case */
532
        // $membersGroupId is the ID of the "Members" user group in an eZ
533
        // Publish demo installation
534
535
        $userGroup = $this->createUserGroupVersion1();
536
537
        // Load the new parent group
538
        $membersUserGroup = $userService->loadUserGroup($membersGroupId);
539
540
        // Move user group from "Users" to "Members"
541
        $userService->moveUserGroup($userGroup, $membersUserGroup);
542
543
        // Reload the user group to get an updated $parentId
544
        $userGroup = $userService->loadUserGroup($userGroup->id);
545
546
        $this->refreshSearch($repository);
547
548
        // The returned array will no contain $userGroup
549
        $subUserGroups = $userService->loadSubUserGroups(
550
            $membersUserGroup
551
        );
552
        /* END: Use Case */
553
554
        $subUserGroupIds = array_map(
555
            function ($content) {
556
                return $content->id;
557
            },
558
            $subUserGroups
559
        );
560
561
        $this->assertEquals($membersGroupId, $userGroup->parentId);
562
        $this->assertEquals([$userGroup->id], $subUserGroupIds);
563
    }
564
565
    /**
566
     * Test moving a user group below another group throws NotFoundException.
567
     *
568
     * @covers \eZ\Publish\API\Repository\UserService::moveUserGroup
569
     * @expectedException \eZ\Publish\API\Repository\Exceptions\NotFoundException
570
     */
571
    public function testMoveUserGroupThrowsNotFoundException()
572
    {
573
        $repository = $this->getRepository();
574
        $userService = $repository->getUserService();
575
576
        $userGroupToMove = new UserGroup(
577
            [
578
                'content' => new Content(
579
                    [
580
                        'versionInfo' => new VersionInfo(
581
                            ['contentInfo' => new ContentInfo(['id' => 123456])]
582
                        ),
583
                        'internalFields' => [],
584
                    ]
585
                ),
586
            ]
587
        );
588
        $parentUserGroup = new UserGroup(
589
            [
590
                'content' => new Content(
591
                    [
592
                        'versionInfo' => new VersionInfo(
593
                            ['contentInfo' => new ContentInfo(['id' => 123455])]
594
                        ),
595
                        'internalFields' => [],
596
                    ]
597
                ),
598
            ]
599
        );
600
        $userService->moveUserGroup($userGroupToMove, $parentUserGroup);
601
    }
602
603
    /**
604
     * Test for the newUserGroupUpdateStruct() method.
605
     *
606
     * @covers \eZ\Publish\API\Repository\UserService::newUserGroupUpdateStruct
607
     */
608
    public function testNewUserGroupUpdateStruct()
609
    {
610
        $repository = $this->getRepository();
611
612
        /* BEGIN: Use Case */
613
        $userService = $repository->getUserService();
614
615
        $groupUpdate = $userService->newUserGroupUpdateStruct();
616
        /* END: Use Case */
617
618
        $this->assertInstanceOf(
619
            UserGroupUpdateStruct::class,
620
            $groupUpdate
621
        );
622
623
        $this->assertNull($groupUpdate->contentUpdateStruct);
624
        $this->assertNull($groupUpdate->contentMetadataUpdateStruct);
625
    }
626
627
    /**
628
     * Test for the updateUserGroup() method.
629
     *
630
     * @see     \eZ\Publish\API\Repository\UserService::updateUserGroup()
631
     * @depends eZ\Publish\API\Repository\Tests\UserServiceTest::testCreateUserGroup
632
     * @depends eZ\Publish\API\Repository\Tests\UserServiceTest::testNewUserGroupUpdateStruct
633
     */
634
    public function testUpdateUserGroup()
635
    {
636
        $repository = $this->getRepository();
637
        $userService = $repository->getUserService();
638
639
        /* BEGIN: Use Case */
640
        $userGroup = $this->createUserGroupVersion1();
641
642
        // Create a group update struct and change nothing
643
        $groupUpdate = $userService->newUserGroupUpdateStruct();
644
645
        // This update will do nothing
646
        $userGroup = $userService->updateUserGroup(
647
            $userGroup,
648
            $groupUpdate
649
        );
650
        /* END: Use Case */
651
652
        $this->assertInstanceOf(
653
            UserGroup::class,
654
            $userGroup
655
        );
656
657
        $this->assertEquals(1, $userGroup->getVersionInfo()->versionNo);
658
    }
659
660
    /**
661
     * Test for the updateUserGroup() method.
662
     *
663
     * @see     \eZ\Publish\API\Repository\UserService::updateUserGroup()
664
     * @depends eZ\Publish\API\Repository\Tests\UserServiceTest::testUpdateUserGroup
665
     */
666
    public function testUpdateUserGroupWithSubContentUpdateStruct()
667
    {
668
        $repository = $this->getRepository();
669
        $userService = $repository->getUserService();
670
671
        /* BEGIN: Use Case */
672
        $userGroup = $this->createUserGroupVersion1();
673
674
        // Load the content service
675
        $contentService = $repository->getContentService();
676
677
        // Create a content update struct and update the group name
678
        $contentUpdate = $contentService->newContentUpdateStruct();
679
        $contentUpdate->setField('name', 'Sindelfingen', 'eng-US');
680
681
        // Create a group update struct and set content update struct
682
        $groupUpdate = $userService->newUserGroupUpdateStruct();
683
        $groupUpdate->contentUpdateStruct = $contentUpdate;
684
685
        // This will update the name and the increment the group version number
686
        $userGroup = $userService->updateUserGroup(
687
            $userGroup,
688
            $groupUpdate
689
        );
690
        /* END: Use Case */
691
692
        $this->assertEquals('Sindelfingen', $userGroup->getFieldValue('name', 'eng-US'));
693
694
        $versionInfo = $userGroup->getVersionInfo();
695
696
        $this->assertEquals(APIVersionInfo::STATUS_PUBLISHED, $versionInfo->status);
697
        $this->assertEquals(2, $versionInfo->versionNo);
698
    }
699
700
    /**
701
     * Test for the updateUserGroup() method.
702
     *
703
     * @see     \eZ\Publish\API\Repository\UserService::updateUserGroup()
704
     * @depends eZ\Publish\API\Repository\Tests\UserServiceTest::testUpdateUserGroup
705
     */
706
    public function testUpdateUserGroupWithSubContentMetadataUpdateStruct()
707
    {
708
        $repository = $this->getRepository();
709
        $userService = $repository->getUserService();
710
711
        /* BEGIN: Use Case */
712
        $userGroup = $this->createUserGroupVersion1();
713
714
        // Load the content service
715
        $contentService = $repository->getContentService();
716
717
        // Create a metadata update struct and change the remoteId
718
        $metadataUpdate = $contentService->newContentMetadataUpdateStruct();
719
        $metadataUpdate->remoteId = '3c61299780663bafa3af2101e52125da';
720
721
        // Create a group update struct and set content update struct
722
        $groupUpdate = $userService->newUserGroupUpdateStruct();
723
        $groupUpdate->contentMetadataUpdateStruct = $metadataUpdate;
724
725
        // This will update the name and the increment the group version number
726
        $userGroup = $userService->updateUserGroup(
727
            $userGroup,
728
            $groupUpdate
729
        );
730
        /* END: Use Case */
731
732
        $this->assertEquals(
733
            '3c61299780663bafa3af2101e52125da',
734
            $userGroup->contentInfo->remoteId
735
        );
736
737
        $versionInfo = $userGroup->getVersionInfo();
738
739
        $this->assertEquals(APIVersionInfo::STATUS_PUBLISHED, $versionInfo->status);
740
        $this->assertEquals(1, $versionInfo->versionNo);
741
    }
742
743
    /**
744
     * Test for the updateUserGroup() method.
745
     *
746
     * @see     \eZ\Publish\API\Repository\UserService::updateUserGroup()
747
     * @expectedException \eZ\Publish\API\Repository\Exceptions\InvalidArgumentException
748
     * @depends eZ\Publish\API\Repository\Tests\UserServiceTest::testUpdateUserGroup
749
     */
750
    public function testUpdateUserGroupThrowsInvalidArgumentExceptionOnFieldTypeNotAccept()
751
    {
752
        $repository = $this->getRepository();
753
        $userService = $repository->getUserService();
754
755
        /* BEGIN: Use Case */
756
        $userGroup = $this->createUserGroupVersion1();
757
758
        // Load the content service
759
        $contentService = $repository->getContentService();
760
761
        // Create a content update struct and update the group name
762
        $contentUpdate = $contentService->newContentUpdateStruct();
763
        // An object of stdClass is not accepted as a value by the field "name"
764
        $contentUpdate->setField('name', new \stdClass(), 'eng-US');
765
766
        // Create a group update struct and set content update struct
767
        $groupUpdate = $userService->newUserGroupUpdateStruct();
768
        $groupUpdate->contentUpdateStruct = $contentUpdate;
769
770
        // This call will fail with an InvalidArgumentException, because the
771
        // field "name" does not accept the given value
772
        $userService->updateUserGroup($userGroup, $groupUpdate);
773
        /* END: Use Case */
774
    }
775
776
    /**
777
     * Test for the newUserCreateStruct() method.
778
     *
779
     * @see \eZ\Publish\API\Repository\UserService::newUserCreateStruct()
780
     */
781
    public function testNewUserCreateStruct()
782
    {
783
        $repository = $this->getRepository();
784
785
        /* BEGIN: Use Case */
786
        $userService = $repository->getUserService();
787
788
        $userCreate = $userService->newUserCreateStruct(
789
            'user',
790
            '[email protected]',
791
            'secret',
792
            'eng-US'
793
        );
794
        /* END: Use Case */
795
796
        $this->assertInstanceOf(
797
            '\\eZ\\Publish\\API\\Repository\\Values\\User\\UserCreateStruct',
798
            $userCreate
799
        );
800
801
        return $userCreate;
802
    }
803
804
    /**
805
     * Test updating a user group throws ContentFieldValidationException.
806
     *
807
     * @covers \eZ\Publish\API\Repository\UserService::updateUserGroup
808
     * @expectedException \eZ\Publish\API\Repository\Exceptions\ContentFieldValidationException
809
     */
810
    public function testUpdateUserGroupThrowsContentFieldValidationExceptionOnRequiredFieldEmpty()
811
    {
812
        $repository = $this->getRepository();
813
        $userService = $repository->getUserService();
814
        $contentService = $repository->getContentService();
815
816
        $userGroup = $userService->loadUserGroup(42);
817
        $userGroupUpdateStruct = $userService->newUserGroupUpdateStruct();
818
        $userGroupUpdateStruct->contentUpdateStruct = $contentService->newContentUpdateStruct();
819
        $userGroupUpdateStruct->contentUpdateStruct->setField('name', '', 'eng-US');
820
821
        $userService->updateUserGroup($userGroup, $userGroupUpdateStruct);
822
    }
823
824
    /**
825
     * Test for the newUserCreateStruct() method.
826
     *
827
     * @param \eZ\Publish\API\Repository\Values\User\UserCreateStruct $userCreate
828
     *
829
     * @see     \eZ\Publish\API\Repository\UserService::newUserCreateStruct()
830
     * @depends eZ\Publish\API\Repository\Tests\UserServiceTest::testNewUserCreateStruct
831
     */
832
    public function testNewUserCreateStructSetsExpectedProperties($userCreate)
833
    {
834
        $this->assertEquals(
835
            [
836
                'login' => 'user',
837
                'email' => '[email protected]',
838
                'password' => 'secret',
839
                'mainLanguageCode' => 'eng-US',
840
            ],
841
            [
842
                'login' => $userCreate->login,
843
                'email' => $userCreate->email,
844
                'password' => $userCreate->password,
845
                'mainLanguageCode' => $userCreate->mainLanguageCode,
846
            ]
847
        );
848
    }
849
850
    /**
851
     * Test for the newUserCreateStruct() method.
852
     *
853
     * @see     \eZ\Publish\API\Repository\UserService::newUserCreateStruct($login, $email, $password, $mainLanguageCode, $contentType)
854
     * @depends eZ\Publish\API\Repository\Tests\UserServiceTest::testNewUserCreateStruct
855
     * @depends eZ\Publish\API\Repository\Tests\ContentTypeServiceTest::testLoadContentTypeByIdentifier
856
     */
857
    public function testNewUserCreateStructWithFifthParameter()
858
    {
859
        if ($this->isVersion4()) {
860
            $this->markTestSkipped('This test is only relevant for eZ Publish versions > 4');
861
        }
862
863
        $repository = $this->getRepository();
864
865
        /* BEGIN: Use Case */
866
        $contentTypeService = $repository->getContentTypeService();
867
        $userService = $repository->getUserService();
868
869
        $userType = $contentTypeService->loadContentTypeByIdentifier('user');
870
871
        $userCreate = $userService->newUserCreateStruct(
872
            'user',
873
            '[email protected]',
874
            'secret',
875
            'eng-US',
876
            $userType
877
        );
878
        /* END: Use Case */
879
880
        $this->assertSame($userType, $userCreate->contentType);
881
    }
882
883
    /**
884
     * Test for creating user with Active Directory login name.
885
     */
886
    public function testNewUserWithDomainName()
887
    {
888
        $repository = $this->getRepository();
889
        $userService = $repository->getUserService();
890
        $createdUser = $this->createUserVersion1('ez-user-Domain\username-by-login');
891
        $loadedUser = $userService->loadUserByLogin('ez-user-Domain\username-by-login');
892
893
        $this->assertEquals($createdUser, $loadedUser);
894
    }
895
896
    /**
897
     * Test for the createUser() method.
898
     *
899
     * @return \eZ\Publish\API\Repository\Values\User\User
900
     *
901
     * @see     \eZ\Publish\API\Repository\UserService::createUser()
902
     * @depends eZ\Publish\API\Repository\Tests\UserServiceTest::testLoadUserGroup
903
     * @depends eZ\Publish\API\Repository\Tests\UserServiceTest::testNewUserCreateStruct
904
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testCreateContent
905
     */
906
    public function testCreateUser()
907
    {
908
        /* BEGIN: Use Case */
909
        $user = $this->createUserVersion1();
910
        /* END: Use Case */
911
912
        $this->assertInstanceOf(
913
            '\\eZ\\Publish\\API\\Repository\\Values\\User\\User',
914
            $user
915
        );
916
917
        return $user;
918
    }
919
920
    /**
921
     * Test for the createUser() method.
922
     *
923
     * @param \eZ\Publish\API\Repository\Values\User\User $user
924
     *
925
     * @see     \eZ\Publish\API\Repository\UserService::createUser()
926
     * @depends eZ\Publish\API\Repository\Tests\UserServiceTest::testCreateUser
927
     */
928
    public function testCreateUserSetsExpectedProperties(User $user)
929
    {
930
        $this->assertEquals(
931
            [
932
                'login' => 'user',
933
                'email' => '[email protected]',
934
                'mainLanguageCode' => 'eng-US',
935
            ],
936
            [
937
                'login' => $user->login,
938
                'email' => $user->email,
939
                'mainLanguageCode' => $user->contentInfo->mainLanguageCode,
940
            ]
941
        );
942
    }
943
944
    /**
945
     * Test for the createUser() method.
946
     *
947
     * @see     \eZ\Publish\API\Repository\UserService::createUser()
948
     * @expectedException \eZ\Publish\API\Repository\Exceptions\ContentFieldValidationException
949
     * @depends eZ\Publish\API\Repository\Tests\UserServiceTest::testCreateUser
950
     */
951
    public function testCreateUserWhenMissingField()
952
    {
953
        $repository = $this->getRepository();
954
955
        $editorsGroupId = $this->generateId('group', 13);
956
        /* BEGIN: Use Case */
957
        // $editorsGroupId is the ID of the "Editors" user group in an eZ
958
        // Publish demo installation
959
960
        $userService = $repository->getUserService();
961
962
        // Instantiate a create struct with mandatory properties
963
        $userCreate = $userService->newUserCreateStruct(
964
            'user',
965
            '[email protected]',
966
            'secret',
967
            'eng-US'
968
        );
969
970
        // Do not set the mandatory fields "first_name" and "last_name"
971
        //$userCreate->setField( 'first_name', 'Example' );
972
        //$userCreate->setField( 'last_name', 'User' );
973
974
        // Load parent group for the user
975
        $group = $userService->loadUserGroup($editorsGroupId);
976
977
        // This call will fail with a "ContentFieldValidationException", because the
978
        // mandatory fields "first_name" and "last_name" are not set.
979
        $userService->createUser($userCreate, [$group]);
980
        /* END: Use Case */
981
    }
982
983
    /**
984
     * Test for the createUser() method.
985
     *
986
     * @see     \eZ\Publish\API\Repository\UserService::createUser()
987
     * @expectedException \eZ\Publish\API\Repository\Exceptions\InvalidArgumentException
988
     * @depends eZ\Publish\API\Repository\Tests\UserServiceTest::testCreateUser
989
     */
990
    public function testCreateUserThrowsInvalidArgumentExceptionOnFieldTypeNotAccept()
991
    {
992
        $repository = $this->getRepository();
993
994
        $editorsGroupId = $this->generateId('group', 13);
995
        /* BEGIN: Use Case */
996
        // $editorsGroupId is the ID of the "Editors" user group in an eZ
997
        // Publish demo installation
998
999
        $userService = $repository->getUserService();
1000
1001
        // Instantiate a create struct with mandatory properties
1002
        $userCreate = $userService->newUserCreateStruct(
1003
            'user',
1004
            '[email protected]',
1005
            'secret',
1006
            'eng-US'
1007
        );
1008
1009
        // An object of stdClass is not a valid value for the field first_name
1010
        $userCreate->setField('first_name', new \stdClass());
1011
        $userCreate->setField('last_name', 'User');
1012
1013
        // Load parent group for the user
1014
        $group = $userService->loadUserGroup($editorsGroupId);
1015
1016
        // This call will fail with an "InvalidArgumentException", because the
1017
        // value for the firled "first_name" is not accepted by the field type.
1018
        $userService->createUser($userCreate, [$group]);
1019
        /* END: Use Case */
1020
    }
1021
1022
    /**
1023
     * Test for the createUser() method.
1024
     *
1025
     * @covers  \eZ\Publish\API\Repository\UserService::createUser
1026
     * @expectedException \eZ\Publish\API\Repository\Exceptions\InvalidArgumentException
1027
     * @expectedExceptionMessage Argument 'userCreateStruct' is invalid: User with provided login already exists
1028
     * @depends eZ\Publish\API\Repository\Tests\UserServiceTest::testCreateUser
1029
     */
1030
    public function testCreateUserThrowsInvalidArgumentException()
1031
    {
1032
        $repository = $this->getRepository();
1033
1034
        $editorsGroupId = $this->generateId('group', 13);
1035
        /* BEGIN: Use Case */
1036
        // $editorsGroupId is the ID of the "Editors" user group in an eZ
1037
        // Publish demo installation
1038
1039
        $userService = $repository->getUserService();
1040
1041
        // Instantiate a create struct with mandatory properties
1042
        $userCreate = $userService->newUserCreateStruct(
1043
        // admin is an existing login
1044
            'admin',
1045
            '[email protected]',
1046
            'secret',
1047
            'eng-US'
1048
        );
1049
1050
        $userCreate->setField('first_name', 'Example');
1051
        $userCreate->setField('last_name', 'User');
1052
1053
        // Load parent group for the user
1054
        $group = $userService->loadUserGroup($editorsGroupId);
1055
1056
        // This call will fail with a "InvalidArgumentException", because the
1057
        // user with "admin" login already exists.
1058
        $userService->createUser($userCreate, [$group]);
1059
        /* END: Use Case */
1060
    }
1061
1062
    /**
1063
     * Test for the createUser() method.
1064
     *
1065
     * @return \eZ\Publish\API\Repository\Values\User\User
1066
     *
1067
     * @see     \eZ\Publish\API\Repository\UserService::createUser()
1068
     * @depends eZ\Publish\API\Repository\Tests\UserServiceTest::testLoadUserGroup
1069
     * @depends eZ\Publish\API\Repository\Tests\UserServiceTest::testNewUserCreateStruct
1070
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testCreateContent
1071
     */
1072
    public function testCreateUserInTransactionWithRollback()
1073
    {
1074
        $repository = $this->getRepository();
1075
        $userService = $repository->getUserService();
1076
1077
        /* BEGIN: Use Case */
1078
        $repository->beginTransaction();
1079
1080
        try {
1081
            $user = $this->createUserVersion1();
1082
        } catch (Exception $e) {
1083
            // Cleanup hanging transaction on error
1084
            $repository->rollback();
1085
            throw $e;
1086
        }
1087
1088
        $repository->rollback();
1089
1090
        try {
1091
            // Throws exception since creation of user was rolled back
1092
            $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...
1093
        } catch (NotFoundException $e) {
1094
            return;
1095
        }
1096
        /* END: Use Case */
1097
1098
        $this->fail('User object still exists after rollback.');
1099
    }
1100
1101
    /**
1102
     * Test creating a user throwing NotFoundException.
1103
     *
1104
     * @expectedException \eZ\Publish\API\Repository\Exceptions\NotFoundException
1105
     * @covers \eZ\Publish\API\Repository\UserService::createUser
1106
     */
1107
    public function testCreateUserThrowsNotFoundException()
1108
    {
1109
        $repository = $this->getRepository();
1110
        $userService = $repository->getUserService();
1111
1112
        $userCreateStruct = $userService->newUserCreateStruct('new_user', '[email protected]', 'password', 'eng-GB');
1113
        $userCreateStruct->setField('first_name', 'New');
1114
        $userCreateStruct->setField('last_name', 'User');
1115
1116
        $parentGroup = new UserGroup(
1117
            [
1118
                'content' => new Content(
1119
                    [
1120
                        'versionInfo' => new VersionInfo(
1121
                            [
1122
                                'contentInfo' => new ContentInfo(['id' => 123456]),
1123
                            ]
1124
                        ),
1125
                        'internalFields' => [],
1126
                    ]
1127
                ),
1128
            ]
1129
        );
1130
        $userService->createUser($userCreateStruct, [$parentGroup]);
1131
    }
1132
1133
    /**
1134
     * Test creating a user throwing UserPasswordValidationException when password doesn't follow specific rules.
1135
     *
1136
     * @expectedException \eZ\Publish\Core\Base\Exceptions\UserPasswordValidationException
1137
     * @expectedExceptionMessage 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
1138
     * @covers \eZ\Publish\API\Repository\UserService::createUser
1139
     */
1140
    public function testCreateUserWithWeakPasswordThrowsUserPasswordValidationException()
1141
    {
1142
        $userContentType = $this->createUserContentTypeWithStrongPassword();
1143
1144
        /* BEGIN: Use Case */
1145
        // This call will fail with a "UserPasswordValidationException" because the
1146
        // the password does not follow specified rules.
1147
        $this->createTestUserWithPassword('pass', $userContentType);
1148
        /* END: Use Case */
1149
    }
1150
1151
    /**
1152
     * Opposite test case for testCreateUserWithWeakPasswordThrowsUserPasswordValidationException.
1153
     *
1154
     * @covers \eZ\Publish\API\Repository\UserService::createUser
1155
     */
1156
    public function testCreateUserWithStrongPassword()
1157
    {
1158
        $userContentType = $this->createUserContentTypeWithStrongPassword();
1159
1160
        /* BEGIN: Use Case */
1161
        $user = $this->createTestUserWithPassword('H@xxi0r!', $userContentType);
1162
        /* END: Use Case */
1163
1164
        $this->assertInstanceOf(User::class, $user);
1165
    }
1166
1167
    /**
1168
     * Test for the loadUser() method.
1169
     *
1170
     * @see     \eZ\Publish\API\Repository\UserService::loadUser()
1171
     * @depends eZ\Publish\API\Repository\Tests\UserServiceTest::testCreateUser
1172
     */
1173
    public function testLoadUser()
1174
    {
1175
        $repository = $this->getRepository();
1176
1177
        $userService = $repository->getUserService();
1178
1179
        /* BEGIN: Use Case */
1180
        $user = $this->createUserVersion1();
1181
1182
        // Load the newly created user
1183
        $userReloaded = $userService->loadUser($user->id);
1184
        /* END: Use Case */
1185
1186
        $this->assertEquals($user, $userReloaded);
1187
1188
        // User happens to also be a Content; isUser() should be true and isUserGroup() should be false
1189
        $this->assertTrue($userService->isUser($user), 'isUser() => false on a user');
1190
        $this->assertFalse($userService->isUserGroup($user), 'isUserGroup() => true on a user group');
1191
    }
1192
1193
    /**
1194
     * Test for the loadUser() method.
1195
     *
1196
     * @see     \eZ\Publish\API\Repository\UserService::loadUser()
1197
     * @expectedException \eZ\Publish\API\Repository\Exceptions\NotFoundException
1198
     * @depends eZ\Publish\API\Repository\Tests\UserServiceTest::testLoadUser
1199
     */
1200
    public function testLoadUserThrowsNotFoundException()
1201
    {
1202
        $repository = $this->getRepository();
1203
1204
        $nonExistingUserId = $this->generateId('user', self::DB_INT_MAX);
1205
        /* BEGIN: Use Case */
1206
        $userService = $repository->getUserService();
1207
1208
        // This call will fail with a "NotFoundException", because no user with
1209
        // an id equal to self::DB_INT_MAX should exist.
1210
        $userService->loadUser($nonExistingUserId);
1211
        /* END: Use Case */
1212
    }
1213
1214
    /**
1215
     * Test for the loadAnonymousUser() method.
1216
     *
1217
     * @see \eZ\Publish\API\Repository\UserService::loadAnonymousUser()
1218
     */
1219
    public function testLoadAnonymousUser()
1220
    {
1221
        $repository = $this->getRepository();
1222
1223
        $anonymousUserId = $this->generateId('user', 10);
1224
        /* BEGIN: Use Case */
1225
        // $anonymousUserId is the ID of the "Anonymous" user in a eZ
1226
        // Publish demo installation.
1227
        $userService = $repository->getUserService();
1228
1229
        // Load default anonymous user available in each eZ Publish installation
1230
        $anonymousUser = $userService->loadUser($anonymousUserId);
1231
        /* END: Use Case */
1232
1233
        $this->assertInstanceOf(
1234
            '\\eZ\\Publish\\API\\Repository\\Values\\User\\User',
1235
            $anonymousUser
1236
        );
1237
1238
        $this->assertEquals('anonymous', $anonymousUser->login);
1239
    }
1240
1241
    /**
1242
     * Test for the loadUserByCredentials() method.
1243
     *
1244
     * @see     \eZ\Publish\API\Repository\UserService::loadUserByCredentials()
1245
     * @depends eZ\Publish\API\Repository\Tests\UserServiceTest::testCreateUser
1246
     */
1247
    public function testLoadUserByCredentials()
1248
    {
1249
        $repository = $this->getRepository();
1250
1251
        $userService = $repository->getUserService();
1252
1253
        /* BEGIN: Use Case */
1254
        $user = $this->createUserVersion1();
1255
1256
        // Load the newly created user
1257
        $userReloaded = $userService->loadUserByCredentials('user', 'secret');
1258
        /* END: Use Case */
1259
1260
        $this->assertEquals($user, $userReloaded);
1261
    }
1262
1263
    /**
1264
     * Test for the loadUserByCredentials() method.
1265
     *
1266
     * @see     \eZ\Publish\API\Repository\UserService::loadUserByCredentials()
1267
     * @expectedException \eZ\Publish\API\Repository\Exceptions\NotFoundException
1268
     * @depends eZ\Publish\API\Repository\Tests\UserServiceTest::testLoadUserByCredentials
1269
     */
1270
    public function testLoadUserByCredentialsThrowsNotFoundExceptionForUnknownPassword()
1271
    {
1272
        $repository = $this->getRepository();
1273
1274
        $userService = $repository->getUserService();
1275
1276
        /* BEGIN: Use Case */
1277
        $this->createUserVersion1();
1278
1279
        // This call will fail with a "NotFoundException", because the given
1280
        // login/password combination does not exist.
1281
        $userService->loadUserByCredentials('user', 'SeCrEt');
1282
        /* END: Use Case */
1283
    }
1284
1285
    /**
1286
     * Test for the loadUserByCredentials() method.
1287
     *
1288
     * @see     \eZ\Publish\API\Repository\UserService::loadUserByCredentials()
1289
     * @expectedException \eZ\Publish\API\Repository\Exceptions\NotFoundException
1290
     * @depends eZ\Publish\API\Repository\Tests\UserServiceTest::testLoadUserByCredentials
1291
     */
1292
    public function testLoadUserByCredentialsThrowsNotFoundExceptionForUnknownPasswordEmtpy()
1293
    {
1294
        $repository = $this->getRepository();
1295
1296
        $userService = $repository->getUserService();
1297
1298
        /* BEGIN: Use Case */
1299
        $this->createUserVersion1();
1300
1301
        // This call will fail with a "NotFoundException", because the given
1302
        // login/password combination does not exist.
1303
        $userService->loadUserByCredentials('user', '');
1304
        /* END: Use Case */
1305
    }
1306
1307
    /**
1308
     * Test for the loadUserByCredentials() method.
1309
     *
1310
     * @see     \eZ\Publish\API\Repository\UserService::loadUserByCredentials()
1311
     * @expectedException \eZ\Publish\API\Repository\Exceptions\NotFoundException
1312
     * @depends eZ\Publish\API\Repository\Tests\UserServiceTest::testLoadUserByCredentials
1313
     */
1314
    public function testLoadUserByCredentialsThrowsNotFoundExceptionForUnknownLogin()
1315
    {
1316
        $repository = $this->getRepository();
1317
1318
        $userService = $repository->getUserService();
1319
1320
        /* BEGIN: Use Case */
1321
        $this->createUserVersion1();
1322
1323
        // This call will fail with a "NotFoundException", because the given
1324
        // login/password combination does not exist.
1325
        $userService->loadUserByCredentials('üser', 'secret');
1326
        /* END: Use Case */
1327
    }
1328
1329
    /**
1330
     * Test for the loadUserByCredentials() method.
1331
     *
1332
     * @see     \eZ\Publish\API\Repository\UserService::loadUserByCredentials()
1333
     * @expectedException \eZ\Publish\Core\Base\Exceptions\InvalidArgumentValue
1334
     * @depends eZ\Publish\API\Repository\Tests\UserServiceTest::testLoadUserByCredentials
1335
     */
1336
    public function testLoadUserByCredentialsThrowsInvalidArgumentValueForEmptyLogin()
1337
    {
1338
        $repository = $this->getRepository();
1339
1340
        $userService = $repository->getUserService();
1341
1342
        /* BEGIN: Use Case */
1343
        $this->createUserVersion1();
1344
1345
        // This call will fail with a "InvalidArgumentValue", because the given
1346
        // login is empty.
1347
        $userService->loadUserByCredentials('', 'secret');
1348
        /* END: Use Case */
1349
    }
1350
1351
    /**
1352
     * Test for the loadUserByLogin() method.
1353
     *
1354
     * @see     \eZ\Publish\API\Repository\UserService::loadUserByLogin()
1355
     * @depends eZ\Publish\API\Repository\Tests\UserServiceTest::testCreateUser
1356
     */
1357
    public function testLoadUserByLogin()
1358
    {
1359
        $repository = $this->getRepository();
1360
1361
        $userService = $repository->getUserService();
1362
1363
        /* BEGIN: Use Case */
1364
        $user = $this->createUserVersion1('User');
1365
1366
        // Load the newly created user
1367
        $userReloaded = $userService->loadUserByLogin('User');
1368
        /* END: Use Case */
1369
1370
        $this->assertPropertiesCorrect(
1371
            [
1372
                'login' => $user->login,
1373
                'email' => $user->email,
1374
                'passwordHash' => $user->passwordHash,
1375
                'hashAlgorithm' => $user->hashAlgorithm,
1376
                'enabled' => $user->enabled,
1377
                'maxLogin' => $user->maxLogin,
1378
                'id' => $user->id,
1379
                'contentInfo' => $user->contentInfo,
1380
                'versionInfo' => $user->versionInfo,
1381
                'fields' => $user->fields,
1382
            ],
1383
            $userReloaded
1384
        );
1385
    }
1386
1387
    /**
1388
     * Test for the loadUserByLogin() method.
1389
     *
1390
     * @see     \eZ\Publish\API\Repository\UserService::loadUserByLogin()
1391
     * @expectedException \eZ\Publish\API\Repository\Exceptions\NotFoundException
1392
     * @depends eZ\Publish\API\Repository\Tests\UserServiceTest::testLoadUserByLogin
1393
     */
1394
    public function testLoadUserByLoginThrowsNotFoundExceptionForUnknownLogin()
1395
    {
1396
        $repository = $this->getRepository();
1397
1398
        $userService = $repository->getUserService();
1399
1400
        /* BEGIN: Use Case */
1401
        $this->createUserVersion1();
1402
1403
        // This call will fail with a "NotFoundException", because the given
1404
        // login/password combination does not exist.
1405
        $userService->loadUserByLogin('user42');
1406
        /* END: Use Case */
1407
    }
1408
1409
    /**
1410
     * Test for the loadUserByLogin() method.
1411
     *
1412
     * @see     \eZ\Publish\API\Repository\UserService::loadUserByLogin()
1413
     * @depends eZ\Publish\API\Repository\Tests\UserServiceTest::testLoadUserByLogin
1414
     */
1415
    public function testLoadUserByLoginWorksForLoginWithWrongCase()
1416
    {
1417
        $repository = $this->getRepository();
1418
1419
        $userService = $repository->getUserService();
1420
1421
        /* BEGIN: Use Case */
1422
        $user = $this->createUserVersion1();
1423
1424
        // Lookup by user login should ignore casing
1425
        $userReloaded = $userService->loadUserByLogin('USER');
1426
        /* END: Use Case */
1427
1428
        $this->assertPropertiesCorrect(
1429
            [
1430
                'login' => $user->login,
1431
                'email' => $user->email,
1432
                'passwordHash' => $user->passwordHash,
1433
                'hashAlgorithm' => $user->hashAlgorithm,
1434
                'enabled' => $user->enabled,
1435
                'maxLogin' => $user->maxLogin,
1436
                'id' => $user->id,
1437
                'contentInfo' => $user->contentInfo,
1438
                'versionInfo' => $user->versionInfo,
1439
                'fields' => $user->fields,
1440
            ],
1441
            $userReloaded
1442
        );
1443
    }
1444
1445
    /**
1446
     * Test for the loadUserByLogin() method.
1447
     *
1448
     * In some cases people use email as login name, make sure system works as exepcted when asking for user by email.
1449
     *
1450
     * @see     \eZ\Publish\API\Repository\UserService::loadUserByLogin()
1451
     * @expectedException \eZ\Publish\API\Repository\Exceptions\NotFoundException
1452
     * @depends eZ\Publish\API\Repository\Tests\UserServiceTest::testLoadUserByLogin
1453
     */
1454
    public function testLoadUserByLoginThrowsNotFoundExceptionForUnknownLoginByEmail()
1455
    {
1456
        $repository = $this->getRepository();
1457
1458
        $userService = $repository->getUserService();
1459
1460
        /* BEGIN: Use Case */
1461
        $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...
1462
1463
        // Lookup by user login by email should behave as normal
1464
        $userService->loadUserByLogin('[email protected]');
1465
        /* END: Use Case */
1466
    }
1467
1468
    /**
1469
     * Test for the loadUsersByEmail() method.
1470
     *
1471
     * @see     \eZ\Publish\API\Repository\UserService::loadUsersByEmail()
1472
     * @depends eZ\Publish\API\Repository\Tests\UserServiceTest::testCreateUser
1473
     */
1474
    public function testLoadUserByEmail()
1475
    {
1476
        $repository = $this->getRepository();
1477
1478
        $userService = $repository->getUserService();
1479
1480
        /* BEGIN: Use Case */
1481
        $user = $this->createUserVersion1();
1482
1483
        // Load the newly created user
1484
        $usersReloaded = $userService->loadUsersByEmail('[email protected]');
1485
        /* END: Use Case */
1486
1487
        $this->assertEquals([$user], $usersReloaded);
1488
    }
1489
1490
    /**
1491
     * Test for the loadUsersByEmail() method.
1492
     *
1493
     * @see     \eZ\Publish\API\Repository\UserService::loadUsersByEmail()
1494
     * @depends eZ\Publish\API\Repository\Tests\UserServiceTest::testLoadUserByEmail
1495
     */
1496
    public function testLoadUserByEmailReturnsEmptyInUnknownEmail()
1497
    {
1498
        $repository = $this->getRepository();
1499
1500
        $userService = $repository->getUserService();
1501
1502
        /* BEGIN: Use Case */
1503
        $this->createUserVersion1();
1504
1505
        // This call will return empty array, because the given
1506
        // login/password combination does not exist.
1507
        $emptyUserList = $userService->loadUsersByEmail('[email protected]');
1508
        /* END: Use Case */
1509
1510
        $this->assertEquals([], $emptyUserList);
1511
    }
1512
1513
    /**
1514
     * Test for the deleteUser() method.
1515
     *
1516
     * @see     \eZ\Publish\API\Repository\UserService::deleteUser()
1517
     * @expectedException \eZ\Publish\API\Repository\Exceptions\NotFoundException
1518
     * @depends eZ\Publish\API\Repository\Tests\UserServiceTest::testCreateUser
1519
     * @depends eZ\Publish\API\Repository\Tests\UserServiceTest::testLoadUser
1520
     */
1521
    public function testDeleteUser()
1522
    {
1523
        $repository = $this->getRepository();
1524
1525
        $userService = $repository->getUserService();
1526
1527
        /* BEGIN: Use Case */
1528
        $user = $this->createUserVersion1();
1529
1530
        // Delete the currently created user
1531
        $userService->deleteUser($user);
1532
        /* END: Use Case */
1533
1534
        // We use the NotFoundException here to verify that the user not exists
1535
        $userService->loadUser($user->id);
1536
    }
1537
1538
    /**
1539
     * Test for the deleteUser() method.
1540
     *
1541
     * @covers  \eZ\Publish\API\Repository\UserService::deleteUser()
1542
     * @depends eZ\Publish\API\Repository\Tests\UserServiceTest::testCreateUser
1543
     * @depends eZ\Publish\API\Repository\Tests\UserServiceTest::testLoadUser
1544
     */
1545
    public function testDeleteUserDeletesRelatedBookmarks()
1546
    {
1547
        $repository = $this->getRepository();
1548
1549
        $userService = $repository->getUserService();
1550
        $locationService = $repository->getLocationService();
1551
        $bookmarkService = $repository->getBookmarkService();
1552
        /* BEGIN: Use Case */
1553
        $admin = $repository->getPermissionResolver()->getCurrentUserReference();
1554
1555
        $user = $this->createUserVersion1();
1556
1557
        $repository->getPermissionResolver()->setCurrentUserReference($user);
1558
1559
        $bookmarkService->createBookmark(
1560
            $locationService->loadLocation($this->generateId('location', 43))
1561
        );
1562
1563
        $repository->getPermissionResolver()->setCurrentUserReference($admin);
1564
        // Delete the currently created user
1565
        $userService->deleteUser($user);
1566
1567
        $repository->getPermissionResolver()->setCurrentUserReference($user);
1568
        /* END: Use Case */
1569
1570
        $this->assertEquals(0, $bookmarkService->loadBookmarks(0, 9999)->totalCount);
1571
    }
1572
1573
    /**
1574
     * Test for the newUserUpdateStruct() method.
1575
     *
1576
     * @see \eZ\Publish\API\Repository\UserService::newUserUpdateStruct()
1577
     */
1578
    public function testNewUserUpdateStruct()
1579
    {
1580
        $repository = $this->getRepository();
1581
1582
        /* BEGIN: Use Case */
1583
        $userService = $repository->getUserService();
1584
1585
        // Create a new update struct instance
1586
        $userUpdate = $userService->newUserUpdateStruct();
1587
        /* END: Use Case */
1588
1589
        $this->assertInstanceOf(
1590
            UserUpdateStruct::class,
1591
            $userUpdate
1592
        );
1593
1594
        $this->assertNull($userUpdate->contentUpdateStruct);
1595
        $this->assertNull($userUpdate->contentMetadataUpdateStruct);
1596
1597
        $this->assertPropertiesCorrect(
1598
            [
1599
                'email' => null,
1600
                'password' => null,
1601
                'enabled' => null,
1602
                'maxLogin' => null,
1603
            ],
1604
            $userUpdate
1605
        );
1606
    }
1607
1608
    /**
1609
     * Test for the updateUser() method.
1610
     *
1611
     * @return \eZ\Publish\API\Repository\Values\User\User
1612
     *
1613
     * @see     \eZ\Publish\API\Repository\UserService::updateUser()
1614
     * @depends eZ\Publish\API\Repository\Tests\UserServiceTest::testCreateUser
1615
     * @depends eZ\Publish\API\Repository\Tests\UserServiceTest::testNewUserUpdateStruct
1616
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testUpdateContent
1617
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testUpdateContentMetadata
1618
     */
1619
    public function testUpdateUser()
1620
    {
1621
        $repository = $this->getRepository();
1622
1623
        $userService = $repository->getUserService();
1624
1625
        /* BEGIN: Use Case */
1626
        $user = $this->createUserVersion1();
1627
1628
        // Create a new update struct instance
1629
        $userUpdate = $userService->newUserUpdateStruct();
1630
1631
        // Set new values for password and maxLogin
1632
        $userUpdate->password = 'my-new-password';
1633
        $userUpdate->maxLogin = 42;
1634
        $userUpdate->enabled = false;
1635
1636
        // Updated the user record.
1637
        $userVersion2 = $userService->updateUser($user, $userUpdate);
1638
        /* END: Use Case */
1639
1640
        $this->assertInstanceOf(User::class, $userVersion2);
1641
1642
        return $userVersion2;
1643
    }
1644
1645
    /**
1646
     * Test for the updateUser() and loadUsersByEmail() method on change to email.
1647
     */
1648
    public function testUpdateUserEmail(): void
1649
    {
1650
        $repository = $this->getRepository();
1651
        $userService = $repository->getUserService();
1652
1653
        // Create a user
1654
        $user = $this->createUserVersion1();
1655
1656
        // Check we get what we expect (and implicit warmup any kind of cache)
1657
        $users = $userService->loadUsersByEmail('[email protected]');
1658
        $this->assertCount(0, $users);
1659
1660
        // Update user with the given email address
1661
        $userUpdate = $userService->newUserUpdateStruct();
1662
        $userUpdate->email = '[email protected]';
1663
        $updatedUser = $userService->updateUser($user, $userUpdate);
1664
        $this->assertInstanceOf(User::class, $updatedUser);
1665
1666
        // Check that we can load user by email
1667
        $users = $userService->loadUsersByEmail('[email protected]');
1668
        $this->assertCount(1, $users);
1669
        $this->assertInstanceOf(User::class, $users[0]);
1670
    }
1671
1672
    /**
1673
     * Test for the updateUser() method.
1674
     *
1675
     * @return \eZ\Publish\API\Repository\Values\User\User
1676
     *
1677
     * @see     \eZ\Publish\API\Repository\UserService::updateUser()
1678
     * @depends eZ\Publish\API\Repository\Tests\UserServiceTest::testCreateUser
1679
     * @depends eZ\Publish\API\Repository\Tests\UserServiceTest::testNewUserUpdateStruct
1680
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testUpdateContent
1681
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testUpdateContentMetadata
1682
     */
1683
    public function testUpdateUserNoPassword()
1684
    {
1685
        $repository = $this->getRepository();
1686
        $signalSlotUserService = $repository->getUserService();
1687
1688
        $signalSlotUserServiceReflection = new ReflectionClass($signalSlotUserService);
1689
        $userServiceProperty = $signalSlotUserServiceReflection->getProperty('service');
1690
        $userServiceProperty->setAccessible(true);
1691
        $userService = $userServiceProperty->getValue($signalSlotUserService);
1692
1693
        $userServiceReflection = new ReflectionClass($userService);
1694
        $settingsProperty = $userServiceReflection->getProperty('settings');
1695
        $settingsProperty->setAccessible(true);
1696
        $settingsProperty->setValue(
1697
            $userService,
1698
            [
1699
                '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...
1700
            ] + $settingsProperty->getValue($userService)
1701
        );
1702
1703
        /* BEGIN: Use Case */
1704
        $user = $this->createUserVersion1();
1705
1706
        $settingsProperty->setValue(
1707
            $userService,
1708
            [
1709
                'hashType' => User::PASSWORD_HASH_PHP_DEFAULT,
1710
            ] + $settingsProperty->getValue($userService)
1711
        );
1712
1713
        // Create a new update struct instance
1714
        $userUpdate = $userService->newUserUpdateStruct();
1715
1716
        // Set new values for maxLogin, don't change password
1717
        $userUpdate->maxLogin = 43;
1718
        $userUpdate->enabled = false;
1719
1720
        // Updated the user record.
1721
        $userVersion2 = $userService->updateUser($user, $userUpdate);
1722
        /* END: Use Case */
1723
1724
        $this->assertInstanceOf(User::class, $user);
1725
1726
        $this->assertEquals(
1727
            [
1728
                'login' => $user->login,
1729
                'email' => $user->email,
1730
                'passwordHash' => $user->passwordHash,
1731
                'hashAlgorithm' => $user->hashAlgorithm,
1732
                'maxLogin' => 43,
1733
                'enabled' => false,
1734
            ],
1735
            [
1736
                'login' => $userVersion2->login,
1737
                'email' => $userVersion2->email,
1738
                'passwordHash' => $userVersion2->passwordHash,
1739
                'hashAlgorithm' => $userVersion2->hashAlgorithm,
1740
                'maxLogin' => $userVersion2->maxLogin,
1741
                'enabled' => $userVersion2->enabled,
1742
            ]
1743
        );
1744
    }
1745
1746
    /**
1747
     * Test for the updateUser() method.
1748
     *
1749
     * @param \eZ\Publish\API\Repository\Values\User\User $user
1750
     *
1751
     * @see     \eZ\Publish\API\Repository\UserService::updateUser()
1752
     * @depends eZ\Publish\API\Repository\Tests\UserServiceTest::testUpdateUser
1753
     */
1754
    public function testUpdateUserUpdatesExpectedProperties(User $user)
1755
    {
1756
        $this->assertEquals(
1757
            [
1758
                'login' => 'user',
1759
                'email' => '[email protected]',
1760
                'maxLogin' => 42,
1761
                'enabled' => false,
1762
            ],
1763
            [
1764
                'login' => $user->login,
1765
                'email' => $user->email,
1766
                'maxLogin' => $user->maxLogin,
1767
                'enabled' => $user->enabled,
1768
            ]
1769
        );
1770
    }
1771
1772
    /**
1773
     * Test for the updateUser() method.
1774
     *
1775
     * @param \eZ\Publish\API\Repository\Values\User\User $user
1776
     *
1777
     * @see     \eZ\Publish\API\Repository\UserService::updateUser()
1778
     * @depends eZ\Publish\API\Repository\Tests\UserServiceTest::testUpdateUser
1779
     */
1780
    public function testUpdateUserReturnsPublishedVersion(User $user)
1781
    {
1782
        $this->assertEquals(
1783
            APIVersionInfo::STATUS_PUBLISHED,
1784
            $user->getVersionInfo()->status
1785
        );
1786
    }
1787
1788
    /**
1789
     * Test for the updateUser() method.
1790
     *
1791
     * @see     \eZ\Publish\API\Repository\UserService::updateUser()
1792
     * @depends eZ\Publish\API\Repository\Tests\UserServiceTest::testUpdateUser
1793
     */
1794
    public function testUpdateUserWithContentMetadataUpdateStruct()
1795
    {
1796
        $repository = $this->getRepository();
1797
1798
        $userService = $repository->getUserService();
1799
1800
        /* BEGIN: Use Case */
1801
        $user = $this->createUserVersion1();
1802
1803
        // Get the ContentService implementation
1804
        $contentService = $repository->getContentService();
1805
1806
        // Create a metadata update struct and change the remote id.
1807
        $metadataUpdate = $contentService->newContentMetadataUpdateStruct();
1808
        $metadataUpdate->remoteId = '85e10037d1ac0a00aa75443ced483e08';
1809
1810
        // Create a new update struct instance
1811
        $userUpdate = $userService->newUserUpdateStruct();
1812
1813
        // Set the metadata update struct.
1814
        $userUpdate->contentMetadataUpdateStruct = $metadataUpdate;
1815
1816
        // Updated the user record.
1817
        $userVersion2 = $userService->updateUser($user, $userUpdate);
1818
1819
        // The contentInfo->remoteId will be changed now.
1820
        $remoteId = $userVersion2->contentInfo->remoteId;
1821
        /* END: Use Case */
1822
1823
        $this->assertEquals('85e10037d1ac0a00aa75443ced483e08', $remoteId);
1824
    }
1825
1826
    /**
1827
     * Test for the updateUser() method.
1828
     *
1829
     * @see     \eZ\Publish\API\Repository\UserService::updateUser()
1830
     * @depends eZ\Publish\API\Repository\Tests\UserServiceTest::testUpdateUser
1831
     */
1832
    public function testUpdateUserWithContentUpdateStruct()
1833
    {
1834
        $repository = $this->getRepository();
1835
1836
        $userService = $repository->getUserService();
1837
1838
        /* BEGIN: Use Case */
1839
        $user = $this->createUserVersion1();
1840
1841
        // Get the ContentService implementation
1842
        $contentService = $repository->getContentService();
1843
1844
        // Create a content update struct and change the remote id.
1845
        $contentUpdate = $contentService->newContentUpdateStruct();
1846
        $contentUpdate->setField('first_name', 'Hello', 'eng-US');
1847
        $contentUpdate->setField('last_name', 'World', 'eng-US');
1848
1849
        // Create a new update struct instance
1850
        $userUpdate = $userService->newUserUpdateStruct();
1851
1852
        // Set the content update struct.
1853
        $userUpdate->contentUpdateStruct = $contentUpdate;
1854
1855
        // Updated the user record.
1856
        $userVersion2 = $userService->updateUser($user, $userUpdate);
1857
1858
        $name = sprintf(
1859
            '%s %s',
1860
            $userVersion2->getFieldValue('first_name'),
1861
            $userVersion2->getFieldValue('last_name')
1862
        );
1863
        /* END: Use Case */
1864
1865
        $this->assertEquals('Hello World', $name);
1866
    }
1867
1868
    /**
1869
     * Test for the updateUser() method.
1870
     *
1871
     * @see     \eZ\Publish\API\Repository\UserService::updateUser()
1872
     * @expectedException \eZ\Publish\API\Repository\Exceptions\ContentFieldValidationException
1873
     * @depends eZ\Publish\API\Repository\Tests\UserServiceTest::testUpdateUser
1874
     */
1875
    public function testUpdateUserWhenMissingField()
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
     * @expectedException \eZ\Publish\API\Repository\Exceptions\InvalidArgumentException
1909
     * @depends eZ\Publish\API\Repository\Tests\UserServiceTest::testUpdateUser
1910
     */
1911
    public function testUpdateUserThrowsInvalidArgumentExceptionOnFieldTypeNotAccept()
1912
    {
1913
        $repository = $this->getRepository();
1914
1915
        $userService = $repository->getUserService();
1916
1917
        /* BEGIN: Use Case */
1918
        $user = $this->createUserVersion1();
1919
1920
        // Get the ContentService implementation
1921
        $contentService = $repository->getContentService();
1922
1923
        $contentUpdate = $contentService->newContentUpdateStruct();
1924
        // An object of stdClass is not valid for the field first_name
1925
        $contentUpdate->setField('first_name', new \stdClass(), 'eng-US');
1926
1927
        // Create a new update struct instance
1928
        $userUpdate = $userService->newUserUpdateStruct();
1929
1930
        // Set the content update struct.
1931
        $userUpdate->contentUpdateStruct = $contentUpdate;
1932
1933
        // This call will fail with a "InvalidArgumentException" because the
1934
        // the field "first_name" does not accept the given value.
1935
        $userService->updateUser($user, $userUpdate);
1936
1937
        /* END: Use Case */
1938
    }
1939
1940
    /**
1941
     * Test updating a user throwing UserPasswordValidationException when password doesn't follow specified rules.
1942
     *
1943
     * @expectedException \eZ\Publish\Core\Base\Exceptions\UserPasswordValidationException
1944
     * @expectedExceptionMessage 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
1945
     * @covers \eZ\Publish\API\Repository\UserService::updateUser
1946
     */
1947
    public function testUpdateUserWithWeakPasswordThrowsUserPasswordValidationException()
1948
    {
1949
        $userService = $this->getRepository()->getUserService();
1950
1951
        $user = $this->createTestUserWithPassword('H@xxxiR!_1', $this->createUserContentTypeWithStrongPassword());
1952
1953
        /* BEGIN: Use Case */
1954
        // Create a new update struct instance
1955
        $userUpdate = $userService->newUserUpdateStruct();
1956
        $userUpdate->password = 'pass';
1957
1958
        // This call will fail with a "UserPasswordValidationException" because the
1959
        // the password does not follow specified rules
1960
        $userService->updateUser($user, $userUpdate);
1961
        /* END: Use Case */
1962
    }
1963
1964
    /**
1965
     * Opposite test case for testUpdateUserWithWeakPasswordThrowsUserPasswordValidationException.
1966
     *
1967
     * @covers \eZ\Publish\API\Repository\UserService::updateUser
1968
     */
1969
    public function testUpdateUserWithStrongPassword()
1970
    {
1971
        $userService = $this->getRepository()->getUserService();
1972
1973
        $user = $this->createTestUserWithPassword('H@xxxiR!_1', $this->createUserContentTypeWithStrongPassword());
1974
1975
        /* BEGIN: Use Case */
1976
        // Create a new update struct instance
1977
        $userUpdate = $userService->newUserUpdateStruct();
1978
        $userUpdate->password = 'H@xxxiR!_2';
1979
1980
        $user = $userService->updateUser($user, $userUpdate);
1981
        /* END: Use Case */
1982
1983
        $this->assertInstanceOf(User::class, $user);
1984
    }
1985
1986
    /**
1987
     * Test for the loadUserGroupsOfUser() method.
1988
     *
1989
     * @covers  \eZ\Publish\API\Repository\UserService::loadUserGroupsOfUser
1990
     * @depends eZ\Publish\API\Repository\Tests\UserServiceTest::testCreateUser
1991
     */
1992
    public function testLoadUserGroupsOfUser()
1993
    {
1994
        $repository = $this->getRepository();
1995
1996
        $userService = $repository->getUserService();
1997
1998
        /* BEGIN: Use Case */
1999
        $user = $this->createUserVersion1();
2000
2001
        // This array will contain the "Editors" user group name
2002
        $userGroupNames = [];
2003
        foreach ($userService->loadUserGroupsOfUser($user) as $userGroup) {
2004
            $this->assertInstanceOf(UserGroup::class, $userGroup);
2005
            $userGroupNames[] = $userGroup->getFieldValue('name');
2006
        }
2007
        /* END: Use Case */
2008
2009
        $this->assertEquals(['Editors'], $userGroupNames);
2010
    }
2011
2012
    /**
2013
     * Test for the loadUsersOfUserGroup() method.
2014
     *
2015
     * @covers  \eZ\Publish\API\Repository\UserService::loadUsersOfUserGroup
2016
     * @depends eZ\Publish\API\Repository\Tests\UserServiceTest::testCreateUser
2017
     */
2018
    public function testLoadUsersOfUserGroup()
2019
    {
2020
        $repository = $this->getRepository();
2021
        $userService = $repository->getUserService();
2022
2023
        $group = $userService->loadUserGroup($this->generateId('group', 13));
2024
2025
        /* BEGIN: Use Case */
2026
        $this->createUserVersion1();
2027
2028
        $this->refreshSearch($repository);
2029
2030
        // This array will contain the email of the newly created "Editor" user
2031
        $email = [];
2032
        foreach ($userService->loadUsersOfUserGroup($group) as $user) {
2033
            $this->assertInstanceOf(User::class, $user);
2034
            $email[] = $user->email;
2035
        }
2036
        /* END: Use Case */
2037
        $this->assertEquals(['[email protected]'], $email);
2038
    }
2039
2040
    /**
2041
     * Test for the assignUserToUserGroup() method.
2042
     *
2043
     * @see     \eZ\Publish\API\Repository\UserService::assignUserToUserGroup()
2044
     * @depends eZ\Publish\API\Repository\Tests\UserServiceTest::testLoadUserGroupsOfUser
2045
     */
2046
    public function testAssignUserToUserGroup()
2047
    {
2048
        $repository = $this->getRepository();
2049
        $userService = $repository->getUserService();
2050
2051
        $administratorGroupId = $this->generateId('group', 12);
2052
        /* BEGIN: Use Case */
2053
        // $administratorGroupId is the ID of the "Administrator" group in an
2054
        // eZ Publish demo installation
2055
2056
        $user = $this->createUserVersion1();
2057
2058
        // Assign group to newly created user
2059
        $userService->assignUserToUserGroup(
2060
            $user,
2061
            $userService->loadUserGroup($administratorGroupId)
2062
        );
2063
2064
        // This array will contain "Editors" and "Administrator users"
2065
        $userGroupNames = [];
2066
        foreach ($userService->loadUserGroupsOfUser($user) as $userGroup) {
2067
            $userGroupNames[] = $userGroup->getFieldValue('name');
2068
        }
2069
        /* END: Use Case */
2070
2071
        sort($userGroupNames, SORT_STRING);
2072
2073
        $this->assertEquals(
2074
            [
2075
                'Administrator users',
2076
                'Editors',
2077
            ],
2078
            $userGroupNames
2079
        );
2080
    }
2081
2082
    /**
2083
     * Test for the assignUserToUserGroup() method.
2084
     *
2085
     * @covers  \eZ\Publish\API\Repository\UserService::assignUserToUserGroup
2086
     * @expectedException \eZ\Publish\API\Repository\Exceptions\InvalidArgumentException
2087
     * @expectedExceptionMessage Argument 'user' is invalid: user is already in the given user group
2088
     * @depends eZ\Publish\API\Repository\Tests\UserServiceTest::testAssignUserToUserGroup
2089
     */
2090
    public function testAssignUserToUserGroupThrowsInvalidArgumentException()
2091
    {
2092
        $repository = $this->getRepository();
2093
        $userService = $repository->getUserService();
2094
2095
        $editorsGroupId = $this->generateId('group', 13);
2096
        /* BEGIN: Use Case */
2097
        $user = $this->createUserVersion1();
2098
        // $editorsGroupId is the ID of the "Editors" group in an
2099
        // eZ Publish demo installation
2100
2101
        // This call will fail with an "InvalidArgumentException", because the
2102
        // user is already assigned to the "Editors" group
2103
        $userService->assignUserToUserGroup(
2104
            $user,
2105
            $userService->loadUserGroup($editorsGroupId)
2106
        );
2107
        /* END: Use Case */
2108
    }
2109
2110
    /**
2111
     * Test for the unAssignUssrFromUserGroup() method.
2112
     *
2113
     * @see     \eZ\Publish\API\Repository\UserService::unAssignUssrFromUserGroup()
2114
     * @depends eZ\Publish\API\Repository\Tests\UserServiceTest::testLoadUserGroupsOfUser
2115
     */
2116
    public function testUnAssignUserFromUserGroup()
2117
    {
2118
        $repository = $this->getRepository();
2119
        $userService = $repository->getUserService();
2120
2121
        $editorsGroupId = $this->generateId('group', 13);
2122
        $anonymousGroupId = $this->generateId('group', 42);
2123
2124
        /* BEGIN: Use Case */
2125
        // $anonymousGroupId is the ID of the "Anonymous Users" group in an eZ
2126
        // Publish demo installation
2127
2128
        $user = $this->createUserVersion1();
2129
2130
        // Assign group to newly created user
2131
        $userService->assignUserToUserGroup(
2132
            $user,
2133
            $userService->loadUserGroup($anonymousGroupId)
2134
        );
2135
2136
        // Unassign user from "Editors" group
2137
        $userService->unAssignUserFromUserGroup(
2138
            $user,
2139
            $userService->loadUserGroup($editorsGroupId)
2140
        );
2141
2142
        // This array will contain "Anonymous Users"
2143
        $userGroupNames = [];
2144
        foreach ($userService->loadUserGroupsOfUser($user) as $userGroup) {
2145
            $userGroupNames[] = $userGroup->getFieldValue('name');
2146
        }
2147
        /* END: Use Case */
2148
2149
        $this->assertEquals(['Anonymous Users'], $userGroupNames);
2150
    }
2151
2152
    /**
2153
     * Test for the unAssignUserFromUserGroup() method.
2154
     *
2155
     * @see     \eZ\Publish\API\Repository\UserService::unAssignUserFromUserGroup()
2156
     * @expectedException \eZ\Publish\API\Repository\Exceptions\InvalidArgumentException
2157
     * @depends eZ\Publish\API\Repository\Tests\UserServiceTest::testUnAssignUserFromUserGroup
2158
     */
2159
    public function testUnAssignUserFromUserGroupThrowsInvalidArgumentException()
2160
    {
2161
        $repository = $this->getRepository();
2162
        $userService = $repository->getUserService();
2163
2164
        $administratorGroupId = $this->generateId('group', 12);
2165
        /* BEGIN: Use Case */
2166
        $user = $this->createUserVersion1();
2167
        // $administratorGroupId is the ID of the "Administrator" group in an
2168
        // eZ Publish demo installation
2169
2170
        // This call will fail with an "InvalidArgumentException", because the
2171
        // user is not assigned to the "Administrator" group
2172
        $userService->unAssignUserFromUserGroup(
2173
            $user,
2174
            $userService->loadUserGroup($administratorGroupId)
2175
        );
2176
        /* END: Use Case */
2177
    }
2178
2179
    /**
2180
     * Test for the unAssignUserFromUserGroup() method removing user from the last group.
2181
     *
2182
     * @covers  \eZ\Publish\API\Repository\UserService::unAssignUserFromUserGroup
2183
     * @expectedException \eZ\Publish\API\Repository\Exceptions\BadStateException
2184
     * @expectedExceptionMessage Argument 'user' has a bad state: user only has one user group, cannot unassign from last group
2185
     * @depends eZ\Publish\API\Repository\Tests\UserServiceTest::testUnAssignUserFromUserGroup
2186
     */
2187
    public function testUnAssignUserFromUserGroupThrowsBadStateArgumentException()
2188
    {
2189
        $repository = $this->getRepository();
2190
        $userService = $repository->getUserService();
2191
2192
        $editorsGroupId = $this->generateId('group', 13);
2193
        /* BEGIN: Use Case */
2194
        $user = $this->createUserVersion1();
2195
2196
        // This call will fail with an "BadStateException", because the
2197
        // user has to be assigned to at least one group
2198
        $userService->unAssignUserFromUserGroup(
2199
            $user,
2200
            $userService->loadUserGroup($editorsGroupId)
2201
        );
2202
        /* END: Use Case */
2203
    }
2204
2205
    /**
2206
     * Test that multi-language logic for the loadUserGroup method respects prioritized language list.
2207
     *
2208
     * @covers       \eZ\Publish\API\Repository\UserService::loadUserGroup
2209
     * @dataProvider getPrioritizedLanguageList
2210
     * @param string[] $prioritizedLanguages
2211
     * @param string|null $expectedLanguageCode language code of expected translation
2212
     */
2213
    public function testLoadUserGroupWithPrioritizedLanguagesList(
2214
        array $prioritizedLanguages,
2215
        $expectedLanguageCode
2216
    ) {
2217
        $repository = $this->getRepository();
2218
        $userService = $repository->getUserService();
2219
2220
        $userGroup = $this->createMultiLanguageUserGroup();
2221
        if ($expectedLanguageCode === null) {
2222
            $expectedLanguageCode = $userGroup->contentInfo->mainLanguageCode;
2223
        }
2224
2225
        $loadedUserGroup = $userService->loadUserGroup($userGroup->id, $prioritizedLanguages);
2226
2227
        self::assertEquals(
2228
            $loadedUserGroup->getName($expectedLanguageCode),
2229
            $loadedUserGroup->getName()
2230
        );
2231
        self::assertEquals(
2232
            $loadedUserGroup->getFieldValue('description', $expectedLanguageCode),
2233
            $loadedUserGroup->getFieldValue('description')
2234
        );
2235
    }
2236
2237
    /**
2238
     * Test that multi-language logic works correctly after updating user group main language.
2239
     *
2240
     * @covers       \eZ\Publish\API\Repository\UserService::loadUserGroup
2241
     * @dataProvider getPrioritizedLanguageList
2242
     * @param string[] $prioritizedLanguages
2243
     * @param string|null $expectedLanguageCode language code of expected translation
2244
     */
2245
    public function testLoadUserGroupWithPrioritizedLanguagesListAfterMainLanguageUpdate(
2246
        array $prioritizedLanguages,
2247
        $expectedLanguageCode
2248
    ) {
2249
        $repository = $this->getRepository();
2250
        $userService = $repository->getUserService();
2251
        $contentService = $repository->getContentService();
2252
2253
        $userGroup = $this->createMultiLanguageUserGroup();
2254
2255
        $userGroupUpdateStruct = $userService->newUserGroupUpdateStruct();
2256
        $userGroupUpdateStruct->contentMetadataUpdateStruct = $contentService->newContentMetadataUpdateStruct();
2257
        $userGroupUpdateStruct->contentMetadataUpdateStruct->mainLanguageCode = 'eng-GB';
2258
        $userService->updateUserGroup($userGroup, $userGroupUpdateStruct);
2259
2260
        if ($expectedLanguageCode === null) {
2261
            $expectedLanguageCode = 'eng-GB';
2262
        }
2263
2264
        $loadedUserGroup = $userService->loadUserGroup($userGroup->id, $prioritizedLanguages);
2265
2266
        self::assertEquals(
2267
            $loadedUserGroup->getName($expectedLanguageCode),
2268
            $loadedUserGroup->getName()
2269
        );
2270
        self::assertEquals(
2271
            $loadedUserGroup->getFieldValue('description', $expectedLanguageCode),
2272
            $loadedUserGroup->getFieldValue('description')
2273
        );
2274
    }
2275
2276
    /**
2277
     * Test that multi-language logic for the loadSubUserGroups method respects prioritized language list.
2278
     *
2279
     * @covers       \eZ\Publish\API\Repository\UserService::loadSubUserGroups
2280
     * @dataProvider getPrioritizedLanguageList
2281
     * @param string[] $prioritizedLanguages
2282
     * @param string|null $expectedLanguageCode language code of expected translation
2283
     */
2284
    public function testLoadSubUserGroupsWithPrioritizedLanguagesList(
2285
        array $prioritizedLanguages,
2286
        $expectedLanguageCode
2287
    ) {
2288
        $repository = $this->getRepository();
2289
        $userService = $repository->getUserService();
2290
2291
        // create main group for subgroups
2292
        $userGroup = $this->createMultiLanguageUserGroup(4);
2293
        if ($expectedLanguageCode === null) {
2294
            $expectedLanguageCode = $userGroup->contentInfo->mainLanguageCode;
2295
        }
2296
2297
        // create subgroups
2298
        $this->createMultiLanguageUserGroup($userGroup->id);
2299
        $this->createMultiLanguageUserGroup($userGroup->id);
2300
2301
        $userGroup = $userService->loadUserGroup($userGroup->id, $prioritizedLanguages);
2302
2303
        $subUserGroups = $userService->loadSubUserGroups($userGroup, 0, 2, $prioritizedLanguages);
2304
        foreach ($subUserGroups as $subUserGroup) {
2305
            self::assertEquals(
2306
                $subUserGroup->getName($expectedLanguageCode),
2307
                $subUserGroup->getName()
2308
            );
2309
            self::assertEquals(
2310
                $subUserGroup->getFieldValue('description', $expectedLanguageCode),
2311
                $subUserGroup->getFieldValue('description')
2312
            );
2313
        }
2314
    }
2315
2316
    /**
2317
     * Test that multi-language logic for the loadUser method respects prioritized language list.
2318
     *
2319
     * @covers       \eZ\Publish\API\Repository\UserService::loadUser
2320
     * @dataProvider getPrioritizedLanguageList
2321
     * @param string[] $prioritizedLanguages
2322
     * @param string|null $expectedLanguageCode language code of expected translation
2323
     */
2324
    public function testLoadUserWithPrioritizedLanguagesList(
2325
        array $prioritizedLanguages,
2326
        $expectedLanguageCode
2327
    ) {
2328
        $repository = $this->getRepository();
2329
        $userService = $repository->getUserService();
2330
2331
        $user = $this->createMultiLanguageUser();
2332
        if ($expectedLanguageCode === null) {
2333
            $expectedLanguageCode = $user->contentInfo->mainLanguageCode;
2334
        }
2335
2336
        $loadedUser = $userService->loadUser($user->id, $prioritizedLanguages);
2337
2338
        self::assertEquals(
2339
            $loadedUser->getName($expectedLanguageCode),
2340
            $loadedUser->getName()
2341
        );
2342
2343
        foreach (['fist_name', 'last_name', 'signature'] as $fieldIdentifier) {
2344
            self::assertEquals(
2345
                $loadedUser->getFieldValue($fieldIdentifier, $expectedLanguageCode),
2346
                $loadedUser->getFieldValue($fieldIdentifier)
2347
            );
2348
        }
2349
    }
2350
2351
    /**
2352
     * Test that multi-language logic for the loadUser method works correctly after updating
2353
     * user content main language.
2354
     *
2355
     * @covers       \eZ\Publish\API\Repository\UserService::loadUserGroup
2356
     * @dataProvider getPrioritizedLanguageList
2357
     * @param string[] $prioritizedLanguages
2358
     * @param string|null $expectedLanguageCode language code of expected translation
2359
     */
2360
    public function testLoadUserWithPrioritizedLanguagesListAfterMainLanguageUpdate(
2361
        array $prioritizedLanguages,
2362
        $expectedLanguageCode
2363
    ) {
2364
        $repository = $this->getRepository();
2365
        $userService = $repository->getUserService();
2366
        $contentService = $repository->getContentService();
2367
2368
        $user = $this->createMultiLanguageUser();
2369
        // sanity check
2370
        self::assertEquals($user->contentInfo->mainLanguageCode, 'eng-US');
2371
2372
        $userUpdateStruct = $userService->newUserUpdateStruct();
2373
        $userUpdateStruct->contentMetadataUpdateStruct = $contentService->newContentMetadataUpdateStruct();
2374
        $userUpdateStruct->contentMetadataUpdateStruct->mainLanguageCode = 'eng-GB';
2375
        $userService->updateUser($user, $userUpdateStruct);
2376
        if ($expectedLanguageCode === null) {
2377
            $expectedLanguageCode = 'eng-GB';
2378
        }
2379
2380
        $loadedUser = $userService->loadUser($user->id, $prioritizedLanguages);
2381
2382
        self::assertEquals(
2383
            $loadedUser->getName($expectedLanguageCode),
2384
            $loadedUser->getName()
2385
        );
2386
2387
        foreach (['fist_name', 'last_name', 'signature'] as $fieldIdentifier) {
2388
            self::assertEquals(
2389
                $loadedUser->getFieldValue($fieldIdentifier, $expectedLanguageCode),
2390
                $loadedUser->getFieldValue($fieldIdentifier)
2391
            );
2392
        }
2393
    }
2394
2395
    /**
2396
     * Test that multi-language logic for the loadUserByLogin method respects prioritized language list.
2397
     *
2398
     * @covers       \eZ\Publish\API\Repository\UserService::loadUserByLogin
2399
     * @dataProvider getPrioritizedLanguageList
2400
     * @param string[] $prioritizedLanguages
2401
     * @param string|null $expectedLanguageCode language code of expected translation
2402
     */
2403
    public function testLoadUserByLoginWithPrioritizedLanguagesList(
2404
        array $prioritizedLanguages,
2405
        $expectedLanguageCode
2406
    ) {
2407
        $repository = $this->getRepository();
2408
        $userService = $repository->getUserService();
2409
        $user = $this->createMultiLanguageUser();
2410
2411
        // load, with prioritized languages, the newly created user
2412
        $loadedUser = $userService->loadUserByLogin($user->login, $prioritizedLanguages);
2413
        if ($expectedLanguageCode === null) {
2414
            $expectedLanguageCode = $loadedUser->contentInfo->mainLanguageCode;
2415
        }
2416
2417
        self::assertEquals(
2418
            $loadedUser->getName($expectedLanguageCode),
2419
            $loadedUser->getName()
2420
        );
2421
2422
        foreach (['first_name', 'last_name', 'signature'] as $fieldIdentifier) {
2423
            self::assertEquals(
2424
                $loadedUser->getFieldValue($fieldIdentifier, $expectedLanguageCode),
2425
                $loadedUser->getFieldValue($fieldIdentifier)
2426
            );
2427
        }
2428
    }
2429
2430
    /**
2431
     * Test that multi-language logic for the loadUserByCredentials method respects
2432
     * prioritized language list.
2433
     *
2434
     * @covers       \eZ\Publish\API\Repository\UserService::loadUserByCredentials
2435
     * @dataProvider getPrioritizedLanguageList
2436
     * @param string[] $prioritizedLanguages
2437
     * @param string|null $expectedLanguageCode language code of expected translation
2438
     */
2439
    public function testLoadUserByCredentialsWithPrioritizedLanguagesList(
2440
        array $prioritizedLanguages,
2441
        $expectedLanguageCode
2442
    ) {
2443
        $repository = $this->getRepository();
2444
        $userService = $repository->getUserService();
2445
        $user = $this->createMultiLanguageUser();
2446
2447
        // load, with prioritized languages, the newly created user
2448
        $loadedUser = $userService->loadUserByCredentials(
2449
            $user->login,
2450
            'secret',
2451
            $prioritizedLanguages
2452
        );
2453
        if ($expectedLanguageCode === null) {
2454
            $expectedLanguageCode = $loadedUser->contentInfo->mainLanguageCode;
2455
        }
2456
2457
        self::assertEquals(
2458
            $loadedUser->getName($expectedLanguageCode),
2459
            $loadedUser->getName()
2460
        );
2461
2462
        foreach (['first_name', 'last_name', 'signature'] as $fieldIdentifier) {
2463
            self::assertEquals(
2464
                $loadedUser->getFieldValue($fieldIdentifier, $expectedLanguageCode),
2465
                $loadedUser->getFieldValue($fieldIdentifier)
2466
            );
2467
        }
2468
    }
2469
2470
    /**
2471
     * Test that multi-language logic for the loadUsersByEmail method respects
2472
     * prioritized language list.
2473
     *
2474
     * @covers       \eZ\Publish\API\Repository\UserService::loadUsersByEmail
2475
     * @dataProvider getPrioritizedLanguageList
2476
     * @param string[] $prioritizedLanguages
2477
     * @param string|null $expectedLanguageCode language code of expected translation
2478
     */
2479
    public function testLoadUsersByEmailWithPrioritizedLanguagesList(
2480
        array $prioritizedLanguages,
2481
        $expectedLanguageCode
2482
    ) {
2483
        $repository = $this->getRepository();
2484
        $userService = $repository->getUserService();
2485
        $user = $this->createMultiLanguageUser();
2486
2487
        // load, with prioritized languages, users by email
2488
        $loadedUsers = $userService->loadUsersByEmail($user->email, $prioritizedLanguages);
2489
2490
        foreach ($loadedUsers as $loadedUser) {
2491
            if ($expectedLanguageCode === null) {
2492
                $expectedLanguageCode = $loadedUser->contentInfo->mainLanguageCode;
2493
            }
2494
            self::assertEquals(
2495
                $loadedUser->getName($expectedLanguageCode),
2496
                $loadedUser->getName()
2497
            );
2498
2499
            foreach (['first_name', 'last_name', 'signature'] as $fieldIdentifier) {
2500
                self::assertEquals(
2501
                    $loadedUser->getFieldValue($fieldIdentifier, $expectedLanguageCode),
2502
                    $loadedUser->getFieldValue($fieldIdentifier)
2503
                );
2504
            }
2505
        }
2506
    }
2507
2508
    /**
2509
     * Test that multi-language logic for the loadUserGroupsOfUser method respects
2510
     * prioritized language list.
2511
     *
2512
     * @covers       \eZ\Publish\API\Repository\UserService::loadUserGroupsOfUser
2513
     * @dataProvider getPrioritizedLanguageList
2514
     * @param string[] $prioritizedLanguages
2515
     * @param string|null $expectedLanguageCode language code of expected translation
2516
     */
2517
    public function testLoadUserGroupsOfUserWithPrioritizedLanguagesList(
2518
        array $prioritizedLanguages,
2519
        $expectedLanguageCode
2520
    ) {
2521
        $repository = $this->getRepository();
2522
        $userService = $repository->getUserService();
2523
        $userGroup = $this->createMultiLanguageUserGroup();
2524
        $user = $this->createMultiLanguageUser($userGroup->id);
2525
2526
        $userGroups = $userService->loadUserGroupsOfUser($user, 0, 25, $prioritizedLanguages);
2527
        foreach ($userGroups as $userGroup) {
2528
            self::assertEquals(
2529
                $userGroup->getName($expectedLanguageCode),
2530
                $userGroup->getName()
2531
            );
2532
            self::assertEquals(
2533
                $userGroup->getFieldValue('description', $expectedLanguageCode),
2534
                $userGroup->getFieldValue('description')
2535
            );
2536
        }
2537
    }
2538
2539
    /**
2540
     * Test that multi-language logic for the loadUsersOfUserGroup method respects
2541
     * prioritized language list.
2542
     *
2543
     * @covers       \eZ\Publish\API\Repository\UserService::loadUsersOfUserGroup
2544
     * @dataProvider getPrioritizedLanguageList
2545
     * @param string[] $prioritizedLanguages
2546
     * @param string|null $expectedLanguageCode language code of expected translation
2547
     */
2548
    public function testLoadUsersOfUserGroupWithPrioritizedLanguagesList(
2549
        array $prioritizedLanguages,
2550
        $expectedLanguageCode
2551
    ) {
2552
        $repository = $this->getRepository();
2553
        $userService = $repository->getUserService();
2554
2555
        // create parent user group
2556
        $userGroup = $this->createMultiLanguageUserGroup();
2557
        // add two users to the created parent user group
2558
        $this->createMultiLanguageUser($userGroup->id);
2559
        $this->createMultiLanguageUser($userGroup->id);
2560
2561
        // test loading of users via user group with prioritized languages list
2562
        $users = $userService->loadUsersOfUserGroup($userGroup, 0, 25, $prioritizedLanguages);
2563
        foreach ($users as $user) {
2564
            if ($expectedLanguageCode === null) {
2565
                $expectedLanguageCode = $user->contentInfo->mainLanguageCode;
2566
            }
2567
            self::assertEquals(
2568
                $user->getName($expectedLanguageCode),
2569
                $user->getName()
2570
            );
2571
2572
            foreach (['first_name', 'last_name', 'signature'] as $fieldIdentifier) {
2573
                self::assertEquals(
2574
                    $user->getFieldValue($fieldIdentifier, $expectedLanguageCode),
2575
                    $user->getFieldValue($fieldIdentifier)
2576
                );
2577
            }
2578
        }
2579
    }
2580
2581
    /**
2582
     * Get prioritized languages list data.
2583
     *
2584
     * Test cases using this data provider should expect the following arguments:
2585
     * <code>
2586
     *   array $prioritizedLanguagesList
2587
     *   string $expectedLanguage (if null - use main language)
2588
     * </code>
2589
     *
2590
     * @return array
2591
     */
2592
    public function getPrioritizedLanguageList()
2593
    {
2594
        return [
2595
            [[], null],
2596
            [['eng-US'], 'eng-US'],
2597
            [['eng-GB'], 'eng-GB'],
2598
            [['eng-US', 'eng-GB'], 'eng-US'],
2599
            [['eng-GB', 'eng-US'], 'eng-GB'],
2600
            // use non-existent group as the first one
2601
            [['ger-DE'], null],
2602
            [['ger-DE', 'eng-GB'], 'eng-GB'],
2603
        ];
2604
    }
2605
2606
    /**
2607
     * @param int $parentGroupId
2608
     * @return \eZ\Publish\API\Repository\Values\User\UserGroup
2609
     */
2610
    private function createMultiLanguageUserGroup($parentGroupId = 4)
2611
    {
2612
        $repository = $this->getRepository();
2613
        $userService = $repository->getUserService();
2614
2615
        // create user group with multiple translations
2616
        $parentGroupId = $this->generateId('group', $parentGroupId);
2617
        $parentGroup = $userService->loadUserGroup($parentGroupId);
2618
2619
        $userGroupCreateStruct = $userService->newUserGroupCreateStruct('eng-US');
2620
        $userGroupCreateStruct->setField('name', 'US user group', 'eng-US');
2621
        $userGroupCreateStruct->setField('name', 'GB user group', 'eng-GB');
2622
        $userGroupCreateStruct->setField('description', 'US user group description', 'eng-US');
2623
        $userGroupCreateStruct->setField('description', 'GB user group description', 'eng-GB');
2624
        $userGroupCreateStruct->alwaysAvailable = true;
2625
2626
        return $userService->createUserGroup($userGroupCreateStruct, $parentGroup);
2627
    }
2628
2629
    /**
2630
     * Create a user group fixture in a variable named <b>$userGroup</b>,.
2631
     *
2632
     * @return \eZ\Publish\API\Repository\Values\User\UserGroup
2633
     */
2634
    private function createUserGroupVersion1()
2635
    {
2636
        $repository = $this->getRepository();
2637
2638
        $mainGroupId = $this->generateId('group', 4);
2639
        /* BEGIN: Inline */
2640
        // $mainGroupId is the ID of the main "Users" group
2641
2642
        $userService = $repository->getUserService();
2643
2644
        // Load main group
2645
        $parentUserGroup = $userService->loadUserGroup($mainGroupId);
2646
2647
        // Instantiate a new create struct
2648
        $userGroupCreate = $userService->newUserGroupCreateStruct('eng-US');
2649
        $userGroupCreate->setField('name', 'Example Group');
2650
2651
        // Create the new user group
2652
        $userGroup = $userService->createUserGroup(
2653
            $userGroupCreate,
2654
            $parentUserGroup
2655
        );
2656
        /* END: Inline */
2657
2658
        return $userGroup;
2659
    }
2660
2661
    /**
2662
     * Create user with multiple translations of User Content fields.
2663
     *
2664
     * @param int $userGroupId User group ID (default 13 - Editors)
2665
     *
2666
     * @return \eZ\Publish\API\Repository\Values\User\User
2667
     */
2668
    private function createMultiLanguageUser($userGroupId = 13)
2669
    {
2670
        $repository = $this->getRepository();
2671
        $userService = $repository->getUserService();
2672
2673
        // Instantiate a create struct with mandatory properties
2674
        $randomLogin = md5(mt_rand() . time());
2675
        $userCreateStruct = $userService->newUserCreateStruct(
2676
            $randomLogin,
2677
            "{$randomLogin}@example.com",
2678
            'secret',
2679
            'eng-US'
2680
        );
2681
        $userCreateStruct->enabled = true;
2682
        $userCreateStruct->alwaysAvailable = true;
2683
2684
        // set field for each language
2685
        foreach (['eng-US', 'eng-GB'] as $languageCode) {
2686
            $userCreateStruct->setField('first_name', "{$languageCode} Example", $languageCode);
2687
            $userCreateStruct->setField('last_name', "{$languageCode} User", $languageCode);
2688
            $userCreateStruct->setField('signature', "{$languageCode} signature", $languageCode);
2689
        }
2690
2691
        // Load parent group for the user
2692
        $group = $userService->loadUserGroup($userGroupId);
2693
2694
        // Create a new user
2695
        return $userService->createUser($userCreateStruct, [$group]);
2696
    }
2697
2698
    /**
2699
     * Test for the createUser() method.
2700
     *
2701
     * @see \eZ\Publish\API\Repository\UserService::createUser()
2702
     */
2703
    public function testCreateUserInvalidPasswordHashTypeThrowsException()
2704
    {
2705
        $this->expectException(InvalidArgumentException::class);
2706
        $this->expectExceptionMessage("Argument 'type' is invalid: Password hash type '42424242' is not recognized");
2707
2708
        $repository = $this->getRepository();
2709
        $signalSlotUserService = $repository->getUserService();
2710
2711
        $signalSlotUserServiceReflection = new ReflectionClass($signalSlotUserService);
2712
        $userServiceProperty = $signalSlotUserServiceReflection->getProperty('service');
2713
        $userServiceProperty->setAccessible(true);
2714
        $userService = $userServiceProperty->getValue($signalSlotUserService);
2715
2716
        $userServiceReflection = new ReflectionClass($userService);
2717
        $settingsProperty = $userServiceReflection->getProperty('settings');
2718
        $settingsProperty->setAccessible(true);
2719
2720
        $defaultUserServiceSettings = $settingsProperty->getValue($userService);
2721
2722
        /* BEGIN: Use Case */
2723
        $settingsProperty->setValue(
2724
            $userService,
2725
            [
2726
                'hashType' => 42424242, // Non-existing hash type
2727
            ] + $settingsProperty->getValue($userService)
2728
        );
2729
2730
        try {
2731
            $this->createUserVersion1();
2732
        } catch (InvalidArgumentException $e) {
2733
            // Reset to default settings, so we don't break other tests
2734
            $settingsProperty->setValue($userService, $defaultUserServiceSettings);
2735
2736
            throw $e;
2737
        }
2738
        /* END: Use Case */
2739
2740
        // Reset to default settings, so we don't break other tests
2741
        $settingsProperty->setValue($userService, $defaultUserServiceSettings);
2742
    }
2743
2744
    /**
2745
     * Test loading User by Token.
2746
     *
2747
     * @covers \eZ\Publish\API\Repository\UserService::loadUserByToken
2748
     */
2749
    public function testLoadUserByToken()
2750
    {
2751
        $repository = $this->getRepository();
2752
        $userService = $repository->getUserService();
2753
2754
        $user = $this->createUserVersion1();
2755
2756
        $userTokenUpdateStruct = new UserTokenUpdateStruct();
2757
        $userTokenUpdateStruct->hashKey = md5('hash');
2758
        $userTokenUpdateStruct->time = new DateTime();
2759
2760
        $userService->updateUserToken($user, $userTokenUpdateStruct);
2761
2762
        $loadedUser = $userService->loadUserByToken($userTokenUpdateStruct->hashKey);
2763
        self::assertEquals($user, $loadedUser);
2764
2765
        return $userTokenUpdateStruct->hashKey;
2766
    }
2767
2768
    /**
2769
     * Test trying to load User by invalid Token.
2770
     *
2771
     * @covers \eZ\Publish\API\Repository\UserService::loadUserByToken
2772
     */
2773
    public function testLoadUserByTokenThrowsNotFoundException()
2774
    {
2775
        $this->expectException(NotFoundException::class);
2776
2777
        $repository = $this->getRepository();
2778
        $userService = $repository->getUserService();
2779
2780
        $user = $this->createUserVersion1();
2781
2782
        $userTokenUpdateStruct = new UserTokenUpdateStruct();
2783
        $userTokenUpdateStruct->hashKey = md5('hash');
2784
        $userTokenUpdateStruct->time = new DateTime();
2785
2786
        $userService->updateUserToken($user, $userTokenUpdateStruct);
2787
2788
        $userService->loadUserByToken('not_existing_token');
2789
    }
2790
2791
    /**
2792
     * Test updating User Token.
2793
     *
2794
     * @covers  \eZ\Publish\API\Repository\UserService::updateUserToken()
2795
     *
2796
     * @depends testLoadUserByToken
2797
     *
2798
     * @param string $originalUserToken
2799
     */
2800
    public function testUpdateUserToken($originalUserToken)
2801
    {
2802
        $repository = $this->getRepository(false);
2803
        $userService = $repository->getUserService();
2804
2805
        $user = $userService->loadUserByToken($originalUserToken);
2806
2807
        $userTokenUpdateStruct = new UserTokenUpdateStruct();
2808
        $userTokenUpdateStruct->hashKey = md5('my_updated_hash');
2809
        $userTokenUpdateStruct->time = new DateTime();
2810
2811
        $userService->updateUserToken($user, $userTokenUpdateStruct);
2812
2813
        $loadedUser = $userService->loadUserByToken($userTokenUpdateStruct->hashKey);
2814
        self::assertEquals($user, $loadedUser);
2815
    }
2816
2817
    /**
2818
     * Test invalidating (expiring) User Token.
2819
     *
2820
     * @covers  \eZ\Publish\API\Repository\UserService::expireUserToken()
2821
     *
2822
     * @depends testLoadUserByToken
2823
     *
2824
     * @param string $userToken
2825
     */
2826
    public function testExpireUserToken($userToken)
2827
    {
2828
        $this->expectException(NotFoundException::class);
2829
2830
        $repository = $this->getRepository(false);
2831
        $userService = $repository->getUserService();
2832
2833
        // sanity check
2834
        $userService->loadUserByToken($userToken);
2835
2836
        $userService->expireUserToken($userToken);
2837
2838
        // should throw NotFoundException now
2839
        $userService->loadUserByToken($userToken);
2840
    }
2841
2842
    /**
2843
     * @covers \eZ\Publish\API\Repository\UserService::validatePassword()
2844
     */
2845
    public function testValidatePasswordWithDefaultContext()
2846
    {
2847
        $userService = $this->getRepository()->getUserService();
2848
2849
        /* BEGIN: Use Case */
2850
        $errors = $userService->validatePassword('pass');
2851
        /* END: Use Case */
2852
2853
        $this->assertEmpty($errors);
2854
    }
2855
2856
    /**
2857
     * @covers       \eZ\Publish\API\Repository\UserService::validatePassword()
2858
     * @dataProvider dataProviderForValidatePassword
2859
     */
2860
    public function testValidatePassword(string $password, array $expectedErrorr)
2861
    {
2862
        $userService = $this->getRepository()->getUserService();
2863
        $contentType = $this->createUserContentTypeWithStrongPassword();
2864
2865
        /* BEGIN: Use Case */
2866
        $context = new PasswordValidationContext([
2867
            'contentType' => $contentType,
2868
        ]);
2869
2870
        $actualErrors = $userService->validatePassword($password, $context);
2871
        /* END: Use Case */
2872
2873
        $this->assertEquals($expectedErrorr, $actualErrors);
2874
    }
2875
2876
    /**
2877
     * Data provider for testValidatePassword.
2878
     *
2879
     * @return array
2880
     */
2881
    public function dataProviderForValidatePassword(): array
2882
    {
2883
        return [
2884
            [
2885
                'pass',
2886
                [
2887
                    new ValidationError('User password must be at least %length% characters long', null, [
2888
                        '%length%' => 8,
2889
                    ], 'password'),
2890
                    new ValidationError('User password must include at least one upper case letter', null, [], 'password'),
2891
                    new ValidationError('User password must include at least one number', null, [], 'password'),
2892
                    new ValidationError('User password must include at least one special character', null, [], 'password'),
2893
                ],
2894
            ],
2895
            [
2896
                'H@xxxi0R!!!',
2897
                [],
2898
            ],
2899
        ];
2900
    }
2901
2902
    public function testIsPasswordExpired(): void
2903
    {
2904
        $passwordExpireAfter = 30;
2905
2906
        $userService = $this->getRepository()->getUserService();
2907
        $contentType = $this->createUserContentTypeWithPasswordExpirationDate($passwordExpireAfter);
2908
2909
        $user = $this->createTestUser($contentType);
2910
2911
        /* BEGIN: Use Case */
2912
        $isPasswordExpired = $userService->isPasswordExpired($user);
2913
        /* END: Use Case */
2914
2915
        $this->assertFalse($isPasswordExpired);
2916
    }
2917
2918
    public function testIsPasswordExpiredIfExpirationIsDisabled(): void
2919
    {
2920
        $userService = $this->getRepository()->getUserService();
2921
        $contentType = $this->createUserContentTypeWithPasswordExpirationDate(null, null);
2922
2923
        $user = $this->createTestUser($contentType);
2924
2925
        /* BEGIN: Use Case */
2926
        $isPasswordExpired = $userService->isPasswordExpired($user);
2927
        /* END: Use Case */
2928
2929
        $this->assertFalse($isPasswordExpired);
2930
    }
2931
2932
    public function testGetPasswordExpirationDate(): void
2933
    {
2934
        $passwordExpireAfter = 30;
2935
2936
        $userService = $this->getRepository()->getUserService();
2937
        $contentType = $this->createUserContentTypeWithPasswordExpirationDate($passwordExpireAfter);
2938
2939
        $user = $this->createTestUser($contentType);
2940
2941
        /* BEGIN: Use Case */
2942
        $passwordExpirationDate = $userService->getPasswordExpirationDate($user);
2943
        /* END: Use Case */
2944
2945
        $passwordUpdatedAt = $user->passwordUpdatedAt;
2946
        if ($passwordUpdatedAt instanceof DateTimeImmutable) {
2947
            $passwordUpdatedAt = DateTime::createFromImmutable($passwordUpdatedAt);
2948
        }
2949
2950
        $expectedPasswordExpirationDate = $passwordUpdatedAt->add(
2951
            new DateInterval(sprintf('P%dD', $passwordExpireAfter))
2952
        );
2953
2954
        $this->assertEquals($expectedPasswordExpirationDate, $passwordExpirationDate);
2955
    }
2956
2957
    public function testGetPasswordExpirationDateIfExpirationIsDisabled(): void
2958
    {
2959
        $userService = $this->getRepository()->getUserService();
2960
        $contentType = $this->createUserContentTypeWithPasswordExpirationDate(null, null);
2961
2962
        $user = $this->createTestUser($contentType);
2963
2964
        /* BEGIN: Use Case */
2965
        $passwordExpirationDate = $userService->getPasswordExpirationDate($user);
2966
        /* END: Use Case */
2967
2968
        $this->assertNull($passwordExpirationDate);
2969
    }
2970
2971
    public function testGetPasswordExpirationWarningDate(): void
2972
    {
2973
        $passwordExpireAfter = 30;
2974
        $passwordExpirationWarningBefore = 14;
2975
2976
        $userService = $this->getRepository()->getUserService();
2977
        $contentType = $this->createUserContentTypeWithPasswordExpirationDate(
2978
            $passwordExpireAfter,
2979
            $passwordExpirationWarningBefore
2980
        );
2981
2982
        $user = $this->createTestUser($contentType);
2983
2984
        /* BEGIN: Use Case */
2985
        $passwordExpirationWarningDate = $userService->getPasswordExpirationWarningDate($user);
2986
        /* END: Use Case */
2987
2988
        $passwordUpdatedAt = $user->passwordUpdatedAt;
2989
        if ($passwordUpdatedAt instanceof DateTimeImmutable) {
2990
            $passwordUpdatedAt = DateTime::createFromImmutable($passwordUpdatedAt);
2991
        }
2992
2993
        $expectedPasswordExpirationWarningDate = $passwordUpdatedAt->add(
2994
            new DateInterval(sprintf('P%dD', $passwordExpireAfter - $passwordExpirationWarningBefore))
2995
        );
2996
2997
        $this->assertEquals($expectedPasswordExpirationWarningDate, $passwordExpirationWarningDate);
2998
    }
2999
3000
    public function testGetPasswordExpirationWarningDateIfExpirationIsDisabled(): void
3001
    {
3002
        $userService = $this->getRepository()->getUserService();
3003
        $contentType = $this->createUserContentTypeWithPasswordExpirationDate(null, null);
3004
3005
        $user = $this->createTestUser($contentType);
3006
3007
        /* BEGIN: Use Case */
3008
        $passwordExpirationWarningDate = $userService->getPasswordExpirationWarningDate($user);
3009
        /* END: Use Case */
3010
3011
        $this->assertNull($passwordExpirationWarningDate);
3012
    }
3013
3014
    public function testGetPasswordExpirationWarningDateIfExpirationWarningIsDisabled(): void
3015
    {
3016
        $userService = $this->getRepository()->getUserService();
3017
        $contentType = $this->createUserContentTypeWithPasswordExpirationDate(30, null);
3018
3019
        $user = $this->createTestUser($contentType);
3020
3021
        /* BEGIN: Use Case */
3022
        $passwordExpirationWarningDate = $userService->getPasswordExpirationWarningDate($user);
3023
        /* END: Use Case */
3024
3025
        $this->assertNull($passwordExpirationWarningDate);
3026
    }
3027
3028
    public function createTestUser(ContentType $contentType): User
3029
    {
3030
        return $this->createTestUserWithPassword(self::EXAMPLE_PASSWORD, $contentType);
3031
    }
3032
3033
    /**
3034
     * Creates a user with given password.
3035
     *
3036
     * @param string $password
3037
     * @param \eZ\Publish\API\Repository\Values\ContentType\ContentType $contentType
3038
     *
3039
     * @return \eZ\Publish\API\Repository\Values\User\User
3040
     */
3041
    private function createTestUserWithPassword(string $password, ContentType $contentType): User
3042
    {
3043
        $userService = $this->getRepository()->getUserService();
3044
        // ID of the "Editors" user group in an eZ Publish demo installation
3045
        $editorsGroupId = 13;
3046
3047
        // Instantiate a create struct with mandatory properties
3048
        $userCreate = $userService->newUserCreateStruct(
3049
            'johndoe',
3050
            '[email protected]',
3051
            $password,
3052
            'eng-US',
3053
            $contentType
3054
        );
3055
        $userCreate->enabled = true;
3056
        $userCreate->setField('first_name', 'John');
3057
        $userCreate->setField('last_name', 'Doe');
3058
3059
        return $userService->createUser($userCreate, [
3060
            $userService->loadUserGroup($editorsGroupId),
3061
        ]);
3062
    }
3063
3064
    /**
3065
     * Creates the User Content Type with password constraints.
3066
     *
3067
     * @return \eZ\Publish\API\Repository\Values\ContentType\ContentType
3068
     */
3069
    private function createUserContentTypeWithStrongPassword(): ContentType
3070
    {
3071
        return $this->createUserContentTypeWithAccountSettings('user-with-strong-password', null, [
3072
            'PasswordValueValidator' => [
3073
                'requireAtLeastOneUpperCaseCharacter' => 1,
3074
                'requireAtLeastOneLowerCaseCharacter' => 1,
3075
                'requireAtLeastOneNumericCharacter' => 1,
3076
                'requireAtLeastOneNonAlphanumericCharacter' => 1,
3077
                'minLength' => 8,
3078
            ],
3079
        ]);
3080
    }
3081
3082
    private function createUserContentTypeWithPasswordExpirationDate(
3083
        ?int $passwordExpireAfter = 30,
3084
        ?int $passwordExpirationWarningBefore = 14
3085
    ): ContentType {
3086
        return $this->createUserContentTypeWithAccountSettings('password-expiration', [
3087
            'PasswordExpireAfter' => $passwordExpireAfter,
3088
            'PasswordWarnBefore' => $passwordExpirationWarningBefore,
3089
        ]);
3090
    }
3091
3092
    private function createUserContentTypeWithAccountSettings(
3093
        string $identifier,
3094
        ?array $fieldSetting = null,
3095
        ?array $validatorConfiguration = null
3096
    ): ContentType {
3097
        $repository = $this->getRepository();
3098
3099
        $contentTypeService = $repository->getContentTypeService();
3100
3101
        $typeCreate = $contentTypeService->newContentTypeCreateStruct($identifier);
3102
        $typeCreate->mainLanguageCode = 'eng-GB';
3103
        $typeCreate->urlAliasSchema = 'url|scheme';
3104
        $typeCreate->nameSchema = 'name|scheme';
3105
        $typeCreate->names = [
3106
            'eng-GB' => 'User: ' . $identifier,
3107
        ];
3108
        $typeCreate->descriptions = [
3109
            'eng-GB' => '',
3110
        ];
3111
        $typeCreate->creatorId = $this->generateId('user', $repository->getPermissionResolver()->getCurrentUserReference()->getUserId());
3112
        $typeCreate->creationDate = $this->createDateTime();
3113
3114
        $firstNameFieldCreate = $contentTypeService->newFieldDefinitionCreateStruct('first_name', 'ezstring');
3115
        $firstNameFieldCreate->names = [
3116
            'eng-GB' => 'First name',
3117
        ];
3118
        $firstNameFieldCreate->descriptions = [
3119
            'eng-GB' => '',
3120
        ];
3121
        $firstNameFieldCreate->fieldGroup = 'default';
3122
        $firstNameFieldCreate->position = 1;
3123
        $firstNameFieldCreate->isTranslatable = false;
3124
        $firstNameFieldCreate->isRequired = true;
3125
        $firstNameFieldCreate->isInfoCollector = false;
3126
        $firstNameFieldCreate->validatorConfiguration = [
3127
            'StringLengthValidator' => [
3128
                'minStringLength' => 0,
3129
                'maxStringLength' => 0,
3130
            ],
3131
        ];
3132
        $firstNameFieldCreate->fieldSettings = [];
3133
        $firstNameFieldCreate->isSearchable = true;
3134
        $firstNameFieldCreate->defaultValue = '';
3135
3136
        $typeCreate->addFieldDefinition($firstNameFieldCreate);
3137
3138
        $lastNameFieldCreate = $contentTypeService->newFieldDefinitionCreateStruct('last_name', 'ezstring');
3139
        $lastNameFieldCreate->names = [
3140
            'eng-GB' => 'Last name',
3141
        ];
3142
        $lastNameFieldCreate->descriptions = [
3143
            'eng-GB' => '',
3144
        ];
3145
        $lastNameFieldCreate->fieldGroup = 'default';
3146
        $lastNameFieldCreate->position = 2;
3147
        $lastNameFieldCreate->isTranslatable = false;
3148
        $lastNameFieldCreate->isRequired = true;
3149
        $lastNameFieldCreate->isInfoCollector = false;
3150
        $lastNameFieldCreate->validatorConfiguration = [
3151
            'StringLengthValidator' => [
3152
                'minStringLength' => 0,
3153
                'maxStringLength' => 0,
3154
            ],
3155
        ];
3156
        $lastNameFieldCreate->fieldSettings = [];
3157
        $lastNameFieldCreate->isSearchable = true;
3158
        $lastNameFieldCreate->defaultValue = '';
3159
3160
        $typeCreate->addFieldDefinition($lastNameFieldCreate);
3161
3162
        $accountFieldCreateStruct = $contentTypeService->newFieldDefinitionCreateStruct('account', 'ezuser');
3163
        $accountFieldCreateStruct->names = [
3164
            'eng-GB' => 'User account',
3165
        ];
3166
        $accountFieldCreateStruct->descriptions = [
3167
            'eng-GB' => '',
3168
        ];
3169
        $accountFieldCreateStruct->fieldGroup = 'default';
3170
        $accountFieldCreateStruct->position = 3;
3171
        $accountFieldCreateStruct->isTranslatable = false;
3172
        $accountFieldCreateStruct->isRequired = true;
3173
        $accountFieldCreateStruct->isInfoCollector = false;
3174
        $accountFieldCreateStruct->validatorConfiguration = $validatorConfiguration;
3175
        $accountFieldCreateStruct->fieldSettings = $fieldSetting;
3176
        $accountFieldCreateStruct->isSearchable = false;
3177
        $accountFieldCreateStruct->defaultValue = null;
3178
3179
        $typeCreate->addFieldDefinition($accountFieldCreateStruct);
3180
3181
        $contentTypeDraft = $contentTypeService->createContentType($typeCreate, [
3182
            $contentTypeService->loadContentTypeGroupByIdentifier('Users'),
3183
        ]);
3184
        $contentTypeService->publishContentTypeDraft($contentTypeDraft);
3185
3186
        return $contentTypeService->loadContentTypeByIdentifier($identifier);
3187
    }
3188
}
3189