여러 줄 주석이 설명보다 경위(예전·실측·지적)를 적고 있어 읽는 사람이 결론을 찾기 어려웠다. - 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>
109 lines
4.6 KiB
Python
109 lines
4.6 KiB
Python
"""내 사이트 목록 — 로그인한 사장님이 자기 사이트 전부를 보는 화면의 뒷단."""
|
|
import uuid
|
|
|
|
from sqlalchemy import text
|
|
|
|
from common.enums import ErrorType, SiteStatus
|
|
|
|
|
|
async def _place(client, headers, name):
|
|
r = await client.post("/v1/place", headers=headers, json={"name": name, "category": 1})
|
|
return r.json()["place"]["place_id"]
|
|
|
|
|
|
async def _list(client, headers, **params):
|
|
return (await client.get("/v1/site/list", headers=headers, params=params)).json()
|
|
|
|
|
|
async def test_place_without_site_is_still_listed(auth_headers, client):
|
|
"""검증: 사이트 행이 없는 사업장(위저드만 걸어온 것)도 목록에 나온다."""
|
|
h = await auth_headers("my1")
|
|
await _place(client, h, "아직펜션")
|
|
|
|
body = await _list(client, h)
|
|
assert body["result"]["code"] == ErrorType.SUCCESS.value
|
|
assert body["total"] == 1
|
|
row = body["sites"][0]
|
|
assert row["name"] == "아직펜션"
|
|
assert row.get("site_id") is None
|
|
assert row.get("status") is None
|
|
|
|
|
|
async def test_site_row_is_joined_into_the_line(auth_headers, client):
|
|
"""검증: 사업장과 사이트가 한 줄로 합쳐져 온다(줄마다 사이트를 다시 묻지 않는다)."""
|
|
h = await auth_headers("my2")
|
|
pid = await _place(client, h, "합쳐진펜션")
|
|
await client.post(f"/v1/place/{pid}/site/template", headers=h, json={"template_id": "paper"})
|
|
await client.post(f"/v1/place/{pid}/site/slug", headers=h, json={"slug": "joined-stay"})
|
|
|
|
row = (await _list(client, h))["sites"][0]
|
|
assert row["site_id"]
|
|
assert row["template_id"] == "paper"
|
|
assert row["domain"] == "joined-stay"
|
|
assert row["status"] == SiteStatus.DRAFT.value
|
|
|
|
|
|
async def test_row_carries_what_the_card_draws(auth_headers, client, db_engine):
|
|
"""검증: 목록 줄이 카드가 그릴 값을 다 들고 온다 — 주소·생성일·썸네일."""
|
|
h = await auth_headers("my2b")
|
|
pid = await _place(client, h, "카드펜션")
|
|
async with db_engine.begin() as conn:
|
|
await conn.execute(
|
|
text("UPDATE places SET road_address = :addr WHERE place_id = :pid"),
|
|
{"addr": "강원특별자치도 양양군 현북면 하조대3길 12", "pid": uuid.UUID(pid)},
|
|
)
|
|
await conn.execute(
|
|
text("INSERT INTO sites (site_id, place_id, domain, status, thumbnail_url) "
|
|
"VALUES (:s, :p, :d, :st, :t)"),
|
|
{"s": uuid.uuid4(), "p": uuid.UUID(pid), "d": "card-stay",
|
|
"st": SiteStatus.PUBLISHED.value, "t": "https://w4ai.o2o.kr/thumbs/card-stay.jpg?v=2"},
|
|
)
|
|
|
|
row = (await _list(client, h))["sites"][0]
|
|
assert row["road_address"] == "강원특별자치도 양양군 현북면 하조대3길 12"
|
|
assert row["created_at"]
|
|
assert row["thumbnail_url"] == "https://w4ai.o2o.kr/thumbs/card-stay.jpg?v=2"
|
|
|
|
|
|
async def test_row_without_a_site_has_no_thumbnail(auth_headers, client):
|
|
"""검증: 아직 발행 안 한 줄은 그림이 없다(키 자체가 없다)."""
|
|
h = await auth_headers("my2c")
|
|
await _place(client, h, "그림없는펜션")
|
|
|
|
row = (await _list(client, h))["sites"][0]
|
|
assert "thumbnail_url" not in row
|
|
|
|
|
|
async def test_other_owners_sites_are_not_listed(auth_headers, client):
|
|
"""검증: 사장님 스코프."""
|
|
mine = await auth_headers("my3")
|
|
theirs = await auth_headers("my3b")
|
|
await _place(client, mine, "내펜션")
|
|
await _place(client, theirs, "남의펜션")
|
|
|
|
assert [r["name"] for r in (await _list(client, mine))["sites"]] == ["내펜션"]
|
|
assert [r["name"] for r in (await _list(client, theirs))["sites"]] == ["남의펜션"]
|
|
|
|
|
|
async def test_needs_rebuild_matches_the_single_site_answer(auth_headers, client, db_engine):
|
|
"""검증: 재빌드 판정이 단건 조회와 같은 답을 낸다."""
|
|
h = await auth_headers("my4")
|
|
pid = await _place(client, h, "고친펜션")
|
|
# 템플릿 저장이 사이트 행을 만든다.
|
|
await client.post(f"/v1/place/{pid}/site/template", headers=h, json={"template_id": "paper"})
|
|
async with db_engine.begin() as conn:
|
|
await conn.execute(
|
|
text("UPDATE places SET content_updated_at = now() WHERE place_id = :pid"),
|
|
{"pid": uuid.UUID(pid)},
|
|
)
|
|
|
|
single = (await client.get(f"/v1/place/{pid}/site", headers=h)).json()
|
|
row = (await _list(client, h))["sites"][0]
|
|
assert row["needs_rebuild"] is True
|
|
assert row["needs_rebuild"] == single["needs_rebuild"]
|
|
|
|
|
|
async def test_list_requires_login(client):
|
|
"""검증: 내 것을 보는 화면이므로 토큰 없이는 열리지 않는다."""
|
|
assert (await client.get("/v1/site/list")).status_code == 401
|