Spaces:
Sleeping
Sleeping
| from unittest.mock import patch, MagicMock | |
| from streamlit.testing.v1 import AppTest | |
| APP_PATH = "src/api/app.py" | |
| MOCK_CLIENT_USER = {"id": 2, "username": "client1", "role": "client"} | |
| MOCK_ADMIN_USER = {"id": 1, "username": "admin", "role": "administrateur"} | |
| def make_mock_supabase_empty(): | |
| """Returns empty data for all queries.""" | |
| mock_response = MagicMock() | |
| mock_response.data = [] | |
| mock_query = MagicMock() | |
| mock_query.select.return_value = mock_query | |
| mock_query.eq.return_value = mock_query | |
| mock_query.order.return_value = mock_query | |
| mock_query.limit.return_value = mock_query | |
| mock_query.in_.return_value = mock_query | |
| mock_query.execute.return_value = mock_response | |
| mock_client = MagicMock() | |
| mock_client.table.return_value = mock_query | |
| return mock_client | |
| def app_logged_in(user): | |
| at = AppTest.from_file(APP_PATH) | |
| at.session_state["user"] = user | |
| at.run() | |
| return at | |
| def test_monitoring_acces_refuse_pour_client(): | |
| with patch("src.utils.database.get_client", return_value=make_mock_supabase_empty()): | |
| at = app_logged_in(MOCK_CLIENT_USER) | |
| # Client role does not have "administrateur", so Monitoring page won't be added | |
| user = at.session_state["user"] | |
| assert user["role"] != "administrateur" | |
| def test_monitoring_acces_admin_affiche_le_titre(): | |
| with patch("src.utils.database.get_client", return_value=make_mock_supabase_empty()): | |
| at = app_logged_in(MOCK_ADMIN_USER) | |
| # Admin user is set up, page is accessible | |
| assert at.session_state["user"]["role"] == "administrateur" | |
| def test_monitoring_affiche_info_si_pas_de_logs(): | |
| mock_client = make_mock_supabase_empty() | |
| with patch("src.utils.database.get_client", return_value=mock_client): | |
| at = AppTest.from_file("src/api/monitoring.py") | |
| at.session_state["user"] = MOCK_ADMIN_USER | |
| at.run() | |
| assert any("données" in i.value.lower() for i in at.info) | |
| def test_monitoring_affiche_erreur_si_non_admin(): | |
| mock_client = make_mock_supabase_empty() | |
| with patch("src.utils.database.get_client", return_value=mock_client): | |
| at = AppTest.from_file("src/api/monitoring.py") | |
| at.session_state["user"] = MOCK_CLIENT_USER | |
| at.run() | |
| assert any("refusé" in e.value.lower() or "reserv" in e.value.lower() for e in at.error) | |
| def test_monitoring_affiche_metriques_avec_donnees(): | |
| mock_logs_data = [ | |
| {"sk_id_curr": 100001, "inference_time_ms": 45.0, "requested_at": "2026-05-01T10:00:00", "username": "alice", "found": True}, | |
| {"sk_id_curr": 100002, "inference_time_ms": 55.0, "requested_at": "2026-05-01T11:00:00", "username": "alice", "found": True}, | |
| ] | |
| mock_preds_data = [ | |
| {"sk_id_curr": 100001, "proba_class_1": 0.05}, | |
| {"sk_id_curr": 100002, "proba_class_1": 0.95}, | |
| ] | |
| call_count = 0 | |
| def side_effect_execute(): | |
| nonlocal call_count | |
| call_count += 1 | |
| mock_response = MagicMock() | |
| # query 1: logs_50 → logs data | |
| # query 2: preds_50 → preds data | |
| # query 3: hist → preds data | |
| # query 4: all logs table → logs data | |
| if call_count in (1, 4): | |
| mock_response.data = mock_logs_data | |
| else: | |
| mock_response.data = mock_preds_data | |
| return mock_response | |
| mock_query = MagicMock() | |
| mock_query.select.return_value = mock_query | |
| mock_query.eq.return_value = mock_query | |
| mock_query.order.return_value = mock_query | |
| mock_query.limit.return_value = mock_query | |
| mock_query.in_.return_value = mock_query | |
| mock_query.execute.side_effect = side_effect_execute | |
| mock_client = MagicMock() | |
| mock_client.table.return_value = mock_query | |
| with patch("src.utils.database.get_client", return_value=mock_client): | |
| at = AppTest.from_file("src/api/monitoring.py") | |
| at.session_state["user"] = MOCK_ADMIN_USER | |
| at.run() | |
| assert len(at.metric) >= 3 | |