| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172 |
- from __future__ import annotations
- from datetime import datetime
- from types import SimpleNamespace
- import pytest
- from pydantic import ValidationError
- from api.schemas.demand_feedback import CreateDemandFeedbackBody
- from api.services import demand_feedback as feedback_service
- from supply_infra.db.models.demand_feedback import DemandFeedback
- def _body(**changes) -> CreateDemandFeedbackBody:
- values = {
- "client_request_id": "request-123",
- "target_type": "demand",
- "demand_grade_id": 10,
- "feedback_action": "support",
- }
- values.update(changes)
- return CreateDemandFeedbackBody(**values)
- def test_feedback_body_validates_target_fields() -> None:
- with pytest.raises(ValidationError):
- _body(target_type="video")
- with pytest.raises(ValidationError):
- _body(
- target_type="hit_content",
- video_id="vid-1",
- )
- with pytest.raises(ValidationError):
- _body(video_id="vid-1")
- body = _body(target_type="video", video_id="vid-1")
- assert body.video_id == "vid-1"
- def test_feedback_body_validates_action_content_and_reason() -> None:
- with pytest.raises(ValidationError):
- _body(feedback_action="oppose")
- with pytest.raises(ValidationError):
- _body(feedback_action="correct")
- with pytest.raises(ValidationError):
- _body(reason_code="irrelevant")
- body = _body(
- feedback_action="correct",
- reason_code="wrong_reason",
- content=" 正确原因应引用后验样本。 ",
- )
- assert body.content == "正确原因应引用后验样本。"
- def test_feedback_model_has_person_but_no_review_or_boolean_state() -> None:
- columns = DemandFeedback.__table__.columns
- assert "feedback_user_id" in columns
- assert "feedback_user_name_snapshot" in columns
- assert "feedback_username_snapshot" in columns
- assert "review_status" not in columns
- assert "has_feedback" not in columns
- assert "is_feedback" not in columns
- def test_create_feedback_uses_server_target_and_current_user(monkeypatch) -> None:
- grade = SimpleNamespace(
- id=10,
- biz_dt="20260730",
- demand_name="老年人智能手机使用",
- grade="A",
- reason="需求有明确内容意图",
- video_list=None,
- )
- expansion = SimpleNamespace(
- id=30,
- biz_dt="20260730",
- source_demand_grade_id=10,
- video_id="vid-1",
- point_type="purpose",
- expanded_text="降低老人使用智能设备的门槛",
- point_desc="解释基础操作",
- reason="覆盖当前需求",
- )
- detail = SimpleNamespace(title="教父母使用手机")
- saved: list[DemandFeedback] = []
- class Session:
- def refresh(self, row) -> None:
- row.id = 99
- row.created_at = datetime(2026, 7, 30, 15, 20)
- def rollback(self) -> None:
- raise AssertionError("unexpected rollback")
- class SessionContext:
- def __enter__(self):
- return Session()
- def __exit__(self, *_args):
- return False
- class GradeRepo:
- def __init__(self, _session):
- pass
- def get_by_id(self, grade_id):
- return grade if grade_id == 10 else None
- class ExpansionRepo:
- def __init__(self, _session):
- pass
- def has_video(self, **kwargs):
- return kwargs["video_id"] == "vid-1"
- def get_active_by_id(self, expansion_id):
- return expansion if expansion_id == 30 else None
- class DetailRepo:
- def __init__(self, _session):
- pass
- def list_by_vids(self, _video_ids):
- return {"vid-1": detail}
- class FeedbackRepo:
- def __init__(self, _session):
- pass
- def get_by_client_request_id(self, _request_id):
- return None
- def add(self, row):
- saved.append(row)
- return row
- def list_for_target(self, **_kwargs):
- return saved, len(saved)
- monkeypatch.setattr(feedback_service, "get_session", lambda: SessionContext())
- monkeypatch.setattr(feedback_service, "DemandGradeRepository", GradeRepo)
- monkeypatch.setattr(feedback_service, "DemandVideoExpansionRepository", ExpansionRepo)
- monkeypatch.setattr(feedback_service, "MultiDemandVideoDetailRepository", DetailRepo)
- monkeypatch.setattr(feedback_service, "DemandFeedbackRepository", FeedbackRepo)
- result = feedback_service.create_demand_feedback(
- _body(
- target_type="hit_content",
- video_id="vid-1",
- demand_video_expansion_id=30,
- feedback_action="oppose",
- reason_code="not_hit",
- content="没有覆盖老人学习使用的需求。",
- ),
- {
- "id": 7,
- "username": "zhangsan",
- "display_name": "张三",
- },
- )
- assert result["feedback_summary"] == {"count": 1}
- assert result["item"]["feedback_user"] == {
- "id": 7,
- "username": "zhangsan",
- "display_name": "张三",
- }
- assert result["item"]["target_snapshot"]["expanded_text"] == "降低老人使用智能设备的门槛"
- assert saved[0].feedback_user_id == 7
- assert saved[0].feedback_user_name_snapshot == "张三"
- assert saved[0].feedback_username_snapshot == "zhangsan"
|