diff --git a/backend/services/negotiation_service.py b/backend/services/negotiation_service.py index 10a11f6..f551bf2 100644 --- a/backend/services/negotiation_service.py +++ b/backend/services/negotiation_service.py @@ -112,6 +112,12 @@ class NegotiationService: ) if err_type != ErrorType.SUCCESS or quote is None: return ErrorType.NEGO_NOT_FOUND, None, None + + # 협상완료 세션은 결과 열람용 재진입(무변경)이므로 견적마감·마감시간 검증을 건너뛴다. + # reject 는 blocked_statuses 로 DONE 을 이미 막으므로 이 분기는 participate 에만 닿는다. + if sess.status == SessionStatus.DONE.value: + return ErrorType.SUCCESS, sess, quote + if quote.status == QuotationStatus.CLOSED.value: return ErrorType.NEGO_QUOTATION_CLOSED, None, None diff --git a/backend/tests/test_negotiation.py b/backend/tests/test_negotiation.py index 8c68603..4c5663c 100644 --- a/backend/tests/test_negotiation.py +++ b/backend/tests/test_negotiation.py @@ -221,6 +221,22 @@ async def test_participate_in_progress_no_state_change(client, nego_seed, db_eng assert await _quotation_status(db_engine, qid) == 2 # 무변경 +async def test_participate_done_bypasses_quotation_closed(client, nego_seed, db_engine): + """협상완료 세션은 결과 열람용 재진입이므로 견적마감·마감시간이 지나도 참여(진입) 가능.""" + token = await _login_token(client) + sid, qid = nego_seed["sids"]["C"], nego_seed["qids"]["C"] # 협상완료 + async with db_engine.begin() as conn: + await conn.execute( + text("UPDATE quotation.quotations SET status = 3, end_time = now() - make_interval(hours => 1) WHERE qt_id = :qid"), + {"qid": qid}, + ) # 견적마감 + 마감시간 경과 + r = await _participate(client, token, sid) + assert r.json()["result"]["success"] is True + assert r.json()["session_id"] == str(sid) + assert await _session_status(db_engine, sid) == 3 # 무변경 (협상완료 유지) + assert await _quotation_status(db_engine, qid) == 3 # 무변경 (견적마감 유지) + + async def test_participate_session_not_found(client, nego_seed): token = await _login_token(client) r = await _participate(client, token, str(uuid.uuid4()))