o2o-site-AEO/solution/backend/tests/test_itinerary_prompt.py

73 lines
3.6 KiB
Python

"""여행 일정 프롬프트 — 무엇을 반드시 물어야 하는가.
DB 도 네트워크도 쓰지 않는 순수 단위 테스트다.
이 파일이 지키는 것(스파이크 2026-09-11 에서 실측으로 얻은 것들):
- 컨셉 5개를 **우리가** 준다. 모델에 맡기면 2박 3일에서 5개 중 4개가 정거장 집합 100% 동일이 된다
- 컨셉당 2개씩, 총 10개를 요청한다(2026-09-11, 사장님 지시: "중복 허용하고 10개로")
- 업소 자신을 정거장에 넣지 말라고 못 박는다. 안 적으면 "스테이,머뭄" 이 정거장으로 들어온다
- 지역명을 넣는다. 없으면 모델이 아무 도시나 고른다(story_service.region_label_of 와 같은 이유)
"""
import pytest
from services.prompts import itinerary as prompts
def test_durations_are_two_render_contract_strings():
"""검증: 기간 문자열.
기대결과: 화면 탭·ItineraryItem.duration 이 되는 값이라 표기가 정확해야 한다."""
assert prompts.DURATIONS == ("1박 2일", "2박 3일")
def test_prompt_carries_place_region_and_duration():
"""검증: 변수 세 개가 프롬프트에 들어간다."""
text = prompts.build_prompt("스테이,머뭄", "전북특별자치도 군산시", "1박 2일")
assert "스테이,머뭄" in text
assert "전북특별자치도 군산시" in text
assert '"1박 2일"' in text # 스키마의 duration 고정값
assert "1박 2일 여행 일정" in text # 해야 할 일
def test_prompt_fixes_five_concepts():
"""검증: 컨셉 5개가 프롬프트에 박혀 있다.
기대결과: 모델이 컨셉을 고르지 않는다 — 고르게 하면 장소가 수렴한다."""
text = prompts.build_prompt("업소", "지역", "2박 3일")
for concept in ("역사·근대건축", "자연 풍경", "미식", "아이와 함께", "야외활동"):
assert concept in text
def test_prompt_asks_for_ten_courses_total():
"""검증: 컨셉당 2개씩 총 10개를 요청한다(2026-09-11: 5개 → 10개, 중복 허용).
기대결과: 컨셉 축 자체는 그대로 5개이고, 개수만 컨셉당 2개로 늘어난다."""
text = prompts.build_prompt("업소", "지역", "1박 2일")
assert "5개 컨셉마다 2개씩, 총 10개" in text
assert "같은 컨셉 안의 두 코스도 서로 다른 일정이어야 한다" in text
def test_prompt_forbids_the_lodging_itself_as_a_stop():
"""검증: 업소를 정거장에 넣지 말라는 규칙."""
text = prompts.build_prompt("업소", "지역", "1박 2일")
assert "[업소] 자신은 정거장에 넣지 않는다" in text
def test_prompt_requires_coordinates_and_forbids_fences():
"""검증: 좌표는 항상 요구하고, 코드펜스는 금지한다.
기대결과: 좌표를 '아는 곳만' 으로 두면 정거장 30곳 중 8곳이 좌표 없이 온다(실측)."""
text = prompts.build_prompt("업소", "지역", "1박 2일")
assert "모든 정거장에 latitude·longitude 를 적는다" in text
assert "코드펜스를 붙이지 않는다" in text
def test_prompt_forbids_identical_courses():
"""검증: 같은 정거장 집합 금지 규칙.
기대결과: 정거장 겹침 자체는 허용이고, '같은 코스' 만 막는다(2026-09-11 결정)."""
text = prompts.build_prompt("업소", "지역", "2박 3일")
assert "같은 정거장 집합" in text
def test_unknown_duration_is_rejected():
"""검증: 모르는 기간.
기대결과: ValueError — 화면에 없는 탭을 만드는 값이 조용히 저장되면 안 된다."""
with pytest.raises(ValueError):
prompts.build_prompt("업소", "지역", "3박 4일")