"""
Tests de robustesse pour gérer les cas limites.
"""
import os
import sys
import asyncio
import sqlite3
# Force UTF-8 encoding for Windows console
if sys.platform == 'win32':
import io
sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding='utf-8')
sys.stderr = io.TextIOWrapper(sys.stderr.buffer, encoding='utf-8')
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
os.environ['DB_PATH'] = r'C:\Users\miche\AppData\Roaming\com.teymz.wealthfolio\app.db'
from mcp_server import get_real_estate_data, call_tool
async def test_no_real_estate_addon():
"""Test quand l'addon Real Estate n'est pas installé."""
print("\n" + "="*80)
print("TEST: Fonctionnement sans addon Real Estate")
print("="*80)
# Simuler l'absence de données (en créant une copie temporaire de la fonction)
# Pour ce test, on vérifie juste que get_real_estate_data() retourne une structure vide
data = get_real_estate_data()
print(f"\nDonnées récupérées:")
print(f" - Properties: {len(data.get('properties', []))}")
print(f" - Loans: {len(data.get('loans', []))}")
print(f" - Valuations: {len(data.get('valuations', []))}")
assert 'properties' in data, "Doit toujours avoir la clé 'properties'"
assert 'loans' in data, "Doit toujours avoir la clé 'loans'"
assert isinstance(data['properties'], list), "Properties doit être une liste"
assert isinstance(data['loans'], list), "Loans doit être une liste"
print("\n✓ get_real_estate_data() retourne une structure valide même sans addon")
async def test_portfolio_summary_without_real_estate():
"""Test de get_portfolio_summary() sans données immobilières."""
print("\n" + "="*80)
print("TEST: Portfolio Summary sans immobilier")
print("="*80)
# Si l'utilisateur n'a pas de données immobilières, la fonction doit
# quand même fonctionner et afficher uniquement les actifs financiers
result = await call_tool("get_portfolio_summary", {})
text = result[0].text
print(text)
assert "PATRIMOINE TOTAL" in text, "Doit afficher le titre"
assert "Actifs financiers" in text, "Doit afficher les actifs financiers"
# Si pas d'immobilier, ne devrait pas planter
print("\n✓ Portfolio Summary fonctionne sans erreur")
async def test_empty_property_list():
"""Test avec liste de propriétés vide."""
print("\n" + "="*80)
print("TEST: Liste de propriétés vide")
print("="*80)
result = await call_tool("get_real_estate_properties", {})
text = result[0].text
print(text)
# Si pas de propriétés, doit afficher un message approprié
if "Aucune propriété" in text or "0)" in text:
print("\n✓ Gère correctement l'absence de propriétés")
else:
print("\n✓ Affiche les propriétés existantes")
async def test_empty_loan_list():
"""Test avec liste de crédits vide."""
print("\n" + "="*80)
print("TEST: Liste de crédits vide")
print("="*80)
result = await call_tool("get_real_estate_loans", {})
text = result[0].text
print(text)
if "Aucun crédit" in text or "0)" in text:
print("\n✓ Gère correctement l'absence de crédits")
else:
print("\n✓ Affiche les crédits existants")
async def test_missing_loan_fields():
"""Test avec un loanId invalide."""
print("\n" + "="*80)
print("TEST: Crédit avec ID invalide")
print("="*80)
result = await call_tool("get_loan_amortization", {"loanId": "INVALID_ID"})
text = result[0].text
print(text)
assert "introuvable" in text or "Aucun crédit" in text, "Doit afficher un message d'erreur approprié"
print("\n✓ Gère correctement les ID invalides")
async def test_accounts_summary_robustness():
"""Test de get_accounts_summary() avec données partielles."""
print("\n" + "="*80)
print("TEST: Accounts Summary robustesse")
print("="*80)
result = await call_tool("get_accounts_summary", {})
text = result[0].text
print(text[:500] + "...") # Afficher un extrait
assert "RÉSUMÉ PAR GROUPE DE COMPTES" in text or "Aucun compte" in text
print("\n✓ Accounts Summary fonctionne correctement")
async def run_all_tests():
"""Exécute tous les tests de robustesse."""
print("\n" + "="*80)
print("TESTS DE ROBUSTESSE")
print("="*80)
tests = [
("No Real Estate Addon", test_no_real_estate_addon),
("Portfolio Summary without RE", test_portfolio_summary_without_real_estate),
("Empty Property List", test_empty_property_list),
("Empty Loan List", test_empty_loan_list),
("Missing Loan Fields", test_missing_loan_fields),
("Accounts Summary", test_accounts_summary_robustness),
]
results = []
for test_name, test_func in tests:
try:
await test_func()
results.append((test_name, True))
except Exception as e:
print(f"\n✗ ERREUR dans {test_name}: {str(e)}")
import traceback
traceback.print_exc()
results.append((test_name, False))
# Résumé
print("\n" + "="*80)
print("RÉSUMÉ DES TESTS DE ROBUSTESSE")
print("="*80)
passed = sum(1 for _, result in results if result)
total = len(results)
for test_name, result in results:
status = "✓ PASS" if result else "✗ FAIL"
print(f"{status}: {test_name}")
print(f"\nRésultat: {passed}/{total} tests réussis")
if passed == total:
print("\n🎉 Tous les tests de robustesse sont passés!")
else:
print(f"\n⚠ {total - passed} test(s) échoué(s)")
if __name__ == "__main__":
asyncio.run(run_all_tests())