createMock(SettingRepositoryInterface::class); $settings->method('getValue')->willReturnCallback(static function (string $key): ?string { return null; }); $gateway = new SettingsFrontendTelemetryGateway(new SettingsMetadataGateway($settings)); $this->assertFalse($gateway->isFrontendTelemetryEnabled()); } public function testIsFrontendTelemetryEnabledReturnsTrueWhenEnabled(): void { $settings = $this->createMock(SettingRepositoryInterface::class); $settings->method('getValue')->willReturnCallback(static function (string $key): ?string { return match ($key) { 'frontend_telemetry_enabled' => '1', default => null, }; }); $gateway = new SettingsFrontendTelemetryGateway(new SettingsMetadataGateway($settings)); $this->assertTrue($gateway->isFrontendTelemetryEnabled()); } public function testGetFrontendTelemetrySampleRateDefaultsToPointTwo(): void { $settings = $this->createMock(SettingRepositoryInterface::class); $settings->method('getValue')->willReturnCallback(static function (string $key): ?string { return null; }); $gateway = new SettingsFrontendTelemetryGateway(new SettingsMetadataGateway($settings)); $this->assertSame(0.2, $gateway->getFrontendTelemetrySampleRate()); } public function testGetFrontendTelemetrySampleRateClampsToZero(): void { $settings = $this->createMock(SettingRepositoryInterface::class); $settings->method('getValue')->willReturnCallback(static function (string $key): ?string { return match ($key) { 'frontend_telemetry_sample_rate' => '-0.5', default => null, }; }); $gateway = new SettingsFrontendTelemetryGateway(new SettingsMetadataGateway($settings)); // Out-of-range values fall back to the default 0.2 $this->assertSame(0.2, $gateway->getFrontendTelemetrySampleRate()); } public function testGetFrontendTelemetrySampleRateClampsToOne(): void { $settings = $this->createMock(SettingRepositoryInterface::class); $settings->method('getValue')->willReturnCallback(static function (string $key): ?string { return match ($key) { 'frontend_telemetry_sample_rate' => '1.5', default => null, }; }); $gateway = new SettingsFrontendTelemetryGateway(new SettingsMetadataGateway($settings)); // Out-of-range values fall back to the default 0.2 $this->assertSame(0.2, $gateway->getFrontendTelemetrySampleRate()); } public function testGetFrontendTelemetryAllowedEventsReturnsDefaults(): void { $settings = $this->createMock(SettingRepositoryInterface::class); $settings->method('getValue')->willReturnCallback(static function (string $key): ?string { return null; }); $gateway = new SettingsFrontendTelemetryGateway(new SettingsMetadataGateway($settings)); $this->assertSame(['warn_once', 'ajax_error'], $gateway->getFrontendTelemetryAllowedEvents()); } public function testSetFrontendTelemetryAllowedEventsNormalizesAndDeduplicates(): void { $settings = $this->createMock(SettingRepositoryInterface::class); $stored = null; $settings->expects($this->once()) ->method('set') ->willReturnCallback(static function (string $key, ?string $value) use (&$stored): bool { if ($key === 'frontend_telemetry_allowed_events') { $stored = $value; } return true; }); $settings->method('getValue')->willReturnCallback(static function (string $key) use (&$stored): ?string { return match ($key) { 'frontend_telemetry_allowed_events' => $stored, default => null, }; }); $gateway = new SettingsFrontendTelemetryGateway(new SettingsMetadataGateway($settings)); // Pass duplicates with mixed casing and frontend. prefix $this->assertTrue($gateway->setFrontendTelemetryAllowedEvents('frontend.WARN_ONCE, warn_once, AJAX_ERROR')); // Stored value should be sorted, deduplicated, and lowercased $this->assertSame('ajax_error,warn_once', $stored); } }