77 lines
3.6 KiB
Python
77 lines
3.6 KiB
Python
"""캔버스 가이드가 일정을 함께 내려보내는가.
|
|
|
|
★ 예전에는 일부러 뺐다 — "캔버스에 그릴 자리가 아직 없다"(get_guide docstring).
|
|
자리를 만들었으므로(ItineraryTickets 의 폴백) 이제 실어 보낸다.
|
|
빼 두면 캔버스와 발행본이 다른 목록을 보이고, 그건 이 함수 자신이 경계한 상황이다.
|
|
"""
|
|
import uuid
|
|
|
|
from sqlalchemy import text
|
|
|
|
from common.enums import PlaceCategory, SourceType
|
|
|
|
|
|
async def _seed_place(db_engine, owner_id, name="스테이,머뭄") -> str:
|
|
pid = uuid.uuid4()
|
|
async with db_engine.begin() as conn:
|
|
await conn.execute(
|
|
text("INSERT INTO places (place_id, owner_user_id, name, category, road_address, "
|
|
"region_code, latitude, longitude, status) "
|
|
"VALUES (:p, :o, :n, :c, :r, :rc, :lat, :lng, 1)"),
|
|
{"p": pid, "o": uuid.UUID(owner_id), "n": name, "c": PlaceCategory.LODGING.value,
|
|
"r": "전북특별자치도 군산시 절골길 18", "rc": "52군산시",
|
|
"lat": 35.98642, "lng": 126.70612},
|
|
)
|
|
return str(pid)
|
|
|
|
|
|
async def _seed_itinerary(db_engine, place_id, duration="1박 2일", course="원도심 코스"):
|
|
body = [{
|
|
"name": course, "duration": duration, "audience": "처음 온 손님", "why": "이유.",
|
|
"days": [{"label": "첫째 날", "startTime": "14:00",
|
|
"stops": [{"name": "군산근대역사박물관", "minutes": 90, "moveMinutes": 15,
|
|
"searchQuery": "군산근대역사박물관",
|
|
"latitude": 35.9985, "longitude": 126.7107}]}],
|
|
"source": {"name": "군산문화관광", "url": "https://www.gunsan.go.kr/tour/"},
|
|
}]
|
|
import json
|
|
async with db_engine.begin() as conn:
|
|
await conn.execute(
|
|
text("INSERT INTO place_itineraries (place_itinerary_id, place_id, duration, body, "
|
|
"generated_by, model, generated_at) "
|
|
"VALUES (:i, :p, :d, CAST(:b AS jsonb), :g, :m, now())"),
|
|
{"i": uuid.uuid4(), "p": uuid.UUID(place_id), "d": duration,
|
|
"b": json.dumps(body, ensure_ascii=False),
|
|
"g": SourceType.LLM.value, "m": "perplexity:sonar"},
|
|
)
|
|
|
|
|
|
async def test_guide_returns_stored_itineraries(client, db_engine, owner_id, monkeypatch):
|
|
"""검증: 저장된 일정이 있는 업장의 캔버스 가이드.
|
|
기대결과: itineraries 가 실려 온다 — 캔버스가 발행본과 같은 목록을 본다."""
|
|
# 생성·수집은 이 테스트의 관심이 아니다. 유료 호출과 잡 등록을 막는다.
|
|
monkeypatch.setattr("services.llm.perplexity.is_configured", lambda: False)
|
|
|
|
pid = await _seed_place(db_engine, owner_id)
|
|
await _seed_itinerary(db_engine, pid)
|
|
|
|
body = (await client.get("/v1/local/guide", params={"place_id": pid})).json()
|
|
|
|
assert body["result"]["success"] is True
|
|
assert [i["name"] for i in body["itineraries"]] == ["원도심 코스"]
|
|
assert body["itineraries"][0]["duration"] == "1박 2일"
|
|
assert body["itineraries"][0]["days"][0]["stops"][0]["name"] == "군산근대역사박물관"
|
|
|
|
|
|
async def test_guide_without_itineraries_returns_empty_list(client, db_engine, owner_id, monkeypatch):
|
|
"""검증: 아직 생성되지 않은 업장.
|
|
기대결과: 빈 배열 — 캔버스는 PasteHint 를 띄운다(에러가 아니다)."""
|
|
monkeypatch.setattr("services.llm.perplexity.is_configured", lambda: False)
|
|
|
|
pid = await _seed_place(db_engine, owner_id)
|
|
|
|
body = (await client.get("/v1/local/guide", params={"place_id": pid})).json()
|
|
|
|
assert body["result"]["success"] is True
|
|
assert body.get("itineraries", []) == []
|