o2o-site-AEO/solution/site/src/seo/directory.test.ts
Mina Choi f008b24574 [fix] solution/site: 자산 보관 코드를 되살린다 — 목업은 재굽기가 안 되므로 자산이 지워지면 끝이다
되돌렸던 6f4e055 를 그대로 되살린다. out/s/ 에는 payload 가 없는 사이트(목업)가 있고,
그건 재굽기 대상이 아니라서 자산이 한 번 지워지면 영영 복구되지 않는다.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018xTWrJ6Mrr6HhEN6hZEER4
2026-09-07 14:04:50 +09:00

47 lines
2.1 KiB
TypeScript

/**
* 구운 HTML → 사이트맵·목록 값.
*
* ★ 이 테스트가 지키는 것은 **커플링 하나**다. 사이트맵의 lastmod 는 페이지가 head 에
* 선언한 dateModified 와 같은 값이어야 한다 — 구글이 lastmod 를 신뢰하는 조건이
* "페이지의 실제 수정과 대조해 맞을 것" 이기 때문이다. head.ts 가 태그 모양을 바꾸면
* readBakedLastmod 는 조용히 undefined 를 내고 사이트맵은 mtime 으로 되돌아간다 —
* 빌드는 통과하고 화면도 멀쩡한, 눈으로 못 찾는 종류의 회귀다. 그래서 붙인다.
*/
import {describe, expect, it} from 'vitest';
import {MOONLIGHT_STAY_PAYLOAD} from '../fixtures/moonlight-stay';
import {readBakedLastmod, readBakedTitle} from './directory';
import {renderHead} from './head';
import {homeMeta} from './meta';
/** 실제 프리렌더와 같은 경로로 head 를 굽는다(prerender.ts prerenderSite). */
function bakedHead(): string {
const payload = MOONLIGHT_STAY_PAYLOAD;
return renderHead({payload, meta: homeMeta(payload)});
}
describe('readBakedLastmod', () => {
it('head 가 선언한 dateModified 를 그대로 돌려준다', () => {
expect(readBakedLastmod(bakedHead())).toBe(MOONLIGHT_STAY_PAYLOAD.site.updatedAt);
});
it('메타가 없으면 undefined — 호출부가 mtime 으로 떨어진다', () => {
expect(readBakedLastmod('<html><head><title>x</title></head></html>')).toBeUndefined();
});
it('날짜로 못 읽는 값은 버린다 — 틀린 lastmod 는 없는 것보다 나쁘다', () => {
expect(readBakedLastmod('<meta name="dateModified" content="어제" />')).toBeUndefined();
expect(readBakedLastmod('<meta name="dateModified" content="" />')).toBeUndefined();
});
});
describe('readBakedTitle', () => {
it('구운 HTML 의 title 을 꺼낸다', () => {
expect(readBakedTitle(bakedHead())).toBe(homeMeta(MOONLIGHT_STAY_PAYLOAD).title);
});
it('title 이 없으면 빈 문자열 — 호출부가 슬러그로 떨어진다', () => {
expect(readBakedTitle('<html><head></head></html>')).toBe('');
});
});