user service test
This commit is contained in:
parent
0cd33e84f8
commit
55c42c81fa
|
|
@ -15,11 +15,6 @@
|
||||||
.phpunit.result.cache
|
.phpunit.result.cache
|
||||||
###< phpunit/phpunit ###
|
###< phpunit/phpunit ###
|
||||||
|
|
||||||
###> symfony/phpunit-bridge ###
|
|
||||||
.phpunit.result.cache
|
|
||||||
/phpunit.xml
|
|
||||||
###< symfony/phpunit-bridge ###
|
|
||||||
|
|
||||||
###> symfony/asset-mapper ###
|
###> symfony/asset-mapper ###
|
||||||
/public/assets/
|
/public/assets/
|
||||||
/assets/vendor/
|
/assets/vendor/
|
||||||
|
|
|
||||||
|
|
@ -35,4 +35,7 @@
|
||||||
- Chaque élément est une carte afin de donner un style uniforme :
|
- Chaque élément est une carte afin de donner un style uniforme :
|
||||||
``` html
|
``` html
|
||||||
<div class="card p-3">
|
<div class="card p-3">
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
php bin/console messenger:consume async -vv
|
||||||
|
|
@ -106,7 +106,7 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"require-dev": {
|
"require-dev": {
|
||||||
"phpunit/phpunit": "^9.5",
|
"phpunit/phpunit": "^11.0",
|
||||||
"symfony/browser-kit": "7.2.*",
|
"symfony/browser-kit": "7.2.*",
|
||||||
"symfony/css-selector": "7.2.*",
|
"symfony/css-selector": "7.2.*",
|
||||||
"symfony/debug-bundle": "7.2.*",
|
"symfony/debug-bundle": "7.2.*",
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load Diff
|
|
@ -1,20 +1,15 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
|
||||||
<!-- https://phpunit.readthedocs.io/en/latest/configuration.html -->
|
|
||||||
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
xsi:noNamespaceSchemaLocation="vendor/phpunit/phpunit/phpunit.xsd"
|
xsi:noNamespaceSchemaLocation="vendor/phpunit/phpunit/phpunit.xsd"
|
||||||
backupGlobals="false"
|
|
||||||
colors="true"
|
|
||||||
bootstrap="tests/bootstrap.php"
|
bootstrap="tests/bootstrap.php"
|
||||||
convertDeprecationsToExceptions="false"
|
colors="true"
|
||||||
>
|
cacheDirectory=".phpunit.cache">
|
||||||
|
|
||||||
<php>
|
<php>
|
||||||
<ini name="display_errors" value="1" />
|
<ini name="display_errors" value="1" />
|
||||||
<ini name="error_reporting" value="-1" />
|
<ini name="error_reporting" value="-1" />
|
||||||
<server name="APP_ENV" value="test" force="true" />
|
<server name="APP_ENV" value="test" force="true" />
|
||||||
<server name="SHELL_VERBOSITY" value="-1" />
|
<server name="SHELL_VERBOSITY" value="-1" />
|
||||||
<server name="SYMFONY_PHPUNIT_REMOVE" value="" />
|
|
||||||
<server name="SYMFONY_PHPUNIT_VERSION" value="9.5" />
|
|
||||||
</php>
|
</php>
|
||||||
|
|
||||||
<testsuites>
|
<testsuites>
|
||||||
|
|
@ -23,16 +18,9 @@
|
||||||
</testsuite>
|
</testsuite>
|
||||||
</testsuites>
|
</testsuites>
|
||||||
|
|
||||||
<coverage processUncoveredFiles="true">
|
<source>
|
||||||
<include>
|
<include>
|
||||||
<directory suffix=".php">src</directory>
|
<directory suffix=".php">src</directory>
|
||||||
</include>
|
</include>
|
||||||
</coverage>
|
</source>
|
||||||
|
</phpunit>
|
||||||
<listeners>
|
|
||||||
<listener class="Symfony\Bridge\PhpUnit\SymfonyTestsListener" />
|
|
||||||
</listeners>
|
|
||||||
|
|
||||||
<extensions>
|
|
||||||
</extensions>
|
|
||||||
</phpunit>
|
|
||||||
|
|
@ -103,7 +103,7 @@ class OrganizationController extends AbstractController
|
||||||
$this->entityManager->persist($organization);
|
$this->entityManager->persist($organization);
|
||||||
$this->entityManager->flush();
|
$this->entityManager->flush();
|
||||||
$this->loggerService->logOrganizationInformation($organization->getId(), $actingUser->getId(), "Organization Created");
|
$this->loggerService->logOrganizationInformation($organization->getId(), $actingUser->getId(), "Organization Created");
|
||||||
$this->loggerService->logSuperAdmin($actingUser->getId(), $organization->getId(), $actingUser->getId(), "Organization Created");
|
$this->loggerService->logSuperAdmin($actingUser->getId(), $actingUser->getId(), "Organization Created", $organization->getId());
|
||||||
$this->actionService->createAction("Create Organization", $actingUser, $organization, $organization->getName());
|
$this->actionService->createAction("Create Organization", $actingUser, $organization, $organization->getName());
|
||||||
return $this->redirectToRoute('organization_index');
|
return $this->redirectToRoute('organization_index');
|
||||||
} catch (Exception $e) {
|
} catch (Exception $e) {
|
||||||
|
|
@ -171,7 +171,7 @@ class OrganizationController extends AbstractController
|
||||||
$this->entityManager->flush();
|
$this->entityManager->flush();
|
||||||
$this->loggerService->logOrganizationInformation($organization->getId(), $actingUser->getId(), "Organization Edited");
|
$this->loggerService->logOrganizationInformation($organization->getId(), $actingUser->getId(), "Organization Edited");
|
||||||
if ($this->isGranted("ROLE_SUPER_ADMIN")) {
|
if ($this->isGranted("ROLE_SUPER_ADMIN")) {
|
||||||
$this->loggerService->logSuperAdmin($actingUser->getId(), $organization->getId(), $actingUser->getId(), "Organization Edited");
|
$this->loggerService->logSuperAdmin($actingUser->getId(), $actingUser->getId(), "Organization Edited", $organization->getId());
|
||||||
}
|
}
|
||||||
$this->actionService->createAction("Edit Organization", $actingUser, $organization, $organization->getName());
|
$this->actionService->createAction("Edit Organization", $actingUser, $organization, $organization->getName());
|
||||||
return $this->redirectToRoute('organization_index');
|
return $this->redirectToRoute('organization_index');
|
||||||
|
|
@ -268,7 +268,7 @@ class OrganizationController extends AbstractController
|
||||||
// $this->userOrganizationService->deactivateAllUserOrganizationLinks($actingUser, null, $organization);
|
// $this->userOrganizationService->deactivateAllUserOrganizationLinks($actingUser, null, $organization);
|
||||||
$this->entityManager->persist($organization);
|
$this->entityManager->persist($organization);
|
||||||
$this->actionService->createAction("Deactivate Organization", $actingUser, $organization, $organization->getName());
|
$this->actionService->createAction("Deactivate Organization", $actingUser, $organization, $organization->getName());
|
||||||
$this->loggerService->logSuperAdmin($actingUser->getId(), $organization->getId(), $actingUser->getId(),'Organization deactivated');
|
$this->loggerService->logSuperAdmin($actingUser->getId(), $actingUser->getId(),'Organization deactivated', $organization->getId());
|
||||||
|
|
||||||
return $this->redirectToRoute('organization_index');
|
return $this->redirectToRoute('organization_index');
|
||||||
}
|
}
|
||||||
|
|
@ -289,7 +289,7 @@ class OrganizationController extends AbstractController
|
||||||
$organization->setIsActive(true);
|
$organization->setIsActive(true);
|
||||||
$this->entityManager->persist($organization);
|
$this->entityManager->persist($organization);
|
||||||
$this->loggerService->logOrganizationInformation($organization->getId(), $actingUser->getId(),'Organization Activated');
|
$this->loggerService->logOrganizationInformation($organization->getId(), $actingUser->getId(),'Organization Activated');
|
||||||
$this->loggerService->logSuperAdmin($actingUser->getId(), $organization->getId(), $actingUser->getId(),'Organization Activated');
|
$this->loggerService->logSuperAdmin($actingUser->getId(), $actingUser->getId(),'Organization Activated', $organization->getId());
|
||||||
$this->actionService->createAction("Activate Organization", $actingUser, $organization, $organization->getName());
|
$this->actionService->createAction("Activate Organization", $actingUser, $organization, $organization->getName());
|
||||||
return $this->redirectToRoute('organization_index');
|
return $this->redirectToRoute('organization_index');
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -218,7 +218,6 @@ class UserController extends AbstractController
|
||||||
if ($this->isGranted('ROLE_SUPER_ADMIN')) {
|
if ($this->isGranted('ROLE_SUPER_ADMIN')) {
|
||||||
$this->loggerService->logSuperAdmin(
|
$this->loggerService->logSuperAdmin(
|
||||||
$user->getId(),
|
$user->getId(),
|
||||||
null,
|
|
||||||
$actingUser->getId(),
|
$actingUser->getId(),
|
||||||
"Super Admin accessed user edit page",
|
"Super Admin accessed user edit page",
|
||||||
);
|
);
|
||||||
|
|
@ -231,7 +230,6 @@ class UserController extends AbstractController
|
||||||
if ($this->isGranted('ROLE_SUPER_ADMIN')) {
|
if ($this->isGranted('ROLE_SUPER_ADMIN')) {
|
||||||
$this->loggerService->logSuperAdmin(
|
$this->loggerService->logSuperAdmin(
|
||||||
$user->getId(),
|
$user->getId(),
|
||||||
null,
|
|
||||||
$actingUser->getId(),
|
$actingUser->getId(),
|
||||||
"Super Admin accessed user edit page",
|
"Super Admin accessed user edit page",
|
||||||
);
|
);
|
||||||
|
|
@ -295,9 +293,9 @@ class UserController extends AbstractController
|
||||||
if ($this->isGranted('ROLE_SUPER_ADMIN')) {
|
if ($this->isGranted('ROLE_SUPER_ADMIN')) {
|
||||||
$this->loggerService->logSuperAdmin(
|
$this->loggerService->logSuperAdmin(
|
||||||
$existingUser->getId(),
|
$existingUser->getId(),
|
||||||
$org->getId(),
|
|
||||||
$actingUser->getId(),
|
$actingUser->getId(),
|
||||||
"Super Admin linked user to organization",
|
"Super Admin linked user to organization",
|
||||||
|
$org->getId(),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
return $this->redirectToRoute('organization_show', ['id' => $orgId]);
|
return $this->redirectToRoute('organization_show', ['id' => $orgId]);
|
||||||
|
|
@ -329,7 +327,6 @@ class UserController extends AbstractController
|
||||||
if ($this->isGranted('ROLE_SUPER_ADMIN')) {
|
if ($this->isGranted('ROLE_SUPER_ADMIN')) {
|
||||||
$this->loggerService->logSuperAdmin(
|
$this->loggerService->logSuperAdmin(
|
||||||
$user->getId(),
|
$user->getId(),
|
||||||
null,
|
|
||||||
$actingUser->getId(),
|
$actingUser->getId(),
|
||||||
"Super Admin created new user",
|
"Super Admin created new user",
|
||||||
|
|
||||||
|
|
@ -347,9 +344,9 @@ class UserController extends AbstractController
|
||||||
if ($this->isGranted('ROLE_SUPER_ADMIN')) {
|
if ($this->isGranted('ROLE_SUPER_ADMIN')) {
|
||||||
$this->loggerService->logSuperAdmin(
|
$this->loggerService->logSuperAdmin(
|
||||||
$user->getId(),
|
$user->getId(),
|
||||||
$org->getId(),
|
|
||||||
$actingUser->getId(),
|
$actingUser->getId(),
|
||||||
"Super Admin linked user to organization during creation",
|
"Super Admin linked user to organization during creation",
|
||||||
|
$org->getId()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -418,7 +415,6 @@ class UserController extends AbstractController
|
||||||
if ($this->isGranted('ROLE_SUPER_ADMIN')) {
|
if ($this->isGranted('ROLE_SUPER_ADMIN')) {
|
||||||
$this->loggerService->logSuperAdmin(
|
$this->loggerService->logSuperAdmin(
|
||||||
$user->getId(),
|
$user->getId(),
|
||||||
null,
|
|
||||||
$actingUser->getId(),
|
$actingUser->getId(),
|
||||||
'Super admin deactivated user'
|
'Super admin deactivated user'
|
||||||
);
|
);
|
||||||
|
|
@ -441,7 +437,6 @@ class UserController extends AbstractController
|
||||||
if ($this->isGranted('ROLE_SUPER_ADMIN')) {
|
if ($this->isGranted('ROLE_SUPER_ADMIN')) {
|
||||||
$this->loggerService->logSuperAdmin(
|
$this->loggerService->logSuperAdmin(
|
||||||
$user->getId(),
|
$user->getId(),
|
||||||
null,
|
|
||||||
$actingUser->getId(),
|
$actingUser->getId(),
|
||||||
'Super admin activated user'
|
'Super admin activated user'
|
||||||
);
|
);
|
||||||
|
|
@ -577,7 +572,6 @@ class UserController extends AbstractController
|
||||||
if ($this->isGranted('ROLE_SUPER_ADMIN')) {
|
if ($this->isGranted('ROLE_SUPER_ADMIN')) {
|
||||||
$this->loggerService->logSuperAdmin(
|
$this->loggerService->logSuperAdmin(
|
||||||
$user->getId(),
|
$user->getId(),
|
||||||
null,
|
|
||||||
$actingUser->getId(),
|
$actingUser->getId(),
|
||||||
'Super admin deleted user'
|
'Super admin deleted user'
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -87,7 +87,7 @@ readonly class LoggerService
|
||||||
]));
|
]));
|
||||||
}
|
}
|
||||||
|
|
||||||
public function logSuperAdmin(int $userId, ?int $orgId = null, int $actingUserId, string $message): void
|
public function logSuperAdmin(int $userId, int $actingUserId, string $message, ?int $orgId = null): void
|
||||||
{
|
{
|
||||||
$this->adminActionsLogger->notice($message, [
|
$this->adminActionsLogger->notice($message, [
|
||||||
'target_user_id' => $userId,
|
'target_user_id' => $userId,
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,369 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Tests\Service;
|
||||||
|
|
||||||
|
use App\Entity\Organizations;
|
||||||
|
use App\Entity\Roles;
|
||||||
|
use App\Entity\User;
|
||||||
|
use App\Entity\UserOrganizatonApp;
|
||||||
|
use App\Entity\UsersOrganizations;
|
||||||
|
use App\Service\ActionService;
|
||||||
|
use App\Service\AwsService;
|
||||||
|
use App\Service\EmailService;
|
||||||
|
use App\Service\LoggerService;
|
||||||
|
use App\Service\OrganizationsService;
|
||||||
|
use App\Service\UserService;
|
||||||
|
use Doctrine\ORM\EntityManagerInterface;
|
||||||
|
use Doctrine\ORM\EntityNotFoundException;
|
||||||
|
use Doctrine\ORM\EntityRepository;
|
||||||
|
use League\Bundle\OAuth2ServerBundle\Model\AccessToken;
|
||||||
|
use PHPUnit\Framework\MockObject\MockObject;
|
||||||
|
use PHPUnit\Framework\TestCase;
|
||||||
|
use Symfony\Bundle\SecurityBundle\Security;
|
||||||
|
use Symfony\Component\HttpFoundation\File\UploadedFile;
|
||||||
|
|
||||||
|
class UserServiceTest extends TestCase
|
||||||
|
{
|
||||||
|
private UserService $userService;
|
||||||
|
|
||||||
|
// Mocks
|
||||||
|
private MockObject|EntityManagerInterface $entityManager;
|
||||||
|
private MockObject|Security $security;
|
||||||
|
private MockObject|AwsService $awsService;
|
||||||
|
private MockObject|LoggerService $loggerService;
|
||||||
|
private MockObject|ActionService $actionService;
|
||||||
|
private MockObject|EmailService $emailService;
|
||||||
|
private MockObject|OrganizationsService $organizationsService;
|
||||||
|
|
||||||
|
protected function setUp(): void
|
||||||
|
{
|
||||||
|
$this->entityManager = $this->createMock(EntityManagerInterface::class);
|
||||||
|
$this->security = $this->createMock(Security::class);
|
||||||
|
$this->awsService = $this->createMock(AwsService::class);
|
||||||
|
$this->actionService = $this->createMock(ActionService::class);
|
||||||
|
$this->emailService = $this->createMock(EmailService::class);
|
||||||
|
$this->organizationsService = $this->createMock(OrganizationsService::class);
|
||||||
|
|
||||||
|
// HANDLING READONLY LOGGER SERVICE
|
||||||
|
// PHPUnit 10+ generally handles readonly classes fine.
|
||||||
|
// If your LoggerService is 'final readonly', you cannot mock it easily.
|
||||||
|
// Assuming it is just 'readonly class LoggerService':
|
||||||
|
$this->loggerService = $this->createMock(LoggerService::class);
|
||||||
|
|
||||||
|
$this->userService = new UserService(
|
||||||
|
$this->entityManager,
|
||||||
|
$this->security,
|
||||||
|
$this->awsService,
|
||||||
|
$this->loggerService,
|
||||||
|
$this->actionService,
|
||||||
|
$this->emailService,
|
||||||
|
$this->organizationsService
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testGenerateRandomPassword(): void
|
||||||
|
{
|
||||||
|
$password = $this->userService->generateRandomPassword();
|
||||||
|
$this->assertEquals(50, strlen($password));
|
||||||
|
$this->assertMatchesRegularExpression('/[a-zA-Z0-9!@#$%^&*()_+]+/', $password);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testIsUserConnectedReturnsTrueIfTokenValid(): void
|
||||||
|
{
|
||||||
|
$userIdentifier = 'test@example.com';
|
||||||
|
|
||||||
|
// Mock the Repository for AccessToken
|
||||||
|
$repo = $this->createMock(EntityRepository::class);
|
||||||
|
|
||||||
|
// Mock a token that expires in the future
|
||||||
|
$token = $this->createMock(AccessToken::class);
|
||||||
|
$token->method('getExpiry')->willReturn(new \DateTimeImmutable('+1 hour'));
|
||||||
|
|
||||||
|
$repo->expects($this->once())
|
||||||
|
->method('findBy')
|
||||||
|
->with(['userIdentifier' => $userIdentifier, 'revoked' => false])
|
||||||
|
->willReturn([$token]);
|
||||||
|
|
||||||
|
$this->entityManager->expects($this->once())
|
||||||
|
->method('getRepository')
|
||||||
|
->with(AccessToken::class)
|
||||||
|
->willReturn($repo);
|
||||||
|
|
||||||
|
$result = $this->userService->isUserConnected($userIdentifier);
|
||||||
|
$this->assertTrue($result);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testIsUserConnectedReturnsFalseIfTokenExpired(): void
|
||||||
|
{
|
||||||
|
$userIdentifier = 'test@example.com';
|
||||||
|
$repo = $this->createMock(EntityRepository::class);
|
||||||
|
|
||||||
|
$token = $this->createMock(AccessToken::class);
|
||||||
|
$token->method('getExpiry')->willReturn(new \DateTimeImmutable('-1 hour'));
|
||||||
|
|
||||||
|
$repo->method('findBy')->willReturn([$token]);
|
||||||
|
$this->entityManager->method('getRepository')->willReturn($repo);
|
||||||
|
|
||||||
|
$result = $this->userService->isUserConnected($userIdentifier);
|
||||||
|
$this->assertFalse($result);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testGetUserByIdentifierFound(): void
|
||||||
|
{
|
||||||
|
$identifier = 'user@test.com';
|
||||||
|
$user = new User();
|
||||||
|
$user->setEmail($identifier);
|
||||||
|
|
||||||
|
$repo = $this->createMock(EntityRepository::class);
|
||||||
|
$repo->expects($this->once())
|
||||||
|
->method('findOneBy')
|
||||||
|
->with(['email' => $identifier])
|
||||||
|
->willReturn($user);
|
||||||
|
|
||||||
|
$this->entityManager->method('getRepository')->with(User::class)->willReturn($repo);
|
||||||
|
|
||||||
|
$result = $this->userService->getUserByIdentifier($identifier);
|
||||||
|
$this->assertSame($user, $result);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testGetUserByIdentifierNotFound(): void
|
||||||
|
{
|
||||||
|
$identifier = 'unknown@test.com';
|
||||||
|
|
||||||
|
$repo = $this->createMock(EntityRepository::class);
|
||||||
|
$repo->method('findOneBy')->willReturn(null);
|
||||||
|
$this->entityManager->method('getRepository')->with(User::class)->willReturn($repo);
|
||||||
|
|
||||||
|
// Expect Logger to be called
|
||||||
|
$this->loggerService->expects($this->once())
|
||||||
|
->method('logEntityNotFound')
|
||||||
|
->with('User', ['user_identifier' => $identifier], null);
|
||||||
|
|
||||||
|
$this->expectException(EntityNotFoundException::class);
|
||||||
|
$this->expectExceptionMessage(UserService::NOT_FOUND);
|
||||||
|
|
||||||
|
$this->userService->getUserByIdentifier($identifier);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testHasAccessToReturnsTrueForSuperAdmin(): void
|
||||||
|
{
|
||||||
|
$this->security->method('isGranted')->with('ROLE_SUPER_ADMIN')->willReturn(true);
|
||||||
|
$user = new User(); // Dummy user
|
||||||
|
$this->assertTrue($this->userService->hasAccessTo($user));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testHasAccessToReturnsTrueForSelf(): void
|
||||||
|
{
|
||||||
|
$this->security->method('isGranted')->willReturn(false);
|
||||||
|
|
||||||
|
$currentUser = new User();
|
||||||
|
$currentUser->setEmail('me@test.com');
|
||||||
|
|
||||||
|
$targetUser = new User();
|
||||||
|
$targetUser->setEmail('me@test.com');
|
||||||
|
|
||||||
|
$this->security->method('getUser')->willReturn($currentUser);
|
||||||
|
|
||||||
|
// skipSelfCheck = false (default)
|
||||||
|
$this->assertTrue($this->userService->hasAccessTo($targetUser));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testHandleProfilePictureUploadsAndLogs(): void
|
||||||
|
{
|
||||||
|
$user = new User();
|
||||||
|
$user->setName('John');
|
||||||
|
$user->setSurname('Doe');
|
||||||
|
|
||||||
|
// Mock UploadedFile
|
||||||
|
$file = $this->createMock(UploadedFile::class);
|
||||||
|
$file->method('guessExtension')->willReturn('jpg');
|
||||||
|
|
||||||
|
// Expect AWS Call
|
||||||
|
$this->awsService->expects($this->once())
|
||||||
|
->method('PutDocObj')
|
||||||
|
->with(
|
||||||
|
$this->anything(), // ENV variable usually
|
||||||
|
$file,
|
||||||
|
$this->stringContains('JohnDoe_'),
|
||||||
|
'jpg',
|
||||||
|
'profile/'
|
||||||
|
);
|
||||||
|
|
||||||
|
// Expect Logger Call
|
||||||
|
$this->loggerService->expects($this->once())
|
||||||
|
->method('logAWSAction');
|
||||||
|
|
||||||
|
// Set fake ENV for test context if needed, or ignore the argument in mock
|
||||||
|
$_ENV['S3_PORTAL_BUCKET'] = 'test-bucket';
|
||||||
|
|
||||||
|
$this->userService->handleProfilePicture($user, $file);
|
||||||
|
|
||||||
|
$this->assertStringContainsString('profile/JohnDoe_', $user->getPictureUrl());
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testSyncUserRolesAddsRole(): void
|
||||||
|
{
|
||||||
|
$user = new User();
|
||||||
|
$user->setRoles(['ROLE_USER']);
|
||||||
|
|
||||||
|
$this->loggerService->expects($this->once())->method('logRoleAssignment');
|
||||||
|
|
||||||
|
$this->userService->syncUserRoles($user, 'ADMIN', true);
|
||||||
|
|
||||||
|
$this->assertContains('ROLE_ADMIN', $user->getRoles());
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testSyncUserRolesRemovesRole(): void
|
||||||
|
{
|
||||||
|
$user = new User();
|
||||||
|
$user->setRoles(['ROLE_USER', 'ROLE_ADMIN']);
|
||||||
|
|
||||||
|
// Mock repositories to ensure no other org gives this role
|
||||||
|
$repoUO = $this->createMock(EntityRepository::class);
|
||||||
|
$repoUO->method('findBy')->willReturn([]); // No active org links
|
||||||
|
|
||||||
|
$this->entityManager->method('getRepository')
|
||||||
|
->willReturnMap([
|
||||||
|
[UsersOrganizations::class, $repoUO]
|
||||||
|
]);
|
||||||
|
|
||||||
|
$this->userService->syncUserRoles($user, 'ADMIN', false);
|
||||||
|
|
||||||
|
$this->assertNotContains('ROLE_ADMIN', $user->getRoles());
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testIsPasswordStrong(): void
|
||||||
|
{
|
||||||
|
$this->assertTrue($this->userService->isPasswordStrong('StrongP@ss1')); // Chars + Digits + Special + Length
|
||||||
|
$this->assertFalse($this->userService->isPasswordStrong('weak')); // Too short
|
||||||
|
$this->assertFalse($this->userService->isPasswordStrong('123456789')); // No letters
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testCreateNewUserSuccess(): void
|
||||||
|
{
|
||||||
|
$newUser = new User();
|
||||||
|
$newUser->setName('jane');
|
||||||
|
$newUser->setSurname('doe');
|
||||||
|
$newUser->setEmail('jane@doe.com');
|
||||||
|
|
||||||
|
$actingUser = new User();
|
||||||
|
$this->setEntityId($actingUser, 99); // Give acting user an ID
|
||||||
|
$actingUser->setEmail('admin@test.com');
|
||||||
|
|
||||||
|
// When persist is called, we force an ID onto $newUser to simulate DB insertion
|
||||||
|
$this->entityManager->expects($this->exactly(2))
|
||||||
|
->method('persist')
|
||||||
|
->with($newUser)
|
||||||
|
->willReturnCallback(function ($entity) {
|
||||||
|
$this->setEntityId($entity, 123); // Simulate DB assigning ID 123
|
||||||
|
});
|
||||||
|
|
||||||
|
$this->entityManager->expects($this->exactly(2))->method('flush');
|
||||||
|
|
||||||
|
// Now expects ID 123
|
||||||
|
$this->loggerService->expects($this->once())
|
||||||
|
->method('logUserCreated')
|
||||||
|
->with(123, 99);
|
||||||
|
|
||||||
|
$this->emailService->expects($this->once())->method('sendPasswordSetupEmail');
|
||||||
|
$this->actionService->expects($this->once())->method('createAction');
|
||||||
|
|
||||||
|
$this->userService->createNewUser($newUser, $actingUser, null);
|
||||||
|
|
||||||
|
// Assertions
|
||||||
|
$this->assertEquals('Jane', $newUser->getName());
|
||||||
|
$this->assertEquals(123, $newUser->getId()); // Verify ID was "generated"
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testLinkUserToOrganization(): void
|
||||||
|
{
|
||||||
|
$user = new User();
|
||||||
|
$this->setEntityId($user, 10); // Pre-set ID for existing user
|
||||||
|
|
||||||
|
$org = new Organizations();
|
||||||
|
$this->setEntityId($org, 50); // Pre-set ID for org
|
||||||
|
|
||||||
|
$actingUser = new User();
|
||||||
|
$this->setEntityId($actingUser, 99);
|
||||||
|
|
||||||
|
// Capture the UsersOrganizations entity when it is persisted to give it an ID
|
||||||
|
$this->entityManager->expects($this->exactly(2))
|
||||||
|
->method('persist')
|
||||||
|
->willReturnCallback(function ($entity) use ($user) {
|
||||||
|
if ($entity instanceof UsersOrganizations) {
|
||||||
|
// This is the UO entity link (Call 1)
|
||||||
|
$this->setEntityId($entity, 555);
|
||||||
|
} elseif ($entity instanceof User && $entity === $user) {
|
||||||
|
// This is the User entity inside generatePasswordToken (Call 2)
|
||||||
|
// The ID is already set, so we do nothing here.
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
$this->entityManager->expects($this->exactly(2))->method('flush');
|
||||||
|
|
||||||
|
|
||||||
|
// Now the logger will receive valid Integers instead of null
|
||||||
|
$this->loggerService->expects($this->once())
|
||||||
|
->method('logUserOrganizationLinkCreated')
|
||||||
|
->with(10, 50, 99, 555);
|
||||||
|
|
||||||
|
$this->emailService->expects($this->once())->method('sendPasswordSetupEmail');
|
||||||
|
$this->organizationsService->expects($this->once())->method('notifyOrganizationAdmins');
|
||||||
|
|
||||||
|
$result = $this->userService->linkUserToOrganization($user, $org, $actingUser);
|
||||||
|
|
||||||
|
$this->assertInstanceOf(UsersOrganizations::class, $result);
|
||||||
|
$this->assertEquals(555, $result->getId());
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testIsAdminOfOrganizationReturnsTrue(): void
|
||||||
|
{
|
||||||
|
$org = new Organizations();
|
||||||
|
|
||||||
|
$currentUser = new User();
|
||||||
|
$currentUser->setEmail('admin@test.com');
|
||||||
|
|
||||||
|
// Mock Security User
|
||||||
|
$this->security->method('getUser')->willReturn($currentUser);
|
||||||
|
$this->security->method('isGranted')->with('ROLE_ADMIN')->willReturn(true);
|
||||||
|
|
||||||
|
// 1. getUserByIdentifier (internal call) mocks
|
||||||
|
$userRepo = $this->createMock(EntityRepository::class);
|
||||||
|
$userRepo->method('findOneBy')->with(['email' => 'admin@test.com'])->willReturn($currentUser);
|
||||||
|
|
||||||
|
// 2. UsersOrganizations mock
|
||||||
|
$uoRepo = $this->createMock(EntityRepository::class);
|
||||||
|
$uo = new UsersOrganizations();
|
||||||
|
$uoRepo->method('findOneBy')->willReturn($uo);
|
||||||
|
|
||||||
|
// 3. Roles mock
|
||||||
|
$rolesRepo = $this->createMock(EntityRepository::class);
|
||||||
|
$adminRole = new Roles();
|
||||||
|
$adminRole->setName('ADMIN');
|
||||||
|
$rolesRepo->method('findOneBy')->with(['name' => 'ADMIN'])->willReturn($adminRole);
|
||||||
|
|
||||||
|
// 4. UserOrganizatonApp mock (The link checking if they are admin active)
|
||||||
|
$uoaRepo = $this->createMock(EntityRepository::class);
|
||||||
|
$uoa = new UserOrganizatonApp();
|
||||||
|
$uoaRepo->method('findOneBy')->willReturn($uoa); // Returns an object, so true
|
||||||
|
|
||||||
|
// Configure EntityManager to return these repos based on class
|
||||||
|
$this->entityManager->method('getRepository')->willReturnMap([
|
||||||
|
[User::class, $userRepo],
|
||||||
|
[UsersOrganizations::class, $uoRepo],
|
||||||
|
[Roles::class, $rolesRepo],
|
||||||
|
[UserOrganizatonApp::class, $uoaRepo],
|
||||||
|
]);
|
||||||
|
|
||||||
|
$result = $this->userService->isAdminOfOrganization($org);
|
||||||
|
$this->assertTrue($result);
|
||||||
|
}
|
||||||
|
|
||||||
|
private function setEntityId(object $entity, int $id): void
|
||||||
|
{
|
||||||
|
$reflection = new \ReflectionClass($entity);
|
||||||
|
$property = $reflection->getProperty('id');
|
||||||
|
// $property->setAccessible(true); // Required for PHP < 8.1
|
||||||
|
$property->setValue($entity, $id);
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue