stay 는 굽기 보호 주소라 그 사업장 글을 승인하면 발행이 거절되고 글은 승인 상태로 남았다. 목업 화면의 미니블로그는 파일에 박힌 글이라 승인해도 바뀌지 않았다. - services/mockup_blog.py: window.__SITE_PAYLOAD__.posts 만 교체 — 기존 글 유지 · 새 글 추가 · 최신순, 직전 파일은 index.html.bak-blog - build_service: 발행 주소가 stay·stay2 면 굽지 않고 글만 갱신 후 승인분을 게재로(버전·Teams 실패 알림 없음) 테스트 3건 추가(test_mockup_blog). 빌드·블로그·롤백·썸네일 105 passed Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
81 lines
3.5 KiB
Python
81 lines
3.5 KiB
Python
import json
|
|
import uuid
|
|
|
|
from sqlalchemy import text
|
|
|
|
from common.enums import PostStatus
|
|
from crud.job_crud import JobQueue
|
|
from services import mockup_blog
|
|
from worker.handlers import build_handler
|
|
from worker.runner import Worker
|
|
|
|
MOCKUP_HTML = (
|
|
'<html><head></head><body><div id="root">옛 마크업</div>'
|
|
'<script>window.__SITE_PAYLOAD__ = {"site":{"slug":"stay"},"posts":[{"postId":"old","body":"옛 글","publishedAt":"2026-09-01T00:00:00+00:00"}]};</script>'
|
|
'</body></html>'
|
|
)
|
|
|
|
|
|
def _write_mockup(tmp_path, monkeypatch, slug="stay"):
|
|
monkeypatch.setenv("SITE_OUTPUT_DIR", str(tmp_path))
|
|
page = tmp_path / "s" / slug
|
|
page.mkdir(parents=True)
|
|
(page / "index.html").write_text(MOCKUP_HTML, encoding="utf-8")
|
|
return page / "index.html"
|
|
|
|
|
|
def _posts(html: str) -> list[dict]:
|
|
start = html.index("{", html.index(mockup_blog.PAYLOAD_MARKER))
|
|
return json.JSONDecoder().raw_decode(html, start)[0]["posts"]
|
|
|
|
|
|
def test_목업만_대상이다():
|
|
assert mockup_blog.is_mockup("stay")
|
|
assert mockup_blog.is_mockup("stay2")
|
|
assert not mockup_blog.is_mockup("stay3")
|
|
assert not mockup_blog.is_mockup("euro")
|
|
|
|
|
|
def test_새_글을_더하고_옛_글은_남기고_최신순이다(tmp_path, monkeypatch):
|
|
path = _write_mockup(tmp_path, monkeypatch)
|
|
|
|
count = mockup_blog.refresh_posts("stay", [
|
|
{"post_id": "new", "body": "새 글 </script> 포함", "published_at": "2026-10-01T00:00:00+00:00"},
|
|
{"post_id": "empty", "body": " ", "published_at": "2026-10-02T00:00:00+00:00"},
|
|
])
|
|
|
|
html = path.read_text(encoding="utf-8")
|
|
assert count == 2
|
|
assert [p["postId"] for p in _posts(html)] == ["new", "old"]
|
|
assert "</script> 포함" not in html
|
|
assert '<div id="root">옛 마크업</div>' in html
|
|
assert (path.parent / mockup_blog.BACKUP_NAME).read_text(encoding="utf-8") == MOCKUP_HTML
|
|
|
|
|
|
async def test_목업_사업장_발행은_굽지_않고_글만_바꾸고_게재로_넘긴다(auth_headers, client, db_engine, tmp_path, monkeypatch):
|
|
path = _write_mockup(tmp_path, monkeypatch)
|
|
h = await auth_headers("mockup-owner")
|
|
pid = (await client.post("/v1/place", headers=h, json={"name": "목업펜션", "category": 1})).json()["place"]["place_id"]
|
|
post_id = uuid.uuid4()
|
|
async with db_engine.begin() as c:
|
|
owner = (await c.execute(text("SELECT owner_user_id FROM places WHERE place_id = :p"), {"p": pid})).scalar()
|
|
await c.execute(
|
|
text("INSERT INTO sites (site_id, place_id, status, domain) VALUES (:s, :p, 1, 'stay')"),
|
|
{"s": uuid.uuid4(), "p": pid},
|
|
)
|
|
await c.execute(
|
|
text("INSERT INTO place_posts (post_id, place_id, body, topic_kind, topic_key, status, approved_at) "
|
|
"VALUES (:id, :p, '승인된 새 글입니다', 1, 'fog', :st, now())"),
|
|
{"id": post_id, "p": pid, "st": PostStatus.APPROVED.value},
|
|
)
|
|
|
|
await JobQueue().enqueue(4, {"place_id": pid, "owner_user_id": str(owner), "publish": True})
|
|
assert await Worker("w", JobQueue(), build_handler(), job_deadline_sec=60).process_one() is True
|
|
|
|
assert [p["postId"] for p in _posts(path.read_text(encoding="utf-8"))][0] == str(post_id)
|
|
async with db_engine.begin() as c:
|
|
status = (await c.execute(text("SELECT status FROM place_posts WHERE post_id = :id"), {"id": post_id})).scalar()
|
|
versions = (await c.execute(text("SELECT count(*) FROM site_versions"))).scalar()
|
|
assert status == PostStatus.PUBLISHED.value
|
|
assert versions == 0
|