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 = (
'
옛 마크업
'
''
''
)
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": "새 글 포함", "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 " 포함" not in html
assert '옛 마크업
' 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