getMethod($method); $target->setAccessible(true); return $target->invokeArgs($route, $args); } beforeEach(function (): void { $this->oldTtl = getenv('INVOICING_PERIOD_DISTRIBUTION_V2_CACHE_TTL'); }); afterEach(function (): void { if ($this->oldTtl === false) { putenv('INVOICING_PERIOD_DISTRIBUTION_V2_CACHE_TTL'); return; } putenv('INVOICING_PERIOD_DISTRIBUTION_V2_CACHE_TTL=' . $this->oldTtl); }); it('uses sane ttl defaults and clamps negative ttl to zero', function (): void { $_SERVER['REQUEST_URI'] = '/superuser/invoicing/period/distribution/v2/all'; $route = new InvoicingPeriodRoute(); putenv('INVOICING_PERIOD_DISTRIBUTION_V2_CACHE_TTL'); expect(invoicing_period_route_invoke_private($route, 'getDistributionV2CacheTtl'))->toBe(300); putenv('INVOICING_PERIOD_DISTRIBUTION_V2_CACHE_TTL=120'); expect(invoicing_period_route_invoke_private($route, 'getDistributionV2CacheTtl'))->toBe(120); putenv('INVOICING_PERIOD_DISTRIBUTION_V2_CACHE_TTL=-10'); expect(invoicing_period_route_invoke_private($route, 'getDistributionV2CacheTtl'))->toBe(0); }); it('builds deterministic cache keys per scope and date range', function (): void { $_SERVER['REQUEST_URI'] = '/superuser/invoicing/period/distribution/v2/all'; $route = new InvoicingPeriodRoute(); $keyA = invoicing_period_route_invoke_private($route, 'getDistributionV2CacheKey', [ 'all', '2026-01-01 00:00:00', '2026-01-31 23:59:59', ]); $keyB = invoicing_period_route_invoke_private($route, 'getDistributionV2CacheKey', [ 'all', '2026-01-01 00:00:00', '2026-01-31 23:59:59', ]); $keyC = invoicing_period_route_invoke_private($route, 'getDistributionV2CacheKey', [ 'wash-subscriptions', '2026-01-01 00:00:00', '2026-01-31 23:59:59', ]); expect($keyA)->toBe($keyB); expect($keyA)->not->toBe($keyC); expect($keyA)->toStartWith('invoicing_period:distribution:v2:all:'); }); it('falls back to resolver directly when cache ttl is disabled', function (): void { $_SERVER['REQUEST_URI'] = '/superuser/invoicing/period/distribution/v2/all'; $route = new InvoicingPeriodRoute(); putenv('INVOICING_PERIOD_DISTRIBUTION_V2_CACHE_TTL=0'); $calls = 0; $result = invoicing_period_route_invoke_private($route, 'withCachedDistributionV2', [ 'all', '2026-01-01 00:00:00', '2026-01-31 23:59:59', function () use (&$calls): array { $calls++; return ['ok' => true]; }, ]); expect($result)->toBe(['ok' => true]); expect($calls)->toBe(1); });