""" Test script for POST /recommendations/check endpoint Tests the new endpoint that checks user data and provides category-specific recommendations """ import requests import json from datetime import datetime # Update this to your API URL # For local: http://localhost:8000 (requires server running) # For Hugging Face: https://logicgoinfotechspaces-smart-budget-recommendation.hf.space BASE_URL = "https://logicgoinfotechspaces-smart-budget-recommendation.hf.space" # Test data from find_user_with_data.py TEST_USER_ID = "6741abd38d30ab5b7176397f" TEST_CATEGORY_ID = "6741abd38d30ab5b71763984" def test_recommendations_check_with_data(): """Test POST /recommendations/check with user that has previous data""" print("=" * 60) print("Test 1: POST /recommendations/check (User with Previous Data)") print("=" * 60) try: request_body = { "user_id": TEST_USER_ID, "category_id": TEST_CATEGORY_ID } print(f"\nRequest Body:") print(json.dumps(request_body, indent=2)) response = requests.post( f"{BASE_URL}/recommendations/check", json=request_body, headers={"Content-Type": "application/json"} ) print(f"\nStatus Code: {response.status_code}") if response.status_code == 200: result = response.json() print(f"\nResponse:") print(json.dumps(result, indent=2)) if result.get("has_previous_data"): print("\n[OK] User has previous data") if result.get("recommendations"): print(f"[OK] Found {len(result['recommendations'])} recommendation(s)") for rec in result["recommendations"]: print(f"\n Category: {rec.get('category')}") print(f" Category ID: {rec.get('category_id')}") print(f" Average Expense: Rs.{rec.get('average_expense', 0):,.2f}") print(f" Recommended Budget: Rs.{rec.get('recommended_budget', 0):,.2f}") print(f" Confidence: {rec.get('confidence', 0)*100:.1f}%") print(f" Action: {rec.get('action', 'N/A')}") print(f" Reason: {rec.get('reason', 'N/A')}") else: print("[WARNING] No recommendations returned") else: print("\n[INFO] User does not have previous data") print(f"Message: {result.get('message', 'N/A')}") return response.status_code == 200 else: print(f"\n[ERROR] Request failed") print(f"Response: {response.text}") return False except Exception as e: print(f"\n[ERROR] Exception: {e}") import traceback traceback.print_exc() return False def test_recommendations_check_with_budget_amount(): """Test POST /recommendations/check with budget_amount provided""" print("\n" + "=" * 60) print("Test 2: POST /recommendations/check (With Budget Amount)") print("=" * 60) try: request_body = { "user_id": TEST_USER_ID, "category_id": TEST_CATEGORY_ID, "budget_amount": 10000.0 } print(f"\nRequest Body:") print(json.dumps(request_body, indent=2)) response = requests.post( f"{BASE_URL}/recommendations/check", json=request_body, headers={"Content-Type": "application/json"} ) print(f"\nStatus Code: {response.status_code}") if response.status_code == 200: result = response.json() print(f"\nResponse:") print(json.dumps(result, indent=2)) if result.get("recommendations"): print(f"\n[OK] Generated {len(result['recommendations'])} recommendation(s) based on budget_amount") for rec in result["recommendations"]: print(f"\n Category: {rec.get('category')}") print(f" Category ID: {rec.get('category_id')}") print(f" Average Expense: Rs.{rec.get('average_expense', 0):,.2f}") print(f" Recommended Budget: Rs.{rec.get('recommended_budget', 0):,.2f}") print(f" Confidence: {rec.get('confidence', 0)*100:.1f}%") print(f" Action: {rec.get('action', 'N/A')}") print(f" Reason: {rec.get('reason', 'N/A')}") else: print("\n[WARNING] No recommendations returned even with budget_amount") return response.status_code == 200 else: print(f"\n[ERROR] Request failed") print(f"Response: {response.text}") return False except Exception as e: print(f"\n[ERROR] Exception: {e}") import traceback traceback.print_exc() return False def test_recommendations_check_new_user(): """Test POST /recommendations/check with a new user (no previous data)""" print("\n" + "=" * 60) print("Test 3: POST /recommendations/check (New User - No Previous Data)") print("=" * 60) try: request_body = { "user_id": "000000000000000000000000", # Non-existent user "category_id": TEST_CATEGORY_ID } print(f"\nRequest Body:") print(json.dumps(request_body, indent=2)) response = requests.post( f"{BASE_URL}/recommendations/check", json=request_body, headers={"Content-Type": "application/json"} ) print(f"\nStatus Code: {response.status_code}") if response.status_code == 200: result = response.json() print(f"\nResponse:") print(json.dumps(result, indent=2)) if not result.get("has_previous_data"): print("\n[OK] Correctly identified user has no previous data") print(f"Message: {result.get('message', 'N/A')}") else: print("\n[WARNING] User was identified as having data (unexpected)") return response.status_code == 200 else: print(f"\n[ERROR] Request failed") print(f"Response: {response.text}") return False except Exception as e: print(f"\n[ERROR] Exception: {e}") import traceback traceback.print_exc() return False def test_recommendations_check_new_user_with_budget(): """Test POST /recommendations/check with new user but with budget_amount""" print("\n" + "=" * 60) print("Test 4: POST /recommendations/check (New User with Budget Amount)") print("=" * 60) try: request_body = { "user_id": "000000000000000000000000", # Non-existent user "category_id": TEST_CATEGORY_ID, "budget_amount": 5000.0 } print(f"\nRequest Body:") print(json.dumps(request_body, indent=2)) response = requests.post( f"{BASE_URL}/recommendations/check", json=request_body, headers={"Content-Type": "application/json"} ) print(f"\nStatus Code: {response.status_code}") if response.status_code == 200: result = response.json() print(f"\nResponse:") print(json.dumps(result, indent=2)) if result.get("recommendations"): print(f"\n[OK] Generated recommendation for new user based on budget_amount") for rec in result["recommendations"]: print(f"\n Category: {rec.get('category')}") print(f" Category ID: {rec.get('category_id')}") print(f" Average Expense: Rs.{rec.get('average_expense', 0):,.2f}") print(f" Recommended Budget: Rs.{rec.get('recommended_budget', 0):,.2f}") print(f" Confidence: {rec.get('confidence', 0)*100:.1f}%") print(f" Action: {rec.get('action', 'N/A')}") print(f" Reason: {rec.get('reason', 'N/A')}") else: print("\n[WARNING] No recommendations returned even with budget_amount") return response.status_code == 200 else: print(f"\n[ERROR] Request failed") print(f"Response: {response.text}") return False except Exception as e: print(f"\n[ERROR] Exception: {e}") import traceback traceback.print_exc() return False if __name__ == "__main__": print("\n" + "=" * 60) print("Smart Budget Recommendation API - Test Suite") print("POST /recommendations/check Endpoint Tests") print("=" * 60) print(f"\nBase URL: {BASE_URL}") print(f"Test User ID: {TEST_USER_ID}") print(f"Test Category ID: {TEST_CATEGORY_ID}") print("\nTesting against Hugging Face deployment") print("(For local testing, change BASE_URL to http://localhost:8000 and start server with: uvicorn app.main:app --reload)\n") results = [] # Run all tests results.append(("User with Previous Data", test_recommendations_check_with_data())) results.append(("With Budget Amount", test_recommendations_check_with_budget_amount())) results.append(("New User (No Data)", test_recommendations_check_new_user())) results.append(("New User with Budget Amount", test_recommendations_check_new_user_with_budget())) # Summary print("\n" + "=" * 60) print("Test Summary") print("=" * 60) for test_name, passed in results: status = "[PASS]" if passed else "[FAIL]" print(f"{status} - {test_name}") passed_count = sum(1 for _, passed in results if passed) print(f"\nTotal: {passed_count}/{len(results)} tests passed") print("\n" + "=" * 60) print("API Documentation available at:") print(f" - Swagger UI: {BASE_URL}/docs") print(f" - ReDoc: {BASE_URL}/redoc") print("=" * 60)