Files
preauth/tests/Unit/ConfigBagTest.php
T
lyra 9ad54f8e2a
Sync GitHub / sync (push) Successful in 7s
Tests / test (pull_request) Successful in 58s
feat: configurable Remote-User header (design consideration 1.2)
Add REMOTE_USER env var with four modes:
- session (default): sends session id, backward-compatible
- static: sends a fixed string (REMOTE_USER_STATIC)
- mapped: looks up session id in REMOTE_USER_MAP
- none: omits the header entirely

New RemoteUserMode enum, ConfigBag parsing/validation, and
StringTrait::authSuccessResponse resolves the header value based
on the configured mode. AcceptListener now receives ConfigBag as
a constructor dependency.

Addresses design consideration 1.2 (Remote-User header value is
user-controlled) from DESIGN_CONSIDERATIONS.md.

241 tests pass, 0 cs-fixer violations.
2026-08-11 22:48:52 -04:00

133 lines
3.4 KiB
PHP

<?php
declare(strict_types=1);
namespace App\Tests\Unit;
use App\ConfigBag;
use App\Utilities;
use PHPUnit\Framework\TestCase;
use Psr\Cache\CacheItemInterface;
use Psr\Cache\CacheItemPoolInterface;
use Psr\Clock\ClockInterface;
final class ConfigBagTest extends TestCase
{
private function createUtilities(?string $totp = null): Utilities
{
$clock = $this->createStub(ClockInterface::class);
$cache = $this->createStub(CacheItemPoolInterface::class);
if ($totp !== null) {
$item = $this->createStub(CacheItemInterface::class);
$item->method('isHit')->willReturn(true);
$item->method('get')->willReturn($totp);
$cache->method('hasItem')->willReturn(true);
$cache->method('getItem')->willReturn($item);
} else {
$cache->method('hasItem')->willReturn(false);
}
return new Utilities($clock, $cache);
}
public function testGettersWithExplicitValues(): void
{
$clock = $this->createStub(ClockInterface::class);
$utilities = $this->createUtilities();
$config = new ConfigBag(
$utilities,
$clock,
3600,
'otpauth://totp/test',
1800,
true,
'Error!',
'Teapot!',
'Too Many!',
'session',
'authenticated',
'',
);
self::assertSame($clock, $config->clock());
self::assertSame(3600, $config->cookieTtl());
self::assertSame('otpauth://totp/test', $config->totpUri());
self::assertSame(1800, $config->ipTtl());
self::assertTrue($config->teapot());
self::assertSame('Error!', $config->errorMessage());
self::assertSame('Teapot!', $config->teapotTitle());
self::assertSame('Too Many!', $config->tooManyTitle());
}
public function testTotpUriFallsBackToUtilitiesWhenEmpty(): void
{
$clock = $this->createStub(ClockInterface::class);
$utilities = $this->createUtilities('fallback-totp');
$config = new ConfigBag(
$utilities,
$clock,
3600,
'',
1800,
false,
'Error',
'Teapot',
'Too Many',
'session',
'authenticated',
'',
);
self::assertSame('fallback-totp', $config->totpUri());
}
public function testIpTtlFallsBackToNullWhenZero(): void
{
$clock = $this->createStub(ClockInterface::class);
$utilities = $this->createUtilities();
$config = new ConfigBag(
$utilities,
$clock,
3600,
'otpauth://totp/test',
0,
false,
'Error',
'Teapot',
'Too Many',
'session',
'authenticated',
'',
);
self::assertNull($config->ipTtl());
}
public function testIpTtlFallsBackToNullWhenNull(): void
{
$clock = $this->createStub(ClockInterface::class);
$utilities = $this->createUtilities();
$config = new ConfigBag(
$utilities,
$clock,
3600,
'otpauth://totp/test',
null,
false,
'Error',
'Teapot',
'Too Many',
'session',
'authenticated',
'',
);
self::assertNull($config->ipTtl());
}
}