"""공급사 관점 협상 결과 파생(SessionResult) 단위 테스트. 목록의 result 코드는 견적 마감상태·마감사유·낙찰자로 파생한다(DDL 무변경). 공급사가 이 배지로 '내가 낙찰인지 / 결렬이라 재협상 요청 대상인지'를 구분한다. 결렬(3)만 renegotiable 과 짝을 이룬다. """ import uuid from common.enums import CloseReason, QuotationStatus from services.negotiation_service import NegotiationService _R = NegotiationService._to_result ME = uuid.uuid4() OTHER = uuid.uuid4() CLOSED = QuotationStatus.CLOSED.value def test_result_undecided_before_close(): """검증: 견적이 아직 마감 전(진행중)이면 결과 미정. 기대결과: 0(미정).""" assert _R(QuotationStatus.IN_PROGRESS.value, None, None, ME) == 0 def test_result_won_when_winner_is_me(): """검증: 낙찰(AWARDED) 마감 + 낙찰자가 나. 기대결과: 1(낙찰).""" assert _R(CLOSED, CloseReason.AWARDED.value, ME, ME) == 1 def test_result_lost_when_winner_is_other(): """검증: 낙찰 마감이지만 낙찰자가 남. 기대결과: 2(미낙찰).""" assert _R(CLOSED, CloseReason.AWARDED.value, OTHER, ME) == 2 def test_result_lost_when_awarded_without_winner_id(): """검증: 낙찰인데 낙찰자 id 가 비어 나와 대조 불가. 기대결과: 2(미낙찰) — 낙찰이라 단정 못 하면 낙찰로 오인시키지 않는다.""" assert _R(CLOSED, CloseReason.AWARDED.value, None, ME) == 2 def test_result_open_is_renegotiable(): """검증: 개찰(OPEN_*) 4종으로 마감(낙찰자 미정=결렬). 기대결과: 전부 3(결렬) — 재협상 요청 대상.""" for cr in (CloseReason.OPEN_PRICE, CloseReason.OPEN_EQUAL, CloseReason.OPEN_NOSHOW, CloseReason.OPEN_REJECT): assert _R(CLOSED, cr.value, None, ME) == 3, cr def test_result_none_when_closed_without_reason(): """검증: 마감됐지만 close_reason 이 아직 없음(경계). 기대결과: 0(미정) — 낙찰/결렬 어느 쪽도 아님.""" assert _R(CLOSED, None, None, ME) == 0