Some checks failed
security-audit / Bandit (scan statique) (push) Successful in 12s
security-audit / pip-audit (CVE dépendances) (push) Successful in 10s
security-audit / Scan secrets (grep) (push) Successful in 8s
tests / Lint (ruff + black) (push) Successful in 13s
tests / Tests unitaires (sans GPU) (push) Failing after 14s
tests / Tests sécurité (critique) (push) Has been skipped
Point de sauvegarde incluant les fichiers non committés des sessions précédentes (systemd, docs, agents, GPU manager). Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
213 lines
7.2 KiB
Python
213 lines
7.2 KiB
Python
"""
|
|
Tests pour le dashboard web RPA Vision V3.
|
|
|
|
Vérifie que les routes principales répondent correctement
|
|
et que le template se rend sans erreur.
|
|
"""
|
|
import sys
|
|
from pathlib import Path
|
|
|
|
import pytest
|
|
|
|
# Ajouter le répertoire racine au path
|
|
sys.path.insert(0, str(Path(__file__).parent.parent.parent))
|
|
|
|
from web_dashboard.app import app
|
|
|
|
|
|
@pytest.fixture
|
|
def client():
|
|
"""Client de test Flask."""
|
|
app.config['TESTING'] = True
|
|
with app.test_client() as c:
|
|
yield c
|
|
|
|
|
|
class TestDashboardRoutes:
|
|
"""Tests des routes du dashboard."""
|
|
|
|
def test_index_renders(self, client):
|
|
"""La page d'accueil se rend correctement."""
|
|
resp = client.get('/')
|
|
assert resp.status_code == 200
|
|
assert b'RPA Vision V3' in resp.data
|
|
|
|
def test_healthz(self, client):
|
|
"""Le healthcheck retourne OK."""
|
|
resp = client.get('/healthz')
|
|
assert resp.status_code == 200
|
|
data = resp.get_json()
|
|
assert data['status'] == 'ok'
|
|
|
|
def test_system_status(self, client):
|
|
"""L'API system/status retourne les compteurs."""
|
|
resp = client.get('/api/system/status')
|
|
assert resp.status_code == 200
|
|
data = resp.get_json()
|
|
assert 'sessions_count' in data
|
|
assert 'workflows_count' in data
|
|
|
|
def test_system_performance(self, client):
|
|
"""L'API system/performance retourne les metriques."""
|
|
resp = client.get('/api/system/performance')
|
|
assert resp.status_code == 200
|
|
data = resp.get_json()
|
|
assert 'faiss' in data
|
|
|
|
def test_version(self, client):
|
|
"""L'API version retourne la version actuelle."""
|
|
resp = client.get('/api/version')
|
|
assert resp.status_code == 200
|
|
data = resp.get_json()
|
|
assert 'version' in data
|
|
# version est un dict avec la clé 'version' (string)
|
|
assert 'version' in data['version']
|
|
|
|
def test_version_system_info(self, client):
|
|
"""L'API version/system-info retourne les infos systeme."""
|
|
resp = client.get('/api/version/system-info')
|
|
assert resp.status_code == 200
|
|
data = resp.get_json()
|
|
assert 'system_info' in data
|
|
si = data['system_info']
|
|
assert 'system' in si
|
|
assert 'python_version' in si['system']
|
|
|
|
def test_version_backups(self, client):
|
|
"""L'API version/backups retourne la liste."""
|
|
resp = client.get('/api/version/backups')
|
|
assert resp.status_code == 200
|
|
data = resp.get_json()
|
|
assert 'backups' in data
|
|
assert isinstance(data['backups'], list)
|
|
|
|
def test_services_list(self, client):
|
|
"""L'API services retourne la liste des services."""
|
|
resp = client.get('/api/services')
|
|
assert resp.status_code == 200
|
|
data = resp.get_json()
|
|
assert 'services' in data
|
|
services = data['services']
|
|
assert len(services) >= 5 # Au moins 5 services configurés
|
|
# Vérifier que le dashboard est dans la liste
|
|
ids = [s['service_id'] for s in services]
|
|
assert 'web_dashboard' in ids
|
|
|
|
def test_config_get(self, client):
|
|
"""L'API config retourne la configuration."""
|
|
resp = client.get('/api/config')
|
|
assert resp.status_code == 200
|
|
data = resp.get_json()
|
|
assert data['success'] is True
|
|
assert 'config' in data
|
|
|
|
def test_backup_stats(self, client):
|
|
"""L'API backup/stats retourne les statistiques."""
|
|
resp = client.get('/api/backup/stats')
|
|
assert resp.status_code == 200
|
|
data = resp.get_json()
|
|
assert 'stats' in data
|
|
stats = data['stats']
|
|
assert 'workflows' in stats
|
|
|
|
def test_workflows_list(self, client):
|
|
"""L'API workflows retourne la liste."""
|
|
resp = client.get('/api/workflows')
|
|
assert resp.status_code == 200
|
|
data = resp.get_json()
|
|
assert 'workflows' in data
|
|
|
|
def test_sessions_list(self, client):
|
|
"""L'API sessions retourne la liste."""
|
|
resp = client.get('/api/agent/sessions')
|
|
assert resp.status_code == 200
|
|
data = resp.get_json()
|
|
assert 'sessions' in data
|
|
|
|
def test_tests_list_removed(self, client):
|
|
"""L'API /api/tests a été retirée (RCE via subprocess)."""
|
|
resp = client.get('/api/tests')
|
|
assert resp.status_code == 404
|
|
|
|
def test_logs(self, client):
|
|
"""L'API logs retourne les logs."""
|
|
resp = client.get('/api/logs')
|
|
assert resp.status_code == 200
|
|
data = resp.get_json()
|
|
assert 'logs' in data
|
|
|
|
def test_chains(self, client):
|
|
"""L'API chains retourne la liste."""
|
|
resp = client.get('/api/chains')
|
|
assert resp.status_code == 200
|
|
data = resp.get_json()
|
|
assert 'chains' in data
|
|
|
|
def test_triggers(self, client):
|
|
"""L'API triggers retourne la liste."""
|
|
resp = client.get('/api/triggers')
|
|
assert resp.status_code == 200
|
|
data = resp.get_json()
|
|
assert 'triggers' in data
|
|
|
|
def test_automation_status_removed(self, client):
|
|
"""L'API /api/automation/status a été retirée."""
|
|
resp = client.get('/api/automation/status')
|
|
assert resp.status_code == 404
|
|
|
|
def test_metrics_endpoint(self, client):
|
|
"""L'endpoint Prometheus /metrics fonctionne."""
|
|
resp = client.get('/metrics')
|
|
assert resp.status_code == 200
|
|
|
|
def test_no_rollback_route(self, client):
|
|
"""La route /api/version/rollback n'existe pas (non implementee)."""
|
|
resp = client.post('/api/version/rollback/test-id')
|
|
assert resp.status_code == 404 or resp.status_code == 405
|
|
|
|
|
|
class TestRemovedRoutes:
|
|
"""Vérifie que les routes supprimées retournent 404."""
|
|
|
|
def test_gestures_page_removed(self, client):
|
|
"""La page /gestures a été retirée."""
|
|
resp = client.get('/gestures')
|
|
assert resp.status_code == 404
|
|
|
|
def test_api_gestures_removed(self, client):
|
|
"""L'API /api/gestures a été retirée."""
|
|
resp = client.get('/api/gestures')
|
|
assert resp.status_code == 404
|
|
|
|
def test_streaming_page_removed(self, client):
|
|
"""La page /streaming a été retirée."""
|
|
resp = client.get('/streaming')
|
|
assert resp.status_code == 404
|
|
|
|
def test_extractions_page_removed(self, client):
|
|
"""La page /extractions a été retirée."""
|
|
resp = client.get('/extractions')
|
|
assert resp.status_code == 404
|
|
|
|
def test_api_extractions_removed(self, client):
|
|
"""L'API /api/extractions a été retirée."""
|
|
resp = client.get('/api/extractions')
|
|
assert resp.status_code == 404
|
|
|
|
def test_chat_page_removed(self, client):
|
|
"""La page /chat a été retirée."""
|
|
resp = client.get('/chat')
|
|
assert resp.status_code == 404
|
|
|
|
|
|
class TestFleetProxy:
|
|
"""Tests du proxy fleet (requiert serveur streaming, donc 502 attendu)."""
|
|
|
|
def test_fleet_list_proxy(self, client):
|
|
"""Le proxy /api/fleet/fleet retourne 200, 401 ou 502 (serveur offline/auth)."""
|
|
resp = client.get('/api/fleet/fleet')
|
|
# 200 = ok, 401 = streaming server rejette le token, 502 = serveur offline
|
|
assert resp.status_code in (200, 401, 502)
|
|
data = resp.get_json()
|
|
assert isinstance(data, dict)
|