test_itinerary_schema.py 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  1. from __future__ import annotations
  2. from datetime import date, time
  3. import pytest
  4. from pydantic import ValidationError
  5. from app.schemas.itinerary import (
  6. DailyItinerary,
  7. FlightSelection,
  8. HotelSelection,
  9. ItineraryActivity,
  10. ItineraryPlan,
  11. )
  12. def build_plan() -> ItineraryPlan:
  13. return ItineraryPlan(
  14. title="上海至成都四日旅行",
  15. overview="轻松游览成都代表性景点。",
  16. selected_flight=FlightSelection(
  17. flight_type="round_trip",
  18. combination_id="round-001",
  19. outbound_option_id="out-001",
  20. return_option_id="ret-001",
  21. quoted_price=1800,
  22. currency="CNY",
  23. selection_reason="综合价格与时间。",
  24. ),
  25. selected_hotel=HotelSelection(
  26. hotel_id="hotel-001",
  27. name="测试酒店",
  28. check_in_date=date(2026, 8, 10),
  29. check_out_date=date(2026, 8, 13),
  30. nights=3,
  31. price_per_night=500,
  32. estimated_total_price=1500,
  33. currency="CNY",
  34. selection_reason="靠近主要景点。",
  35. ),
  36. days=[
  37. DailyItinerary(
  38. day_index=1,
  39. date=date(2026, 8, 10),
  40. theme="抵达成都",
  41. activities=[
  42. ItineraryActivity(
  43. sequence=1,
  44. activity_type="flight",
  45. name="前往成都",
  46. start_time=time(9, 0),
  47. end_time=time(12, 0),
  48. )
  49. ],
  50. )
  51. ],
  52. )
  53. def test_valid_itinerary_plan() -> None:
  54. plan = build_plan()
  55. assert plan.selected_hotel.nights == 3
  56. assert plan.selected_flight.quoted_price == 1800
  57. assert len(plan.days) == 1
  58. def test_round_trip_requires_return_option() -> None:
  59. with pytest.raises(ValidationError):
  60. FlightSelection(
  61. flight_type="round_trip",
  62. combination_id="round-001",
  63. outbound_option_id="out-001",
  64. return_option_id=None,
  65. selection_reason="测试",
  66. )
  67. def test_duplicate_day_date_is_rejected() -> None:
  68. plan = build_plan()
  69. duplicate_day = plan.days[0].model_copy(
  70. update={
  71. "day_index": 2,
  72. }
  73. )
  74. with pytest.raises(ValidationError):
  75. ItineraryPlan(
  76. title=plan.title,
  77. overview=plan.overview,
  78. selected_flight=(
  79. plan.selected_flight
  80. ),
  81. selected_hotel=(
  82. plan.selected_hotel
  83. ),
  84. days=[
  85. plan.days[0],
  86. duplicate_day,
  87. ],
  88. )