Completed
Push — ezp_30797 ( b39740...a92ef0 )
by
unknown
17:49
created

testGetPasswordInfoIfExpirationWarningIsDisabled()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 22

Duplication

Lines 0
Ratio 0 %

Importance

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