o2o-site-AEO/solution/backend/tests/test_site_template.py
Mina Choi 11d30bb3d1 [chore] solution,admin,ontology: 코드 주석을 한 줄로 — 히스토리 주석 삭제
여러 줄 주석이 설명보다 경위(예전·실측·지적)를 적고 있어 읽는 사람이 결론을 찾기 어려웠다.

- ts·tsx·js·mjs·css·py 478개: 여러 줄 주석은 첫 문장 한 줄로, 과거형·날짜 문장은 삭제
- 주석 위치는 TypeScript 파서·파이썬 tokenize/ast 로 찾는다 — 문자열 안의 # · /* 는 건드리지 않는다
- eslint·ts·noqa·type: ignore 같은 지시 주석은 그대로 둔다

파이썬 275개 정리 전후 AST 동일, TS 298개 주석 뺀 토큰 동일(빈 JSX 주석 10곳만 차이).
site·frontend·admin tsc, site vitest 105 passed

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-09-28 16:05:19 +09:00

105 lines
4.4 KiB
Python

"""템플릿 선택 저장."""
import uuid
from sqlalchemy import text
from common.enums import ErrorType, PlaceCategory, SiteStatus
from common.template_catalog import INDUSTRIES
from services.site_payload import to_site_payload
async def _place(client, headers, name="템플릿펜션", category=1):
r = await client.post("/v1/place", headers=headers, json={"name": name, "category": category})
return r.json()["place"]["place_id"]
async def _set_template(client, headers, pid, template_id):
return (await client.post(f"/v1/place/{pid}/site/template", headers=headers,
json={"template_id": template_id})).json()
async def _get_site(client, headers, pid):
return (await client.get(f"/v1/place/{pid}/site", headers=headers)).json()
async def test_set_template_creates_site_row(auth_headers, client):
"""검증: 사이트 행이 없어도 템플릿을 먼저 고를 수 있고, 조회에도 그대로 나온다."""
h = await auth_headers("tpl1")
pid = await _place(client, h)
saved = await _set_template(client, h, pid, "paper")
assert saved["result"]["code"] == ErrorType.SUCCESS.value
assert saved["site"]["template_id"] == "paper"
assert (await _get_site(client, h, pid))["site"]["template_id"] == "paper"
async def test_unknown_template_is_refused(auth_headers, client):
"""검증: 등록되지 않은 id는 거절한다."""
h = await auth_headers("tpl2")
pid = await _place(client, h)
refused = await _set_template(client, h, pid, "stay-retro")
assert refused["result"]["code"] == ErrorType.INVALID_REQUEST_DATA.value
assert "site" not in refused
async def test_template_outside_industry_list_is_refused(auth_headers, client):
"""검증: 등록된 템플릿이라도 그 업종 허용 목록에 없으면 거절한다(병원은 레트로를 못 쓴다)."""
h = await auth_headers("tpl3")
pid = await _place(client, h, name="템플릿의원", category=PlaceCategory.CLINIC.value)
refused = await _set_template(client, h, pid, "retro")
assert refused["result"]["code"] == ErrorType.INVALID_REQUEST_DATA.value
async def test_empty_value_clears_to_default(auth_headers, client):
"""검증: 빈 값은 '고르지 않음'이다 — NULL로 돌아가 업종 기본 템플릿으로 나간다."""
h = await auth_headers("tpl4")
pid = await _place(client, h)
await _set_template(client, h, pid, "paper")
cleared = await _set_template(client, h, pid, "")
assert cleared["result"]["code"] == ErrorType.SUCCESS.value
assert "template_id" not in cleared["site"]
async def test_published_site_template_is_not_locked(auth_headers, client, db_engine):
"""검증: 발행된 사이트도 템플릿을 바꿀 수 있고, 재빌드 표시가 선다."""
h = await auth_headers("tpl5")
pid = await _place(client, h)
await _set_template(client, h, pid, "simple")
async with db_engine.begin() as conn:
await conn.execute(
text("UPDATE sites SET status = :st, published_at = now() WHERE place_id = :p"),
{"st": SiteStatus.PUBLISHED.value, "p": uuid.UUID(pid)},
)
changed = await _set_template(client, h, pid, "paper")
assert changed["result"]["code"] == ErrorType.SUCCESS.value
assert changed["site"]["template_id"] == "paper"
assert changed["needs_rebuild"] is True
async def test_other_owners_place_is_blocked(auth_headers, client):
"""검증: 남의 사업장의 템플릿은 바꿀 수 없다(PLACE_NOT_FOUND)."""
h = await auth_headers("tpl6")
intruder = await auth_headers("tpl7")
pid = await _place(client, h)
blocked = await _set_template(client, intruder, pid, "paper")
assert blocked["result"]["code"] == ErrorType.PLACE_NOT_FOUND.value
def test_payload_uses_saved_template_and_falls_back():
"""검증: payload의 templateId는 저장값, 없으면 업종 기본 템플릿이다."""
place = {"place_id": uuid.uuid4(), "category": PlaceCategory.LODGING.value, "name": "스테이,머뭄"}
snapshot = {"place": {"name": "스테이,머뭄", "category": PlaceCategory.LODGING.value}}
version = {"version": 1}
chosen = to_site_payload(place, snapshot, {"template_id": "paper"}, version, [])
assert chosen["theme"]["templateId"] == "paper"
fallback = to_site_payload(place, snapshot, {"template_id": None}, version, [])
assert fallback["theme"]["templateId"] == INDUSTRIES["stay"]["defaultTemplate"]