forked from fa/breadcrumb-the-shire
606 lines
24 KiB
PHP
606 lines
24 KiB
PHP
<?php
|
|
|
|
namespace MintyPHP\Tests\Service\User;
|
|
|
|
use MintyPHP\Repository\Support\DatabaseSessionRepository;
|
|
use MintyPHP\Repository\User\UserListQueryRepositoryInterface;
|
|
use MintyPHP\Repository\User\UserReadRepositoryInterface;
|
|
use MintyPHP\Repository\User\UserWriteRepositoryInterface;
|
|
use MintyPHP\Service\Audit\SystemAuditService;
|
|
use MintyPHP\Service\Tenant\TenantScopeService;
|
|
use MintyPHP\Service\User\UserAccountService;
|
|
use MintyPHP\Service\User\UserAssignmentService;
|
|
use MintyPHP\Service\User\UserDirectoryGateway;
|
|
use MintyPHP\Service\User\UserPasswordService;
|
|
use MintyPHP\Service\User\UserSettingsGateway;
|
|
use PHPUnit\Framework\TestCase;
|
|
|
|
class UserAccountServiceTest extends TestCase
|
|
{
|
|
public function testListPagedDropsTenantUserIdForGlobalAccess(): void
|
|
{
|
|
$scopeGateway = $this->createMock(TenantScopeService::class);
|
|
$scopeGateway->expects($this->once())
|
|
->method('hasGlobalAccess')
|
|
->with(99)
|
|
->willReturn(true);
|
|
|
|
$listQueryRepository = $this->createMock(UserListQueryRepositoryInterface::class);
|
|
$listQueryRepository->expects($this->once())
|
|
->method('listPaged')
|
|
->with($this->callback(static function (array $options): bool {
|
|
return !isset($options['tenantUserId'])
|
|
&& (int) ($options['page'] ?? 0) === 2;
|
|
}))
|
|
->willReturn(['rows' => [], 'total' => 0]);
|
|
|
|
$service = $this->newService(null, null, $listQueryRepository, null, null, null, $scopeGateway);
|
|
$result = $service->listPaged(['page' => 2, 'tenantUserId' => 99]);
|
|
|
|
$this->assertSame(0, (int) ($result['total'] ?? -1));
|
|
}
|
|
|
|
public function testDeleteByUuidReturnsNotFoundForEmptyUuid(): void
|
|
{
|
|
$service = $this->newService();
|
|
|
|
$result = $service->deleteByUuid('');
|
|
|
|
$this->assertFalse($result['ok']);
|
|
$this->assertSame(404, (int) ($result['status'] ?? 0));
|
|
$this->assertSame('not_found', (string) ($result['error'] ?? ''));
|
|
}
|
|
|
|
public function testDeleteByUuidPreventsSelfDelete(): void
|
|
{
|
|
$readRepository = $this->createMock(UserReadRepositoryInterface::class);
|
|
$readRepository->expects($this->once())
|
|
->method('findByUuid')
|
|
->with('user-uuid')
|
|
->willReturn(['id' => 10, 'uuid' => 'user-uuid']);
|
|
|
|
$writeRepository = $this->createMock(UserWriteRepositoryInterface::class);
|
|
$writeRepository->expects($this->never())->method('delete');
|
|
|
|
$service = $this->newService($readRepository, $writeRepository);
|
|
$result = $service->deleteByUuid('user-uuid', 10);
|
|
|
|
$this->assertFalse($result['ok']);
|
|
$this->assertSame(400, (int) ($result['status'] ?? 0));
|
|
$this->assertSame('self_delete', (string) ($result['error'] ?? ''));
|
|
}
|
|
|
|
public function testDeleteByUuidDeletesAndRecordsAuditEvent(): void
|
|
{
|
|
$readRepository = $this->createMock(UserReadRepositoryInterface::class);
|
|
$readRepository->expects($this->once())
|
|
->method('findByUuid')
|
|
->with('user-uuid')
|
|
->willReturn(['id' => 11, 'uuid' => 'user-uuid']);
|
|
|
|
$writeRepository = $this->createMock(UserWriteRepositoryInterface::class);
|
|
$writeRepository->expects($this->once())
|
|
->method('delete')
|
|
->with(11)
|
|
->willReturn(true);
|
|
|
|
$auditService = $this->createMock(SystemAuditService::class);
|
|
$auditService->expects($this->once())
|
|
->method('record')
|
|
->with(
|
|
'admin.users.delete',
|
|
'success',
|
|
$this->callback(static function (array $context): bool {
|
|
return (int) ($context['actor_user_id'] ?? 0) === 44
|
|
&& (int) ($context['target_id'] ?? 0) === 11
|
|
&& (string) ($context['target_uuid'] ?? '') === 'user-uuid';
|
|
})
|
|
);
|
|
|
|
$service = $this->newService($readRepository, $writeRepository, null, null, null, null, null, null, $auditService);
|
|
$result = $service->deleteByUuid('user-uuid', 44);
|
|
|
|
$this->assertTrue($result['ok']);
|
|
$this->assertSame(11, (int) (($result['user'] ?? [])['id'] ?? 0));
|
|
}
|
|
|
|
public function testDeleteByUuidsReturnsPermissionDeniedWhenNothingIsInScope(): void
|
|
{
|
|
$readRepository = $this->createMock(UserReadRepositoryInterface::class);
|
|
$readRepository->method('findByUuid')->willReturn(['id' => 51, 'uuid' => 'other-uuid']);
|
|
|
|
$scopeGateway = $this->createMock(TenantScopeService::class);
|
|
$scopeGateway->method('canAccess')->willReturn(false);
|
|
|
|
$writeRepository = $this->createMock(UserWriteRepositoryInterface::class);
|
|
$writeRepository->expects($this->never())->method('deleteByUuids');
|
|
|
|
$service = $this->newService($readRepository, $writeRepository, null, null, null, null, $scopeGateway);
|
|
$result = $service->deleteByUuids(['other-uuid'], 99);
|
|
|
|
$this->assertFalse($result['ok']);
|
|
$this->assertSame('permission_denied', (string) ($result['error'] ?? ''));
|
|
}
|
|
|
|
public function testDeleteByUuidsReturnsSelfDeleteWhenOnlyOwnUuidRemains(): void
|
|
{
|
|
$readRepository = $this->createMock(UserReadRepositoryInterface::class);
|
|
$readRepository->expects($this->once())
|
|
->method('findByUuid')
|
|
->with('self-uuid')
|
|
->willReturn(['id' => 99, 'uuid' => 'self-uuid']);
|
|
$readRepository->expects($this->once())
|
|
->method('find')
|
|
->with(99)
|
|
->willReturn(['id' => 99, 'uuid' => 'self-uuid']);
|
|
|
|
$writeRepository = $this->createMock(UserWriteRepositoryInterface::class);
|
|
$writeRepository->expects($this->never())->method('deleteByUuids');
|
|
|
|
$service = $this->newService($readRepository, $writeRepository);
|
|
$result = $service->deleteByUuids(['self-uuid'], 99);
|
|
|
|
$this->assertFalse($result['ok']);
|
|
$this->assertSame('self_delete', (string) ($result['error'] ?? ''));
|
|
}
|
|
|
|
public function testSetActiveByUuidPreventsSelfDeactivate(): void
|
|
{
|
|
$readRepository = $this->createMock(UserReadRepositoryInterface::class);
|
|
$readRepository->method('findByUuid')->willReturn(['id' => 42, 'uuid' => 'u-42']);
|
|
|
|
$writeRepository = $this->createMock(UserWriteRepositoryInterface::class);
|
|
$writeRepository->expects($this->never())->method('setActive');
|
|
|
|
$service = $this->newService($readRepository, $writeRepository);
|
|
$result = $service->setActiveByUuid('u-42', false, 42);
|
|
|
|
$this->assertFalse($result['ok']);
|
|
$this->assertSame(400, (int) ($result['status'] ?? 0));
|
|
$this->assertSame('self_deactivate', (string) ($result['error'] ?? ''));
|
|
}
|
|
|
|
public function testSetActiveByUuidUpdatesAssignmentsAndAudit(): void
|
|
{
|
|
$readRepository = $this->createMock(UserReadRepositoryInterface::class);
|
|
$readRepository->method('findByUuid')->willReturn(['id' => 33, 'uuid' => 'u-33', 'active' => 0]);
|
|
|
|
$writeRepository = $this->createMock(UserWriteRepositoryInterface::class);
|
|
$writeRepository->expects($this->once())
|
|
->method('setActive')
|
|
->with(33, true, 90)
|
|
->willReturn(true);
|
|
|
|
$assignmentService = $this->createMock(UserAssignmentService::class);
|
|
$assignmentService->expects($this->once())
|
|
->method('bumpAuthzVersion')
|
|
->with(33);
|
|
|
|
$auditService = $this->createMock(SystemAuditService::class);
|
|
$auditService->expects($this->once())
|
|
->method('record')
|
|
->with(
|
|
'admin.users.activate',
|
|
'success',
|
|
$this->callback(static fn ($context): bool => is_array($context))
|
|
);
|
|
|
|
$service = $this->newService($readRepository, $writeRepository, null, $assignmentService, null, null, null, null, $auditService);
|
|
$result = $service->setActiveByUuid('u-33', true, 90);
|
|
|
|
$this->assertTrue($result['ok']);
|
|
}
|
|
|
|
public function testSetActiveByUuidsBumpsAuthzVersionForResolvedUserIds(): void
|
|
{
|
|
$writeRepository = $this->createMock(UserWriteRepositoryInterface::class);
|
|
$writeRepository->expects($this->once())
|
|
->method('setActiveByUuids')
|
|
->with(['u-1', 'u-2'], false, 7)
|
|
->willReturn(true);
|
|
$writeRepository->expects($this->once())
|
|
->method('bumpAuthzVersionByUserIds')
|
|
->with([11, 12])
|
|
->willReturn(2);
|
|
|
|
$readRepository = $this->createMock(UserReadRepositoryInterface::class);
|
|
$readRepository->method('findByUuid')->willReturnMap([
|
|
['u-1', ['id' => 11, 'uuid' => 'u-1']],
|
|
['u-2', ['id' => 12, 'uuid' => 'u-2']],
|
|
]);
|
|
|
|
$scopeGateway = $this->createMock(TenantScopeService::class);
|
|
$scopeGateway->method('canAccess')->willReturn(true);
|
|
|
|
$auditService = $this->createMock(SystemAuditService::class);
|
|
$auditService->expects($this->once())
|
|
->method('record')
|
|
->with(
|
|
'admin.users.bulk_update',
|
|
'success',
|
|
$this->callback(static fn ($context): bool => is_array($context))
|
|
);
|
|
|
|
$service = $this->newService($readRepository, $writeRepository, null, null, null, null, $scopeGateway, null, $auditService);
|
|
$result = $service->setActiveByUuids(['u-1', 'u-2'], false, 7);
|
|
|
|
$this->assertTrue($result['ok']);
|
|
$this->assertSame(2, (int) ($result['count'] ?? 0));
|
|
}
|
|
|
|
public function testRegisterCreatesUserAndAssignsDefaultEntities(): void
|
|
{
|
|
$passwordService = $this->createMock(UserPasswordService::class);
|
|
$passwordService->method('validatePassword')->willReturn([]);
|
|
|
|
$settingsGateway = $this->createMock(UserSettingsGateway::class);
|
|
$settingsGateway->method('getAppTheme')->willReturn('dark');
|
|
$settingsGateway->method('getDefaultTenantId')->willReturn(3);
|
|
$settingsGateway->method('getDefaultRoleId')->willReturn(4);
|
|
$settingsGateway->method('getDefaultDepartmentId')->willReturn(5);
|
|
|
|
$writeRepository = $this->createMock(UserWriteRepositoryInterface::class);
|
|
$writeRepository->expects($this->once())
|
|
->method('create')
|
|
->with($this->callback(static function (array $data): bool {
|
|
return (string) ($data['email'] ?? '') === 'user@example.com'
|
|
&& (string) ($data['theme'] ?? '') === 'dark'
|
|
&& (int) ($data['primary_tenant_id'] ?? 0) === 3
|
|
&& (int) ($data['active'] ?? 0) === 1;
|
|
}))
|
|
->willReturn(77);
|
|
|
|
$readRepository = $this->createMock(UserReadRepositoryInterface::class);
|
|
$readRepository->expects($this->exactly(2))
|
|
->method('findByEmail')
|
|
->with('user@example.com')
|
|
->willReturnOnConsecutiveCalls(
|
|
null,
|
|
['id' => 77, 'uuid' => 'user-uuid']
|
|
);
|
|
|
|
$assignmentService = $this->createMock(UserAssignmentService::class);
|
|
$assignmentService->expects($this->once())->method('syncTenants')->with(77, [3])->willReturn(true);
|
|
$assignmentService->expects($this->once())->method('syncRoles')->with(77, [4])->willReturn(true);
|
|
$assignmentService->expects($this->once())->method('syncDepartments')->with(77, [5])->willReturn(true);
|
|
|
|
$service = $this->newService(
|
|
$readRepository,
|
|
$writeRepository,
|
|
null,
|
|
$assignmentService,
|
|
$passwordService,
|
|
$settingsGateway
|
|
);
|
|
|
|
$result = $service->register([
|
|
'first_name' => 'Max',
|
|
'last_name' => 'Mustermann',
|
|
'email' => 'user@example.com',
|
|
'password' => 'StrongPass1!',
|
|
'password2' => 'StrongPass1!',
|
|
]);
|
|
|
|
$this->assertTrue($result['ok']);
|
|
}
|
|
|
|
public function testCreateFromAdminRollsBackTransactionWhenTenantSyncFails(): void
|
|
{
|
|
$passwordService = $this->createMock(UserPasswordService::class);
|
|
$passwordService->method('validatePassword')->willReturn([]);
|
|
|
|
$settingsGateway = $this->createMock(UserSettingsGateway::class);
|
|
$settingsGateway->method('getDefaultTenantId')->willReturn(null);
|
|
$settingsGateway->method('getDefaultRoleId')->willReturn(null);
|
|
$settingsGateway->method('getDefaultDepartmentId')->willReturn(null);
|
|
$settingsGateway->method('getAppTheme')->willReturn('light');
|
|
|
|
$writeRepository = $this->createMock(UserWriteRepositoryInterface::class);
|
|
$writeRepository->expects($this->once())->method('create')->willReturn(88);
|
|
|
|
$readRepository = $this->createMock(UserReadRepositoryInterface::class);
|
|
$readRepository->expects($this->exactly(2))
|
|
->method('findByEmail')
|
|
->with('create@example.com')
|
|
->willReturnOnConsecutiveCalls(
|
|
null,
|
|
['id' => 88, 'uuid' => 'user-uuid-88']
|
|
);
|
|
|
|
$assignmentService = $this->createMock(UserAssignmentService::class);
|
|
$assignmentService->expects($this->once())->method('normalizeTenantIds')->with([3])->willReturn([3]);
|
|
$assignmentService->expects($this->once())->method('syncTenants')->with(88, [3])->willReturn(false);
|
|
$assignmentService->expects($this->never())->method('syncRoles');
|
|
$assignmentService->expects($this->never())->method('syncDepartments');
|
|
|
|
$auditService = $this->createMock(SystemAuditService::class);
|
|
$auditService->expects($this->never())->method('record');
|
|
|
|
$databaseSessionRepository = $this->createMock(DatabaseSessionRepository::class);
|
|
$databaseSessionRepository->expects($this->once())->method('beginTransaction');
|
|
$databaseSessionRepository->expects($this->never())->method('commitTransaction');
|
|
$databaseSessionRepository->expects($this->once())->method('rollbackTransaction');
|
|
|
|
$service = $this->newService(
|
|
$readRepository,
|
|
$writeRepository,
|
|
null,
|
|
$assignmentService,
|
|
$passwordService,
|
|
$settingsGateway,
|
|
null,
|
|
null,
|
|
$auditService,
|
|
$databaseSessionRepository
|
|
);
|
|
|
|
$result = $service->createFromAdmin([
|
|
'first_name' => 'Max',
|
|
'last_name' => 'Mustermann',
|
|
'email' => 'create@example.com',
|
|
'password' => 'StrongPass1!',
|
|
'password2' => 'StrongPass1!',
|
|
'tenant_ids' => [3],
|
|
'active' => 1,
|
|
], 42);
|
|
|
|
$this->assertFalse($result['ok']);
|
|
$this->assertNotEmpty($result['errors'] ?? []);
|
|
}
|
|
|
|
public function testRegisterRollsBackTransactionWhenRoleSyncFails(): void
|
|
{
|
|
$passwordService = $this->createMock(UserPasswordService::class);
|
|
$passwordService->method('validatePassword')->willReturn([]);
|
|
|
|
$settingsGateway = $this->createMock(UserSettingsGateway::class);
|
|
$settingsGateway->method('getAppTheme')->willReturn('dark');
|
|
$settingsGateway->method('getDefaultTenantId')->willReturn(3);
|
|
$settingsGateway->method('getDefaultRoleId')->willReturn(4);
|
|
$settingsGateway->method('getDefaultDepartmentId')->willReturn(5);
|
|
|
|
$writeRepository = $this->createMock(UserWriteRepositoryInterface::class);
|
|
$writeRepository->expects($this->once())->method('create')->willReturn(77);
|
|
|
|
$readRepository = $this->createMock(UserReadRepositoryInterface::class);
|
|
$readRepository->expects($this->exactly(2))
|
|
->method('findByEmail')
|
|
->with('user@example.com')
|
|
->willReturnOnConsecutiveCalls(
|
|
null,
|
|
['id' => 77, 'uuid' => 'user-uuid']
|
|
);
|
|
|
|
$assignmentService = $this->createMock(UserAssignmentService::class);
|
|
$assignmentService->expects($this->once())->method('syncTenants')->with(77, [3])->willReturn(true);
|
|
$assignmentService->expects($this->once())->method('syncRoles')->with(77, [4])->willReturn(false);
|
|
$assignmentService->expects($this->never())->method('syncDepartments');
|
|
|
|
$databaseSessionRepository = $this->createMock(DatabaseSessionRepository::class);
|
|
$databaseSessionRepository->expects($this->once())->method('beginTransaction');
|
|
$databaseSessionRepository->expects($this->never())->method('commitTransaction');
|
|
$databaseSessionRepository->expects($this->once())->method('rollbackTransaction');
|
|
|
|
$service = $this->newService(
|
|
$readRepository,
|
|
$writeRepository,
|
|
null,
|
|
$assignmentService,
|
|
$passwordService,
|
|
$settingsGateway,
|
|
null,
|
|
null,
|
|
null,
|
|
$databaseSessionRepository
|
|
);
|
|
|
|
$result = $service->register([
|
|
'first_name' => 'Max',
|
|
'last_name' => 'Mustermann',
|
|
'email' => 'user@example.com',
|
|
'password' => 'StrongPass1!',
|
|
'password2' => 'StrongPass1!',
|
|
]);
|
|
|
|
$this->assertFalse($result['ok']);
|
|
$this->assertNotSame('', trim((string) ($result['error'] ?? '')));
|
|
}
|
|
|
|
public function testUpdateSelfProfileReturnsErrorWhenRequestedTenantIsNotAssigned(): void
|
|
{
|
|
$readRepository = $this->createMock(UserReadRepositoryInterface::class);
|
|
$readRepository->expects($this->once())
|
|
->method('find')
|
|
->with(15)
|
|
->willReturn([
|
|
'id' => 15,
|
|
'first_name' => 'Max',
|
|
'last_name' => 'Mustermann',
|
|
'locale' => 'de',
|
|
'theme' => 'light',
|
|
]);
|
|
|
|
$directoryGateway = $this->createMock(UserDirectoryGateway::class);
|
|
$directoryGateway->expects($this->once())
|
|
->method('findTenantByUuid')
|
|
->with('tenant-uuid-2')
|
|
->willReturn(['id' => 2, 'uuid' => 'tenant-uuid-2']);
|
|
|
|
$assignmentService = $this->createMock(UserAssignmentService::class);
|
|
$assignmentService->expects($this->once())
|
|
->method('buildAssignmentsForUser')
|
|
->with(15)
|
|
->willReturn([
|
|
'tenants' => [['id' => 1, 'uuid' => 'tenant-uuid-1']],
|
|
'roles' => [],
|
|
'departments' => [],
|
|
]);
|
|
|
|
$writeRepository = $this->createMock(UserWriteRepositoryInterface::class);
|
|
$writeRepository->expects($this->never())->method('update');
|
|
|
|
$service = $this->newService(
|
|
$readRepository,
|
|
$writeRepository,
|
|
null,
|
|
$assignmentService,
|
|
null,
|
|
null,
|
|
null,
|
|
$directoryGateway
|
|
);
|
|
|
|
$result = $service->updateSelfProfile(15, [
|
|
'first_name' => 'Max',
|
|
'last_name' => 'Mustermann',
|
|
'current_tenant_uuid' => 'tenant-uuid-2',
|
|
]);
|
|
|
|
$this->assertFalse($result['ok']);
|
|
$this->assertNotEmpty($result['errors']);
|
|
}
|
|
|
|
public function testUpdateSelfProfilePersistsDataAndTenantSwitchWhenAllowed(): void
|
|
{
|
|
$readRepository = $this->createMock(UserReadRepositoryInterface::class);
|
|
$readRepository->expects($this->once())
|
|
->method('find')
|
|
->with(21)
|
|
->willReturn([
|
|
'id' => 21,
|
|
'first_name' => 'Max',
|
|
'last_name' => 'Mustermann',
|
|
'profile_description' => '',
|
|
'job_title' => '',
|
|
'phone' => '',
|
|
'mobile' => '',
|
|
'short_dial' => '',
|
|
'address' => '',
|
|
'postal_code' => '',
|
|
'city' => '',
|
|
'country' => '',
|
|
'region' => '',
|
|
'locale' => 'de',
|
|
'theme' => 'light',
|
|
]);
|
|
|
|
$directoryGateway = $this->createMock(UserDirectoryGateway::class);
|
|
$directoryGateway->expects($this->once())
|
|
->method('findTenantByUuid')
|
|
->with('tenant-uuid-9')
|
|
->willReturn(['id' => 9, 'uuid' => 'tenant-uuid-9']);
|
|
|
|
$assignmentService = $this->createMock(UserAssignmentService::class);
|
|
$assignmentService->expects($this->once())
|
|
->method('buildAssignmentsForUser')
|
|
->with(21)
|
|
->willReturn([
|
|
'tenants' => [['id' => 9, 'uuid' => 'tenant-uuid-9']],
|
|
'roles' => [],
|
|
'departments' => [],
|
|
]);
|
|
|
|
$writeRepository = $this->createMock(UserWriteRepositoryInterface::class);
|
|
$writeRepository->expects($this->once())
|
|
->method('update')
|
|
->with(21, $this->callback(static fn ($payload): bool => is_array($payload)))
|
|
->willReturn(true);
|
|
$writeRepository->expects($this->once())
|
|
->method('setCurrentTenant')
|
|
->with(21, 9)
|
|
->willReturn(true);
|
|
|
|
$service = $this->newService(
|
|
$readRepository,
|
|
$writeRepository,
|
|
null,
|
|
$assignmentService,
|
|
null,
|
|
null,
|
|
null,
|
|
$directoryGateway
|
|
);
|
|
|
|
$result = $service->updateSelfProfile(21, [
|
|
'first_name' => 'Max',
|
|
'last_name' => 'Mustermann',
|
|
'current_tenant_uuid' => 'tenant-uuid-9',
|
|
'locale' => 'de',
|
|
'theme' => 'light',
|
|
]);
|
|
|
|
$this->assertTrue($result['ok']);
|
|
}
|
|
|
|
private function newService(
|
|
?UserReadRepositoryInterface $readRepository = null,
|
|
?UserWriteRepositoryInterface $writeRepository = null,
|
|
?UserListQueryRepositoryInterface $listQueryRepository = null,
|
|
?UserAssignmentService $assignmentService = null,
|
|
?UserPasswordService $passwordService = null,
|
|
?UserSettingsGateway $settingsGateway = null,
|
|
?TenantScopeService $scopeGateway = null,
|
|
?UserDirectoryGateway $directoryGateway = null,
|
|
?SystemAuditService $auditService = null,
|
|
?DatabaseSessionRepository $databaseSessionRepository = null
|
|
): UserAccountService {
|
|
$readRepository = $readRepository ?? $this->createMock(UserReadRepositoryInterface::class);
|
|
$writeRepository = $writeRepository ?? $this->createMock(UserWriteRepositoryInterface::class);
|
|
$listQueryRepository = $listQueryRepository ?? $this->createMock(UserListQueryRepositoryInterface::class);
|
|
|
|
if ($assignmentService === null) {
|
|
$assignmentService = $this->createMock(UserAssignmentService::class);
|
|
$assignmentService->method('normalizeTenantIds')->willReturn([]);
|
|
$assignmentService->method('normalizeIdInput')->willReturn([]);
|
|
$assignmentService->method('buildAssignmentsForUser')->willReturn([
|
|
'tenants' => [],
|
|
'roles' => [],
|
|
'departments' => [],
|
|
]);
|
|
$assignmentService->method('syncTenants')->willReturn(true);
|
|
$assignmentService->method('syncRoles')->willReturn(true);
|
|
$assignmentService->method('syncDepartments')->willReturn(true);
|
|
}
|
|
|
|
if ($passwordService === null) {
|
|
$passwordService = $this->createMock(UserPasswordService::class);
|
|
$passwordService->method('validatePassword')->willReturn([]);
|
|
}
|
|
|
|
if ($settingsGateway === null) {
|
|
$settingsGateway = $this->createMock(UserSettingsGateway::class);
|
|
$settingsGateway->method('getDefaultTenantId')->willReturn(null);
|
|
$settingsGateway->method('getDefaultRoleId')->willReturn(null);
|
|
$settingsGateway->method('getDefaultDepartmentId')->willReturn(null);
|
|
$settingsGateway->method('getAppTheme')->willReturn('light');
|
|
}
|
|
|
|
if ($scopeGateway === null) {
|
|
$scopeGateway = $this->createMock(TenantScopeService::class);
|
|
$scopeGateway->method('hasGlobalAccess')->willReturn(false);
|
|
$scopeGateway->method('canAccess')->willReturn(false);
|
|
}
|
|
|
|
if ($directoryGateway === null) {
|
|
$directoryGateway = $this->createMock(UserDirectoryGateway::class);
|
|
$directoryGateway->method('findTenantByUuid')->willReturn(null);
|
|
}
|
|
|
|
$auditService = $auditService ?? $this->createMock(SystemAuditService::class);
|
|
$databaseSessionRepository = $databaseSessionRepository ?? $this->createMock(DatabaseSessionRepository::class);
|
|
|
|
return new UserAccountService(
|
|
$readRepository,
|
|
$writeRepository,
|
|
$listQueryRepository,
|
|
$assignmentService,
|
|
$passwordService,
|
|
$settingsGateway,
|
|
$scopeGateway,
|
|
$directoryGateway,
|
|
$auditService,
|
|
$databaseSessionRepository
|
|
);
|
|
}
|
|
}
|