from typing import Any from unittest import mock import pytest from fansifter_common.email import EmailType from app.exceptions import RequestValidationError from app.models import ReplyRequest, UnsubRequest def test_request_fields_v1(test_event: dict[str, Any]) -> None: request = UnsubRequest.model_validate(test_event) assert request.version == "v1" assert request.email == "sender@example.com" assert request.recipient_email == "dGVzdF9jYW1wYWlnbl9pZA==.v1@example.com" assert request.email_campaign_id == "test_campaign_id" assert request.email_type == EmailType.CAMPAIGN assert request.email_id == "test_campaign_id" assert request.automated_email_trigger_id is None def test_request_fields_v2_campaign(test_event_v2_campaign: dict[str, Any]) -> None: request = UnsubRequest.model_validate(test_event_v2_campaign) assert request.version == "v2" assert request.email == "sender@example.com" assert request.recipient_email == "Y2FtcC50ZXN0X2VtYWlsX2lk.v2@example.com" assert request.email_type == EmailType.CAMPAIGN assert request.email_id == "test_email_id" assert request.automated_email_trigger_id is None assert request.email_campaign_id == "test_email_id" def test_request_fields_v2_campaign_recipient_with_display_name( test_event_v2_campaign_recipient_display_name: dict[str, Any], ) -> None: request = UnsubRequest.model_validate(test_event_v2_campaign_recipient_display_name) assert request.version == "v2" assert request.recipient_email == "Y2FtcC50ZXN0X2VtYWlsX2lk.v2@example.com" assert request.email_type == EmailType.CAMPAIGN assert request.email_id == "test_email_id" def test_request_fields_sender_with_display_name( test_event_display_name: dict[str, Any], ) -> None: request = UnsubRequest.model_validate(test_event_display_name) assert request.email == "user@example.com" assert request.version == "v2" assert request.recipient_email == "Y2FtcC50ZXN0X2VtYWlsX2lk.v2@example.com" assert request.email_type == EmailType.CAMPAIGN assert request.email_id == "test_email_id" def test_request_fields_v2_automated(test_event_v2_automated: dict[str, Any]) -> None: request = UnsubRequest.model_validate(test_event_v2_automated) assert request.version == "v2" assert request.email == "sender@example.com" assert ( request.recipient_email == "YXV0by50ZXN0X2VtYWlsX2lkLnRlc3RfdHJpZ2dlcl9pZA==.v2@example.com" ) assert request.email_type == EmailType.AUTOMATED assert request.email_id == "test_email_id" assert request.automated_email_trigger_id == "test_trigger_id" assert request.email_campaign_id == "test_email_id" def test_request_reply_fields(test_reply_event: dict[str, Any]) -> None: request = ReplyRequest.model_validate( test_reply_event, context={"secret_key": "test"}, ) assert request.email == "sender@example.com" assert request.subject == "Re: Hello Inbox" assert request.text == "This is the reply body text." assert request.html == "" def test_request_reply_fields_recipient_with_display_name( test_reply_event_recipient_display_name: dict[str, Any], ) -> None: request = ReplyRequest.model_validate( test_reply_event_recipient_display_name, context={"secret_key": "test"}, ) assert request.email == "sender@example.com" assert ( request.recipient_email == "c.11111111111111111111111111111111.96f958cd6cccac64@example.com" ) assert request.subject == "Re: Hello Inbox" assert request.text == "This is the reply body text." def test_request_reply_fields_with_html( test_reply_event_with_html: dict[str, Any], ) -> None: request = ReplyRequest.model_validate( test_reply_event_with_html, context={"secret_key": "test"}, ) assert request.email == "sender@example.com" assert request.subject == "Re: Hello Inbox" assert request.text == "This is the reply body text." assert ( request.html == "

This is the reply body in HTML.

" ) def test_request_reply_fields_latin1_encoding( test_reply_event_latin1: dict[str, Any], ) -> None: request = ReplyRequest.model_validate( test_reply_event_latin1, context={"secret_key": "test"}, ) assert request.email == "sender@example.com" assert request.subject == "Re: Hello Inbox" assert request.text == "© 2026 Sony Music." assert request.html == "

© 2026 Sony Music.

" def test_request_reply_invalid_signature_logs_and_raises( test_reply_event_invalid_signature: dict[str, Any], ) -> None: request = ReplyRequest.model_validate( test_reply_event_invalid_signature, context={"secret_key": "test"}, ) with mock.patch("app.models.logger.error") as logger_error_mock: with pytest.raises(RequestValidationError): _ = request.email_id logger_error_mock.assert_called_once() assert "Failed to decode reply-to local part" in logger_error_mock.call_args.args[0]