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