#!/usr/bin/env python3 """ Final verification test for 15-year financial data fixes Tests all the key improvements made to resolve the issues """ import requests import json from datetime import datetime from typing import Dict, Any # API configuration API_URL = "http://localhost:18001/api/v1" def test_database_cleanup(): """Test database cleanup functionality""" print("๐Ÿงน Testing database cleanup...") response = requests.post(f"{API_URL}/database/cleanup/duplicates") if response.status_code == 200: print(" โœ… Database cleanup successful") return True else: print(f" โŒ Database cleanup failed: {response.status_code}") return False def test_multiple_tickers_quarterly(): """Test quarterly data for multiple tickers""" print("\n๐Ÿ“Š Testing quarterly data for multiple tickers...") tickers = ["AAPL", "MSFT", "GOOGL"] results = {} for ticker in tickers: request_data = { "ticker": ticker, "start_date": "2023-01-01", "end_date": "2024-12-31", "period_type": "quarterly", "include_metrics": True, "force_refresh": False } try: response = requests.post(f"{API_URL}/financial/data", json=request_data, timeout=30) if response.status_code == 200: data = response.json() financial_data = data.get('financial_data', []) results[ticker] = { 'success': True, 'records': len(financial_data), 'real_data': sum(1 for d in financial_data if not d.get('is_estimated', True)) } print(f" โœ… {ticker}: {len(financial_data)} records, {results[ticker]['real_data']} real data") else: results[ticker] = {'success': False, 'error': response.status_code} print(f" โŒ {ticker}: Failed with {response.status_code}") except Exception as e: results[ticker] = {'success': False, 'error': str(e)} print(f" โŒ {ticker}: Exception - {str(e)}") success_count = sum(1 for r in results.values() if r.get('success', False)) print(f" ๐Ÿ“Š Summary: {success_count}/{len(tickers)} tickers successful") return success_count == len(tickers) def test_historical_data_range(): """Test historical data requests with different ranges""" print("\n๐Ÿ•ฐ๏ธ Testing historical data ranges...") test_cases = [ { "name": "3-year quarterly", "ticker": "AAPL", "start_date": "2022-01-01", "end_date": "2024-12-31", "period_type": "quarterly", "expected_min": 8 # At least 8 quarters }, { "name": "5-year annual", "ticker": "AAPL", "start_date": "2020-01-01", "end_date": "2024-12-31", "period_type": "annual", "expected_min": 4 # At least 4 years (yfinance_plus limitation) }, { "name": "15-year annual (auto-switch)", "ticker": "MSFT", "start_date": "2009-01-01", "end_date": "2024-12-31", "period_type": "annual", "expected_min": 3 # At least 3 years due to yfinance_plus limitations } ] results = [] for test_case in test_cases: print(f" ๐Ÿ” Testing {test_case['name']}...") request_data = { "ticker": test_case["ticker"], "start_date": test_case["start_date"], "end_date": test_case["end_date"], "period_type": test_case["period_type"], "include_metrics": True, "force_refresh": True } try: response = requests.post(f"{API_URL}/financial/data", json=request_data, timeout=60) if response.status_code == 200: data = response.json() financial_data = data.get('financial_data', []) if len(financial_data) >= test_case["expected_min"]: print(f" โœ… Success: {len(financial_data)} records (expected โ‰ฅ{test_case['expected_min']})") # Check data quality real_data = sum(1 for d in financial_data if not d.get('is_estimated', True)) years_covered = set() for d in financial_data: year = d.get('period_date', '')[:4] years_covered.add(year) print(f" ๐Ÿ“ˆ Real data: {real_data}/{len(financial_data)}") print(f" ๐Ÿ“… Years: {sorted(years_covered)}") results.append(True) else: print(f" โŒ Insufficient data: {len(financial_data)} < {test_case['expected_min']}") results.append(False) else: print(f" โŒ Request failed: {response.status_code}") results.append(False) except Exception as e: print(f" โŒ Exception: {str(e)}") results.append(False) success_count = sum(results) print(f" ๐Ÿ“Š Summary: {success_count}/{len(test_cases)} test cases passed") return success_count == len(test_cases) def test_performance_improvements(): """Test performance and caching""" print("\nโšก Testing performance improvements...") ticker = "GOOGL" request_data = { "ticker": ticker, "start_date": "2023-01-01", "end_date": "2024-12-31", "period_type": "quarterly", "include_metrics": True } # Test cache usage (should be fast) print(" ๐Ÿ”„ Testing cache usage...") start_time = datetime.now() request_data["force_refresh"] = False response1 = requests.post(f"{API_URL}/financial/data", json=request_data, timeout=30) cache_time = (datetime.now() - start_time).total_seconds() if response1.status_code == 200: data1 = response1.json() print(f" โœ… Cache request: {len(data1.get('financial_data', []))} records in {cache_time:.1f}s") cache_success = True else: print(f" โŒ Cache request failed: {response1.status_code}") cache_success = False # Test force refresh (should work but be slower) print(" ๐Ÿ”„ Testing force refresh...") start_time = datetime.now() request_data["force_refresh"] = True response2 = requests.post(f"{API_URL}/financial/data", json=request_data, timeout=60) refresh_time = (datetime.now() - start_time).total_seconds() if response2.status_code == 200: data2 = response2.json() print(f" โœ… Refresh request: {len(data2.get('financial_data', []))} records in {refresh_time:.1f}s") refresh_success = True # Performance comparison if cache_success and refresh_time > cache_time: speed_diff = refresh_time / cache_time if cache_time > 0 else 1 print(f" โšก Performance: Cache {speed_diff:.1f}x faster than refresh") else: print(f" โŒ Refresh request failed: {response2.status_code}") refresh_success = False return cache_success and refresh_success def test_error_handling(): """Test error handling and validation""" print("\n๐Ÿšจ Testing error handling...") error_tests = [ { "name": "Invalid ticker", "data": {"ticker": "INVALID", "start_date": "2023-01-01", "end_date": "2023-12-31", "period_type": "quarterly"}, "expected_codes": [422, 400] }, { "name": "Future dates", "data": {"ticker": "AAPL", "start_date": "2030-01-01", "end_date": "2030-12-31", "period_type": "quarterly"}, "expected_codes": [400] }, { "name": "Very old dates", "data": {"ticker": "AAPL", "start_date": "1990-01-01", "end_date": "1990-12-31", "period_type": "quarterly"}, "expected_codes": [400] } ] results = [] for test in error_tests: try: response = requests.post(f"{API_URL}/financial/data", json=test["data"], timeout=30) if response.status_code in test["expected_codes"]: print(f" โœ… {test['name']}: Properly handled ({response.status_code})") results.append(True) else: print(f" โŒ {test['name']}: Unexpected response ({response.status_code})") results.append(False) except Exception as e: print(f" โŒ {test['name']}: Exception - {str(e)}") results.append(False) success_count = sum(results) print(f" ๐Ÿ“Š Summary: {success_count}/{len(error_tests)} error cases handled correctly") return success_count == len(error_tests) def main(): """Run all verification tests""" print("๐Ÿ”ง Stock Oracle 15-Year Financial Data Fix Verification") print("=" * 70) print(f"๐Ÿš€ Test started: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}") print(f"๐ŸŽฏ API URL: {API_URL}") # Run all tests tests = [ ("Database Cleanup", test_database_cleanup), ("Multiple Tickers Quarterly", test_multiple_tickers_quarterly), ("Historical Data Range", test_historical_data_range), ("Performance Improvements", test_performance_improvements), ("Error Handling", test_error_handling), ] results = [] for test_name, test_func in tests: print(f"\n{'='*70}") print(f"๐Ÿ” {test_name}") print('='*70) try: result = test_func() results.append((test_name, "PASS" if result else "FAIL")) except Exception as e: print(f"โŒ {test_name} threw exception: {str(e)}") results.append((test_name, "ERROR")) # Final summary print(f"\n{'='*70}") print("๐Ÿ“‹ FINAL TEST RESULTS") print('='*70) for test_name, result in results: icon = "โœ…" if result == "PASS" else "โŒ" print(f"{icon} {test_name}: {result}") pass_count = sum(1 for _, result in results if result == "PASS") total_count = len(results) print(f"\n๐Ÿ“Š Overall Result: {pass_count}/{total_count} tests passed ({pass_count/total_count*100:.1f}%)") print(f"๐Ÿ• Test completed: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}") if pass_count == total_count: print("\n๐ŸŽ‰ ALL TESTS PASSED! 15-year financial data fixes are working correctly.") else: print(f"\nโš ๏ธ {total_count - pass_count} tests failed. Some issues may remain.") if __name__ == "__main__": main()