'core', 'source_identifier' => 'og_image_default', 'hash' => bin2hex(random_bytes(6)), 'original_filename' => 'og-default.png', 'stored_filename' => 'og-default-'.uniqid().'.png', 'disk' => 'public', 'path' => 'settings/og-default.png', 'mime_type' => 'image/png', 'size' => 1024, 'collection' => 'og_image_default', 'order' => 0, ]); } /** * 기존 설치본에도 새 키가 기본값으로 노출되는지 확인합니다 (defaults 병합). * * @scenario image_chain=none, setting_state=absent * * @effects og_default_image_persists_to_seo_category */ public function test_new_key_present_through_defaults_merge(): void { $seo = app(ConfigRepositoryInterface::class)->getCategory('seo'); $this->assertArrayHasKey('og_image_default', $seo); $this->assertSame([], $seo['og_image_default']); } /** * seo 탭 저장 시 첨부 ID 배열이 정제되어 seo 카테고리에 기록되는지 확인합니다. * * @scenario image_chain=site_default, setting_state=saved * * @effects og_default_image_persists_to_seo_category */ public function test_saved_attachment_ids_persist_to_seo_category(): void { $attachment = $this->createOgImageAttachment(); $saved = app(SettingsService::class)->saveSettings([ '_tab' => 'seo', 'seo' => [ // 화면 제출 형태(첨부 객체 배열)와 ID 배열 모두 수용해야 한다 'og_image_default' => [['id' => $attachment->id, 'hash' => $attachment->hash]], ], ]); $this->assertTrue($saved, 'seo 탭 저장이 실패했습니다.'); $seo = app(ConfigRepositoryInterface::class)->getCategory('seo'); $this->assertSame([$attachment->id], $seo['og_image_default']); // 존재하지 않는 첨부 ID 는 정제 단계에서 걸러진다 app(SettingsService::class)->saveSettings([ '_tab' => 'seo', 'seo' => ['og_image_default' => [999999]], ]); $this->assertSame([], app(ConfigRepositoryInterface::class)->getCategory('seo')['og_image_default']); } /** * 저장된 첨부가 getOgDefaultImageUrl 로 첫 이미지 URL 로 해석되는지 확인합니다. * * @scenario image_chain=site_default, setting_state=saved * * @effects og_default_image_resolves_first_image_url */ public function test_resolves_first_image_url(): void { $attachment = $this->createOgImageAttachment(); app(SettingsService::class)->saveSettings([ '_tab' => 'seo', 'seo' => ['og_image_default' => [$attachment->id]], ]); $url = app(SettingsService::class)->getOgDefaultImageUrl(); $this->assertNotNull($url, '저장된 기본 OG 이미지가 URL 로 해석되어야 합니다.'); $this->assertStringContainsString($attachment->hash, $url); } /** * 미설정이면 null 을 돌려주는지 확인합니다 (og:image 태그 미출력 경로). * * @scenario image_chain=none, setting_state=absent * * @effects og_default_image_resolves_first_image_url */ public function test_resolves_null_when_not_configured(): void { $this->assertNull(app(SettingsService::class)->getOgDefaultImageUrl()); } }