Files
Gnuboard7/tests/Unit/Seo/SeoBotPreviewServiceTest.php
2026-07-01 10:30:32 +09:00

94 lines
3.5 KiB
PHP

<?php
namespace Tests\Unit\Seo;
use App\Seo\Contracts\SeoRendererInterface;
use App\Seo\Editor\SeoBotPreviewService;
use Illuminate\Http\Request;
use PHPUnit\Framework\TestCase;
/**
* SeoBotPreviewService 단위 테스트.
*
* 봇 미리보기는 검색엔진 탭·레이아웃·모듈/코어 SEO 설정이 **산출한 데이터만** 보여준다.
* 종전 `extractSeoMarkup`(완성 HTML 을 태그/속성 휴리스틱으로 가지치기)은 폐기 — 대신 렌더 파이프
* 라인을 `seoOnly=true` 로 호출해 SEO 산출물 전용 블레이드(seo-preview)로 조립한 HTML 을 그대로
* 돌려준다. 본 단위 테스트는 서비스가 ① seoOnly=true 로 호출하는지 ② 결과를 가공 없이 통과시키는지
* ③ null 분기를 검증한다. SEO 산출물만 담기는지는 seo-preview 블레이드 Feature 테스트가 SSoT.
*/
class SeoBotPreviewServiceTest extends TestCase
{
/** renderer mock — 호출 인자를 캡처하고 주어진 HTML 을 반환한다. */
private function recordingRenderer(?string $html): object
{
return new class($html) implements SeoRendererInterface
{
public ?bool $lastSeoOnly = null;
public int $calls = 0;
public function __construct(private readonly ?string $html) {}
public function render(Request $request): ?string
{
return $this->html;
}
public function renderFromResolved(
array $mergedLayout,
array $routeParams,
string $url,
string $locale,
string $templateIdentifier,
string $layoutName,
?string $moduleId,
?string $pluginId,
array $context,
?string $defaultLocale = null,
bool $seoOnly = false,
): ?string {
$this->calls++;
$this->lastSeoOnly = $seoOnly;
return $this->html;
}
};
}
private function render(SeoBotPreviewService $svc): ?string
{
return $svc->render([], [], '/x', 'ko', 'sirsoft-admin_basic', null, null, []);
}
public function test_seo_only_true_로_렌더_파이프라인을_호출한다(): void
{
// 봇 미리보기는 SEO 설정 산출물만 받아야 하므로 seoOnly=true 로 호출한다.
$renderer = $this->recordingRenderer('<head><title>T</title></head>');
$svc = new SeoBotPreviewService($renderer);
$this->render($svc);
$this->assertSame(1, $renderer->calls);
$this->assertTrue($renderer->lastSeoOnly, '봇 미리보기는 seoOnly=true 로 호출');
}
public function test_렌더_결과를_가공_없이_그대로_통과시킨다(): void
{
// 종전 extractSeoMarkup 후처리 폐기 — 파이프라인이 돌려준 SEO 전용 HTML 을 그대로 반환.
$html = '<head><title>봇 제목</title><meta property="og:title" content="봇"></head>';
$renderer = $this->recordingRenderer($html);
$svc = new SeoBotPreviewService($renderer);
$this->assertSame($html, $this->render($svc));
}
public function test_seo_비활성_render_null_은_null_로_전달된다(): void
{
// seoOnly 경로에서도 meta.seo.enabled=false → renderFromResolved 가 null → null 통과.
$renderer = $this->recordingRenderer(null);
$svc = new SeoBotPreviewService($renderer);
$this->assertNull($this->render($svc));
}
}