Adding features to find public toilets and shopping streets #41
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
							
								
								
									
										42
									
								
								backend/src/tests/test_cache.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										42
									
								
								backend/src/tests/test_cache.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,42 @@ | ||||
| """Collection of tests to ensure correct handling of invalid input.""" | ||||
|  | ||||
| from fastapi.testclient import TestClient | ||||
| import pytest | ||||
|  | ||||
| from .test_utils import load_trip_landmarks | ||||
| from ..main import app | ||||
|  | ||||
|  | ||||
| @pytest.fixture(scope="module") | ||||
| def client(): | ||||
|     """Client used to call the app.""" | ||||
|     return TestClient(app) | ||||
|  | ||||
|  | ||||
| def test_cache(client, request):    # pylint: disable=redefined-outer-name | ||||
|     """ | ||||
|     Test n°1 : Custom test in Turckheim to ensure small villages are also supported. | ||||
|  | ||||
|     Args: | ||||
|         client: | ||||
|         request: | ||||
|     """ | ||||
|     duration_minutes = 15 | ||||
|     response = client.post( | ||||
|         "/trip/new", | ||||
|         json={ | ||||
|             "preferences": {"sightseeing": {"type": "sightseeing", "score": 5}, | ||||
|             "nature": {"type": "nature", "score": 5}, | ||||
|             "shopping": {"type": "shopping", "score": 5}, | ||||
|             "max_time_minute": duration_minutes, | ||||
|             "detour_tolerance_minute": 0}, | ||||
|             "start": [48.084588, 7.280405] | ||||
|             } | ||||
|         ) | ||||
|     result = response.json() | ||||
|     landmarks = load_trip_landmarks(client, result['first_landmark_uuid']) | ||||
|     landmarks_cached = load_trip_landmarks(client, result['first_landmark_uuid'], True) | ||||
|  | ||||
|     # checks : | ||||
|     assert response.status_code == 200  # check for successful planning | ||||
|     assert landmarks_cached == landmarks | ||||
| @@ -2,8 +2,10 @@ | ||||
| import logging | ||||
| from typing import List | ||||
| from fastapi import HTTPException | ||||
| from pydantic import ValidationError | ||||
|  | ||||
| from ..structs.landmark import Landmark | ||||
| from ..persistence import client as cache_client | ||||
|  | ||||
|  | ||||
| def landmarks_to_osmid(landmarks: List[Landmark]) -> List[int] : | ||||
| @@ -42,18 +44,58 @@ def fetch_landmark(client, landmark_uuid: str): | ||||
|     try: | ||||
|         json_data = response.json() | ||||
|         logger.info(f"API Response: {json_data}") | ||||
|         print(f"API Response of type {type(json_data)} in json format: {json_data}") | ||||
|     except ValueError as e: | ||||
|         logger.error(f"Failed to parse response as JSON: {response.text}") | ||||
|         raise HTTPException(status_code=500, detail="Invalid response format from API") | ||||
|      | ||||
|     # Try validating against the Landmark model here to ensure consistency | ||||
|     try: | ||||
|         landmark = Landmark(**json_data) | ||||
|     except ValidationError as ve: | ||||
|         logging.error(f"Validation error: {ve}") | ||||
|         raise HTTPException(status_code=500, detail="Invalid data format received from API") | ||||
|      | ||||
|  | ||||
|     if "detail" in json_data: | ||||
|         raise HTTPException(status_code=500, detail=json_data["detail"]) | ||||
|  | ||||
|     return json_data | ||||
|     return Landmark(**json_data) | ||||
|  | ||||
|  | ||||
| def load_trip_landmarks(client, first_uuid: str) -> List[Landmark]: | ||||
| def fetch_landmark_cache(landmark_uuid: str): | ||||
|     """ | ||||
|     Fetch landmark data from the cache based on the landmark UUID. | ||||
|  | ||||
|     Args: | ||||
|         landmark_uuid (str): The UUID of the landmark. | ||||
|  | ||||
|     Returns: | ||||
|         dict: Landmark data fetched from the cache or raises an HTTP exception. | ||||
|     """ | ||||
|     logger = logging.getLogger(__name__) | ||||
|  | ||||
|     # Try to fetch the landmark data from the cache | ||||
|     try: | ||||
|         landmark = cache_client.get(f"landmark_{landmark_uuid}") | ||||
|         if not landmark : | ||||
|             logger.warning(f"Cache miss for landmark UUID: {landmark_uuid}") | ||||
|             raise HTTPException(status_code=404, detail=f"Landmark with UUID {landmark_uuid} not found in cache.") | ||||
|          | ||||
|         # Validate that the fetched data is a dictionary | ||||
|         if not isinstance(landmark, Landmark): | ||||
|             logger.error(f"Invalid cache data format for landmark UUID: {landmark_uuid}. Expected dict, got {type(landmark).__name__}.") | ||||
|             raise HTTPException(status_code=500, detail="Invalid cache data format.") | ||||
|  | ||||
|         return landmark | ||||
|      | ||||
|     except Exception as exc: | ||||
|         logger.error(f"Unexpected error occurred while fetching landmark UUID {landmark_uuid}: {exc}") | ||||
|         raise HTTPException(status_code=500, detail="An unexpected error occurred while fetching the landmark from the cache") from exc | ||||
|      | ||||
|      | ||||
|  | ||||
|  | ||||
| def load_trip_landmarks(client, first_uuid: str, from_cache=None) -> List[Landmark]: | ||||
|     """ | ||||
|     Load all landmarks for a trip using the response from the API. | ||||
|  | ||||
| @@ -67,14 +109,13 @@ def load_trip_landmarks(client, first_uuid: str) -> List[Landmark]: | ||||
|     next_uuid = first_uuid | ||||
|  | ||||
|     while next_uuid is not None: | ||||
|         landmark_data = fetch_landmark(client, next_uuid) | ||||
|         # # Convert UUIDs to strings explicitly | ||||
|         # landmark_data = { | ||||
|         #     key: str(value) if isinstance(value, UUID) else value | ||||
|         #     for key, value in landmark_data.items() | ||||
|         # } | ||||
|         landmarks.append(Landmark(**landmark_data)) # Create Landmark objects | ||||
|         next_uuid = landmark_data.get('next_uuid')  # Prepare for the next iteration | ||||
|         if from_cache : | ||||
|             landmark = fetch_landmark_cache(next_uuid) | ||||
|         else : | ||||
|             landmark = fetch_landmark(client, next_uuid) | ||||
|  | ||||
|         landmarks.append(landmark) | ||||
|         next_uuid = landmark.next_uuid  # Prepare for the next iteration | ||||
|  | ||||
|     return landmarks | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user