Completed
Push — symfony5 ( 074008...b11eb2 )
by
unknown
267:19 queued 255:17
created

testLoadUserByCredentialsThrowsInvalidArgumentValueForEmptyLogin()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 16

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
nc 1
nop 0
dl 0
loc 16
rs 9.7333
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);
0 ignored issues
show
Deprecated Code introduced by
The method eZ\Publish\API\Repositor...vice::loadUserByLogin() has been deprecated with message: since eZ Platform 2.5, will be dropped in the next major version as authentication may depend on various user providers. Use UserService::checkUserCredentials() instead.

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

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

Loading history...
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
     * @see \eZ\Publish\API\Repository\UserService::checkUserCredentials()
1256
     * @depends \eZ\Publish\API\Repository\Tests\UserServiceTest::testCreateUser
1257
     */
1258
    public function testCheckUserCredentialsValid(): void
1259
    {
1260
        $repository = $this->getRepository();
1261
1262
        $userService = $repository->getUserService();
1263
1264
        /* BEGIN: Use Case */
1265
        $user = $this->createUserVersion1();
1266
1267
        // Load the newly created user credentials
1268
        $credentialsValid = $userService->loadUserByCredentials($user, 'secret');
0 ignored issues
show
Bug introduced by
The method loadUserByCredentials() does not exist on eZ\Publish\API\Repository\UserService. Did you maybe mean loadUser()?

This check marks calls to methods that do not seem to exist on an object.

This is most likely the result of a method being renamed without all references to it being renamed likewise.

Loading history...
1269
        /* END: Use Case */
1270
1271
        $this->assertTrue($credentialsValid);
1272
    }
1273
1274
    /**
1275
     * @see \eZ\Publish\API\Repository\UserService::checkUserCredentials()
1276
     * @depends \eZ\Publish\API\Repository\Tests\UserServiceTest::testCreateUser
1277
     */
1278
    public function testCheckUserCredentialsInvalid(): void
1279
    {
1280
        $repository = $this->getRepository();
1281
1282
        $userService = $repository->getUserService();
1283
1284
        /* BEGIN: Use Case */
1285
        $user = $this->createUserVersion1();
1286
1287
        // Load the newly created user credentials
1288
        $credentialsValid = $userService->loadUserByCredentials($user, '1234');
0 ignored issues
show
Bug introduced by
The method loadUserByCredentials() does not exist on eZ\Publish\API\Repository\UserService. Did you maybe mean loadUser()?

This check marks calls to methods that do not seem to exist on an object.

This is most likely the result of a method being renamed without all references to it being renamed likewise.

Loading history...
1289
        /* END: Use Case */
1290
1291
        $this->assertFalse($credentialsValid);
1292
    }
1293
1294
    /**
1295
     * Test for the loadUserByLogin() method.
1296
     *
1297
     * @see \eZ\Publish\API\Repository\UserService::loadUserByLogin()
1298
     * @depends eZ\Publish\API\Repository\Tests\UserServiceTest::testCreateUser
1299
     */
1300
    public function testLoadUserByLogin()
1301
    {
1302
        $repository = $this->getRepository();
1303
1304
        $userService = $repository->getUserService();
1305
1306
        /* BEGIN: Use Case */
1307
        $user = $this->createUserVersion1('User');
1308
1309
        // Load the newly created user
1310
        $userReloaded = $userService->loadUserByLogin('User');
0 ignored issues
show
Deprecated Code introduced by
The method eZ\Publish\API\Repositor...vice::loadUserByLogin() has been deprecated with message: since eZ Platform 2.5, will be dropped in the next major version as authentication may depend on various user providers. Use UserService::checkUserCredentials() instead.

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

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

Loading history...
1311
        /* END: Use Case */
1312
1313
        $this->assertPropertiesCorrect(
1314
            [
1315
                'login' => $user->login,
1316
                'email' => $user->email,
1317
                'passwordHash' => $user->passwordHash,
1318
                'hashAlgorithm' => $user->hashAlgorithm,
1319
                'enabled' => $user->enabled,
1320
                'maxLogin' => $user->maxLogin,
1321
                'id' => $user->id,
1322
                'contentInfo' => $user->contentInfo,
1323
                'versionInfo' => $user->versionInfo,
1324
                'fields' => $user->fields,
1325
            ],
1326
            $userReloaded
1327
        );
1328
    }
1329
1330
    /**
1331
     * Test for the loadUserByLogin() method.
1332
     *
1333
     * @see \eZ\Publish\API\Repository\UserService::loadUserByLogin()
1334
     * @depends eZ\Publish\API\Repository\Tests\UserServiceTest::testLoadUserByLogin
1335
     */
1336
    public function testLoadUserByLoginThrowsNotFoundExceptionForUnknownLogin()
1337
    {
1338
        $this->expectException(\eZ\Publish\API\Repository\Exceptions\NotFoundException::class);
1339
1340
        $repository = $this->getRepository();
1341
1342
        $userService = $repository->getUserService();
1343
1344
        /* BEGIN: Use Case */
1345
        $this->createUserVersion1();
1346
1347
        // This call will fail with a "NotFoundException", because the given
1348
        // login/password combination does not exist.
1349
        $userService->loadUserByLogin('user42');
0 ignored issues
show
Deprecated Code introduced by
The method eZ\Publish\API\Repositor...vice::loadUserByLogin() has been deprecated with message: since eZ Platform 2.5, will be dropped in the next major version as authentication may depend on various user providers. Use UserService::checkUserCredentials() instead.

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

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

Loading history...
1350
        /* END: Use Case */
1351
    }
1352
1353
    /**
1354
     * Test for the loadUserByLogin() method.
1355
     *
1356
     * @see \eZ\Publish\API\Repository\UserService::loadUserByLogin()
1357
     * @depends eZ\Publish\API\Repository\Tests\UserServiceTest::testLoadUserByLogin
1358
     */
1359
    public function testLoadUserByLoginWorksForLoginWithWrongCase()
1360
    {
1361
        $repository = $this->getRepository();
1362
1363
        $userService = $repository->getUserService();
1364
1365
        /* BEGIN: Use Case */
1366
        $user = $this->createUserVersion1();
1367
1368
        // Lookup by user login should ignore casing
1369
        $userReloaded = $userService->loadUserByLogin('USER');
0 ignored issues
show
Deprecated Code introduced by
The method eZ\Publish\API\Repositor...vice::loadUserByLogin() has been deprecated with message: since eZ Platform 2.5, will be dropped in the next major version as authentication may depend on various user providers. Use UserService::checkUserCredentials() instead.

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

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

Loading history...
1370
        /* END: Use Case */
1371
1372
        $this->assertPropertiesCorrect(
1373
            [
1374
                'login' => $user->login,
1375
                'email' => $user->email,
1376
                'passwordHash' => $user->passwordHash,
1377
                'hashAlgorithm' => $user->hashAlgorithm,
1378
                'enabled' => $user->enabled,
1379
                'maxLogin' => $user->maxLogin,
1380
                'id' => $user->id,
1381
                'contentInfo' => $user->contentInfo,
1382
                'versionInfo' => $user->versionInfo,
1383
                'fields' => $user->fields,
1384
            ],
1385
            $userReloaded
1386
        );
1387
    }
1388
1389
    /**
1390
     * Test for the loadUserByLogin() method.
1391
     *
1392
     * In some cases people use email as login name, make sure system works as exepcted when asking for user by email.
1393
     *
1394
     * @see \eZ\Publish\API\Repository\UserService::loadUserByLogin()
1395
     * @depends eZ\Publish\API\Repository\Tests\UserServiceTest::testLoadUserByLogin
1396
     */
1397
    public function testLoadUserByLoginThrowsNotFoundExceptionForUnknownLoginByEmail()
1398
    {
1399
        $this->expectException(\eZ\Publish\API\Repository\Exceptions\NotFoundException::class);
1400
1401
        $repository = $this->getRepository();
1402
1403
        $userService = $repository->getUserService();
1404
1405
        /* BEGIN: Use Case */
1406
        $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...
1407
1408
        // Lookup by user login by email should behave as normal
1409
        $userService->loadUserByLogin('[email protected]');
0 ignored issues
show
Deprecated Code introduced by
The method eZ\Publish\API\Repositor...vice::loadUserByLogin() has been deprecated with message: since eZ Platform 2.5, will be dropped in the next major version as authentication may depend on various user providers. Use UserService::checkUserCredentials() instead.

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

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

Loading history...
1410
        /* END: Use Case */
1411
    }
1412
1413
    /**
1414
     * Test for the loadUsersByEmail() method.
1415
     *
1416
     * @see \eZ\Publish\API\Repository\UserService::loadUsersByEmail()
1417
     * @depends eZ\Publish\API\Repository\Tests\UserServiceTest::testCreateUser
1418
     */
1419
    public function testLoadUserByEmail()
1420
    {
1421
        $repository = $this->getRepository();
1422
1423
        $userService = $repository->getUserService();
1424
1425
        /* BEGIN: Use Case */
1426
        $user = $this->createUserVersion1();
1427
1428
        // Load the newly created user
1429
        $usersReloaded = $userService->loadUsersByEmail('[email protected]', Language::ALL);
1430
        /* END: Use Case */
1431
1432
        $this->assertEquals([$user], $usersReloaded);
1433
    }
1434
1435
    /**
1436
     * Test for the loadUsersByEmail() method.
1437
     *
1438
     * @see \eZ\Publish\API\Repository\UserService::loadUsersByEmail()
1439
     * @depends eZ\Publish\API\Repository\Tests\UserServiceTest::testLoadUserByEmail
1440
     */
1441
    public function testLoadUserByEmailReturnsEmptyInUnknownEmail()
1442
    {
1443
        $repository = $this->getRepository();
1444
1445
        $userService = $repository->getUserService();
1446
1447
        /* BEGIN: Use Case */
1448
        $this->createUserVersion1();
1449
1450
        // This call will return empty array, because the given
1451
        // login/password combination does not exist.
1452
        $emptyUserList = $userService->loadUsersByEmail('[email protected]');
1453
        /* END: Use Case */
1454
1455
        $this->assertEquals([], $emptyUserList);
1456
    }
1457
1458
    /**
1459
     * Test for the deleteUser() method.
1460
     *
1461
     * @see \eZ\Publish\API\Repository\UserService::deleteUser()
1462
     * @depends eZ\Publish\API\Repository\Tests\UserServiceTest::testCreateUser
1463
     * @depends eZ\Publish\API\Repository\Tests\UserServiceTest::testLoadUser
1464
     */
1465
    public function testDeleteUser()
1466
    {
1467
        $this->expectException(\eZ\Publish\API\Repository\Exceptions\NotFoundException::class);
1468
1469
        $repository = $this->getRepository();
1470
1471
        $userService = $repository->getUserService();
1472
1473
        /* BEGIN: Use Case */
1474
        $user = $this->createUserVersion1();
1475
1476
        // Delete the currently created user
1477
        $userService->deleteUser($user);
1478
        /* END: Use Case */
1479
1480
        // We use the NotFoundException here to verify that the user not exists
1481
        $userService->loadUser($user->id);
1482
    }
1483
1484
    /**
1485
     * Test for the deleteUser() method.
1486
     *
1487
     * @covers \eZ\Publish\API\Repository\UserService::deleteUser()
1488
     * @depends eZ\Publish\API\Repository\Tests\UserServiceTest::testCreateUser
1489
     * @depends eZ\Publish\API\Repository\Tests\UserServiceTest::testLoadUser
1490
     */
1491
    public function testDeleteUserDeletesRelatedBookmarks()
1492
    {
1493
        $repository = $this->getRepository();
1494
1495
        $userService = $repository->getUserService();
1496
        $locationService = $repository->getLocationService();
1497
        $bookmarkService = $repository->getBookmarkService();
1498
        /* BEGIN: Use Case */
1499
        $admin = $repository->getPermissionResolver()->getCurrentUserReference();
1500
1501
        $user = $this->createUserVersion1();
1502
1503
        $repository->getPermissionResolver()->setCurrentUserReference($user);
1504
1505
        $bookmarkService->createBookmark(
1506
            $locationService->loadLocation($this->generateId('location', 43))
1507
        );
1508
1509
        $repository->getPermissionResolver()->setCurrentUserReference($admin);
1510
        // Delete the currently created user
1511
        $userService->deleteUser($user);
1512
1513
        $repository->getPermissionResolver()->setCurrentUserReference($user);
1514
        /* END: Use Case */
1515
1516
        $this->assertEquals(0, $bookmarkService->loadBookmarks(0, 9999)->totalCount);
1517
    }
1518
1519
    /**
1520
     * Test for the newUserUpdateStruct() method.
1521
     *
1522
     * @see \eZ\Publish\API\Repository\UserService::newUserUpdateStruct()
1523
     */
1524
    public function testNewUserUpdateStruct()
1525
    {
1526
        $repository = $this->getRepository();
1527
1528
        /* BEGIN: Use Case */
1529
        $userService = $repository->getUserService();
1530
1531
        // Create a new update struct instance
1532
        $userUpdate = $userService->newUserUpdateStruct();
1533
        /* END: Use Case */
1534
1535
        $this->assertInstanceOf(
1536
            UserUpdateStruct::class,
1537
            $userUpdate
1538
        );
1539
1540
        $this->assertNull($userUpdate->contentUpdateStruct);
1541
        $this->assertNull($userUpdate->contentMetadataUpdateStruct);
1542
1543
        $this->assertPropertiesCorrect(
1544
            [
1545
                'email' => null,
1546
                'password' => null,
1547
                'enabled' => null,
1548
                'maxLogin' => null,
1549
            ],
1550
            $userUpdate
1551
        );
1552
    }
1553
1554
    /**
1555
     * Test for the updateUser() method.
1556
     *
1557
     * @return \eZ\Publish\API\Repository\Values\User\User
1558
     *
1559
     * @see \eZ\Publish\API\Repository\UserService::updateUser()
1560
     * @depends eZ\Publish\API\Repository\Tests\UserServiceTest::testCreateUser
1561
     * @depends eZ\Publish\API\Repository\Tests\UserServiceTest::testNewUserUpdateStruct
1562
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testUpdateContent
1563
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testUpdateContentMetadata
1564
     */
1565
    public function testUpdateUser()
1566
    {
1567
        $repository = $this->getRepository();
1568
1569
        $userService = $repository->getUserService();
1570
1571
        /* BEGIN: Use Case */
1572
        $user = $this->createUserVersion1();
1573
1574
        // Create a new update struct instance
1575
        $userUpdate = $userService->newUserUpdateStruct();
1576
1577
        // Set new values for password and maxLogin
1578
        $userUpdate->password = 'my-new-password';
1579
        $userUpdate->maxLogin = 42;
1580
        $userUpdate->enabled = false;
1581
1582
        // Updated the user record.
1583
        $userVersion2 = $userService->updateUser($user, $userUpdate);
1584
        /* END: Use Case */
1585
1586
        $this->assertInstanceOf(User::class, $userVersion2);
1587
1588
        return $userVersion2;
1589
    }
1590
1591
    /**
1592
     * Test for the updateUser() and loadUsersByEmail() method on change to email.
1593
     */
1594
    public function testUpdateUserEmail(): void
1595
    {
1596
        $repository = $this->getRepository();
1597
        $userService = $repository->getUserService();
1598
1599
        // Create a user
1600
        $user = $this->createUserVersion1();
1601
1602
        // Check we get what we expect (and implicit warmup any kind of cache)
1603
        $users = $userService->loadUsersByEmail('[email protected]');
1604
        $this->assertCount(0, $users);
1605
1606
        // Update user with the given email address
1607
        $userUpdate = $userService->newUserUpdateStruct();
1608
        $userUpdate->email = '[email protected]';
1609
        $updatedUser = $userService->updateUser($user, $userUpdate);
1610
        $this->assertInstanceOf(User::class, $updatedUser);
1611
1612
        // Check that we can load user by email
1613
        $users = $userService->loadUsersByEmail('[email protected]');
1614
        $this->assertCount(1, $users);
1615
        $this->assertInstanceOf(User::class, $users[0]);
1616
    }
1617
1618
    /**
1619
     * Test for the updateUser() method.
1620
     *
1621
     * @return \eZ\Publish\API\Repository\Values\User\User
1622
     *
1623
     * @see \eZ\Publish\API\Repository\UserService::updateUser()
1624
     * @depends eZ\Publish\API\Repository\Tests\UserServiceTest::testCreateUser
1625
     * @depends eZ\Publish\API\Repository\Tests\UserServiceTest::testNewUserUpdateStruct
1626
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testUpdateContent
1627
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testUpdateContentMetadata
1628
     */
1629
    public function testUpdateUserNoPassword()
1630
    {
1631
        $repository = $this->getRepository();
1632
        $userService = $repository->getUserService();
1633
1634
        /* BEGIN: Use Case */
1635
        $user = $this->createUserVersion1();
1636
1637
        // Create a new update struct instance
1638
        $userUpdate = $userService->newUserUpdateStruct();
1639
1640
        // Set new values for maxLogin, don't change password
1641
        $userUpdate->maxLogin = 43;
1642
        $userUpdate->enabled = false;
1643
1644
        // Updated the user record.
1645
        $userVersion2 = $userService->updateUser($user, $userUpdate);
1646
        /* END: Use Case */
1647
1648
        $this->assertInstanceOf(User::class, $user);
1649
1650
        $this->assertEquals(
1651
            [
1652
                'login' => $user->login,
1653
                'email' => $user->email,
1654
                'passwordHash' => $user->passwordHash,
1655
                'hashAlgorithm' => $user->hashAlgorithm,
1656
                'maxLogin' => 43,
1657
                'enabled' => false,
1658
            ],
1659
            [
1660
                'login' => $userVersion2->login,
1661
                'email' => $userVersion2->email,
1662
                'passwordHash' => $userVersion2->passwordHash,
1663
                'hashAlgorithm' => $userVersion2->hashAlgorithm,
1664
                'maxLogin' => $userVersion2->maxLogin,
1665
                'enabled' => $userVersion2->enabled,
1666
            ]
1667
        );
1668
    }
1669
1670
    /**
1671
     * Test for the updateUser() method.
1672
     *
1673
     * @param \eZ\Publish\API\Repository\Values\User\User $user
1674
     *
1675
     * @see \eZ\Publish\API\Repository\UserService::updateUser()
1676
     * @depends eZ\Publish\API\Repository\Tests\UserServiceTest::testUpdateUser
1677
     */
1678
    public function testUpdateUserUpdatesExpectedProperties(User $user)
1679
    {
1680
        $this->assertEquals(
1681
            [
1682
                'login' => 'user',
1683
                'email' => '[email protected]',
1684
                'maxLogin' => 42,
1685
                'enabled' => false,
1686
            ],
1687
            [
1688
                'login' => $user->login,
1689
                'email' => $user->email,
1690
                'maxLogin' => $user->maxLogin,
1691
                'enabled' => $user->enabled,
1692
            ]
1693
        );
1694
    }
1695
1696
    /**
1697
     * Test for the updateUser() method.
1698
     *
1699
     * @param \eZ\Publish\API\Repository\Values\User\User $user
1700
     *
1701
     * @see \eZ\Publish\API\Repository\UserService::updateUser()
1702
     * @depends eZ\Publish\API\Repository\Tests\UserServiceTest::testUpdateUser
1703
     */
1704
    public function testUpdateUserReturnsPublishedVersion(User $user)
1705
    {
1706
        $this->assertEquals(
1707
            APIVersionInfo::STATUS_PUBLISHED,
1708
            $user->getVersionInfo()->status
1709
        );
1710
    }
1711
1712
    /**
1713
     * Test for the updateUser() method.
1714
     *
1715
     * @see \eZ\Publish\API\Repository\UserService::updateUser()
1716
     * @depends eZ\Publish\API\Repository\Tests\UserServiceTest::testUpdateUser
1717
     */
1718
    public function testUpdateUserWithContentMetadataUpdateStruct()
1719
    {
1720
        $repository = $this->getRepository();
1721
1722
        $userService = $repository->getUserService();
1723
1724
        /* BEGIN: Use Case */
1725
        $user = $this->createUserVersion1();
1726
1727
        // Get the ContentService implementation
1728
        $contentService = $repository->getContentService();
1729
1730
        // Create a metadata update struct and change the remote id.
1731
        $metadataUpdate = $contentService->newContentMetadataUpdateStruct();
1732
        $metadataUpdate->remoteId = '85e10037d1ac0a00aa75443ced483e08';
1733
1734
        // Create a new update struct instance
1735
        $userUpdate = $userService->newUserUpdateStruct();
1736
1737
        // Set the metadata update struct.
1738
        $userUpdate->contentMetadataUpdateStruct = $metadataUpdate;
1739
1740
        // Updated the user record.
1741
        $userVersion2 = $userService->updateUser($user, $userUpdate);
1742
1743
        // The contentInfo->remoteId will be changed now.
1744
        $remoteId = $userVersion2->contentInfo->remoteId;
1745
        /* END: Use Case */
1746
1747
        $this->assertEquals('85e10037d1ac0a00aa75443ced483e08', $remoteId);
1748
    }
1749
1750
    /**
1751
     * Test for the updateUser() method.
1752
     *
1753
     * @see \eZ\Publish\API\Repository\UserService::updateUser()
1754
     * @depends eZ\Publish\API\Repository\Tests\UserServiceTest::testUpdateUser
1755
     */
1756
    public function testUpdateUserWithContentUpdateStruct()
1757
    {
1758
        $repository = $this->getRepository();
1759
1760
        $userService = $repository->getUserService();
1761
1762
        /* BEGIN: Use Case */
1763
        $user = $this->createUserVersion1();
1764
1765
        // Get the ContentService implementation
1766
        $contentService = $repository->getContentService();
1767
1768
        // Create a content update struct and change the remote id.
1769
        $contentUpdate = $contentService->newContentUpdateStruct();
1770
        $contentUpdate->setField('first_name', 'Hello', 'eng-US');
1771
        $contentUpdate->setField('last_name', 'World', 'eng-US');
1772
1773
        // Create a new update struct instance
1774
        $userUpdate = $userService->newUserUpdateStruct();
1775
1776
        // Set the content update struct.
1777
        $userUpdate->contentUpdateStruct = $contentUpdate;
1778
1779
        // Updated the user record.
1780
        $userVersion2 = $userService->updateUser($user, $userUpdate);
1781
1782
        $name = sprintf(
1783
            '%s %s',
1784
            $userVersion2->getFieldValue('first_name'),
1785
            $userVersion2->getFieldValue('last_name')
1786
        );
1787
        /* END: Use Case */
1788
1789
        $this->assertEquals('Hello World', $name);
1790
    }
1791
1792
    /**
1793
     * Test for the updateUser() method.
1794
     *
1795
     * @see \eZ\Publish\API\Repository\UserService::updateUser()
1796
     * @depends eZ\Publish\API\Repository\Tests\UserServiceTest::testUpdateUser
1797
     */
1798
    public function testUpdateUserWhenMissingField()
1799
    {
1800
        $this->expectException(\eZ\Publish\API\Repository\Exceptions\ContentFieldValidationException::class);
1801
1802
        $repository = $this->getRepository();
1803
1804
        $userService = $repository->getUserService();
1805
1806
        /* BEGIN: Use Case */
1807
        $user = $this->createUserVersion1();
1808
1809
        // Get the ContentService implementation
1810
        $contentService = $repository->getContentService();
1811
1812
        // Create a content update struct and change the remote id.
1813
        $contentUpdate = $contentService->newContentUpdateStruct();
1814
        $contentUpdate->setField('first_name', null, 'eng-US');
1815
1816
        // Create a new update struct instance
1817
        $userUpdate = $userService->newUserUpdateStruct();
1818
1819
        // Set the content update struct.
1820
        $userUpdate->contentUpdateStruct = $contentUpdate;
1821
1822
        // This call will fail with a "ContentFieldValidationException" because the
1823
        // mandatory field "first_name" is set to an empty value.
1824
        $userService->updateUser($user, $userUpdate);
1825
1826
        /* END: Use Case */
1827
    }
1828
1829
    /**
1830
     * Test for the updateUser() method.
1831
     *
1832
     * @see \eZ\Publish\API\Repository\UserService::updateUser()
1833
     * @depends eZ\Publish\API\Repository\Tests\UserServiceTest::testUpdateUser
1834
     */
1835
    public function testUpdateUserThrowsInvalidArgumentExceptionOnFieldTypeNotAccept()
1836
    {
1837
        $this->expectException(\eZ\Publish\API\Repository\Exceptions\InvalidArgumentException::class);
1838
1839
        $repository = $this->getRepository();
1840
1841
        $userService = $repository->getUserService();
1842
1843
        /* BEGIN: Use Case */
1844
        $user = $this->createUserVersion1();
1845
1846
        // Get the ContentService implementation
1847
        $contentService = $repository->getContentService();
1848
1849
        $contentUpdate = $contentService->newContentUpdateStruct();
1850
        // An object of stdClass is not valid for the field first_name
1851
        $contentUpdate->setField('first_name', new \stdClass(), 'eng-US');
1852
1853
        // Create a new update struct instance
1854
        $userUpdate = $userService->newUserUpdateStruct();
1855
1856
        // Set the content update struct.
1857
        $userUpdate->contentUpdateStruct = $contentUpdate;
1858
1859
        // This call will fail with a "InvalidArgumentException" because the
1860
        // the field "first_name" does not accept the given value.
1861
        $userService->updateUser($user, $userUpdate);
1862
1863
        /* END: Use Case */
1864
    }
1865
1866
    /**
1867
     * Test updating a user throwing UserPasswordValidationException when password doesn't follow specified rules.
1868
     *
1869
     * @covers \eZ\Publish\API\Repository\UserService::updateUser
1870
     */
1871
    public function testUpdateUserWithWeakPasswordThrowsUserPasswordValidationException()
1872
    {
1873
        $userService = $this->getRepository()->getUserService();
1874
1875
        $user = $this->createTestUserWithPassword('H@xxxiR!_1', $this->createUserContentTypeWithStrongPassword());
1876
1877
        /* BEGIN: Use Case */
1878
        // Create a new update struct instance
1879
        $userUpdate = $userService->newUserUpdateStruct();
1880
        $userUpdate->password = 'pass';
1881
1882
        try {
1883
            // This call will fail with a "UserPasswordValidationException" because the
1884
            // the password does not follow specified rules
1885
            $userService->updateUser($user, $userUpdate);
1886
            /* END: Use Case */
1887
        } catch (ContentFieldValidationException $e) {
1888
            // Exception is caught, as there is no other way to check exception properties.
1889
            $this->assertValidationErrorOccurs($e, 'User password must include at least one special character');
1890
            $this->assertValidationErrorOccurs($e, 'User password must be at least %length% characters long');
1891
            $this->assertValidationErrorOccurs($e, 'User password must include at least one upper case letter');
1892
            $this->assertValidationErrorOccurs($e, 'User password must include at least one number');
1893
1894
            /* END: Use Case */
1895
            return;
1896
        }
1897
1898
        $this->fail('Expected ValidationError messages did not occur.');
1899
    }
1900
1901
    /**
1902
     * Opposite test case for testUpdateUserWithWeakPasswordThrowsUserPasswordValidationException.
1903
     *
1904
     * @covers \eZ\Publish\API\Repository\UserService::updateUser
1905
     */
1906
    public function testUpdateUserWithStrongPassword()
1907
    {
1908
        $userService = $this->getRepository()->getUserService();
1909
1910
        $user = $this->createTestUserWithPassword('H@xxxiR!_1', $this->createUserContentTypeWithStrongPassword());
1911
1912
        /* BEGIN: Use Case */
1913
        // Create a new update struct instance
1914
        $userUpdate = $userService->newUserUpdateStruct();
1915
        $userUpdate->password = 'H@xxxiR!_2';
1916
1917
        $user = $userService->updateUser($user, $userUpdate);
1918
        /* END: Use Case */
1919
1920
        $this->assertInstanceOf(User::class, $user);
1921
    }
1922
1923
    /**
1924
     * Test for the loadUserGroupsOfUser() method.
1925
     *
1926
     * @covers \eZ\Publish\API\Repository\UserService::loadUserGroupsOfUser
1927
     * @depends eZ\Publish\API\Repository\Tests\UserServiceTest::testCreateUser
1928
     */
1929
    public function testLoadUserGroupsOfUser()
1930
    {
1931
        $repository = $this->getRepository();
1932
1933
        $userService = $repository->getUserService();
1934
1935
        /* BEGIN: Use Case */
1936
        $user = $this->createUserVersion1();
1937
1938
        // This array will contain the "Editors" user group name
1939
        $userGroupNames = [];
1940
        foreach ($userService->loadUserGroupsOfUser($user) as $userGroup) {
1941
            $this->assertInstanceOf(UserGroup::class, $userGroup);
1942
            $userGroupNames[] = $userGroup->getFieldValue('name');
1943
        }
1944
        /* END: Use Case */
1945
1946
        $this->assertEquals(['Editors'], $userGroupNames);
1947
    }
1948
1949
    /**
1950
     * Test for the loadUsersOfUserGroup() method.
1951
     *
1952
     * @covers \eZ\Publish\API\Repository\UserService::loadUsersOfUserGroup
1953
     * @depends eZ\Publish\API\Repository\Tests\UserServiceTest::testCreateUser
1954
     */
1955
    public function testLoadUsersOfUserGroup()
1956
    {
1957
        $repository = $this->getRepository();
1958
        $userService = $repository->getUserService();
1959
1960
        $group = $userService->loadUserGroup($this->generateId('group', 13));
1961
1962
        /* BEGIN: Use Case */
1963
        $this->createUserVersion1();
1964
1965
        $this->refreshSearch($repository);
1966
1967
        // This array will contain the email of the newly created "Editor" user
1968
        $email = [];
1969
        foreach ($userService->loadUsersOfUserGroup($group) as $user) {
1970
            $this->assertInstanceOf(User::class, $user);
1971
            $email[] = $user->email;
1972
        }
1973
        /* END: Use Case */
1974
        $this->assertEquals(['[email protected]'], $email);
1975
    }
1976
1977
    /**
1978
     * Test for the assignUserToUserGroup() method.
1979
     *
1980
     * @see \eZ\Publish\API\Repository\UserService::assignUserToUserGroup()
1981
     * @depends eZ\Publish\API\Repository\Tests\UserServiceTest::testLoadUserGroupsOfUser
1982
     */
1983
    public function testAssignUserToUserGroup()
1984
    {
1985
        $repository = $this->getRepository();
1986
        $userService = $repository->getUserService();
1987
1988
        $administratorGroupId = $this->generateId('group', 12);
1989
        /* BEGIN: Use Case */
1990
        // $administratorGroupId is the ID of the "Administrator" group in an
1991
        // eZ Publish demo installation
1992
1993
        $user = $this->createUserVersion1();
1994
1995
        // Assign group to newly created user
1996
        $userService->assignUserToUserGroup(
1997
            $user,
1998
            $userService->loadUserGroup($administratorGroupId)
1999
        );
2000
2001
        // This array will contain "Editors" and "Administrator users"
2002
        $userGroupNames = [];
2003
        foreach ($userService->loadUserGroupsOfUser($user) as $userGroup) {
2004
            $userGroupNames[] = $userGroup->getFieldValue('name');
2005
        }
2006
        /* END: Use Case */
2007
2008
        sort($userGroupNames, SORT_STRING);
2009
2010
        $this->assertEquals(
2011
            [
2012
                'Administrator users',
2013
                'Editors',
2014
            ],
2015
            $userGroupNames
2016
        );
2017
    }
2018
2019
    /**
2020
     * Test for the assignUserToUserGroup() method.
2021
     *
2022
     * @covers \eZ\Publish\API\Repository\UserService::assignUserToUserGroup
2023
     * @depends eZ\Publish\API\Repository\Tests\UserServiceTest::testAssignUserToUserGroup
2024
     */
2025
    public function testAssignUserToUserGroupThrowsInvalidArgumentException()
2026
    {
2027
        $this->expectException(\eZ\Publish\API\Repository\Exceptions\InvalidArgumentException::class);
2028
        $this->expectExceptionMessage('Argument \'user\' is invalid: User is already in the given User Group');
2029
2030
        $repository = $this->getRepository();
2031
        $userService = $repository->getUserService();
2032
2033
        $editorsGroupId = $this->generateId('group', 13);
2034
        /* BEGIN: Use Case */
2035
        $user = $this->createUserVersion1();
2036
        // $editorsGroupId is the ID of the "Editors" group in an
2037
        // eZ Publish demo installation
2038
2039
        // This call will fail with an "InvalidArgumentException", because the
2040
        // user is already assigned to the "Editors" group
2041
        $userService->assignUserToUserGroup(
2042
            $user,
2043
            $userService->loadUserGroup($editorsGroupId)
2044
        );
2045
        /* END: Use Case */
2046
    }
2047
2048
    /**
2049
     * Test for the unAssignUssrFromUserGroup() method.
2050
     *
2051
     * @see \eZ\Publish\API\Repository\UserService::unAssignUssrFromUserGroup()
2052
     * @depends eZ\Publish\API\Repository\Tests\UserServiceTest::testLoadUserGroupsOfUser
2053
     */
2054
    public function testUnAssignUserFromUserGroup()
2055
    {
2056
        $repository = $this->getRepository();
2057
        $userService = $repository->getUserService();
2058
2059
        $editorsGroupId = $this->generateId('group', 13);
2060
        $anonymousGroupId = $this->generateId('group', 42);
2061
2062
        /* BEGIN: Use Case */
2063
        // $anonymousGroupId is the ID of the "Anonymous Users" group in an eZ
2064
        // Publish demo installation
2065
2066
        $user = $this->createUserVersion1();
2067
2068
        // Assign group to newly created user
2069
        $userService->assignUserToUserGroup(
2070
            $user,
2071
            $userService->loadUserGroup($anonymousGroupId)
2072
        );
2073
2074
        // Unassign user from "Editors" group
2075
        $userService->unAssignUserFromUserGroup(
2076
            $user,
2077
            $userService->loadUserGroup($editorsGroupId)
2078
        );
2079
2080
        // This array will contain "Anonymous Users"
2081
        $userGroupNames = [];
2082
        foreach ($userService->loadUserGroupsOfUser($user) as $userGroup) {
2083
            $userGroupNames[] = $userGroup->getFieldValue('name');
2084
        }
2085
        /* END: Use Case */
2086
2087
        $this->assertEquals(['Anonymous Users'], $userGroupNames);
2088
    }
2089
2090
    /**
2091
     * Test for the unAssignUserFromUserGroup() method.
2092
     *
2093
     * @see \eZ\Publish\API\Repository\UserService::unAssignUserFromUserGroup()
2094
     * @depends eZ\Publish\API\Repository\Tests\UserServiceTest::testUnAssignUserFromUserGroup
2095
     */
2096
    public function testUnAssignUserFromUserGroupThrowsInvalidArgumentException()
2097
    {
2098
        $this->expectException(\eZ\Publish\API\Repository\Exceptions\InvalidArgumentException::class);
2099
2100
        $repository = $this->getRepository();
2101
        $userService = $repository->getUserService();
2102
2103
        $administratorGroupId = $this->generateId('group', 12);
2104
        /* BEGIN: Use Case */
2105
        $user = $this->createUserVersion1();
2106
        // $administratorGroupId is the ID of the "Administrator" group in an
2107
        // eZ Publish demo installation
2108
2109
        // This call will fail with an "InvalidArgumentException", because the
2110
        // user is not assigned to the "Administrator" group
2111
        $userService->unAssignUserFromUserGroup(
2112
            $user,
2113
            $userService->loadUserGroup($administratorGroupId)
2114
        );
2115
        /* END: Use Case */
2116
    }
2117
2118
    /**
2119
     * Test for the unAssignUserFromUserGroup() method removing user from the last group.
2120
     *
2121
     * @covers \eZ\Publish\API\Repository\UserService::unAssignUserFromUserGroup
2122
     * @depends eZ\Publish\API\Repository\Tests\UserServiceTest::testUnAssignUserFromUserGroup
2123
     */
2124
    public function testUnAssignUserFromUserGroupThrowsBadStateArgumentException()
2125
    {
2126
        $this->expectException(\eZ\Publish\API\Repository\Exceptions\BadStateException::class);
2127
        $this->expectExceptionMessage('Argument \'user\' has a bad state: User only has one User Group, cannot unassign from last group');
2128
2129
        $repository = $this->getRepository();
2130
        $userService = $repository->getUserService();
2131
2132
        $editorsGroupId = $this->generateId('group', 13);
2133
        /* BEGIN: Use Case */
2134
        $user = $this->createUserVersion1();
2135
2136
        // This call will fail with an "BadStateException", because the
2137
        // user has to be assigned to at least one group
2138
        $userService->unAssignUserFromUserGroup(
2139
            $user,
2140
            $userService->loadUserGroup($editorsGroupId)
2141
        );
2142
        /* END: Use Case */
2143
    }
2144
2145
    /**
2146
     * Test that multi-language logic for the loadUserGroup method respects prioritized language list.
2147
     *
2148
     * @covers \eZ\Publish\API\Repository\UserService::loadUserGroup
2149
     * @dataProvider getPrioritizedLanguageList
2150
     * @param string[] $prioritizedLanguages
2151
     * @param string|null $expectedLanguageCode language code of expected translation
2152
     */
2153
    public function testLoadUserGroupWithPrioritizedLanguagesList(
2154
        array $prioritizedLanguages,
2155
        $expectedLanguageCode
2156
    ) {
2157
        $repository = $this->getRepository();
2158
        $userService = $repository->getUserService();
2159
2160
        $userGroup = $this->createMultiLanguageUserGroup();
2161
        if ($expectedLanguageCode === null) {
2162
            $expectedLanguageCode = $userGroup->contentInfo->mainLanguageCode;
2163
        }
2164
2165
        $loadedUserGroup = $userService->loadUserGroup($userGroup->id, $prioritizedLanguages);
2166
2167
        self::assertEquals(
2168
            $loadedUserGroup->getName($expectedLanguageCode),
2169
            $loadedUserGroup->getName()
2170
        );
2171
        self::assertEquals(
2172
            $loadedUserGroup->getFieldValue('description', $expectedLanguageCode),
2173
            $loadedUserGroup->getFieldValue('description')
2174
        );
2175
    }
2176
2177
    /**
2178
     * Test that multi-language logic works correctly after updating user group main language.
2179
     *
2180
     * @covers \eZ\Publish\API\Repository\UserService::loadUserGroup
2181
     * @dataProvider getPrioritizedLanguageList
2182
     * @param string[] $prioritizedLanguages
2183
     * @param string|null $expectedLanguageCode language code of expected translation
2184
     */
2185
    public function testLoadUserGroupWithPrioritizedLanguagesListAfterMainLanguageUpdate(
2186
        array $prioritizedLanguages,
2187
        $expectedLanguageCode
2188
    ) {
2189
        $repository = $this->getRepository();
2190
        $userService = $repository->getUserService();
2191
        $contentService = $repository->getContentService();
2192
2193
        $userGroup = $this->createMultiLanguageUserGroup();
2194
2195
        $userGroupUpdateStruct = $userService->newUserGroupUpdateStruct();
2196
        $userGroupUpdateStruct->contentMetadataUpdateStruct = $contentService->newContentMetadataUpdateStruct();
2197
        $userGroupUpdateStruct->contentMetadataUpdateStruct->mainLanguageCode = 'eng-GB';
2198
        $userService->updateUserGroup($userGroup, $userGroupUpdateStruct);
2199
2200
        if ($expectedLanguageCode === null) {
2201
            $expectedLanguageCode = 'eng-GB';
2202
        }
2203
2204
        $loadedUserGroup = $userService->loadUserGroup($userGroup->id, $prioritizedLanguages);
2205
2206
        self::assertEquals(
2207
            $loadedUserGroup->getName($expectedLanguageCode),
2208
            $loadedUserGroup->getName()
2209
        );
2210
        self::assertEquals(
2211
            $loadedUserGroup->getFieldValue('description', $expectedLanguageCode),
2212
            $loadedUserGroup->getFieldValue('description')
2213
        );
2214
    }
2215
2216
    /**
2217
     * Test that multi-language logic for the loadSubUserGroups method respects prioritized language list.
2218
     *
2219
     * @covers \eZ\Publish\API\Repository\UserService::loadSubUserGroups
2220
     * @dataProvider getPrioritizedLanguageList
2221
     * @param string[] $prioritizedLanguages
2222
     * @param string|null $expectedLanguageCode language code of expected translation
2223
     */
2224
    public function testLoadSubUserGroupsWithPrioritizedLanguagesList(
2225
        array $prioritizedLanguages,
2226
        $expectedLanguageCode
2227
    ) {
2228
        $repository = $this->getRepository();
2229
        $userService = $repository->getUserService();
2230
2231
        // create main group for subgroups
2232
        $userGroup = $this->createMultiLanguageUserGroup(4);
2233
        if ($expectedLanguageCode === null) {
2234
            $expectedLanguageCode = $userGroup->contentInfo->mainLanguageCode;
2235
        }
2236
2237
        // create subgroups
2238
        $this->createMultiLanguageUserGroup($userGroup->id);
2239
        $this->createMultiLanguageUserGroup($userGroup->id);
2240
2241
        $userGroup = $userService->loadUserGroup($userGroup->id, $prioritizedLanguages);
2242
2243
        $subUserGroups = $userService->loadSubUserGroups($userGroup, 0, 2, $prioritizedLanguages);
2244
        foreach ($subUserGroups as $subUserGroup) {
2245
            self::assertEquals(
2246
                $subUserGroup->getName($expectedLanguageCode),
2247
                $subUserGroup->getName()
2248
            );
2249
            self::assertEquals(
2250
                $subUserGroup->getFieldValue('description', $expectedLanguageCode),
2251
                $subUserGroup->getFieldValue('description')
2252
            );
2253
        }
2254
    }
2255
2256
    /**
2257
     * Test that multi-language logic for the loadUser method respects prioritized language list.
2258
     *
2259
     * @covers \eZ\Publish\API\Repository\UserService::loadUser
2260
     * @dataProvider getPrioritizedLanguageList
2261
     * @param string[] $prioritizedLanguages
2262
     * @param string|null $expectedLanguageCode language code of expected translation
2263
     */
2264
    public function testLoadUserWithPrioritizedLanguagesList(
2265
        array $prioritizedLanguages,
2266
        $expectedLanguageCode
2267
    ) {
2268
        $repository = $this->getRepository();
2269
        $userService = $repository->getUserService();
2270
2271
        $user = $this->createMultiLanguageUser();
2272
        if ($expectedLanguageCode === null) {
2273
            $expectedLanguageCode = $user->contentInfo->mainLanguageCode;
2274
        }
2275
2276
        $loadedUser = $userService->loadUser($user->id, $prioritizedLanguages);
2277
2278
        self::assertEquals(
2279
            $loadedUser->getName($expectedLanguageCode),
2280
            $loadedUser->getName()
2281
        );
2282
2283
        foreach (['fist_name', 'last_name', 'signature'] as $fieldIdentifier) {
2284
            self::assertEquals(
2285
                $loadedUser->getFieldValue($fieldIdentifier, $expectedLanguageCode),
2286
                $loadedUser->getFieldValue($fieldIdentifier)
2287
            );
2288
        }
2289
    }
2290
2291
    /**
2292
     * Test that multi-language logic for the loadUser method works correctly after updating
2293
     * user content main language.
2294
     *
2295
     * @covers \eZ\Publish\API\Repository\UserService::loadUserGroup
2296
     * @dataProvider getPrioritizedLanguageList
2297
     * @param string[] $prioritizedLanguages
2298
     * @param string|null $expectedLanguageCode language code of expected translation
2299
     */
2300
    public function testLoadUserWithPrioritizedLanguagesListAfterMainLanguageUpdate(
2301
        array $prioritizedLanguages,
2302
        $expectedLanguageCode
2303
    ) {
2304
        $repository = $this->getRepository();
2305
        $userService = $repository->getUserService();
2306
        $contentService = $repository->getContentService();
2307
2308
        $user = $this->createMultiLanguageUser();
2309
        // sanity check
2310
        self::assertEquals($user->contentInfo->mainLanguageCode, 'eng-US');
2311
2312
        $userUpdateStruct = $userService->newUserUpdateStruct();
2313
        $userUpdateStruct->contentMetadataUpdateStruct = $contentService->newContentMetadataUpdateStruct();
2314
        $userUpdateStruct->contentMetadataUpdateStruct->mainLanguageCode = 'eng-GB';
2315
        $userService->updateUser($user, $userUpdateStruct);
2316
        if ($expectedLanguageCode === null) {
2317
            $expectedLanguageCode = 'eng-GB';
2318
        }
2319
2320
        $loadedUser = $userService->loadUser($user->id, $prioritizedLanguages);
2321
2322
        self::assertEquals(
2323
            $loadedUser->getName($expectedLanguageCode),
2324
            $loadedUser->getName()
2325
        );
2326
2327
        foreach (['fist_name', 'last_name', 'signature'] as $fieldIdentifier) {
2328
            self::assertEquals(
2329
                $loadedUser->getFieldValue($fieldIdentifier, $expectedLanguageCode),
2330
                $loadedUser->getFieldValue($fieldIdentifier)
2331
            );
2332
        }
2333
    }
2334
2335
    /**
2336
     * Test that multi-language logic for the loadUserByLogin method respects prioritized language list.
2337
     *
2338
     * @covers \eZ\Publish\API\Repository\UserService::loadUserByLogin
2339
     * @dataProvider getPrioritizedLanguageList
2340
     * @param string[] $prioritizedLanguages
2341
     * @param string|null $expectedLanguageCode language code of expected translation
2342
     */
2343
    public function testLoadUserByLoginWithPrioritizedLanguagesList(
2344
        array $prioritizedLanguages,
2345
        $expectedLanguageCode
2346
    ) {
2347
        $repository = $this->getRepository();
2348
        $userService = $repository->getUserService();
2349
        $user = $this->createMultiLanguageUser();
2350
2351
        // load, with prioritized languages, the newly created user
2352
        $loadedUser = $userService->loadUserByLogin($user->login, $prioritizedLanguages);
0 ignored issues
show
Deprecated Code introduced by
The method eZ\Publish\API\Repositor...vice::loadUserByLogin() has been deprecated with message: since eZ Platform 2.5, will be dropped in the next major version as authentication may depend on various user providers. Use UserService::checkUserCredentials() instead.

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

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

Loading history...
2353
        if ($expectedLanguageCode === null) {
2354
            $expectedLanguageCode = $loadedUser->contentInfo->mainLanguageCode;
2355
        }
2356
2357
        self::assertEquals(
2358
            $loadedUser->getName($expectedLanguageCode),
2359
            $loadedUser->getName()
2360
        );
2361
2362
        foreach (['first_name', 'last_name', 'signature'] as $fieldIdentifier) {
2363
            self::assertEquals(
2364
                $loadedUser->getFieldValue($fieldIdentifier, $expectedLanguageCode),
2365
                $loadedUser->getFieldValue($fieldIdentifier)
2366
            );
2367
        }
2368
    }
2369
2370
    /**
2371
     * Test that multi-language logic for the loadUsersByEmail method respects
2372
     * prioritized language list.
2373
     *
2374
     * @covers \eZ\Publish\API\Repository\UserService::loadUsersByEmail
2375
     * @dataProvider getPrioritizedLanguageList
2376
     * @param string[] $prioritizedLanguages
2377
     * @param string|null $expectedLanguageCode language code of expected translation
2378
     */
2379
    public function testLoadUsersByEmailWithPrioritizedLanguagesList(
2380
        array $prioritizedLanguages,
2381
        $expectedLanguageCode
2382
    ) {
2383
        $repository = $this->getRepository();
2384
        $userService = $repository->getUserService();
2385
        $user = $this->createMultiLanguageUser();
2386
2387
        // load, with prioritized languages, users by email
2388
        $loadedUsers = $userService->loadUsersByEmail($user->email, $prioritizedLanguages);
2389
2390
        foreach ($loadedUsers as $loadedUser) {
2391
            if ($expectedLanguageCode === null) {
2392
                $expectedLanguageCode = $loadedUser->contentInfo->mainLanguageCode;
2393
            }
2394
            self::assertEquals(
2395
                $loadedUser->getName($expectedLanguageCode),
2396
                $loadedUser->getName()
2397
            );
2398
2399
            foreach (['first_name', 'last_name', 'signature'] as $fieldIdentifier) {
2400
                self::assertEquals(
2401
                    $loadedUser->getFieldValue($fieldIdentifier, $expectedLanguageCode),
2402
                    $loadedUser->getFieldValue($fieldIdentifier)
2403
                );
2404
            }
2405
        }
2406
    }
2407
2408
    /**
2409
     * Test that multi-language logic for the loadUserGroupsOfUser method respects
2410
     * prioritized language list.
2411
     *
2412
     * @covers \eZ\Publish\API\Repository\UserService::loadUserGroupsOfUser
2413
     * @dataProvider getPrioritizedLanguageList
2414
     * @param string[] $prioritizedLanguages
2415
     * @param string|null $expectedLanguageCode language code of expected translation
2416
     */
2417
    public function testLoadUserGroupsOfUserWithPrioritizedLanguagesList(
2418
        array $prioritizedLanguages,
2419
        $expectedLanguageCode
2420
    ) {
2421
        $repository = $this->getRepository();
2422
        $userService = $repository->getUserService();
2423
        $userGroup = $this->createMultiLanguageUserGroup();
2424
        $user = $this->createMultiLanguageUser($userGroup->id);
2425
2426
        $userGroups = $userService->loadUserGroupsOfUser($user, 0, 25, $prioritizedLanguages);
2427
        foreach ($userGroups as $userGroup) {
2428
            self::assertEquals(
2429
                $userGroup->getName($expectedLanguageCode),
2430
                $userGroup->getName()
2431
            );
2432
            self::assertEquals(
2433
                $userGroup->getFieldValue('description', $expectedLanguageCode),
2434
                $userGroup->getFieldValue('description')
2435
            );
2436
        }
2437
    }
2438
2439
    /**
2440
     * Test that multi-language logic for the loadUsersOfUserGroup method respects
2441
     * prioritized language list.
2442
     *
2443
     * @covers \eZ\Publish\API\Repository\UserService::loadUsersOfUserGroup
2444
     * @dataProvider getPrioritizedLanguageList
2445
     * @param string[] $prioritizedLanguages
2446
     * @param string|null $expectedLanguageCode language code of expected translation
2447
     */
2448
    public function testLoadUsersOfUserGroupWithPrioritizedLanguagesList(
2449
        array $prioritizedLanguages,
2450
        $expectedLanguageCode
2451
    ) {
2452
        $repository = $this->getRepository();
2453
        $userService = $repository->getUserService();
2454
2455
        // create parent user group
2456
        $userGroup = $this->createMultiLanguageUserGroup();
2457
        // add two users to the created parent user group
2458
        $this->createMultiLanguageUser($userGroup->id);
2459
        $this->createMultiLanguageUser($userGroup->id);
2460
2461
        // test loading of users via user group with prioritized languages list
2462
        $users = $userService->loadUsersOfUserGroup($userGroup, 0, 25, $prioritizedLanguages);
2463
        foreach ($users as $user) {
2464
            if ($expectedLanguageCode === null) {
2465
                $expectedLanguageCode = $user->contentInfo->mainLanguageCode;
2466
            }
2467
            self::assertEquals(
2468
                $user->getName($expectedLanguageCode),
2469
                $user->getName()
2470
            );
2471
2472
            foreach (['first_name', 'last_name', 'signature'] as $fieldIdentifier) {
2473
                self::assertEquals(
2474
                    $user->getFieldValue($fieldIdentifier, $expectedLanguageCode),
2475
                    $user->getFieldValue($fieldIdentifier)
2476
                );
2477
            }
2478
        }
2479
    }
2480
2481
    /**
2482
     * Get prioritized languages list data.
2483
     *
2484
     * Test cases using this data provider should expect the following arguments:
2485
     * <code>
2486
     *   array $prioritizedLanguagesList
2487
     *   string $expectedLanguage (if null - use main language)
2488
     * </code>
2489
     *
2490
     * @return array
2491
     */
2492
    public function getPrioritizedLanguageList()
2493
    {
2494
        return [
2495
            [[], null],
2496
            [['eng-US'], 'eng-US'],
2497
            [['eng-GB'], 'eng-GB'],
2498
            [['eng-US', 'eng-GB'], 'eng-US'],
2499
            [['eng-GB', 'eng-US'], 'eng-GB'],
2500
            // use non-existent group as the first one
2501
            [['ger-DE'], null],
2502
            [['ger-DE', 'eng-GB'], 'eng-GB'],
2503
        ];
2504
    }
2505
2506
    /**
2507
     * @param int $parentGroupId
2508
     * @return \eZ\Publish\API\Repository\Values\User\UserGroup
2509
     */
2510
    private function createMultiLanguageUserGroup($parentGroupId = 4)
2511
    {
2512
        $repository = $this->getRepository();
2513
        $userService = $repository->getUserService();
2514
2515
        // create user group with multiple translations
2516
        $parentGroupId = $this->generateId('group', $parentGroupId);
2517
        $parentGroup = $userService->loadUserGroup($parentGroupId);
2518
2519
        $userGroupCreateStruct = $userService->newUserGroupCreateStruct('eng-US');
2520
        $userGroupCreateStruct->setField('name', 'US user group', 'eng-US');
2521
        $userGroupCreateStruct->setField('name', 'GB user group', 'eng-GB');
2522
        $userGroupCreateStruct->setField('description', 'US user group description', 'eng-US');
2523
        $userGroupCreateStruct->setField('description', 'GB user group description', 'eng-GB');
2524
        $userGroupCreateStruct->alwaysAvailable = true;
2525
2526
        return $userService->createUserGroup($userGroupCreateStruct, $parentGroup);
2527
    }
2528
2529
    /**
2530
     * Create a user group fixture in a variable named <b>$userGroup</b>,.
2531
     *
2532
     * @return \eZ\Publish\API\Repository\Values\User\UserGroup
2533
     */
2534
    private function createUserGroupVersion1()
2535
    {
2536
        $repository = $this->getRepository();
2537
2538
        $mainGroupId = $this->generateId('group', 4);
2539
        /* BEGIN: Inline */
2540
        // $mainGroupId is the ID of the main "Users" group
2541
2542
        $userService = $repository->getUserService();
2543
2544
        // Load main group
2545
        $parentUserGroup = $userService->loadUserGroup($mainGroupId);
2546
2547
        // Instantiate a new create struct
2548
        $userGroupCreate = $userService->newUserGroupCreateStruct('eng-US');
2549
        $userGroupCreate->setField('name', 'Example Group');
2550
2551
        // Create the new user group
2552
        $userGroup = $userService->createUserGroup(
2553
            $userGroupCreate,
2554
            $parentUserGroup
2555
        );
2556
        /* END: Inline */
2557
2558
        return $userGroup;
2559
    }
2560
2561
    /**
2562
     * Create user with multiple translations of User Content fields.
2563
     *
2564
     * @param int $userGroupId User group ID (default 13 - Editors)
2565
     *
2566
     * @return \eZ\Publish\API\Repository\Values\User\User
2567
     */
2568
    private function createMultiLanguageUser($userGroupId = 13)
2569
    {
2570
        $repository = $this->getRepository();
2571
        $userService = $repository->getUserService();
2572
2573
        // Instantiate a create struct with mandatory properties
2574
        $randomLogin = md5(mt_rand() . time());
2575
        $userCreateStruct = $userService->newUserCreateStruct(
2576
            $randomLogin,
2577
            "{$randomLogin}@example.com",
2578
            'secret',
2579
            'eng-US'
2580
        );
2581
        $userCreateStruct->enabled = true;
2582
        $userCreateStruct->alwaysAvailable = true;
2583
2584
        // set field for each language
2585
        foreach (['eng-US', 'eng-GB'] as $languageCode) {
2586
            $userCreateStruct->setField('first_name', "{$languageCode} Example", $languageCode);
2587
            $userCreateStruct->setField('last_name', "{$languageCode} User", $languageCode);
2588
            $userCreateStruct->setField('signature', "{$languageCode} signature", $languageCode);
2589
        }
2590
2591
        // Load parent group for the user
2592
        $group = $userService->loadUserGroup($userGroupId);
2593
2594
        // Create a new user
2595
        return $userService->createUser($userCreateStruct, [$group]);
2596
    }
2597
2598
    /**
2599
     * Test for the createUser() method.
2600
     *
2601
     * @see \eZ\Publish\API\Repository\UserService::createUser()
2602
     */
2603
    public function testCreateUserInvalidPasswordHashTypeThrowsException()
2604
    {
2605
        $repository = $this->getRepository();
2606
        $eventUserService = $repository->getUserService();
2607
2608
        // Instantiate a create struct with mandatory properties.
2609
        $createStruct = $eventUserService->newUserCreateStruct(
2610
            'user',
2611
            '[email protected]',
2612
            'secret',
2613
            'eng-US'
2614
        );
2615
2616
        // Set some fields required by the user ContentType.
2617
        $createStruct->setField('first_name', 'Example');
2618
        $createStruct->setField('last_name', 'User');
2619
2620
        // Get User fieldType.
2621
        $userFieldDef = null;
2622
        foreach ($createStruct->fields as $field) {
2623
            if ($field->fieldTypeIdentifier === 'ezuser') {
2624
                $userFieldDef = $field;
2625
                break;
2626
            }
2627
        }
2628
2629
        if (!$userFieldDef) {
2630
            $this->fail('User FieldType not found in userCreateStruct!');
2631
        }
2632
2633
        /** @var \eZ\Publish\Core\FieldType\User\Value $userValue */
2634
        $userValue = $userFieldDef->value;
2635
2636
        // Set not supported hash type.
2637
        $userValue->passwordHashType = 42424242;
2638
2639
        $this->expectException(InvalidArgumentException::class);
2640
        $this->expectExceptionMessage("Argument 'hashType' is invalid: Password hash type '42424242' is not recognized");
2641
2642
        // Create a new user instance.
2643
        // 13 is ID of the "Editors" user group in an eZ Publish demo installation.
2644
        $eventUserService->createUser($createStruct, [$eventUserService->loadUserGroup(13)]);
2645
    }
2646
2647
    /**
2648
     * Test loading User by Token.
2649
     *
2650
     * @covers \eZ\Publish\API\Repository\UserService::loadUserByToken
2651
     */
2652
    public function testLoadUserByToken()
2653
    {
2654
        $repository = $this->getRepository();
2655
        $userService = $repository->getUserService();
2656
2657
        $user = $this->createUserVersion1();
2658
2659
        $userTokenUpdateStruct = new UserTokenUpdateStruct();
2660
        $userTokenUpdateStruct->hashKey = md5('hash');
2661
        $userTokenUpdateStruct->time = (new DateTime())->add(new DateInterval('PT10S'));
2662
2663
        $userService->updateUserToken($user, $userTokenUpdateStruct);
2664
2665
        $loadedUser = $userService->loadUserByToken($userTokenUpdateStruct->hashKey, Language::ALL);
2666
        self::assertEquals($user, $loadedUser);
2667
2668
        return $userTokenUpdateStruct->hashKey;
2669
    }
2670
2671
    /**
2672
     * Test trying to load User by invalid Token.
2673
     *
2674
     * @covers \eZ\Publish\API\Repository\UserService::loadUserByToken
2675
     */
2676
    public function testLoadUserByTokenThrowsNotFoundException()
2677
    {
2678
        $this->expectException(NotFoundException::class);
2679
2680
        $repository = $this->getRepository();
2681
        $userService = $repository->getUserService();
2682
2683
        $user = $this->createUserVersion1();
2684
2685
        $userTokenUpdateStruct = new UserTokenUpdateStruct();
2686
        $userTokenUpdateStruct->hashKey = md5('hash');
2687
        $userTokenUpdateStruct->time = new DateTime();
2688
2689
        $userService->updateUserToken($user, $userTokenUpdateStruct);
2690
2691
        $userService->loadUserByToken('not_existing_token');
2692
    }
2693
2694
    /**
2695
     * Test updating User Token.
2696
     *
2697
     * @covers \eZ\Publish\API\Repository\UserService::updateUserToken()
2698
     *
2699
     * @depends testLoadUserByToken
2700
     *
2701
     * @param string $originalUserToken
2702
     */
2703
    public function testUpdateUserToken($originalUserToken)
2704
    {
2705
        $repository = $this->getRepository(false);
2706
        $userService = $repository->getUserService();
2707
2708
        $user = $userService->loadUserByToken($originalUserToken);
2709
2710
        $userTokenUpdateStruct = new UserTokenUpdateStruct();
2711
        $userTokenUpdateStruct->hashKey = md5('my_updated_hash');
2712
        $userTokenUpdateStruct->time = (new DateTime())->add(new DateInterval('PT10S'));
2713
2714
        $userService->updateUserToken($user, $userTokenUpdateStruct);
2715
2716
        $loadedUser = $userService->loadUserByToken($userTokenUpdateStruct->hashKey);
2717
        self::assertEquals($user, $loadedUser);
2718
    }
2719
2720
    /**
2721
     * Test invalidating (expiring) User Token.
2722
     *
2723
     * @covers \eZ\Publish\API\Repository\UserService::expireUserToken()
2724
     *
2725
     * @depends testLoadUserByToken
2726
     *
2727
     * @param string $userToken
2728
     */
2729
    public function testExpireUserToken($userToken)
2730
    {
2731
        $this->expectException(NotFoundException::class);
2732
2733
        $repository = $this->getRepository(false);
2734
        $userService = $repository->getUserService();
2735
2736
        // sanity check
2737
        $userService->loadUserByToken($userToken);
2738
2739
        $userService->expireUserToken($userToken);
2740
2741
        // should throw NotFoundException now
2742
        $userService->loadUserByToken($userToken);
2743
    }
2744
2745
    /**
2746
     * @covers \eZ\Publish\API\Repository\UserService::validatePassword()
2747
     */
2748
    public function testValidatePasswordWithDefaultContext()
2749
    {
2750
        $userService = $this->getRepository()->getUserService();
2751
2752
        /* BEGIN: Use Case */
2753
        $errors = $userService->validatePassword('pass');
2754
        /* END: Use Case */
2755
2756
        $this->assertEmpty($errors);
2757
    }
2758
2759
    /**
2760
     * @covers \eZ\Publish\API\Repository\UserService::validatePassword()
2761
     * @dataProvider dataProviderForValidatePassword
2762
     */
2763
    public function testValidatePassword(string $password, array $expectedErrors)
2764
    {
2765
        $userService = $this->getRepository()->getUserService();
2766
        $contentType = $this->createUserContentTypeWithStrongPassword();
2767
2768
        /* BEGIN: Use Case */
2769
        $context = new PasswordValidationContext([
2770
            'contentType' => $contentType,
2771
        ]);
2772
2773
        $actualErrors = $userService->validatePassword($password, $context);
2774
        /* END: Use Case */
2775
2776
        $this->assertEquals($expectedErrors, $actualErrors);
2777
    }
2778
2779
    public function testValidatePasswordReturnsErrorWhenOldPasswordIsReused(): void
2780
    {
2781
        $password = 'P@blish123!';
2782
2783
        $userService = $this->getRepository()->getUserService();
2784
        // Password expiration needs to be enabled
2785
        $contentType = $this->createUserContentTypeWithPasswordExpirationDate();
2786
2787
        $user = $this->createTestUserWithPassword($password, $contentType);
2788
2789
        $context = new PasswordValidationContext([
2790
            'contentType' => $contentType,
2791
            'user' => $user,
2792
        ]);
2793
2794
        $actualErrors = $userService->validatePassword($password, $context);
2795
2796
        $this->assertEquals(
2797
            [new ValidationError('New password cannot be the same as old password', null, [], 'password')],
2798
            $actualErrors
2799
        );
2800
    }
2801
2802
    /**
2803
     * Data provider for testValidatePassword.
2804
     *
2805
     * @return array
2806
     */
2807
    public function dataProviderForValidatePassword(): array
2808
    {
2809
        return [
2810
            [
2811
                'pass',
2812
                [
2813
                    new ValidationError('User password must be at least %length% characters long', null, [
2814
                        '%length%' => 8,
2815
                    ], 'password'),
2816
                    new ValidationError('User password must include at least one upper case letter', null, [], 'password'),
2817
                    new ValidationError('User password must include at least one number', null, [], 'password'),
2818
                    new ValidationError('User password must include at least one special character', null, [], 'password'),
2819
                ],
2820
            ],
2821
            [
2822
                'H@xxxi0R!!!',
2823
                [],
2824
            ],
2825
        ];
2826
    }
2827
2828
    public function testGetPasswordInfo(): void
2829
    {
2830
        $userService = $this->getRepository()->getUserService();
2831
        $contentType = $this->createUserContentTypeWithPasswordExpirationDate(
2832
            self::EXAMPLE_PASSWORD_TTL,
2833
            self::EXAMPLE_PASSWORD_TTL_WARNING
2834
        );
2835
2836
        $user = $this->createTestUser($contentType);
2837
2838
        /* BEGIN: Use Case */
2839
        $passwordInfo = $userService->getPasswordInfo($user);
2840
        /* END: Use Case */
2841
2842
        $passwordUpdatedAt = $user->passwordUpdatedAt;
2843
        if ($passwordUpdatedAt instanceof DateTime) {
2844
            $passwordUpdatedAt = DateTimeImmutable::createFromFormat(DateTime::ATOM, $passwordUpdatedAt->format(DateTime::ATOM));
2845
        }
2846
2847
        $expectedPasswordExpirationDate = $passwordUpdatedAt->add(
2848
            new DateInterval(sprintf('P%dD', self::EXAMPLE_PASSWORD_TTL))
2849
        );
2850
2851
        $expectedPasswordExpirationWarningDate = $passwordUpdatedAt->add(
2852
            new DateInterval(sprintf('P%dD', self::EXAMPLE_PASSWORD_TTL - self::EXAMPLE_PASSWORD_TTL_WARNING))
2853
        );
2854
2855
        $this->assertEquals(new PasswordInfo(
2856
            $expectedPasswordExpirationDate,
2857
            $expectedPasswordExpirationWarningDate
2858
        ), $passwordInfo);
2859
    }
2860
2861
    public function testGetPasswordInfoIfExpirationIsDisabled(): void
2862
    {
2863
        $userService = $this->getRepository()->getUserService();
2864
        $contentType = $this->createUserContentTypeWithPasswordExpirationDate(null, null);
2865
2866
        $user = $this->createTestUser($contentType);
2867
2868
        /* BEGIN: Use Case */
2869
        $passwordInfo = $userService->getPasswordInfo($user);
2870
        /* END: Use Case */
2871
2872
        $this->assertEquals(new PasswordInfo(), $passwordInfo);
2873
    }
2874
2875
    public function testGetPasswordInfoIfExpirationWarningIsDisabled(): void
2876
    {
2877
        $userService = $this->getRepository()->getUserService();
2878
        $contentType = $this->createUserContentTypeWithPasswordExpirationDate(self::EXAMPLE_PASSWORD_TTL, null);
2879
2880
        $user = $this->createTestUser($contentType);
2881
2882
        /* BEGIN: Use Case */
2883
        $passwordInfo = $userService->getPasswordInfo($user);
2884
        /* END: Use Case */
2885
2886
        $passwordUpdatedAt = $user->passwordUpdatedAt;
2887
        if ($passwordUpdatedAt instanceof DateTime) {
2888
            $passwordUpdatedAt = DateTimeImmutable::createFromFormat(DateTime::ATOM, $passwordUpdatedAt->format(DateTime::ATOM));
2889
        }
2890
2891
        $expectedPasswordExpirationDate = $passwordUpdatedAt->add(
2892
            new DateInterval(sprintf('P%dD', self::EXAMPLE_PASSWORD_TTL))
2893
        );
2894
2895
        $this->assertEquals(new PasswordInfo($expectedPasswordExpirationDate, null), $passwordInfo);
2896
    }
2897
2898
    public function createTestUser(ContentType $contentType): User
2899
    {
2900
        return $this->createTestUserWithPassword(self::EXAMPLE_PASSWORD, $contentType);
2901
    }
2902
2903
    /**
2904
     * Creates a user with given password.
2905
     *
2906
     * @param string $password
2907
     * @param \eZ\Publish\API\Repository\Values\ContentType\ContentType $contentType
2908
     *
2909
     * @return \eZ\Publish\API\Repository\Values\User\User
2910
     */
2911
    private function createTestUserWithPassword(string $password, ContentType $contentType): User
2912
    {
2913
        $userService = $this->getRepository()->getUserService();
2914
        // ID of the "Editors" user group in an eZ Publish demo installation
2915
        $editorsGroupId = 13;
2916
2917
        // Instantiate a create struct with mandatory properties
2918
        $userCreate = $userService->newUserCreateStruct(
2919
            'johndoe',
2920
            '[email protected]',
2921
            $password,
2922
            'eng-US',
2923
            $contentType
2924
        );
2925
        $userCreate->enabled = true;
2926
        $userCreate->setField('first_name', 'John');
2927
        $userCreate->setField('last_name', 'Doe');
2928
2929
        return $userService->createUser($userCreate, [
2930
            $userService->loadUserGroup($editorsGroupId),
2931
        ]);
2932
    }
2933
2934
    /**
2935
     * Creates the User Content Type with password constraints.
2936
     *
2937
     * @return \eZ\Publish\API\Repository\Values\ContentType\ContentType
2938
     */
2939
    private function createUserContentTypeWithStrongPassword(): ContentType
2940
    {
2941
        return $this->createUserContentTypeWithAccountSettings('user-with-strong-password', null, [
2942
            'PasswordValueValidator' => [
2943
                'requireAtLeastOneUpperCaseCharacter' => 1,
2944
                'requireAtLeastOneLowerCaseCharacter' => 1,
2945
                'requireAtLeastOneNumericCharacter' => 1,
2946
                'requireAtLeastOneNonAlphanumericCharacter' => 1,
2947
                'requireNewPassword' => 1,
2948
                'minLength' => 8,
2949
            ],
2950
        ]);
2951
    }
2952
2953
    private function createUserContentTypeWithPasswordExpirationDate(
2954
        ?int $passwordTTL = self::EXAMPLE_PASSWORD_TTL,
2955
        ?int $passwordTTLWarning = self::EXAMPLE_PASSWORD_TTL_WARNING
2956
    ): ContentType {
2957
        return $this->createUserContentTypeWithAccountSettings('password-expiration', [
2958
            'PasswordTTL' => $passwordTTL,
2959
            'PasswordTTLWarning' => $passwordTTLWarning,
2960
        ]);
2961
    }
2962
2963
    private function createUserContentTypeWithAccountSettings(
2964
        string $identifier,
2965
        ?array $fieldSetting = null,
2966
        ?array $validatorConfiguration = null
2967
    ): ContentType {
2968
        $repository = $this->getRepository();
2969
2970
        $contentTypeService = $repository->getContentTypeService();
2971
        $permissionResolver = $repository->getPermissionResolver();
2972
2973
        $typeCreate = $contentTypeService->newContentTypeCreateStruct($identifier);
2974
        $typeCreate->mainLanguageCode = 'eng-GB';
2975
        $typeCreate->urlAliasSchema = 'url|scheme';
2976
        $typeCreate->nameSchema = 'name|scheme';
2977
        $typeCreate->names = [
2978
            'eng-GB' => 'User: ' . $identifier,
2979
        ];
2980
        $typeCreate->descriptions = [
2981
            'eng-GB' => '',
2982
        ];
2983
        $typeCreate->creatorId = $this->generateId('user', $permissionResolver->getCurrentUserReference()->getUserId());
2984
        $typeCreate->creationDate = $this->createDateTime();
2985
2986
        $firstNameFieldCreate = $contentTypeService->newFieldDefinitionCreateStruct('first_name', 'ezstring');
2987
        $firstNameFieldCreate->names = [
2988
            'eng-GB' => 'First name',
2989
        ];
2990
        $firstNameFieldCreate->descriptions = [
2991
            'eng-GB' => '',
2992
        ];
2993
        $firstNameFieldCreate->fieldGroup = 'default';
2994
        $firstNameFieldCreate->position = 1;
2995
        $firstNameFieldCreate->isTranslatable = false;
2996
        $firstNameFieldCreate->isRequired = true;
2997
        $firstNameFieldCreate->isInfoCollector = false;
2998
        $firstNameFieldCreate->validatorConfiguration = [
2999
            'StringLengthValidator' => [
3000
                'minStringLength' => 0,
3001
                'maxStringLength' => 0,
3002
            ],
3003
        ];
3004
        $firstNameFieldCreate->fieldSettings = [];
3005
        $firstNameFieldCreate->isSearchable = true;
3006
        $firstNameFieldCreate->defaultValue = '';
3007
3008
        $typeCreate->addFieldDefinition($firstNameFieldCreate);
3009
3010
        $lastNameFieldCreate = $contentTypeService->newFieldDefinitionCreateStruct('last_name', 'ezstring');
3011
        $lastNameFieldCreate->names = [
3012
            'eng-GB' => 'Last name',
3013
        ];
3014
        $lastNameFieldCreate->descriptions = [
3015
            'eng-GB' => '',
3016
        ];
3017
        $lastNameFieldCreate->fieldGroup = 'default';
3018
        $lastNameFieldCreate->position = 2;
3019
        $lastNameFieldCreate->isTranslatable = false;
3020
        $lastNameFieldCreate->isRequired = true;
3021
        $lastNameFieldCreate->isInfoCollector = false;
3022
        $lastNameFieldCreate->validatorConfiguration = [
3023
            'StringLengthValidator' => [
3024
                'minStringLength' => 0,
3025
                'maxStringLength' => 0,
3026
            ],
3027
        ];
3028
        $lastNameFieldCreate->fieldSettings = [];
3029
        $lastNameFieldCreate->isSearchable = true;
3030
        $lastNameFieldCreate->defaultValue = '';
3031
3032
        $typeCreate->addFieldDefinition($lastNameFieldCreate);
3033
3034
        $accountFieldCreateStruct = $contentTypeService->newFieldDefinitionCreateStruct('account', 'ezuser');
3035
        $accountFieldCreateStruct->names = [
3036
            'eng-GB' => 'User account',
3037
        ];
3038
        $accountFieldCreateStruct->descriptions = [
3039
            'eng-GB' => '',
3040
        ];
3041
        $accountFieldCreateStruct->fieldGroup = 'default';
3042
        $accountFieldCreateStruct->position = 3;
3043
        $accountFieldCreateStruct->isTranslatable = false;
3044
        $accountFieldCreateStruct->isRequired = true;
3045
        $accountFieldCreateStruct->isInfoCollector = false;
3046
        $accountFieldCreateStruct->validatorConfiguration = $validatorConfiguration;
3047
        $accountFieldCreateStruct->fieldSettings = $fieldSetting;
3048
        $accountFieldCreateStruct->isSearchable = false;
3049
        $accountFieldCreateStruct->defaultValue = null;
3050
3051
        $typeCreate->addFieldDefinition($accountFieldCreateStruct);
3052
3053
        $contentTypeDraft = $contentTypeService->createContentType($typeCreate, [
3054
            $contentTypeService->loadContentTypeGroupByIdentifier('Users'),
3055
        ]);
3056
        $contentTypeService->publishContentTypeDraft($contentTypeDraft);
3057
3058
        return $contentTypeService->loadContentTypeByIdentifier($identifier);
3059
    }
3060
}
3061