2026-03-19 19:45:16 +01:00
|
|
|
<?php
|
|
|
|
|
|
|
|
|
|
namespace MintyPHP\Tests\Service\Settings;
|
|
|
|
|
|
|
|
|
|
use MintyPHP\Repository\Settings\SettingRepositoryInterface;
|
|
|
|
|
use MintyPHP\Service\Settings\SettingsLoginPersistenceGateway;
|
|
|
|
|
use MintyPHP\Service\Settings\SettingsMetadataGateway;
|
|
|
|
|
use MintyPHP\Service\Settings\SettingsSessionGateway;
|
|
|
|
|
use PHPUnit\Framework\TestCase;
|
|
|
|
|
|
|
|
|
|
final class SettingsSessionPolicyGatewayTest extends TestCase
|
|
|
|
|
{
|
|
|
|
|
public function testSessionTimeoutsUseFallbacksWhenMissing(): void
|
|
|
|
|
{
|
|
|
|
|
$gateway = $this->newSessionGateway(null, null);
|
|
|
|
|
|
|
|
|
|
self::assertSame(30, $gateway->getSessionIdleTimeoutMinutes());
|
|
|
|
|
self::assertSame(8, $gateway->getSessionAbsoluteTimeoutHours());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function testSessionTimeoutsUseStoredValuesWhenValid(): void
|
|
|
|
|
{
|
|
|
|
|
$gateway = $this->newSessionGateway('15', '12');
|
|
|
|
|
|
|
|
|
|
self::assertSame(15, $gateway->getSessionIdleTimeoutMinutes());
|
|
|
|
|
self::assertSame(12, $gateway->getSessionAbsoluteTimeoutHours());
|
|
|
|
|
self::assertSame(900, $gateway->getSessionIdleTimeoutSeconds());
|
|
|
|
|
self::assertSame(43200, $gateway->getSessionAbsoluteTimeoutSeconds());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function testSessionTimeoutsFallbackWhenOutOfBounds(): void
|
|
|
|
|
{
|
|
|
|
|
$gateway = $this->newSessionGateway('2', '100');
|
|
|
|
|
|
|
|
|
|
self::assertSame(30, $gateway->getSessionIdleTimeoutMinutes());
|
|
|
|
|
self::assertSame(8, $gateway->getSessionAbsoluteTimeoutHours());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function testSessionSettersRejectInvalidValues(): void
|
|
|
|
|
{
|
|
|
|
|
$settings = $this->createMock(SettingRepositoryInterface::class);
|
|
|
|
|
$settings->expects($this->never())->method('set');
|
|
|
|
|
|
|
|
|
|
$gateway = new SettingsSessionGateway(new SettingsMetadataGateway($settings));
|
|
|
|
|
self::assertFalse($gateway->setSessionIdleTimeoutMinutes(2));
|
|
|
|
|
self::assertFalse($gateway->setSessionIdleTimeoutMinutes(2000));
|
|
|
|
|
self::assertFalse($gateway->setSessionAbsoluteTimeoutHours(0));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function testAutoRememberDefaultUsesExpectedBooleanNormalization(): void
|
|
|
|
|
{
|
|
|
|
|
$metadata = $this->createMock(SettingsMetadataGateway::class);
|
|
|
|
|
$metadata->method('getValue')->willReturnMap([
|
|
|
|
|
['microsoft_auto_remember_default', null],
|
|
|
|
|
['microsoft_auto_remember_default', '1'],
|
|
|
|
|
]);
|
|
|
|
|
|
|
|
|
|
$gateway = new SettingsLoginPersistenceGateway($metadata);
|
|
|
|
|
self::assertFalse($gateway->isMicrosoftAutoRememberDefault());
|
|
|
|
|
|
|
|
|
|
$metadataTrue = $this->createMock(SettingsMetadataGateway::class);
|
2026-03-22 14:15:36 +01:00
|
|
|
$metadataTrue->expects($this->any())->method('getValue')->with('microsoft_auto_remember_default')->willReturn('1');
|
2026-03-19 19:45:16 +01:00
|
|
|
$gatewayTrue = new SettingsLoginPersistenceGateway($metadataTrue);
|
|
|
|
|
self::assertTrue($gatewayTrue->isMicrosoftAutoRememberDefault());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function testAutoRememberSetterPersistsBooleanFlag(): void
|
|
|
|
|
{
|
|
|
|
|
$metadata = $this->createMock(SettingsMetadataGateway::class);
|
|
|
|
|
$metadata->expects($this->exactly(2))
|
|
|
|
|
->method('set')
|
|
|
|
|
->willReturnCallback(static function (string $key, ?string $value): bool {
|
|
|
|
|
return $key === 'microsoft_auto_remember_default'
|
|
|
|
|
&& in_array($value, ['0', '1'], true);
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
$gateway = new SettingsLoginPersistenceGateway($metadata);
|
|
|
|
|
self::assertTrue($gateway->setMicrosoftAutoRememberDefault(true));
|
|
|
|
|
self::assertTrue($gateway->setMicrosoftAutoRememberDefault(false));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function testRememberTokenLifetimeUsesFallbackWhenMissingOrInvalid(): void
|
|
|
|
|
{
|
|
|
|
|
$metadataMissing = $this->createMock(SettingsMetadataGateway::class);
|
2026-03-22 14:15:36 +01:00
|
|
|
$metadataMissing->expects($this->any())->method('getInt')->with('remember_token_lifetime_days')->willReturn(null);
|
2026-03-19 19:45:16 +01:00
|
|
|
$gatewayMissing = new SettingsLoginPersistenceGateway($metadataMissing);
|
|
|
|
|
self::assertSame(30, $gatewayMissing->getRememberTokenLifetimeDays());
|
|
|
|
|
self::assertSame(30 * 86400, $gatewayMissing->getRememberTokenLifetimeSeconds());
|
|
|
|
|
|
|
|
|
|
$metadataInvalid = $this->createMock(SettingsMetadataGateway::class);
|
2026-03-22 14:15:36 +01:00
|
|
|
$metadataInvalid->expects($this->any())->method('getInt')->with('remember_token_lifetime_days')->willReturn(500);
|
2026-03-19 19:45:16 +01:00
|
|
|
$gatewayInvalid = new SettingsLoginPersistenceGateway($metadataInvalid);
|
|
|
|
|
self::assertSame(30, $gatewayInvalid->getRememberTokenLifetimeDays());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function testRememberTokenLifetimeAcceptsValidRangeAndComputesSeconds(): void
|
|
|
|
|
{
|
|
|
|
|
$metadata = $this->createMock(SettingsMetadataGateway::class);
|
2026-03-22 14:15:36 +01:00
|
|
|
$metadata->expects($this->any())->method('getInt')->with('remember_token_lifetime_days')->willReturn(7);
|
2026-03-19 19:45:16 +01:00
|
|
|
$metadata->expects($this->once())
|
|
|
|
|
->method('set')
|
|
|
|
|
->with('remember_token_lifetime_days', '14', $this->anything())
|
|
|
|
|
->willReturn(true);
|
|
|
|
|
|
|
|
|
|
$gateway = new SettingsLoginPersistenceGateway($metadata);
|
|
|
|
|
self::assertSame(7, $gateway->getRememberTokenLifetimeDays());
|
|
|
|
|
self::assertSame(7 * 86400, $gateway->getRememberTokenLifetimeSeconds());
|
|
|
|
|
self::assertTrue($gateway->setRememberTokenLifetimeDays(14));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function testRememberTokenLifetimeRejectsInvalidRangeAndNullUsesDefault(): void
|
|
|
|
|
{
|
|
|
|
|
$rejectingMetadata = $this->createMock(SettingsMetadataGateway::class);
|
|
|
|
|
$rejectingMetadata->expects($this->never())->method('set');
|
|
|
|
|
$rejectingGateway = new SettingsLoginPersistenceGateway($rejectingMetadata);
|
|
|
|
|
self::assertFalse($rejectingGateway->setRememberTokenLifetimeDays(0));
|
|
|
|
|
self::assertFalse($rejectingGateway->setRememberTokenLifetimeDays(400));
|
|
|
|
|
|
|
|
|
|
$defaultingMetadata = $this->createMock(SettingsMetadataGateway::class);
|
|
|
|
|
$defaultingMetadata->expects($this->once())
|
|
|
|
|
->method('set')
|
|
|
|
|
->with('remember_token_lifetime_days', '30', $this->anything())
|
|
|
|
|
->willReturn(true);
|
|
|
|
|
$defaultingGateway = new SettingsLoginPersistenceGateway($defaultingMetadata);
|
|
|
|
|
self::assertTrue($defaultingGateway->setRememberTokenLifetimeDays(null));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private function newSessionGateway(?string $idle, ?string $absolute): SettingsSessionGateway
|
|
|
|
|
{
|
|
|
|
|
$settings = $this->createMock(SettingRepositoryInterface::class);
|
|
|
|
|
$settings->method('getValue')->willReturnCallback(
|
|
|
|
|
static function (string $key) use ($idle, $absolute): ?string {
|
|
|
|
|
return match ($key) {
|
|
|
|
|
'session_idle_timeout_minutes' => $idle,
|
|
|
|
|
'session_absolute_timeout_hours' => $absolute,
|
|
|
|
|
default => null,
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
return new SettingsSessionGateway(new SettingsMetadataGateway($settings));
|
|
|
|
|
}
|
|
|
|
|
}
|