backend/feature/supabase #60
							
								
								
									
										3
									
								
								backend/.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										3
									
								
								backend/.gitignore
									
									
									
									
										vendored
									
									
								
							| @@ -1,6 +1,9 @@ | ||||
| # osm-cache | ||||
| cache_XML/ | ||||
|  | ||||
| # secrets | ||||
| *secrets.yaml | ||||
|  | ||||
| # Byte-compiled / optimized / DLL files | ||||
| __pycache__/ | ||||
| *.py[cod] | ||||
|   | ||||
| @@ -328,7 +328,7 @@ div.media { | ||||
|   </head> | ||||
|   <body> | ||||
|     <h1 id="title">Backend Testing Report</h1> | ||||
|     <p>Report generated on 12-Feb-2025 at 21:34:08 by <a href="https://pypi.python.org/pypi/pytest-html">pytest-html</a> | ||||
|     <p>Report generated on 14-Feb-2025 at 10:33:15 by <a href="https://pypi.python.org/pypi/pytest-html">pytest-html</a> | ||||
|         v4.1.1</p> | ||||
|     <div id="environment-header"> | ||||
|       <h2>Environment</h2> | ||||
| @@ -382,7 +382,7 @@ div.media { | ||||
|         <h2>Summary</h2> | ||||
|         <div class="additional-summary prefix"> | ||||
|         </div> | ||||
|         <p class="run-count">0 test took 0 ms.</p> | ||||
|         <p class="run-count">1 test took 681 ms.</p> | ||||
|         <p class="filter">(Un)check the boxes to filter the results.</p> | ||||
|         <div class="summary__reload"> | ||||
|           <div class="summary__reload__button hidden" onclick="location.reload()"> | ||||
| @@ -394,16 +394,16 @@ div.media { | ||||
|           <div class="filters"> | ||||
|             <input checked="true" class="filter" name="filter_checkbox" type="checkbox" data-test-result="failed" disabled/> | ||||
|             <span class="failed">0 Failed,</span> | ||||
|             <input checked="true" class="filter" name="filter_checkbox" type="checkbox" data-test-result="passed" disabled/> | ||||
|             <span class="passed">0 Passed,</span> | ||||
|             <input checked="true" class="filter" name="filter_checkbox" type="checkbox" data-test-result="passed" /> | ||||
|             <span class="passed">1 Passed,</span> | ||||
|             <input checked="true" class="filter" name="filter_checkbox" type="checkbox" data-test-result="skipped" disabled/> | ||||
|             <span class="skipped">0 Skipped,</span> | ||||
|             <input checked="true" class="filter" name="filter_checkbox" type="checkbox" data-test-result="xfailed" disabled/> | ||||
|             <span class="xfailed">0 Expected failures,</span> | ||||
|             <input checked="true" class="filter" name="filter_checkbox" type="checkbox" data-test-result="xpassed" disabled/> | ||||
|             <span class="xpassed">0 Unexpected passes,</span> | ||||
|             <input checked="true" class="filter" name="filter_checkbox" type="checkbox" data-test-result="error" /> | ||||
|             <span class="error">1 Errors,</span> | ||||
|             <input checked="true" class="filter" name="filter_checkbox" type="checkbox" data-test-result="error" disabled/> | ||||
|             <span class="error">0 Errors,</span> | ||||
|             <input checked="true" class="filter" name="filter_checkbox" type="checkbox" data-test-result="rerun" disabled/> | ||||
|             <span class="rerun">0 Reruns</span> | ||||
|           </div> | ||||
| @@ -432,7 +432,7 @@ div.media { | ||||
|     </table> | ||||
|   </body> | ||||
|   <footer> | ||||
|     <div id="data-container" data-jsonblob="{"environment": {"Python": "3.12.3", "Platform": "Linux-6.8.0-52-generic-x86_64-with-glibc2.39", "Packages": {"pytest": "8.3.4", "pluggy": "1.5.0"}, "Plugins": {"html": "4.1.1", "anyio": "4.8.0", "metadata": "3.1.1"}}, "tests": {"src/tests/test_main.py": [{"extras": [], "result": "Error", "testId": "src/tests/test_main.py::collect", "resultsTableRow": ["<td class=\"col-result\">Error</td>", "<td class=\"col-testId\">src/tests/test_main.py::collect</td>", "<td>N/A</td>", "<td>N/A</td>", "<td>N/A</td>", "<td class=\"col-duration\">0 ms</td>", "<td class=\"col-links\"></td>"], "log": "src/tests/test_main.py:6: in &lt;module&gt;\n    from .test_utils import load_trip_landmarks, log_trip_details\n&lt;frozen importlib._bootstrap&gt;:1360: in _find_and_load\n    ???\n&lt;frozen importlib._bootstrap&gt;:1331: in _find_and_load_unlocked\n    ???\n&lt;frozen importlib._bootstrap&gt;:935: in _load_unlocked\n    ???\n../../../../.local/share/virtualenvs/backend-rQjUbAgS/lib/python3.12/site-packages/_pytest/assertion/rewrite.py:184: in exec_module\n    exec(co, module.__dict__)\nsrc/tests/test_utils.py:7: in &lt;module&gt;\n    from ..cache import client as cache_client\nsrc/cache.py:5: in &lt;module&gt;\n    from .constants import MEMCACHED_HOST_PATH\nsrc/constants.py:19: in &lt;module&gt;\n    SUPABASE_URL = os.environ[&quot;SUPABASE_URL&quot;]\n&lt;frozen os&gt;:685: in __getitem__\n    ???\nE   KeyError: &#x27;SUPABASE_URL&#x27;\n"}]}, "renderCollapsed": ["passed"], "initialSort": "result", "title": "Backend Testing Report"}"></div> | ||||
|     <div id="data-container" data-jsonblob="{"environment": {"Python": "3.12.3", "Platform": "Linux-6.8.0-53-generic-x86_64-with-glibc2.39", "Packages": {"pytest": "8.3.4", "pluggy": "1.5.0"}, "Plugins": {"html": "4.1.1", "anyio": "4.8.0", "metadata": "3.1.1"}}, "tests": {"src/tests/test_main.py::test_turckheim": [{"extras": [], "result": "Passed", "testId": "src/tests/test_main.py::test_turckheim", "resultsTableRow": ["<td class=\"col-result\">Passed</td>", "<td class=\"col-testId\">src/tests/test_main.py::test_turckheim</td>", "<td>start (0 | 0) - 6 - H\u00f4tel de ville (238 | 5) - 1 - H\u00f4tel des Deux-Clefs (217 | 5) - 6 - finish (0 | 0) - 0</td>", "<td>23 min</td>", "<td>20 min</td>", "<td class=\"col-duration\">681 ms</td>", "<td class=\"col-links\"></td>"], "log": "------------------------------ Captured log call -------------------------------\nDEBUG    src.tests.test_main:test_main.py:30 Running test in Turckheim\nDEBUG    asyncio:selector_events.py:64 Using selector: EpollSelector\nDEBUG    src.main:main.py:65 user id: e6dae20d-50ed-4241-8e16-af1ad1f3572f\nDEBUG    src.payments.supabase:supabase.py:53 Credits of user e6dae20d-50ed-4241-8e16-af1ad1f3572f: 999999\nINFO     src.payments.supabase:supabase.py:56 Credit balance is positive. Proceeding with trip generation\nINFO     src.main:main.py:88 No end coordinates provided. Using start=end.\nDEBUG    src.utils.landmarks_manager:landmarks_manager.py:75 Starting to fetch landmarks...\nDEBUG    src.utils.landmarks_manager:landmarks_manager.py:87 Fetching sightseeing landmarks...\nDEBUG    src.overpass.overpass:overpass.py:55 Cache hit for 1/1 quadrants.\nDEBUG    src.overpass.overpass:overpass.py:55 Cache hit for 1/1 quadrants.\nDEBUG    src.overpass.overpass:overpass.py:55 Cache hit for 1/1 quadrants.\nDEBUG    src.overpass.overpass:overpass.py:55 Cache hit for 1/1 quadrants.\nDEBUG    src.overpass.overpass:overpass.py:55 Cache hit for 1/1 quadrants.\nDEBUG    src.overpass.overpass:overpass.py:55 Cache hit for 1/1 quadrants.\nINFO     src.utils.landmarks_manager:landmarks_manager.py:90 Found 9 sightseeing landmarks\nDEBUG    src.overpass.overpass:overpass.py:55 Cache hit for 1/1 quadrants.\nINFO     src.utils.cluster_manager:cluster_manager.py:145 Found 0 sightseeing clusters.\nINFO     src.main:main.py:125 Fetched 7 landmarks in  \t: 0.004 seconds\nDEBUG    src.optimization.optimizer:optimizer.py:597 First results are out. Looking out for circles and correcting...\nINFO     src.optimization.optimizer:optimizer.py:637 Re-optimized 0 times, objective value : 455\nDEBUG    src.optimization.refiner:refiner.py:345 Using 4 minor landmarks around the predicted path\nDEBUG    src.optimization.optimizer:optimizer.py:597 First results are out. Looking out for circles and correcting...\nINFO     src.optimization.optimizer:optimizer.py:637 Re-optimized 0 times, objective value : 455\nDEBUG    src.main:main.py:151 First stage optimization\t: 0.023 seconds\nDEBUG    src.main:main.py:152 Second stage optimization\t: 0.024 seconds\nINFO     src.main:main.py:153 Total computation time\t: 0.048 seconds\nINFO     src.main:main.py:158 Generated a trip of 23 minutes with 4 landmarks in 0.052 seconds.\nDEBUG    src.main:main.py:159 Detailed trip :\n\tLandmark(start): [start @(48.084588, 7.280405), score=0, time_to_next=6]\n\tLandmark(sightseeing): [H\u00f4tel de ville @(48.0874108, 7.2779686), score=238, time_to_next=1]\n\tLandmark(sightseeing): [H\u00f4tel des Deux-Clefs @(48.0871764, 7.2776559), score=217, time_to_next=6]\n\tLandmark(finish): [finish @(48.084588, 7.280405), score=0]\nDEBUG    src.payments.supabase:supabase.py:100 Credit balance successfully decremented.\nDEBUG    src.tests.test_main:test_main.py:47 API response : {&#x27;uuid&#x27;: &#x27;e139ea9c-a290-46df-b30f-7c7530ac7480&#x27;, &#x27;total_time&#x27;: 23, &#x27;first_landmark_uuid&#x27;: &#x27;efc6ecc0-345b-4b43-9d47-fd2ec1897074&#x27;}\nDEBUG    src.payments.supabase:supabase.py:143 Credit balance successfully incremented.\n\n"}]}, "renderCollapsed": ["passed"], "initialSort": "result", "title": "Backend Testing Report"}"></div> | ||||
|     <script> | ||||
|       (function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c="function"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error("Cannot find module '"+i+"'");throw a.code="MODULE_NOT_FOUND",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u="function"==typeof require&&require,i=0;i<t.length;i++)o(t[i]);return o}return r})()({1:[function(require,module,exports){ | ||||
| const { getCollapsedCategory, setCollapsedIds } = require('./storage.js') | ||||
|   | ||||
| @@ -12,13 +12,13 @@ LANDMARK_PARAMETERS_PATH = PARAMETERS_DIR / 'landmark_parameters.yaml' | ||||
| OPTIMIZER_PARAMETERS_PATH = PARAMETERS_DIR / 'optimizer_parameters.yaml' | ||||
|  | ||||
|  | ||||
| PAYPAL_CLIENT_ID = 0 # os.getenv("your-paypal-client-id") | ||||
| PAYPAL_SECRET = 0 # os.getenv("your-paypal-secret") | ||||
| PAYPAL_API_URL = 0 # "https://api-m.sandbox.paypal.com" | ||||
| PAYPAL_CLIENT_ID = os.getenv("future-paypal-client-id", None) | ||||
| PAYPAL_SECRET = os.getenv("future-paypal-secret", None) | ||||
| PAYPAL_API_URL = "https://api-m.sandbox.paypal.com" | ||||
|  | ||||
| SUPABASE_URL = os.environ["SUPABASE_URL"] | ||||
| SUPABASE_KEY = os.environ["SUPABASE_API_KEY"] | ||||
| SUPABASE_TEST_USER_ID = os.environ["SUPABASE_TEST_USER_ID"] | ||||
| SUPABASE_URL = os.getenv("SUPABASE_URL", None) | ||||
| SUPABASE_KEY = os.getenv("SUPABASE_API_KEY", None) | ||||
| SUPABASE_TEST_USER_ID = os.getenv("SUPABASE_TEST_USER_ID", None) | ||||
|  | ||||
|  | ||||
| cache_dir_string = os.getenv('OSM_CACHE_DIR', './cache') | ||||
|   | ||||
| @@ -1,9 +1,10 @@ | ||||
| """Main app for backend api""" | ||||
|  | ||||
| import logging | ||||
| import traceback | ||||
| import time | ||||
| from contextlib import asynccontextmanager | ||||
| from fastapi import FastAPI, HTTPException, BackgroundTasks, Query | ||||
| from fastapi import FastAPI, HTTPException, BackgroundTasks, Query, Body | ||||
|  | ||||
| from .logging_config import configure_logging | ||||
| from .structs.landmark import Landmark, Toilets | ||||
| @@ -16,7 +17,7 @@ from .optimization.optimizer import Optimizer | ||||
| from .optimization.refiner import Refiner | ||||
| from .overpass.overpass import fill_cache | ||||
| from .cache import client as cache_client | ||||
| from .payments.payment_routes import router as payment_router | ||||
| # from .payments.payment_routes import router as payment_router | ||||
| from .payments.supabase import Supabase | ||||
|  | ||||
|  | ||||
| @@ -41,14 +42,14 @@ app = FastAPI(lifespan=lifespan) | ||||
|  | ||||
|  | ||||
| # Include the payment routes | ||||
| app.include_router(payment_router, prefix="/payments") | ||||
| # app.include_router(payment_router, prefix="/payments") | ||||
|  | ||||
|  | ||||
| @app.post("/trip/new") | ||||
| def new_trip(user_id: str, | ||||
|              preferences: Preferences, | ||||
|              start: tuple[float, float], | ||||
|              end: tuple[float, float] | None = None,  | ||||
| def new_trip(user_id: str = Body(...), | ||||
|              preferences: Preferences = Body(...), | ||||
|              start: tuple[float, float] = Body(...), | ||||
|              end: tuple[float, float] | None = Body(None),  | ||||
|              background_tasks: BackgroundTasks = None) -> Trip: | ||||
|     """ | ||||
|     Main function to call the optimizer. | ||||
| @@ -61,7 +62,15 @@ def new_trip(user_id: str, | ||||
|         (uuid) : The uuid of the first landmark in the optimized route | ||||
|     """ | ||||
|     # Check for valid user balance. | ||||
|     supabase.check_balance(user_id=user_id) | ||||
|     logger.debug(f'user id: {user_id}') | ||||
|  | ||||
|     try :  | ||||
|         if not supabase.check_balance(user_id=user_id) : | ||||
|             logger.warning('Insufficient credits to perform this action.') | ||||
|             return None | ||||
|     except Exception as exc : | ||||
|         traceback.print_exc()   | ||||
|         raise HTTPException(status_code=500, detail=str(exc)) from exc | ||||
|  | ||||
|     # Check for invalid input. | ||||
|     if preferences is None: | ||||
| @@ -150,7 +159,7 @@ def new_trip(user_id: str, | ||||
|     logger.debug('Detailed trip :\n\t' + '\n\t'.join(f'{landmark}' for landmark in refined_tour)) | ||||
|  | ||||
|     background_tasks.add_task(fill_cache) | ||||
|     supabase.increment_credit_balance(user_id=user_id) | ||||
|     supabase.decrement_credit_balance(user_id=user_id) | ||||
|  | ||||
|     return trip | ||||
|  | ||||
|   | ||||
| @@ -1,15 +1,34 @@ | ||||
| import os | ||||
| import logging | ||||
| import yaml | ||||
| from fastapi import HTTPException, status | ||||
| from supabase import create_client, Client | ||||
| from ..constants import SUPABASE_URL, SUPABASE_KEY | ||||
| from supabase import create_client, Client, ClientOptions | ||||
|  | ||||
| from ..constants import PARAMETERS_DIR | ||||
|  | ||||
| # Silence the supabase logger | ||||
| logging.getLogger("httpx").setLevel(logging.CRITICAL) | ||||
| logging.getLogger("hpack").setLevel(logging.CRITICAL) | ||||
| logging.getLogger("httpcore").setLevel(logging.CRITICAL) | ||||
|  | ||||
|  | ||||
| class Supabase: | ||||
|  | ||||
|     logger = logging.getLogger(__name__) | ||||
|  | ||||
|     def __init__(self): | ||||
|         # Initialize Supabase client | ||||
|         print(SUPABASE_URL) | ||||
|         self.supabase: Client = create_client(SUPABASE_URL, SUPABASE_KEY) | ||||
|  | ||||
|         with open(os.path.join(PARAMETERS_DIR, 'secrets.yaml')) as f: | ||||
|             secrets = yaml.safe_load(f) | ||||
|             self.SUPABASE_URL = secrets['SUPABASE_URL'] | ||||
|             self.SUPABASE_KEY = secrets['SUPABASE_API_KEY'] | ||||
|             self.SUPABASE_TEST_USER_ID = secrets['SUPABASE_TEST_USER_ID'] | ||||
|  | ||||
|         self.supabase: Client = create_client(self.SUPABASE_URL, self.SUPABASE_KEY, options=ClientOptions(schema='public')) | ||||
|         self.logger.debug('Supabase client initialized.') | ||||
|  | ||||
|  | ||||
|     def check_balance(self, user_id: str): | ||||
|     def check_balance(self, user_id: str) -> bool: | ||||
|         """ | ||||
|         Checks if the user has enough 'credit' for generating a new trip. | ||||
|  | ||||
| @@ -21,22 +40,30 @@ class Supabase: | ||||
|         """ | ||||
|         try: | ||||
|             # Query the public.credits table to get the user's credits | ||||
|             response = self.supabase.table('credits').select('credits').eq('user_id', user_id).single().execute() | ||||
|  | ||||
|             response = ( | ||||
|                 self.supabase.table("credits") | ||||
|                 .select('*') | ||||
|                 .eq('id', user_id) | ||||
|                 .single() | ||||
|                 .execute() | ||||
|             ) | ||||
|             # Check if the response was successful and contains data | ||||
|             if response.get('data') and 'credits' in response['data']: | ||||
|                 credits = response['data']['credits'] | ||||
|             if response.data : | ||||
|                 credits = response.data['credit_amount'] | ||||
|                 self.logger.debug(f'Credits of user {user_id}: {credits}') | ||||
|  | ||||
|                 if credits <= 0:  | ||||
|                     raise HTTPException(status_code=403, detail="Insufficient credits to perform this action.") | ||||
|                 if credits > 0: | ||||
|                     self.logger.info(f'Credit balance is positive. Proceeding with trip generation') | ||||
|                     return True | ||||
|  | ||||
|                 self.logger.warning(f'Insufficient balance. Trip generation cannot be granted') | ||||
|                 return False | ||||
|  | ||||
|             # If user or credits not found, raise a 404 error | ||||
|             raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="User data not found.") | ||||
|             raise HTTPException(status_code=404, detail="User data not found.") | ||||
|  | ||||
|         except Exception: | ||||
|             # Handle exceptions (like if the user ID doesn't exist or database issues) | ||||
|             raise HTTPException(status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, detail="Error retrieving credit balance") | ||||
|         except Exception as exc: | ||||
|             raise HTTPException(status_code=500, detail="Error retrieving credit balance") from exc | ||||
|  | ||||
|  | ||||
|     def decrement_credit_balance(self, user_id: str) -> bool: | ||||
| @@ -48,30 +75,39 @@ class Supabase: | ||||
|         """ | ||||
|         try: | ||||
|             # Query the public.credits table to get the user's current credits | ||||
|             response = self.supabase.table('credits').select('credits').eq('user_id', user_id).single().execute() | ||||
|  | ||||
|             response = ( | ||||
|                 self.supabase.table("credits") | ||||
|                 .select('*') | ||||
|                 .eq('id', user_id) | ||||
|                 .single() | ||||
|                 .execute() | ||||
|             ) | ||||
|             # Check if the response was successful and contains data | ||||
|             if response.get('data') and 'credits' in response['data']: | ||||
|                 current_credits = response['data']['credits'] | ||||
|                 # Decrement the credit balance by 1 | ||||
|             if response.data : | ||||
|                 current_credits = response.data['credit_amount'] | ||||
|                 updated_credits = current_credits - 1 | ||||
|  | ||||
|                 # Update the user's credits in the table | ||||
|                 update_response = self.supabase.table('credits').update({'credits': updated_credits}).eq('user_id', user_id).execute() | ||||
|                 update_response = ( | ||||
|                     self.supabase.table('credits') | ||||
|                     .update({'credit_amount': updated_credits}) | ||||
|                     .eq('id', user_id) | ||||
|                     .execute() | ||||
|                 ) | ||||
|  | ||||
|                 # Check if the update was successful | ||||
|                 if update_response.get('status_code') == 200: | ||||
|                 if update_response.data: | ||||
|                     self.logger.debug(f'Credit balance successfully decremented.') | ||||
|                     return True | ||||
|                 else: | ||||
|                     raise HTTPException(status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, detail="Error updating credit balance.") | ||||
|                     raise HTTPException(status_code=500, detail="Error decrementing credit balance.") | ||||
|  | ||||
|             # If user or credits not found, raise a 404 error | ||||
|             raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="User data not found.") | ||||
|             raise HTTPException(status_code=404, detail="User data not found.") | ||||
|  | ||||
|         except Exception: | ||||
|             # Handle exceptions (like if the user ID doesn't exist or there are database issues) | ||||
|             raise HTTPException(status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, detail="Error updating credit balance") | ||||
|  | ||||
|             raise HTTPException(status_code=500, detail="Error decrementing credit balance") | ||||
|  | ||||
|     def increment_credit_balance(self, user_id: str) -> bool: | ||||
|         """ | ||||
| @@ -82,26 +118,36 @@ class Supabase: | ||||
|         """ | ||||
|         try: | ||||
|             # Query the public.credits table to get the user's current credits | ||||
|             response = self.supabase.table('credits').select('credits').eq('user_id', user_id).single().execute() | ||||
|  | ||||
|             response = ( | ||||
|                 self.supabase.table("credits") | ||||
|                 .select('*') | ||||
|                 .eq('id', user_id) | ||||
|                 .single() | ||||
|                 .execute() | ||||
|             ) | ||||
|             # Check if the response was successful and contains data | ||||
|             if response.get('data') and 'credits' in response['data']: | ||||
|                 current_credits = response['data']['credits'] | ||||
|                 # Increment the credit balance by 1 | ||||
|             if response.data : | ||||
|                 current_credits = response.data['credit_amount'] | ||||
|                 updated_credits = current_credits + 1 | ||||
|  | ||||
|                 # Update the user's credits in the table | ||||
|                 update_response = self.supabase.table('credits').update({'credits': updated_credits}).eq('user_id', user_id).execute() | ||||
|                 update_response = ( | ||||
|                     self.supabase.table('credits') | ||||
|                     .update({'credit_amount': updated_credits}) | ||||
|                     .eq('id', user_id) | ||||
|                     .execute() | ||||
|                 ) | ||||
|  | ||||
|                 # Check if the update was successful | ||||
|                 if update_response.get('status_code') == 200: | ||||
|                 if update_response.data: | ||||
|                     self.logger.debug(f'Credit balance successfully incremented.') | ||||
|                     return True | ||||
|                 else: | ||||
|                     raise HTTPException(status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, detail="Error updating credit balance.") | ||||
|                     raise HTTPException(status_code=500, detail="Error incrementing credit balance.") | ||||
|  | ||||
|             # If user or credits not found, raise a 404 error | ||||
|             raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="User data not found.") | ||||
|             raise HTTPException(status_code=404, detail="User data not found.") | ||||
|  | ||||
|         except Exception: | ||||
|             # Handle exceptions (like if the user ID doesn't exist or there are database issues) | ||||
|             raise HTTPException(status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, detail="Error updating credit balance") | ||||
|             raise HTTPException(status_code=500, detail="Error incrementing credit balance") | ||||
|   | ||||
| @@ -1,13 +1,16 @@ | ||||
| """Collection of tests to ensure correct implementation and track progress. """ | ||||
| import time | ||||
| import logging | ||||
| from fastapi.testclient import TestClient | ||||
| import pytest | ||||
|  | ||||
| from .test_utils import load_trip_landmarks, log_trip_details | ||||
| from ..main import app | ||||
| from ..constants import SUPABASE_TEST_USER_ID | ||||
| from ..payments.supabase import Supabase | ||||
|  | ||||
| supabase = Supabase() | ||||
| logger = logging.getLogger(__name__) | ||||
|  | ||||
| @pytest.fixture(scope="module") | ||||
| def client(): | ||||
|     """Client used to call the app.""" | ||||
| @@ -24,24 +27,25 @@ def test_turckheim(client, request):    # pylint: disable=redefined-outer-name | ||||
|     """ | ||||
|     start_time = time.time()  # Start timer | ||||
|     duration_minutes = 20 | ||||
|     logger.debug('Running test in Turckheim') | ||||
|  | ||||
|     response = client.post( | ||||
|         "/trip/new", | ||||
|         json={ | ||||
|             "user_id": SUPABASE_TEST_USER_ID, | ||||
|             "user_id": supabase.SUPABASE_TEST_USER_ID, | ||||
|             "preferences": {"sightseeing": {"type": "sightseeing", "score": 5}, | ||||
|             "nature": {"type": "nature", "score": 0}, | ||||
|             "shopping": {"type": "shopping", "score": 0}, | ||||
|             "max_time_minute": duration_minutes, | ||||
|             "detour_tolerance_minute": 0}, | ||||
|                 "nature": {"type": "nature", "score": 0}, | ||||
|                 "shopping": {"type": "shopping", "score": 0}, | ||||
|                 "max_time_minute": duration_minutes, | ||||
|                 "detour_tolerance_minute": 0}, | ||||
|             "start": [48.084588, 7.280405] | ||||
|             # "start": [45.74445023349939, 4.8222687890538865] | ||||
|             # "start": [45.75156398104873, 4.827154464827647] | ||||
|             } | ||||
|         ) | ||||
|     result = response.json() | ||||
|     supabase = Supabase() | ||||
|     supabase.increment_credit_balance(user_id=SUPABASE_TEST_USER_ID) | ||||
|     logger.debug(f'API response : {result}') | ||||
|     supabase.increment_credit_balance(user_id=supabase.SUPABASE_TEST_USER_ID) | ||||
|     landmarks = load_trip_landmarks(client, result['first_landmark_uuid']) | ||||
|  | ||||
|  | ||||
| @@ -80,7 +84,7 @@ def test_bellecour(client, request) :   # pylint: disable=redefined-outer-name | ||||
|     response = client.post( | ||||
|         "/trip/new", | ||||
|         json={ | ||||
|             "user_id": SUPABASE_TEST_USER_ID, | ||||
|             "user_id": supabase.SUPABASE_TEST_USER_ID, | ||||
|             "preferences": {"sightseeing": {"type": "sightseeing", "score": 5}, | ||||
|                             "nature": {"type": "nature", "score": 5}, | ||||
|                             "shopping": {"type": "shopping", "score": 5}, | ||||
| @@ -90,8 +94,7 @@ def test_bellecour(client, request) :   # pylint: disable=redefined-outer-name | ||||
|             } | ||||
|         ) | ||||
|     result = response.json() | ||||
|     supabase = Supabase() | ||||
|     supabase.increment_credit_balance(user_id=SUPABASE_TEST_USER_ID) | ||||
|     supabase.increment_credit_balance(user_id=supabase.SUPABASE_TEST_USER_ID) | ||||
|     landmarks = load_trip_landmarks(client, result['first_landmark_uuid']) | ||||
|  | ||||
|     # Get computation time | ||||
| @@ -123,7 +126,7 @@ def test_cologne(client, request) :   # pylint: disable=redefined-outer-name | ||||
|     response = client.post( | ||||
|         "/trip/new", | ||||
|         json={ | ||||
|             "user_id": SUPABASE_TEST_USER_ID, | ||||
|             "user_id": supabase.SUPABASE_TEST_USER_ID, | ||||
|             "preferences": {"sightseeing": {"type": "sightseeing", "score": 5}, | ||||
|                             "nature": {"type": "nature", "score": 5}, | ||||
|                             "shopping": {"type": "shopping", "score": 5}, | ||||
| @@ -133,8 +136,7 @@ def test_cologne(client, request) :   # pylint: disable=redefined-outer-name | ||||
|             } | ||||
|         ) | ||||
|     result = response.json() | ||||
|     supabase = Supabase() | ||||
|     supabase.increment_credit_balance(user_id=SUPABASE_TEST_USER_ID) | ||||
|     supabase.increment_credit_balance(user_id=supabase.SUPABASE_TEST_USER_ID) | ||||
|     landmarks = load_trip_landmarks(client, result['first_landmark_uuid']) | ||||
|  | ||||
|     # Get computation time | ||||
| @@ -167,7 +169,7 @@ def test_strasbourg(client, request) :   # pylint: disable=redefined-outer-name | ||||
|     response = client.post( | ||||
|         "/trip/new", | ||||
|         json={ | ||||
|             "user_id": SUPABASE_TEST_USER_ID, | ||||
|             "user_id": supabase.SUPABASE_TEST_USER_ID, | ||||
|             "preferences": {"sightseeing": {"type": "sightseeing", "score": 5}, | ||||
|                             "nature": {"type": "nature", "score": 5}, | ||||
|                             "shopping": {"type": "shopping", "score": 5}, | ||||
| @@ -177,8 +179,7 @@ def test_strasbourg(client, request) :   # pylint: disable=redefined-outer-name | ||||
|             } | ||||
|         ) | ||||
|     result = response.json() | ||||
|     supabase = Supabase() | ||||
|     supabase.increment_credit_balance(user_id=SUPABASE_TEST_USER_ID) | ||||
|     supabase.increment_credit_balance(user_id=supabase.SUPABASE_TEST_USER_ID) | ||||
|     landmarks = load_trip_landmarks(client, result['first_landmark_uuid']) | ||||
|  | ||||
|     # Get computation time | ||||
| @@ -211,7 +212,7 @@ def test_zurich(client, request) :   # pylint: disable=redefined-outer-name | ||||
|     response = client.post( | ||||
|         "/trip/new", | ||||
|         json={ | ||||
|             "user_id": SUPABASE_TEST_USER_ID, | ||||
|             "user_id": supabase.SUPABASE_TEST_USER_ID, | ||||
|             "preferences": {"sightseeing": {"type": "sightseeing", "score": 5}, | ||||
|                             "nature": {"type": "nature", "score": 5}, | ||||
|                             "shopping": {"type": "shopping", "score": 5}, | ||||
| @@ -221,8 +222,7 @@ def test_zurich(client, request) :   # pylint: disable=redefined-outer-name | ||||
|             } | ||||
|         ) | ||||
|     result = response.json() | ||||
|     supabase = Supabase() | ||||
|     supabase.increment_credit_balance(user_id=SUPABASE_TEST_USER_ID) | ||||
|     supabase.increment_credit_balance(user_id=supabase.SUPABASE_TEST_USER_ID) | ||||
|     landmarks = load_trip_landmarks(client, result['first_landmark_uuid']) | ||||
|  | ||||
|     # Get computation time | ||||
| @@ -255,7 +255,7 @@ def test_paris(client, request) :   # pylint: disable=redefined-outer-name | ||||
|     response = client.post( | ||||
|         "/trip/new", | ||||
|         json={ | ||||
|             "user_id": SUPABASE_TEST_USER_ID, | ||||
|             "user_id": supabase.SUPABASE_TEST_USER_ID, | ||||
|             "preferences": {"sightseeing": {"type": "sightseeing", "score": 5}, | ||||
|                             "nature": {"type": "nature", "score": 0}, | ||||
|                             "shopping": {"type": "shopping", "score": 5}, | ||||
| @@ -265,8 +265,7 @@ def test_paris(client, request) :   # pylint: disable=redefined-outer-name | ||||
|             } | ||||
|         ) | ||||
|     result = response.json() | ||||
|     supabase = Supabase() | ||||
|     supabase.increment_credit_balance(user_id=SUPABASE_TEST_USER_ID) | ||||
|     supabase.increment_credit_balance(user_id=supabase.SUPABASE_TEST_USER_ID) | ||||
|     landmarks = load_trip_landmarks(client, result['first_landmark_uuid']) | ||||
|  | ||||
|     # Get computation time | ||||
| @@ -299,7 +298,7 @@ def test_new_york(client, request) :   # pylint: disable=redefined-outer-name | ||||
|     response = client.post( | ||||
|         "/trip/new", | ||||
|         json={ | ||||
|             "user_id": SUPABASE_TEST_USER_ID, | ||||
|             "user_id": supabase.SUPABASE_TEST_USER_ID, | ||||
|             "preferences": {"sightseeing": {"type": "sightseeing", "score": 5}, | ||||
|                             "nature": {"type": "nature", "score": 5}, | ||||
|                             "shopping": {"type": "shopping", "score": 5}, | ||||
| @@ -309,8 +308,7 @@ def test_new_york(client, request) :   # pylint: disable=redefined-outer-name | ||||
|             } | ||||
|         ) | ||||
|     result = response.json() | ||||
|     supabase = Supabase() | ||||
|     supabase.increment_credit_balance(user_id=SUPABASE_TEST_USER_ID) | ||||
|     supabase.increment_credit_balance(user_id=supabase.SUPABASE_TEST_USER_ID) | ||||
|     landmarks = load_trip_landmarks(client, result['first_landmark_uuid']) | ||||
|  | ||||
|     # Get computation time | ||||
| @@ -343,7 +341,7 @@ def test_shopping(client, request) :   # pylint: disable=redefined-outer-name | ||||
|     response = client.post( | ||||
|         "/trip/new", | ||||
|         json={ | ||||
|             "user_id": SUPABASE_TEST_USER_ID, | ||||
|             "user_id": supabase.SUPABASE_TEST_USER_ID, | ||||
|             "preferences": {"sightseeing": {"type": "sightseeing", "score": 0}, | ||||
|                             "nature": {"type": "nature", "score": 0}, | ||||
|                             "shopping": {"type": "shopping", "score": 5}, | ||||
| @@ -353,8 +351,7 @@ def test_shopping(client, request) :   # pylint: disable=redefined-outer-name | ||||
|             } | ||||
|         ) | ||||
|     result = response.json() | ||||
|     supabase = Supabase() | ||||
|     supabase.increment_credit_balance(user_id=SUPABASE_TEST_USER_ID) | ||||
|     supabase.increment_credit_balance(user_id=supabase.SUPABASE_TEST_USER_ID) | ||||
|     landmarks = load_trip_landmarks(client, result['first_landmark_uuid']) | ||||
|  | ||||
|     # Get computation time | ||||
|   | ||||
							
								
								
									
										1091
									
								
								report.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1091
									
								
								report.html
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
		Reference in New Issue
	
	Block a user