import base64 from collections.abc import Callable from typing import Any from unittest import mock import pytest from twilio.twiml.messaging_response import MessagingResponse from app.adapters.db.twilio.models import TwilioAccount from app.handler import TwilioWebhooksInboundHandler from tests.unit.types import CreateModel @pytest.mark.db def test_handle_invalid_request_signature( handler: TwilioWebhooksInboundHandler, create_model: CreateModel, generate_test_event: Callable[[str], dict[str, Any]], ows_text_campaigns_client_mock: mock.MagicMock, test_account_sid: str, test_auth_token: str, ) -> None: create_model( TwilioAccount, account_sid=test_account_sid, auth_token=base64.b64encode(test_auth_token.encode()).decode(), ) test_event = generate_test_event("hi") # Corrupt signature header to make validation fail test_event["headers"]["x-twilio-signature"] = "invalid-signature" response = handler.handle(test_event) assert ows_text_campaigns_client_mock.forward_message.call_count == 0 assert response.get("statusCode") == 403 assert response.get("body") == "Forbidden" @pytest.mark.db def test_handle_valid_request_signature( handler: TwilioWebhooksInboundHandler, create_model: CreateModel, generate_test_event: Callable[[str], dict[str, Any]], ows_text_campaigns_client_mock: mock.MagicMock, test_account_sid: str, test_auth_token: str, ) -> None: create_model( TwilioAccount, account_sid=test_account_sid, auth_token=base64.b64encode(test_auth_token.encode()).decode(), ) test_event = generate_test_event("hi") response = handler.handle(test_event) assert ows_text_campaigns_client_mock.forward_message.call_count == 1 assert response.get("statusCode") == 200 assert response.get("body") == MessagingResponse().to_xml()