Files
breadcrumb-the-shire/tests/Service/Auth/AuthSessionTenantContextServiceTest.php

153 lines
5.8 KiB
PHP
Raw Normal View History

2026-03-06 00:44:52 +01:00
<?php
namespace MintyPHP\Tests\Service\Auth;
use MintyPHP\App\AppContainer;
use MintyPHP\App\Module\Contracts\SessionProvider;
use MintyPHP\App\Module\ModuleRegistry;
2026-03-06 00:44:52 +01:00
use MintyPHP\Http\SessionStore;
use MintyPHP\Service\Auth\AuthSessionTenantContextService;
use MintyPHP\Service\User\UserTenantContextService;
use PHPUnit\Framework\TestCase;
class AuthSessionTenantContextServiceTest extends TestCase
{
protected function setUp(): void
{
$_SESSION = [];
DummyAuthSessionProvider::$populateCalls = 0;
DummyAuthSessionProvider::$clearCalls = 0;
2026-03-06 00:44:52 +01:00
}
public function testHydrateMarksNoActiveTenantWhenUserHasNoTenants(): void
{
$_SESSION['current_tenant'] = ['id' => 9];
$userTenantContextService = $this->createMock(UserTenantContextService::class);
$userTenantContextService->method('getAvailableTenants')->willReturn([]);
$userTenantContextService->expects($this->never())->method('getCurrentTenant');
$service = $this->createService($userTenantContextService);
2026-03-06 00:44:52 +01:00
$service->hydrateForUser(5);
$this->assertSame([], $_SESSION['available_tenants']);
$this->assertTrue((bool) $_SESSION['no_active_tenant']);
$this->assertArrayNotHasKey('current_tenant', $_SESSION);
$this->assertArrayNotHasKey('module.addressbook.departments_by_tenant', $_SESSION);
2026-03-06 00:44:52 +01:00
}
public function testHydrateUsesFirstAvailableTenantAsFallback(): void
{
$availableTenants = [
['id' => 7, 'uuid' => 'tenant-7'],
['id' => 8, 'uuid' => 'tenant-8'],
];
$userTenantContextService = $this->createMock(UserTenantContextService::class);
$userTenantContextService->method('getAvailableTenants')->willReturn($availableTenants);
$userTenantContextService->method('getCurrentTenant')->willReturn(null);
$service = $this->createService($userTenantContextService);
2026-03-06 00:44:52 +01:00
$service->hydrateForUser(5);
$this->assertSame($availableTenants, $_SESSION['available_tenants']);
$this->assertFalse((bool) $_SESSION['no_active_tenant']);
$this->assertSame(7, (int) ($_SESSION['current_tenant']['id'] ?? 0));
$this->assertArrayNotHasKey('module.addressbook.departments_by_tenant', $_SESSION);
2026-03-06 00:44:52 +01:00
}
public function testHydratePreservesThemeAndPolicyFieldsInSession(): void
{
$availableTenants = [
[
'id' => 3,
'uuid' => 'tenant-3',
'default_theme' => 'dark',
'allow_user_theme' => '0',
],
];
$userTenantContextService = $this->createMock(UserTenantContextService::class);
$userTenantContextService->method('getAvailableTenants')->willReturn($availableTenants);
$userTenantContextService->method('getCurrentTenant')->willReturn($availableTenants[0]);
$service = $this->createService($userTenantContextService);
$service->hydrateForUser(10);
$tenant = $_SESSION['current_tenant'] ?? [];
$this->assertSame('dark', $tenant['default_theme'] ?? null);
$this->assertSame('0', $tenant['allow_user_theme'] ?? null);
}
public function testHydrateAndClearInvokeConfiguredModuleSessionProviders(): void
{
$fixturesDir = sys_get_temp_dir() . '/auth-session-provider-test-' . uniqid();
mkdir($fixturesDir . '/mod-session', 0777, true);
file_put_contents(
$fixturesDir . '/mod-session/module.php',
'<?php return ' . var_export([
'id' => 'mod-session',
'session_providers' => [DummyAuthSessionProvider::class],
], true) . ';'
);
try {
$registry = ModuleRegistry::boot($fixturesDir, ['mod-session']);
$userTenantContextService = $this->createMock(UserTenantContextService::class);
$userTenantContextService->method('getAvailableTenants')->willReturn([['id' => 7, 'uuid' => 'tenant-7']]);
$userTenantContextService->method('getCurrentTenant')->willReturn(['id' => 7, 'uuid' => 'tenant-7']);
$service = $this->createService($userTenantContextService, $registry);
$_SESSION['user'] = ['id' => 42];
$service->hydrateForUser(42);
$this->assertSame(1, DummyAuthSessionProvider::$populateCalls);
$this->assertSame(42, (int) ($_SESSION['dummy_provider_user_id'] ?? 0));
$service->clearModuleSessionData();
$this->assertSame(1, DummyAuthSessionProvider::$clearCalls);
$this->assertArrayNotHasKey('dummy_provider_user_id', $_SESSION);
} finally {
@unlink($fixturesDir . '/mod-session/module.php');
@rmdir($fixturesDir . '/mod-session');
@rmdir($fixturesDir);
}
}
private function createService(
UserTenantContextService $userTenantContextService,
?ModuleRegistry $registry = null
): AuthSessionTenantContextService {
$registry ??= ModuleRegistry::boot(sys_get_temp_dir() . '/module-registry-empty-' . uniqid(), []);
$container = new AppContainer();
$container->set(ModuleRegistry::class, static fn (): ModuleRegistry => $registry);
return new AuthSessionTenantContextService(
$userTenantContextService,
new SessionStore(),
$container
);
}
}
final class DummyAuthSessionProvider implements SessionProvider
{
public static int $populateCalls = 0;
public static int $clearCalls = 0;
public function populate(array $user, AppContainer $container): void
{
self::$populateCalls++;
$_SESSION['dummy_provider_user_id'] = (int) ($user['id'] ?? 0);
}
public function clear(AppContainer $container): void
{
self::$clearCalls++;
unset($_SESSION['dummy_provider_user_id']);
}
2026-03-06 00:44:52 +01:00
}