| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178 |
- from __future__ import annotations
- from app.schemas.route import RouteLeg
- from app.schemas.selection import (
- RankedHotelCandidate,
- )
- from app.services.route_evaluation_service import (
- RouteEvaluationService,
- )
- def build_hotel(
- hotel_id: str,
- name: str,
- score: float,
- ) -> RankedHotelCandidate:
- return RankedHotelCandidate(
- hotel_id=hotel_id,
- score=score,
- reasons=[],
- warnings=[],
- hotel={
- "hotel_id": hotel_id,
- "name": name,
- },
- )
- def test_central_hotel_ranks_first() -> None:
- service = RouteEvaluationService()
- hotels = [
- build_hotel(
- "central",
- "中心酒店",
- 80,
- ),
- build_hotel(
- "remote",
- "远郊酒店",
- 82,
- ),
- ]
- legs_by_hotel = {
- "central": [
- RouteLeg(
- origin_name="中心酒店",
- origin_location=(
- "104.0700,30.6700"
- ),
- destination_name="景点A",
- destination_location=(
- "104.0800,30.6800"
- ),
- distance_meters=2000,
- duration_seconds=600,
- ),
- RouteLeg(
- origin_name="中心酒店",
- origin_location=(
- "104.0700,30.6700"
- ),
- destination_name="景点B",
- destination_location=(
- "104.0900,30.6900"
- ),
- distance_meters=3000,
- duration_seconds=900,
- ),
- ],
- "remote": [
- RouteLeg(
- origin_name="远郊酒店",
- origin_location=(
- "104.2000,30.8000"
- ),
- destination_name="景点A",
- destination_location=(
- "104.0800,30.6800"
- ),
- distance_meters=15000,
- duration_seconds=2400,
- ),
- RouteLeg(
- origin_name="远郊酒店",
- origin_location=(
- "104.2000,30.8000"
- ),
- destination_name="景点B",
- destination_location=(
- "104.0900,30.6900"
- ),
- distance_meters=18000,
- duration_seconds=3000,
- ),
- ],
- }
- result = service.rank_hotels(
- hotels,
- legs_by_hotel,
- {
- "central": None,
- "remote": None,
- },
- require_near_subway=False,
- )
- assert result[0].hotel_id == "central"
- assert (
- result[0].average_distance_meters
- == 2500
- )
- def test_subway_distance_affects_score() -> None:
- service = RouteEvaluationService()
- hotels = [
- build_hotel(
- "near-subway",
- "地铁酒店",
- 80,
- ),
- build_hotel(
- "far-subway",
- "远离地铁酒店",
- 80,
- ),
- ]
- same_legs = [
- RouteLeg(
- origin_name="酒店",
- origin_location="104.0,30.0",
- destination_name="景点",
- destination_location=(
- "104.1,30.1"
- ),
- distance_meters=5000,
- )
- ]
- result = service.rank_hotels(
- hotels,
- {
- "near-subway": same_legs,
- "far-subway": same_legs,
- },
- {
- "near-subway": 300,
- "far-subway": 1800,
- },
- require_near_subway=True,
- )
- assert (
- result[0].hotel_id
- == "near-subway"
- )
- def test_haversine_fallback() -> None:
- service = RouteEvaluationService()
- leg = service.build_haversine_leg(
- origin_name="酒店",
- origin_location="104.0600,30.6700",
- destination_name="景点",
- destination_location=(
- "104.0700,30.6800"
- ),
- )
- assert leg.distance_meters > 0
- assert leg.source == "haversine_fallback"
- assert leg.duration_seconds is None
|