first commit

This commit is contained in:
mathieu 2025-07-14 17:56:57 +02:00
commit a233e18c0b
48 changed files with 55300 additions and 0 deletions

3
tests/__init__.py Normal file
View file

@ -0,0 +1,3 @@
"""
Test package for Atmo Data Wrapper
"""

View file

@ -0,0 +1,174 @@
#!/usr/bin/env python3
"""
Test du système de credentials sans connexion réelle
"""
from atmo_data_wrapper import AtmoDataClient, AtmoDataException
import json
import os
import tempfile
def test_credentials_loading():
"""Test du chargement des credentials"""
print("=== Test du système de credentials ===\n")
# Test 1: Fichier manquant
print("1. Test fichier credentials manquant...")
client = AtmoDataClient(credentials_file="inexistant.json")
try:
client._load_credentials()
print("❌ Erreur: Exception attendue pour fichier manquant")
except AtmoDataException as e:
if "non trouvé" in str(e):
print("✅ Exception correcte pour fichier manquant")
else:
print(f"❌ Message d'erreur inattendu: {e}")
# Test 2: Fichier JSON invalide
print("\n2. Test fichier JSON invalide...")
with tempfile.NamedTemporaryFile(mode='w', delete=False, suffix='.json') as f:
f.write("{ invalid json }")
invalid_file = f.name
try:
client_invalid = AtmoDataClient(credentials_file=invalid_file)
client_invalid._load_credentials()
print("❌ Erreur: Exception attendue pour JSON invalide")
except AtmoDataException as e:
if "JSON" in str(e):
print("✅ Exception correcte pour JSON invalide")
else:
print(f"❌ Message d'erreur inattendu: {e}")
finally:
os.unlink(invalid_file)
# Test 3: Champs manquants
print("\n3. Test champs manquants...")
with tempfile.NamedTemporaryFile(mode='w', delete=False, suffix='.json') as f:
json.dump({"username": "test"}, f) # Manque password
incomplete_file = f.name
try:
client_incomplete = AtmoDataClient(credentials_file=incomplete_file)
client_incomplete._load_credentials()
print("❌ Erreur: Exception attendue pour champs manquants")
except ValueError as e:
if "manquants" in str(e):
print("✅ Exception correcte pour champs manquants")
else:
print(f"❌ Message d'erreur inattendu: {e}")
finally:
os.unlink(incomplete_file)
# Test 4: Fichier valide
print("\n4. Test fichier credentials valide...")
test_credentials = {
"username": "test_user",
"password": "test_pass",
"api_url": "https://test-api.example.com"
}
with tempfile.NamedTemporaryFile(mode='w', delete=False, suffix='.json') as f:
json.dump(test_credentials, f)
valid_file = f.name
try:
client_valid = AtmoDataClient(credentials_file=valid_file)
credentials = client_valid._load_credentials()
if credentials['username'] == 'test_user' and credentials['password'] == 'test_pass':
print("✅ Credentials chargés correctement")
print(f" Username: {credentials['username']}")
print(f" API URL mise à jour: {client_valid.base_url}")
else:
print("❌ Credentials incorrects")
except Exception as e:
print(f"❌ Erreur inattendue: {e}")
finally:
os.unlink(valid_file)
# Test 5: Login avec credentials
print("\n5. Test méthode login avec credentials...")
# Créer un client avec mock
client_mock = AtmoDataClient(credentials_file=valid_file)
# Mock de la méthode _make_request pour simuler réponse login
def mock_post(url, json=None):
class MockResponse:
def raise_for_status(self):
pass
def json(self):
return {"token": "test_token_123"}
return MockResponse()
# Remplacer temporairement
original_post = client_mock.session.post
client_mock.session.post = mock_post
# Créer un fichier credentials temporaire pour ce test
with tempfile.NamedTemporaryFile(mode='w', delete=False, suffix='.json') as f:
json.dump(test_credentials, f)
temp_cred_file = f.name
try:
client_mock.credentials_file = temp_cred_file
success = client_mock.login() # Sans paramètres, doit utiliser le fichier
if success and client_mock.token == "test_token_123":
print("✅ Login avec credentials automatique réussi")
else:
print("❌ Login avec credentials échoué")
except Exception as e:
print(f"❌ Erreur login: {e}")
finally:
client_mock.session.post = original_post
os.unlink(temp_cred_file)
print("\n=== Tests du système de credentials terminés ===")
def test_auto_login():
"""Test de la méthode auto_login"""
print("\n=== Test auto_login ===\n")
test_credentials = {
"username": "auto_user",
"password": "auto_pass"
}
with tempfile.NamedTemporaryFile(mode='w', delete=False, suffix='.json') as f:
json.dump(test_credentials, f)
cred_file = f.name
try:
client = AtmoDataClient(credentials_file=cred_file)
# Mock de la session
def mock_post(url, json=None):
class MockResponse:
def raise_for_status(self):
pass
def json(self):
return {"token": "auto_token_456"}
return MockResponse()
client.session.post = mock_post
success = client.auto_login()
if success and client.token == "auto_token_456":
print("✅ auto_login() fonctionne correctement")
else:
print("❌ auto_login() a échoué")
except Exception as e:
print(f"❌ Erreur auto_login: {e}")
finally:
os.unlink(cred_file)
if __name__ == "__main__":
test_credentials_loading()
test_auto_login()

View file

@ -0,0 +1,187 @@
#!/usr/bin/env python3
"""
Test de connexion réelle à l'API Atmo Data
Nécessite un fichier credentials.json valide
"""
from atmo_data_wrapper import AtmoDataClient, AtmoDataException
from datetime import datetime
def test_real_api_connection():
"""Test de connexion et requêtes réelles à l'API"""
print("=== Test de connexion réelle à l'API Atmo Data ===\n")
try:
# Initialisation du client
client = AtmoDataClient()
print("Client initialisé")
# Test de connexion automatique
print("Tentative de connexion avec credentials.json...")
success = client.auto_login()
if not success:
print("❌ Échec de l'authentification")
return False
print("✅ Connexion réussie !")
print(f"URL de l'API: {client.base_url}")
# Test 1: Récupération des indices ATMO
print("\n=== Test 1: Indices ATMO ===")
try:
indices = client.get_indices_atmo(format="geojson")
print(f"✅ Indices ATMO récupérés: {len(indices)} éléments")
# Afficher un échantillon
if len(indices) > 0:
first_item = indices[0]
print(f" Premier élément - Zone: {first_item.lib_zone}")
print(f" Qualité: {first_item.get_qualificatif()}")
print(f" AASQA: {first_item.get_aasqa_name()}")
# Statistiques
stats = indices.get_statistics()
print(f" Statistiques: {stats}")
except Exception as e:
print(f"❌ Erreur récupération indices: {e}")
# Test 2: Épisodes de pollution
print("\n=== Test 2: Épisodes de pollution ===")
try:
episodes = client.get_episodes_3jours(format="geojson")
print(f"✅ Épisodes récupérés: {len(episodes)} éléments")
if len(episodes) > 0:
alerts_actives = [ep for ep in episodes if ep.is_alert_active()]
print(f" Alertes actives: {len(alerts_actives)}")
for episode in alerts_actives[:3]: # Max 3 exemples
print(f" - {episode.lib_zone}: {episode.get_alert_level()} ({episode.lib_pol})")
except Exception as e:
print(f"❌ Erreur récupération épisodes: {e}")
# Test 3: Données d'émissions (région)
print("\n=== Test 3: Données d'émissions ===")
try:
emissions = client.get_emissions(
echelle="region",
format="geojson"
)
print(f"✅ Données d'émissions récupérées: {len(emissions)} éléments")
if len(emissions) > 0:
first_emission = emissions[0]
print(f" Premier territoire: {first_emission.name}")
total_em = first_emission.get_total_emissions()
print(f" NOx: {total_em['NOx']:.1f} t/an")
except Exception as e:
print(f"❌ Erreur récupération émissions: {e}")
# Test 4: Indices pollen
print("\n=== Test 4: Indices pollen ===")
try:
pollens = client.get_indices_pollens(format="geojson")
print(f"✅ Indices pollen récupérés: {len(pollens)} éléments")
if len(pollens) > 0:
alerts_pollen = [p for p in pollens if p.is_alert_active()]
print(f" Alertes pollen actives: {len(alerts_pollen)}")
for pollen in alerts_pollen[:3]: # Max 3 exemples
dangerous = pollen.get_dangerous_pollens()
if dangerous:
print(f" - Pollens à risque: {', '.join(dangerous)}")
except Exception as e:
print(f"❌ Erreur récupération pollens: {e}")
# Test 5: Filtrage géographique (Paris)
print("\n=== Test 5: Filtrage géographique ===")
try:
# Bounding box de Paris
bbox = "2.2 48.8 2.4 48.9"
indices_paris = client.get_indices_atmo(
bounding_box=bbox,
format="geojson"
)
print(f"✅ Indices Paris récupérés: {len(indices_paris)} éléments")
# Filtrage par proximité
if len(indices_paris) > 0:
from atmo_data_wrapper import Coordinates
paris_center = Coordinates(2.3522, 48.8566)
nearby = indices_paris.filter_by_coordinates(paris_center, 10.0)
print(f" Dans un rayon de 10km: {len(nearby)} éléments")
except Exception as e:
print(f"❌ Erreur filtrage géographique: {e}")
print("\n✅ Tests terminés avec succès !")
return True
except AtmoDataException as e:
print(f"❌ Erreur API: {e}")
return False
except Exception as e:
print(f"❌ Erreur inattendue: {e}")
return False
def test_credentials_file():
"""Test de présence et validité du fichier credentials"""
print("=== Vérification du fichier credentials ===\n")
import os
import json
credentials_file = "credentials.json"
example_file = "credentials.json.example"
# Vérifier la présence du fichier exemple
if os.path.exists(example_file):
print(f"✅ Fichier exemple trouvé: {example_file}")
else:
print(f"❌ Fichier exemple manquant: {example_file}")
# Vérifier la présence du fichier credentials
if os.path.exists(credentials_file):
print(f"✅ Fichier credentials trouvé: {credentials_file}")
try:
with open(credentials_file, 'r') as f:
creds = json.load(f)
required_fields = ['username', 'password']
missing_fields = [field for field in required_fields if field not in creds]
if missing_fields:
print(f"❌ Champs manquants: {missing_fields}")
else:
print("✅ Structure du fichier credentials valide")
# Masquer les credentials sensibles
safe_creds = {k: "***" if k in ['password'] else v for k, v in creds.items()}
print(f" Contenu: {safe_creds}")
except json.JSONDecodeError as e:
print(f"❌ Erreur de format JSON: {e}")
else:
print(f"❌ Fichier credentials manquant: {credentials_file}")
print(f"💡 Créez le fichier à partir de {example_file}")
print(" 1. Copiez credentials.json.example vers credentials.json")
print(" 2. Remplacez les valeurs par vos vrais identifiants")
if __name__ == "__main__":
# Test du fichier credentials d'abord
test_credentials_file()
print()
# Puis test de connexion réelle si possible
if input("Tester la connexion réelle à l'API ? (y/n): ").lower() == 'y':
test_real_api_connection()
else:
print("Test de connexion ignoré.")

View file

@ -0,0 +1,177 @@
#!/usr/bin/env python3
"""
Tests pour la fonctionnalité de sauvegarde
"""
from atmo_data_wrapper import AtmoDataClient
import os
import json
import csv
from pathlib import Path
def test_save_functionality():
"""Test complet de la fonctionnalité de sauvegarde"""
print("=== Tests de la fonctionnalité de sauvegarde ===\n")
client = AtmoDataClient()
# Données de test
test_data = {
"type": "FeatureCollection",
"features": [
{
"type": "Feature",
"geometry": {
"type": "Point",
"coordinates": [2.3522, 48.8566]
},
"properties": {
"nom": "Test Paris",
"valeur": 42.5,
"date": "2024-07-07"
}
}
]
}
test_dir = "test_files"
# Test 1: Validation du format
print("1. Test de validation du format...")
try:
client._validate_save_format("json")
print("✅ Format JSON valide")
except Exception as e:
print(f"❌ Erreur format JSON: {e}")
try:
client._validate_save_format("xml")
print("❌ Format XML invalide accepté")
except ValueError as e:
print(f"✅ Format XML correctement rejeté: {e}")
# Test 2: Sauvegarde JSON
print("\n2. Test sauvegarde JSON...")
try:
json_file = client.save_to_file(test_data, f"{test_dir}/test", "json")
if os.path.exists(json_file):
# Vérifier que le fichier est du JSON valide
with open(json_file, 'r') as f:
loaded_data = json.load(f)
print("✅ Fichier JSON créé et valide")
else:
print("❌ Fichier JSON non créé")
except Exception as e:
print(f"❌ Erreur JSON: {e}")
# Test 3: Sauvegarde CSV
print("\n3. Test sauvegarde CSV...")
try:
csv_file = client.save_to_file(test_data, f"{test_dir}/test", "csv")
if os.path.exists(csv_file):
# Vérifier le contenu CSV
with open(csv_file, 'r') as f:
reader = csv.reader(f)
rows = list(reader)
if len(rows) >= 2: # Header + au moins une ligne
print("✅ Fichier CSV créé avec en-tête et données")
else:
print("❌ Fichier CSV incomplet")
else:
print("❌ Fichier CSV non créé")
except Exception as e:
print(f"❌ Erreur CSV: {e}")
# Test 4: Sauvegarde GeoJSON
print("\n4. Test sauvegarde GeoJSON...")
try:
geojson_file = client.save_to_file(test_data, f"{test_dir}/test", "geojson")
if os.path.exists(geojson_file):
# Vérifier que c'est du GeoJSON valide
with open(geojson_file, 'r') as f:
loaded_data = json.load(f)
if loaded_data.get('type') == 'FeatureCollection':
print("✅ Fichier GeoJSON créé et valide")
else:
print("❌ Fichier GeoJSON invalide")
else:
print("❌ Fichier GeoJSON non créé")
except Exception as e:
print(f"❌ Erreur GeoJSON: {e}")
# Test 5: Création de répertoires
print("\n5. Test création de répertoires...")
try:
nested_file = client.save_to_file(test_data, f"{test_dir}/nested/deep/test", "json")
if os.path.exists(nested_file):
print("✅ Répertoires imbriqués créés automatiquement")
else:
print("❌ Répertoires imbriqués non créés")
except Exception as e:
print(f"❌ Erreur création répertoires: {e}")
# Test 6: Extension automatique
print("\n6. Test ajout automatique d'extension...")
try:
auto_ext_file = client.save_to_file(test_data, f"{test_dir}/sans_extension", "json")
if auto_ext_file.endswith('.json'):
print("✅ Extension .json ajoutée automatiquement")
else:
print("❌ Extension non ajoutée")
except Exception as e:
print(f"❌ Erreur extension automatique: {e}")
# Test 7: Données sans géométrie
print("\n7. Test données sans géométrie...")
data_no_geom = {
"type": "FeatureCollection",
"features": [
{
"type": "Feature",
"geometry": None,
"properties": {
"nom": "Test sans géométrie",
"valeur": 123
}
}
]
}
try:
no_geom_file = client.save_to_file(data_no_geom, f"{test_dir}/no_geom", "csv")
if os.path.exists(no_geom_file):
with open(no_geom_file, 'r') as f:
content = f.read()
if 'nom,valeur' in content and 'Test sans géométrie,123' in content:
print("✅ CSV sans géométrie créé correctement")
else:
print("❌ CSV sans géométrie incorrect")
else:
print("❌ Fichier sans géométrie non créé")
except Exception as e:
print(f"❌ Erreur données sans géométrie: {e}")
# Test 8: Données invalides pour GeoJSON
print("\n8. Test données invalides pour GeoJSON...")
invalid_geojson = {"data": "not a geojson"}
try:
client.save_to_file(invalid_geojson, f"{test_dir}/invalid", "geojson")
print("❌ Données invalides acceptées pour GeoJSON")
except ValueError as e:
print(f"✅ Données invalides correctement rejetées: {e}")
# Nettoyage
print("\n9. Nettoyage des fichiers de test...")
try:
import shutil
if os.path.exists(test_dir):
shutil.rmtree(test_dir)
print("✅ Fichiers de test supprimés")
except Exception as e:
print(f"❌ Erreur nettoyage: {e}")
print("\n=== Tests terminés ===")
if __name__ == "__main__":
test_save_functionality()

107
tests/test_typed_client.py Normal file
View file

@ -0,0 +1,107 @@
#!/usr/bin/env python3
"""
Test simple du client avec les nouveaux objets typés
"""
from atmo_data_wrapper import AtmoDataClient
from atmo_data_wrapper import AtmoDataCollection, IndiceAtmo
def test_client_integration():
"""Test que le client retourne bien les bons types d'objets"""
print("=== Test d'intégration client/modèles ===\n")
client = AtmoDataClient()
# Test avec données simulées (sans vraie connexion API)
# Simuler _make_request pour retourner des données de test
def mock_make_request(endpoint, params=None):
return {
"type": "FeatureCollection",
"features": [
{
"type": "Feature",
"geometry": {
"type": "Point",
"coordinates": [2.3522, 48.8566]
},
"properties": {
"aasqa": "11",
"code_qual": 3,
"lib_qual": "Dégradé",
"lib_zone": "Test Zone"
}
}
]
}
# Remplacer temporairement la méthode
original_make_request = client._make_request
client._make_request = mock_make_request
client.token = "test_token" # Simuler une connexion
try:
# Test 1: get_indices_atmo avec format geojson -> AtmoDataCollection
print("1. Test get_indices_atmo format geojson...")
result = client.get_indices_atmo(format="geojson")
if isinstance(result, AtmoDataCollection):
print("✅ Retourne bien AtmoDataCollection")
print(f" Type de données: {result.data_type}")
print(f" Nombre d'éléments: {len(result)}")
# Vérifier que les éléments sont du bon type
if len(result) > 0 and isinstance(result[0], IndiceAtmo):
print("✅ Les éléments sont bien des objets IndiceAtmo")
print(f" Zone: {result[0].lib_zone}")
print(f" Qualité: {result[0].get_qualificatif()}")
else:
print("❌ Les éléments ne sont pas des objets IndiceAtmo")
else:
print(f"❌ Retourne {type(result)} au lieu de AtmoDataCollection")
print()
# Test 2: Simuler format CSV -> dict
def mock_csv_request(endpoint, params=None):
return {"data": "csv,data,here"}
client._make_request = mock_csv_request
print("2. Test get_indices_atmo format csv...")
result_csv = client.get_indices_atmo(format="csv")
if isinstance(result_csv, dict):
print("✅ Format CSV retourne bien un dict")
else:
print(f"❌ Format CSV retourne {type(result_csv)} au lieu de dict")
print()
# Test 3: Test différents endpoints
client._make_request = mock_make_request
endpoints_to_test = [
("get_episodes_3jours", "episodes"),
("get_emissions", "emissions"),
("get_indices_pollens", "pollens")
]
print("3. Test autres endpoints...")
for method_name, expected_type in endpoints_to_test:
method = getattr(client, method_name)
result = method(format="geojson")
if isinstance(result, AtmoDataCollection) and result.data_type == expected_type:
print(f"{method_name} retourne bien AtmoDataCollection({expected_type})")
else:
print(f"{method_name} problème de type: {type(result)}, data_type: {getattr(result, 'data_type', 'N/A')}")
print("\n=== Test terminé ===")
finally:
# Restaurer la méthode originale
client._make_request = original_make_request
if __name__ == "__main__":
test_client_integration()

261
tests/test_validations.py Normal file
View file

@ -0,0 +1,261 @@
#!/usr/bin/env python3
"""
Script de test pour valider les validations du wrapper AtmoDataClient
"""
from atmo_data_wrapper import AtmoDataClient
def test_validations():
"""Test des validations des paramètres"""
client = AtmoDataClient()
print("=== Test des validations ===\n")
# Test format invalide
try:
client._validate_format("xml")
print("❌ Format invalide non détecté")
except ValueError as e:
print(f"✅ Format invalide détecté: {e}")
# Test format valide
try:
client._validate_format("geojson")
print("✅ Format valide accepté")
except ValueError as e:
print(f"❌ Format valide rejeté: {e}")
# Test AASQA invalide
try:
client._validate_aasqa("99")
print("❌ Code AASQA invalide non détecté")
except ValueError as e:
print(f"✅ Code AASQA invalide détecté: {e}")
# Test AASQA valide
try:
client._validate_aasqa("11")
print("✅ Code AASQA valide accepté")
except ValueError as e:
print(f"❌ Code AASQA valide rejeté: {e}")
# Test polluant invalide
try:
client._validate_polluant("CO")
print("❌ Polluant invalide non détecté")
except ValueError as e:
print(f"✅ Polluant invalide détecté: {e}")
# Test polluant valide
try:
client._validate_polluant("PM10")
print("✅ Polluant valide accepté")
except ValueError as e:
print(f"❌ Polluant valide rejeté: {e}")
# Test date invalide (format)
try:
client._validate_date("2024/06/08")
print("❌ Format de date invalide non détecté")
except ValueError as e:
print(f"✅ Format de date invalide détecté: {e}")
# Test date invalide (date inexistante)
try:
client._validate_date("2024-02-30")
print("❌ Date inexistante non détectée")
except ValueError as e:
print(f"✅ Date inexistante détectée: {e}")
# Test date valide
try:
client._validate_date("2024-06-08")
print("✅ Date valide acceptée")
except ValueError as e:
print(f"❌ Date valide rejetée: {e}")
# Test code qualificatif ATMO invalide
try:
client._validate_code_qualificatif_atmo("8")
print("❌ Code qualificatif ATMO invalide non détecté")
except ValueError as e:
print(f"✅ Code qualificatif ATMO invalide détecté: {e}")
# Test code qualificatif ATMO valide
try:
client._validate_code_qualificatif_atmo("3")
print("✅ Code qualificatif ATMO valide accepté")
except ValueError as e:
print(f"❌ Code qualificatif ATMO valide rejeté: {e}")
# Test code qualificatif pollen invalide
try:
client._validate_code_qualificatif_pollen("7")
print("❌ Code qualificatif pollen invalide non détecté")
except ValueError as e:
print(f"✅ Code qualificatif pollen invalide détecté: {e}")
# Test code qualificatif pollen valide
try:
client._validate_code_qualificatif_pollen("4")
print("✅ Code qualificatif pollen valide accepté")
except ValueError as e:
print(f"❌ Code qualificatif pollen valide rejeté: {e}")
# Test type épisode invalide
try:
client._validate_type_episode("CRITIQUE")
print("❌ Type épisode invalide non détecté")
except ValueError as e:
print(f"✅ Type épisode invalide détecté: {e}")
# Test type épisode valide
try:
client._validate_type_episode("ALERTE")
print("✅ Type épisode valide accepté")
except ValueError as e:
print(f"❌ Type épisode valide rejeté: {e}")
# Test échéance invalide
try:
client._validate_echeance("2")
print("❌ Échéance invalide non détectée")
except ValueError as e:
print(f"✅ Échéance invalide détectée: {e}")
# Test échéance valide
try:
client._validate_echeance("-1")
print("✅ Échéance valide acceptée")
except ValueError as e:
print(f"❌ Échéance valide rejetée: {e}")
# Test échelle invalide
try:
client._validate_echelle("commune")
print("❌ Échelle invalide non détectée")
except ValueError as e:
print(f"✅ Échelle invalide détectée: {e}")
# Test échelle valide
try:
client._validate_echelle("epci")
print("✅ Échelle valide acceptée")
except ValueError as e:
print(f"❌ Échelle valide rejetée: {e}")
# Test secteur invalide
try:
client._validate_secteur("99")
print("❌ Secteur invalide non détecté")
except ValueError as e:
print(f"✅ Secteur invalide détecté: {e}")
# Test secteur valide
try:
client._validate_secteur("5")
print("✅ Secteur valide accepté")
except ValueError as e:
print(f"❌ Secteur valide rejeté: {e}")
# Test bounding box invalide (format)
try:
client._validate_bounding_box("2.2 48.8 2.4")
print("❌ Format bounding box invalide non détecté")
except ValueError as e:
print(f"✅ Format bounding box invalide détecté: {e}")
# Test bounding box invalide (coordonnées)
try:
client._validate_bounding_box("2.4 48.8 2.2 48.9")
print("❌ Coordonnées bounding box invalides non détectées")
except ValueError as e:
print(f"✅ Coordonnées bounding box invalides détectées: {e}")
# Test bounding box valide
try:
client._validate_bounding_box("2.2 48.8 2.4 48.9")
print("✅ Bounding box valide acceptée")
except ValueError as e:
print(f"❌ Bounding box valide rejetée: {e}")
print("\n=== Test des méthodes avec validations ===\n")
# Test méthode avec paramètres invalides
try:
client.get_indices_atmo(format="xml")
print("❌ Méthode avec format invalide non bloquée")
except ValueError as e:
print(f"✅ Méthode avec format invalide bloquée: {e}")
try:
client.get_episodes_3jours(aasqa="99")
print("❌ Méthode avec AASQA invalide non bloquée")
except ValueError as e:
print(f"✅ Méthode avec AASQA invalide bloquée: {e}")
try:
client.get_episodes_historique(date="2024/06/08")
print("❌ Méthode avec date invalide non bloquée")
except ValueError as e:
print(f"✅ Méthode avec date invalide bloquée: {e}")
try:
client.get_emissions(echelle="commune")
print("❌ Méthode avec échelle invalide non bloquée")
except ValueError as e:
print(f"✅ Méthode avec échelle invalide bloquée: {e}")
try:
client.get_indices_pollens(code_qualificatif="7")
print("❌ Méthode avec code qualificatif pollen invalide non bloquée")
except ValueError as e:
print(f"✅ Méthode avec code qualificatif pollen invalide bloquée: {e}")
print("\n=== Tests terminés ===")
def test_integration_examples():
"""Test d'intégration avec des exemples réalistes"""
print("\n=== Test d'intégration ===\n")
client = AtmoDataClient()
# Test avec paramètres valides (sans authentification)
try:
# Ces appels échoueront sur l'authentification mais les validations passeront
client.get_indices_atmo(
format="geojson",
date="2024-06-08",
aasqa="11",
code_qualificatif="3"
)
print("❌ Appel réussi sans authentification")
except ValueError as e:
print(f"❌ Validation échouée avec paramètres valides: {e}")
except Exception as e:
if "Token non disponible" in str(e):
print("✅ Validations réussies, échec sur l'authentification comme attendu")
else:
print(f"❌ Erreur inattendue: {e}")
try:
client.get_episodes_3jours(
format="csv",
polluant="PM10",
type_episode="ALERTE",
echeance="0"
)
print("❌ Appel réussi sans authentification")
except ValueError as e:
print(f"❌ Validation échouée avec paramètres valides: {e}")
except Exception as e:
if "Token non disponible" in str(e):
print("✅ Validations réussies, échec sur l'authentification comme attendu")
else:
print(f"❌ Erreur inattendue: {e}")
if __name__ == "__main__":
test_validations()
test_integration_examples()