createMock(SettingRepositoryInterface::class); $settings->expects($this->once())->method('set')->with('app_locale', null, 'setting.app_locale')->willReturn(true); $gateway = $this->newGateway($settings); $this->assertTrue($gateway->setAppLocale(' ')); } public function testSetAppThemeStoresNullForUnknownTheme(): void { $settings = $this->createMock(SettingRepositoryInterface::class); $settings->expects($this->once())->method('set')->with('app_theme', null, 'setting.app_theme')->willReturn(true); $gateway = $this->newGateway($settings); $this->assertTrue($gateway->setAppTheme('unknown')); } public function testBooleanFlagsUseExpectedDefaults(): void { $settings = $this->createMock(SettingRepositoryInterface::class); $settings->method('getValue')->willReturnMap([ ['app_theme_user', null], ['app_registration', null], ]); $gateway = $this->newGateway($settings); $this->assertTrue($gateway->isUserThemeAllowed()); $this->assertTrue($gateway->isRegistrationEnabled()); } public function testSetAppPrimaryColorNormalizesHexWithoutHash(): void { $settings = $this->createMock(SettingRepositoryInterface::class); $settings->expects($this->once()) ->method('set') ->with('app_primary_color', '#abc', 'setting.app_primary_color') ->willReturn(true); $gateway = $this->newGateway($settings); $this->assertTrue($gateway->setAppPrimaryColor('abc')); } public function testSetAppPrimaryColorRejectsInvalidValue(): void { $settings = $this->createMock(SettingRepositoryInterface::class); $settings->expects($this->never())->method('set'); $gateway = $this->newGateway($settings); $this->assertFalse($gateway->setAppPrimaryColor('not-a-color')); } private function newGateway(SettingRepositoryInterface $settingRepository): SettingsAppGateway { $themeConfigService = $this->createMock(ThemeConfigService::class); $themeConfigService->method('all')->willReturn(['light' => 'Light', 'dark' => 'Dark']); return new SettingsAppGateway(new SettingsMetadataGateway($settingRepository), $themeConfigService); } }