homelab_automation/tests/backend/test_routes_notifications.py
Bruno Charest ecefbc8611
Some checks failed
Tests / Backend Tests (Python) (3.10) (push) Has been cancelled
Tests / Backend Tests (Python) (3.11) (push) Has been cancelled
Tests / Backend Tests (Python) (3.12) (push) Has been cancelled
Tests / Frontend Tests (JS) (push) Has been cancelled
Tests / Integration Tests (push) Has been cancelled
Tests / All Tests Passed (push) Has been cancelled
Clean up test files and debug artifacts, add node_modules to gitignore, export DashboardManager for testing, and enhance pytest configuration with comprehensive test markers and settings
2025-12-15 08:15:49 -05:00

259 lines
9.9 KiB
Python

"""
Tests pour les routes de notifications ntfy.
Couvre:
- GET /api/notifications/config
- POST /api/notifications/test
- POST /api/notifications/send
- POST /api/notifications/toggle
"""
import pytest
from unittest.mock import patch, MagicMock, AsyncMock
from httpx import AsyncClient
pytestmark = [pytest.mark.unit, pytest.mark.asyncio]
class TestGetNotificationConfig:
"""Tests pour GET /api/notifications/config."""
async def test_get_config_success(self, client: AsyncClient):
"""Récupère la configuration des notifications."""
mock_config = MagicMock()
mock_config.enabled = True
mock_config.base_url = "https://ntfy.sh"
mock_config.default_topic = "homelab"
mock_config.timeout = 10
mock_config.has_auth = False
with patch("app.routes.notifications.notification_service") as mock_service:
mock_service.config = mock_config
response = await client.get("/api/notifications/config")
assert response.status_code == 200
data = response.json()
assert data["enabled"] is True
assert data["base_url"] == "https://ntfy.sh"
assert data["default_topic"] == "homelab"
assert data["timeout"] == 10
assert data["has_auth"] is False
async def test_get_config_with_auth(self, client: AsyncClient):
"""Récupère la configuration avec authentification."""
mock_config = MagicMock()
mock_config.enabled = True
mock_config.base_url = "https://ntfy.example.com"
mock_config.default_topic = "alerts"
mock_config.timeout = 30
mock_config.has_auth = True
with patch("app.routes.notifications.notification_service") as mock_service:
mock_service.config = mock_config
response = await client.get("/api/notifications/config")
assert response.status_code == 200
data = response.json()
assert data["has_auth"] is True
class TestTestNotification:
"""Tests pour POST /api/notifications/test."""
async def test_send_test_notification_success(self, client: AsyncClient):
"""Envoi d'une notification de test réussie."""
mock_config = MagicMock()
mock_config.default_topic = "homelab"
with patch("app.routes.notifications.notification_service") as mock_service:
mock_service.send = AsyncMock(return_value=True)
mock_service.config = mock_config
response = await client.post("/api/notifications/test")
assert response.status_code == 200
data = response.json()
assert data["success"] is True
assert data["topic"] == "homelab"
assert "envoyée" in data["message"]
async def test_send_test_notification_with_custom_topic(self, client: AsyncClient):
"""Envoi d'une notification de test avec topic personnalisé."""
with patch("app.routes.notifications.notification_service") as mock_service:
mock_service.send = AsyncMock(return_value=True)
mock_service.config.default_topic = "default"
response = await client.post("/api/notifications/test?topic=custom-topic")
assert response.status_code == 200
data = response.json()
assert data["topic"] == "custom-topic"
async def test_send_test_notification_with_custom_message(self, client: AsyncClient):
"""Envoi d'une notification de test avec message personnalisé."""
mock_config = MagicMock()
mock_config.default_topic = "homelab"
with patch("app.routes.notifications.notification_service") as mock_service:
mock_service.send = AsyncMock(return_value=True)
mock_service.config = mock_config
response = await client.post(
"/api/notifications/test?message=Custom%20test%20message"
)
assert response.status_code == 200
mock_service.send.assert_called_once()
call_args = mock_service.send.call_args
assert call_args.kwargs["message"] == "Custom test message"
async def test_send_test_notification_failure(self, client: AsyncClient):
"""Échec de l'envoi d'une notification de test."""
mock_config = MagicMock()
mock_config.default_topic = "homelab"
with patch("app.routes.notifications.notification_service") as mock_service:
mock_service.send = AsyncMock(return_value=False)
mock_service.config = mock_config
response = await client.post("/api/notifications/test")
assert response.status_code == 200
data = response.json()
assert data["success"] is False
assert "Échec" in data["message"]
class TestSendCustomNotification:
"""Tests pour POST /api/notifications/send."""
async def test_send_custom_notification_success(self, client: AsyncClient):
"""Envoi d'une notification personnalisée réussie."""
with patch("app.routes.notifications.notification_service") as mock_service:
mock_service.send_request = AsyncMock(return_value={
"success": True,
"topic": "alerts",
"message": "Notification envoyée"
})
response = await client.post(
"/api/notifications/send",
json={
"message": "Alert: Server down!",
"title": "Critical Alert",
"priority": 5,
"tags": ["warning", "server"]
}
)
assert response.status_code == 200
data = response.json()
assert data["success"] is True
async def test_send_custom_notification_with_topic(self, client: AsyncClient):
"""Envoi d'une notification avec topic spécifique."""
with patch("app.routes.notifications.notification_service") as mock_service:
mock_service.send_request = AsyncMock(return_value={
"success": True,
"topic": "custom-alerts",
"message": "Notification envoyée"
})
response = await client.post(
"/api/notifications/send",
json={
"topic": "custom-alerts",
"message": "Custom notification"
}
)
assert response.status_code == 200
async def test_send_custom_notification_minimal(self, client: AsyncClient):
"""Envoi d'une notification avec payload minimal."""
with patch("app.routes.notifications.notification_service") as mock_service:
mock_service.send_request = AsyncMock(return_value={
"success": True,
"topic": "default",
"message": "OK"
})
response = await client.post(
"/api/notifications/send",
json={"message": "Simple message"}
)
assert response.status_code == 200
class TestToggleNotifications:
"""Tests pour POST /api/notifications/toggle."""
async def test_toggle_notifications_enable(self, client: AsyncClient):
"""Active les notifications."""
mock_config = MagicMock()
mock_config.base_url = "https://ntfy.sh"
mock_config.default_topic = "homelab"
mock_config.timeout = 10
mock_config.username = None
mock_config.password = None
mock_config.token = None
with patch("app.routes.notifications.notification_service") as mock_service:
mock_service.config = mock_config
mock_service.reconfigure = MagicMock()
response = await client.post("/api/notifications/toggle?enabled=true")
assert response.status_code == 200
data = response.json()
assert data["enabled"] is True
assert "activées" in data["message"]
mock_service.reconfigure.assert_called_once()
async def test_toggle_notifications_disable(self, client: AsyncClient):
"""Désactive les notifications."""
mock_config = MagicMock()
mock_config.base_url = "https://ntfy.sh"
mock_config.default_topic = "homelab"
mock_config.timeout = 10
mock_config.username = None
mock_config.password = None
mock_config.token = None
with patch("app.routes.notifications.notification_service") as mock_service:
mock_service.config = mock_config
mock_service.reconfigure = MagicMock()
response = await client.post("/api/notifications/toggle?enabled=false")
assert response.status_code == 200
data = response.json()
assert data["enabled"] is False
assert "désactivées" in data["message"]
async def test_toggle_preserves_config(self, client: AsyncClient):
"""Toggle préserve la configuration existante."""
mock_config = MagicMock()
mock_config.base_url = "https://custom.ntfy.sh"
mock_config.default_topic = "custom-topic"
mock_config.timeout = 30
mock_config.username = "user"
mock_config.password = "pass"
mock_config.token = "token123"
with patch("app.routes.notifications.notification_service") as mock_service:
mock_service.config = mock_config
mock_service.reconfigure = MagicMock()
response = await client.post("/api/notifications/toggle?enabled=true")
assert response.status_code == 200
# Verify reconfigure was called with preserved values
call_args = mock_service.reconfigure.call_args[0][0]
assert call_args.base_url == "https://custom.ntfy.sh"
assert call_args.default_topic == "custom-topic"
assert call_args.timeout == 30