import pytest from unittest.mock import MagicMock, patch import sys from app.services.routing_optimizer import RoutingOptimizer # Mock OR-Tools if not installed in the test environment try: from ortools.constraint_solver import routing_enums_pb2 from ortools.constraint_solver import pywrapcp HAS_ORTOOLS = True except ImportError: HAS_ORTOOLS = False @pytest.mark.asyncio async def test_routing_optimizer_initialization(): optimizer = RoutingOptimizer() assert optimizer.has_ortools == HAS_ORTOOLS @pytest.mark.asyncio async def test_optimize_daily_routes_fallback(): # Force fallback by mocking has_ortools to False optimizer = RoutingOptimizer() optimizer.has_ortools = False depot_location = (40.7128, -74.0060) # NYC deliveries = [ { 'id': 'd1', 'location': (40.730610, -73.935242), # Brooklyn 'weight_kg': 100 }, { 'id': 'd2', 'location': (40.758896, -73.985130), # Times Square 'weight_kg': 50 } ] result = await optimizer.optimize_daily_routes(deliveries, depot_location) assert result['status'] == 'success' assert result['algorithm_used'] == 'fallback_sequential' assert len(result['routes']) == 1 assert len(result['routes'][0]['stops']) == 4 # Start + 2 deliveries + End @pytest.mark.asyncio async def test_optimize_daily_routes_vrp(): if not HAS_ORTOOLS: pytest.skip("OR-Tools not installed") optimizer = RoutingOptimizer() depot_location = (40.7128, -74.0060) # NYC deliveries = [ { 'id': 'd1', 'location': (40.730610, -73.935242), # Brooklyn 'weight_kg': 100 }, { 'id': 'd2', 'location': (40.758896, -73.985130), # Times Square 'weight_kg': 50 }, { 'id': 'd3', 'location': (40.7829, -73.9654), # Central Park 'weight_kg': 200 } ] # Run optimization result = await optimizer.optimize_daily_routes(deliveries, depot_location) assert result['status'] == 'success' assert result['algorithm_used'] == 'ortools_vrp' assert len(result['routes']) >= 1 # Check if all deliveries are covered delivery_ids = [] for route in result['routes']: for stop in route['stops']: if 'delivery_id' in stop and not stop.get('location') == 'depot': delivery_ids.append(stop['delivery_id']) assert 'd1' in delivery_ids assert 'd2' in delivery_ids assert 'd3' in delivery_ids