Completed
Push — ezp_30981_content_info_proxy ( a78a98...0757d2 )
by
unknown
15:21
created

UserServiceTest::testUpdateUserNoPassword()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 40

Duplication

Lines 0
Ratio 0 %

Importance

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