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
259 lines
9.9 KiB
Python
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
|