"""Tests API endpoints webhooks.""" from datetime import datetime from unittest.mock import MagicMock, patch import pytest from fastapi import HTTPException from sqlalchemy.exc import IntegrityError, SQLAlchemyError from pricewatch.app.api.main import ( list_webhooks, create_webhook, update_webhook, delete_webhook, ) from pricewatch.app.api.schemas import WebhookCreate, WebhookUpdate class MockWebhook: """Mock Webhook model.""" def __init__(self, **kwargs): self.id = kwargs.get("id", 1) self.url = kwargs.get("url", "https://example.com/webhook") self.events = kwargs.get("events", ["price_change", "stock_change"]) self.active = kwargs.get("active", True) self.created_at = kwargs.get("created_at", datetime.now()) self.last_triggered_at = kwargs.get("last_triggered_at") class TestListWebhooks: """Tests list_webhooks endpoint.""" def test_list_webhooks_empty(self): """Liste vide de webhooks.""" session = MagicMock() mock_query = MagicMock() mock_query.all.return_value = [] session.query.return_value = mock_query with patch("pricewatch.app.api.main._webhook_to_out") as mock_to_out: result = list_webhooks(session=session) assert result == [] class TestCreateWebhook: """Tests create_webhook endpoint.""" def test_create_webhook_integrity_error(self): """Erreur d'integrite lors de creation webhook leve 500.""" # Note: le code actuel ne distingue pas IntegrityError de SQLAlchemyError session = MagicMock() session.add = MagicMock() session.commit = MagicMock(side_effect=IntegrityError("duplicate", {}, None)) session.rollback = MagicMock() payload = WebhookCreate( event="price_change", url="https://example.com/webhook", ) with patch("pricewatch.app.api.main.Webhook"): with pytest.raises(HTTPException) as exc_info: create_webhook(payload, session) assert exc_info.value.status_code == 500 def test_create_webhook_db_error(self): """Erreur DB lors de creation webhook leve 500.""" session = MagicMock() session.add = MagicMock() session.commit = MagicMock(side_effect=SQLAlchemyError("error")) session.rollback = MagicMock() payload = WebhookCreate( event="price_change", url="https://example.com/webhook", ) with patch("pricewatch.app.api.main.Webhook"): with pytest.raises(HTTPException) as exc_info: create_webhook(payload, session) assert exc_info.value.status_code == 500 class TestUpdateWebhook: """Tests update_webhook endpoint.""" def test_update_webhook_not_found(self): """Update webhook non trouve leve 404.""" session = MagicMock() mock_query = MagicMock() mock_query.filter.return_value.one_or_none.return_value = None session.query.return_value = mock_query payload = WebhookUpdate(active=False) with pytest.raises(HTTPException) as exc_info: update_webhook(99999, payload, session) assert exc_info.value.status_code == 404 def test_update_webhook_db_error(self): """Erreur DB lors d'update webhook leve 500.""" session = MagicMock() mock_webhook = MockWebhook() mock_query = MagicMock() mock_query.filter.return_value.one_or_none.return_value = mock_webhook session.query.return_value = mock_query session.commit = MagicMock(side_effect=SQLAlchemyError("error")) session.rollback = MagicMock() payload = WebhookUpdate(active=False) with patch("pricewatch.app.api.main._webhook_to_out"): with pytest.raises(HTTPException) as exc_info: update_webhook(1, payload, session) assert exc_info.value.status_code == 500 class TestDeleteWebhook: """Tests delete_webhook endpoint.""" def test_delete_webhook_not_found(self): """Delete webhook non trouve leve 404.""" session = MagicMock() mock_query = MagicMock() mock_query.filter.return_value.one_or_none.return_value = None session.query.return_value = mock_query with pytest.raises(HTTPException) as exc_info: delete_webhook(99999, session) assert exc_info.value.status_code == 404 def test_delete_webhook_success(self): """Delete webhook avec succes.""" session = MagicMock() mock_webhook = MockWebhook() mock_query = MagicMock() mock_query.filter.return_value.one_or_none.return_value = mock_webhook session.query.return_value = mock_query session.delete = MagicMock() session.commit = MagicMock() result = delete_webhook(1, session) assert result == {"status": "deleted"} session.delete.assert_called_once() def test_delete_webhook_db_error(self): """Erreur DB lors de delete webhook leve 500.""" session = MagicMock() mock_webhook = MockWebhook() mock_query = MagicMock() mock_query.filter.return_value.one_or_none.return_value = mock_webhook session.query.return_value = mock_query session.delete = MagicMock() session.commit = MagicMock(side_effect=SQLAlchemyError("error")) session.rollback = MagicMock() with pytest.raises(HTTPException) as exc_info: delete_webhook(1, session) assert exc_info.value.status_code == 500