cache = new CoreCacheDriver('array'); $this->app->instance(CacheInterface::class, $this->cache); } protected function tearDown(): void { Cache::flush(); // 설정 초기화 Config::set('g7_settings.core.cache', []); parent::tearDown(); } /** * S-1: AbstractCacheDriver 기본 TTL 이 g7_core_settings('cache.default_ttl') 추종. */ #[Test] public function s_1_default_ttl_follows_settings(): void { Config::set('g7_settings.core.cache.default_ttl', 7200); $reflection = new \ReflectionMethod(CoreCacheDriver::class, 'getDefaultTtl'); $reflection->setAccessible(true); $this->assertSame(7200, $reflection->invoke($this->cache)); } /** * S-2: g7_core_settings 변경 시 TTL 즉시 반영. */ #[Test] public function s_2_settings_change_reflects_immediately(): void { Config::set('g7_settings.core.cache.default_ttl', 86400); $reflection = new \ReflectionMethod(CoreCacheDriver::class, 'getDefaultTtl'); $reflection->setAccessible(true); $this->assertSame(86400, $reflection->invoke($this->cache)); // 설정 변경 Config::set('g7_settings.core.cache.default_ttl', 3600); $this->assertSame(3600, $reflection->invoke($this->cache)); } /** * S-3: 레이아웃 캐시 TTL 이 cache.layout_ttl 추종. */ #[Test] public function s_3_layout_ttl_follows_settings(): void { Config::set('g7_settings.core.cache.layout_ttl', 1800); $service = app(\App\Services\LayoutService::class); $reflection = new \ReflectionMethod($service, 'getCacheTtl'); $reflection->setAccessible(true); $this->assertSame(1800, $reflection->invoke($service)); } /** * S-4: SEO 캐시 TTL 이 cache.seo_ttl 추종. */ #[Test] public function s_4_seo_ttl_follows_settings(): void { Config::set('g7_settings.core.cache.seo_ttl', 3600); $manager = new \App\Seo\SeoCacheManager($this->cache); $reflection = new \ReflectionMethod($manager, 'getCacheTtl'); $reflection->setAccessible(true); $this->assertSame(3600, $reflection->invoke($manager)); } /** * S-5: 알림 캐시 TTL 이 cache.notification_ttl 추종. */ #[Test] public function s_5_notification_ttl_follows_settings(): void { Config::set('g7_settings.core.cache.notification_ttl', 7200); $service = app(\App\Services\NotificationDefinitionService::class); $reflection = new \ReflectionMethod($service, 'getCacheTtl'); $reflection->setAccessible(true); $this->assertSame(7200, $reflection->invoke($service)); } /** * S-6: GeoIP 캐시 TTL 이 cache.geoip_ttl 추종. */ #[Test] public function s_6_geoip_ttl_follows_settings(): void { Config::set('g7_settings.core.cache.geoip_ttl', 43200); Config::set('geoip.enabled', true); Config::set('geoip.cache.enabled', true); Config::set('geoip.database_path', '/nonexistent'); $service = app(\App\Services\GeoIpService::class); $service->getTimezoneByIp('1.2.3.4', ['Asia/Seoul']); // 빈 문자열이 캐시되었는지 + TTL 설정 값 반영 (간접 검증) $this->assertTrue($this->cache->has('geoip.timezone.1.2.3.4')); $this->assertSame( 43200, (int) g7_core_settings('cache.geoip_ttl', 86400) ); } /** * S-7: 버전 검증 캐시 TTL 이 cache.version_check_ttl 추종. */ #[Test] public function s_7_version_check_ttl_follows_settings(): void { Config::set('g7_settings.core.cache.version_check_ttl', 7200); $this->assertSame(7200, CoreVersionChecker::getCacheTtl()); } /** * S-8: 확장 상태 캐시 TTL 이 cache.extension_status_ttl 추종. */ #[Test] public function s_8_extension_status_ttl_follows_settings(): void { Config::set('g7_settings.core.cache.extension_status_ttl', 43200); $this->assertSame( 43200, (int) g7_core_settings('cache.extension_status_ttl', 86400) ); } /** * S-9: Sitemap 캐시 TTL 이 cache.seo_sitemap_ttl 추종. */ #[Test] public function s_9_sitemap_ttl_follows_settings(): void { Config::set('g7_settings.core.cache.seo_sitemap_ttl', 172800); $this->assertSame( 172800, (int) g7_core_settings('cache.seo_sitemap_ttl', 86400) ); } /** * S-10: SEO 캐시 비활성화 시 저장 안 함. */ #[Test] public function s_10_seo_disable_does_not_store(): void { Config::set('g7_settings.core.cache.seo_enabled', false); $manager = new \App\Seo\SeoCacheManager($this->cache); $manager->put('/page', 'ko', ''); $this->assertNull($manager->get('/page', 'ko')); } /** * S-11: GeoIP 캐시 비활성화 시 저장 안 함. */ #[Test] public function s_11_geoip_disable_does_not_store(): void { Config::set('geoip.enabled', true); Config::set('g7_settings.core.cache.geoip_enabled', false); Config::set('geoip.database_path', '/nonexistent'); $service = app(\App\Services\GeoIpService::class); $service->getTimezoneByIp('5.6.7.8', ['Asia/Seoul']); $this->assertFalse($this->cache->has('geoip.timezone.5.6.7.8')); } /** * S-12: 레이아웃 캐시 비활성화 시 캐시 미사용. */ #[Test] public function s_12_layout_disable_skips_cache(): void { Config::set('g7_settings.core.cache.layout_enabled', false); // LayoutService 의 loadAndMergeLayout 은 cacheEnabled=false 인 경우 // 캐시 키를 사용하지 않고 매번 병합한다 (단위 테스트로는 통합 검증 불가). // 대신 설정이 false 로 인식되는지만 검증. $this->assertFalse((bool) g7_core_settings('cache.layout_enabled', true)); } /** * S-13: remember() 명시적 TTL 이 g7_core_settings 기본값보다 우선. */ #[Test] public function s_13_explicit_ttl_overrides_settings(): void { Config::set('g7_settings.core.cache.default_ttl', 86400); // 300 초로 명시 — 기본값이 무시되어야 함 $this->cache->put('explicit.ttl.test', 'value', 300); // put 은 storage 에 저장만 하므로 TTL 값을 직접 검증할 수는 없으나, // 명시적 TTL 인자를 받았을 때 default 가 사용되지 않음은 코드로 보장됨. $this->assertTrue($this->cache->has('explicit.ttl.test')); } /** * S-14: defaults.json 미설정 시 하드코딩 fallback 사용. */ #[Test] public function s_14_missing_setting_uses_hardcoded_fallback(): void { // 명시적으로 미설정 Config::set('g7_settings.core.cache.notification_ttl', null); $service = app(\App\Services\NotificationDefinitionService::class); $reflection = new \ReflectionMethod($service, 'getCacheTtl'); $reflection->setAccessible(true); // null 일 때 fallback 3600 사용 $this->assertSame(3600, $reflection->invoke($service)); } }