File: test_unisender_go_integration.py

package info (click to toggle)
django-anymail 13.0-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, trixie
  • size: 2,480 kB
  • sloc: python: 27,832; makefile: 132; javascript: 33; sh: 9
file content (184 lines) | stat: -rw-r--r-- 8,308 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
import os
import unittest
from datetime import datetime, timedelta
from email.headerregistry import Address

from django.test import SimpleTestCase, override_settings, tag

from anymail.exceptions import AnymailAPIError
from anymail.message import AnymailMessage

from .utils import AnymailTestMixin

ANYMAIL_TEST_UNISENDER_GO_API_KEY = os.getenv("ANYMAIL_TEST_UNISENDER_GO_API_KEY")
ANYMAIL_TEST_UNISENDER_GO_API_URL = os.getenv("ANYMAIL_TEST_UNISENDER_GO_API_URL")
ANYMAIL_TEST_UNISENDER_GO_DOMAIN = os.getenv("ANYMAIL_TEST_UNISENDER_GO_DOMAIN")
ANYMAIL_TEST_UNISENDER_GO_TEMPLATE_ID = os.getenv(
    "ANYMAIL_TEST_UNISENDER_GO_TEMPLATE_ID"
)


@tag("unisender_go", "live")
@unittest.skipUnless(
    ANYMAIL_TEST_UNISENDER_GO_API_KEY
    and ANYMAIL_TEST_UNISENDER_GO_API_URL
    and ANYMAIL_TEST_UNISENDER_GO_DOMAIN,
    "Set ANYMAIL_TEST_UNISENDER_GO_API_KEY, ANYMAIL_TEST_UNISENDER_GO_API_URL"
    " and ANYMAIL_TEST_UNISENDER_GO_DOMAIN environment variables to run Unisender Go"
    " integration tests",
)
@override_settings(
    ANYMAIL_UNISENDER_GO_API_KEY=ANYMAIL_TEST_UNISENDER_GO_API_KEY,
    ANYMAIL_UNISENDER_GO_API_URL=ANYMAIL_TEST_UNISENDER_GO_API_URL,
    EMAIL_BACKEND="anymail.backends.unisender_go.EmailBackend",
)
class UnisenderGoBackendIntegrationTests(AnymailTestMixin, SimpleTestCase):
    """
    Unisender Go API integration tests

    These tests run against the **live** Unisender Go API, using the
    environment variable `ANYMAIL_TEST_UNISENDER_GO_API_KEY` as the API key,
    `ANYMAIL_UNISENDER_GO_API_URL` as the API URL where that key was issued,
    and `ANYMAIL_TEST_UNISENDER_GO_DOMAIN` to construct the sender addresses.
    If any of those variables are not set, these tests won't run.

    To run the template test, also set ANYMAIL_TEST_UNISENDER_GO_TEMPLATE_ID
    to a valid template in your account.

    The tests send actual email to a sink address at anymail.dev.
    """

    def setUp(self):
        super().setUp()
        self.from_email = f"from@{ANYMAIL_TEST_UNISENDER_GO_DOMAIN}"
        self.message = AnymailMessage(
            "Anymail Unisender Go integration test",
            "Text content",
            self.from_email,
            ["test+to1@anymail.dev"],
        )
        self.message.attach_alternative("<p>HTML content</p>", "text/html")

    def test_simple_send(self):
        # Example of getting the Unisender Go send status and message id from the message
        sent_count = self.message.send()
        self.assertEqual(sent_count, 1)

        anymail_status = self.message.anymail_status
        sent_status = anymail_status.recipients["test+to1@anymail.dev"].status
        message_id = anymail_status.recipients["test+to1@anymail.dev"].message_id

        self.assertEqual(sent_status, "queued")  # Unisender Go always queues
        self.assertRegex(message_id, r".+")
        # set of all recipient statuses:
        self.assertEqual(anymail_status.status, {sent_status})
        self.assertEqual(anymail_status.message_id, message_id)

    def test_all_options(self):
        send_at = datetime.now() + timedelta(minutes=2)
        message = AnymailMessage(
            subject="Anymail Unisender Go all-options integration test",
            body="This is the text body",
            from_email=str(
                Address(display_name="Test From, with comma", addr_spec=self.from_email)
            ),
            to=["test+to1@anymail.dev", '"Recipient 2, OK?" <test+to2@anymail.dev>'],
            cc=["test+cc1@anymail.dev", '"Copy 2, OK?" <test+cc2@anymail.dev>'],
            bcc=[
                f"test+bcc1@{ANYMAIL_TEST_UNISENDER_GO_DOMAIN}",
                f'"BCC 2, OK?" <test+bcc2@{ANYMAIL_TEST_UNISENDER_GO_DOMAIN}>',
            ],
            # Unisender Go only supports a single reply-to:
            reply_to=['"Reply, with comma (and parens)" <reply@example.com>'],
            headers={"X-Anymail-Test": "value", "X-Anymail-Count": 3},
            metadata={"meta1": "simple string", "meta2": 2},
            send_at=send_at,
            tags=["tag 1", "tag 2"],
            track_opens=False,
            track_clicks=False,
            esp_extra={
                "global_language": "en",
                "options": {"unsubscribe_url": "https://example.com/unsubscribe?id=1"},
            },
        )
        message.attach_alternative("<p>HTML content</p>", "text/html")
        message.attach_alternative("<p>AMP HTML content</p>", "text/x-amp-html")

        message.attach("attachment1.txt", "Here is some\ntext for you", "text/plain")
        message.attach("attachment2.csv", "ID,Name\n1,Amy Lina", "text/csv")

        message.send()
        self.assertEqual(message.anymail_status.status, {"queued"})
        recipient_status = message.anymail_status.recipients
        self.assertEqual(recipient_status["test+to1@anymail.dev"].status, "queued")
        self.assertEqual(recipient_status["test+to2@anymail.dev"].status, "queued")
        self.assertRegex(recipient_status["test+to1@anymail.dev"].message_id, r".+")
        self.assertRegex(recipient_status["test+to2@anymail.dev"].message_id, r".+")
        # Anymail generates unique message_id for each recipient:
        self.assertNotEqual(
            recipient_status["test+to1@anymail.dev"].message_id,
            recipient_status["test+to2@anymail.dev"].message_id,
        )

    @unittest.skipUnless(
        ANYMAIL_TEST_UNISENDER_GO_TEMPLATE_ID,
        "Set ANYMAIL_TEST_UNISENDER_GO_TEMPLATE_ID to run the"
        " Unisender Go template integration test",
    )
    def test_template(self):
        """
        To run this test, create a template in your account containing
        "{{order_id}}" and "{{ship_date}}" substitutions, and set
        ANYMAIL_TEST_UNISENDER_GO_TEMPLATE_ID to the template's id.
        """
        message = AnymailMessage(
            # This is an actual template in the Anymail test account:
            template_id=ANYMAIL_TEST_UNISENDER_GO_TEMPLATE_ID,
            to=["Recipient 1 <test+to1@anymail.dev>", "test+to2@anymail.dev"],
            reply_to=["Do not reply <reply@example.dev>"],
            tags=["using-template"],
            merge_data={
                "test+to1@anymail.dev": {"order_id": "12345"},
                "test+to2@anymail.dev": {"order_id": "23456"},
            },
            merge_global_data={"ship_date": "yesterday"},
            metadata={"customer-id": "unknown", "meta2": 2},
            merge_metadata={
                "test+to1@anymail.dev": {"customer-id": "ZXK9123"},
                "test+to2@anymail.dev": {"customer-id": "ZZT4192"},
            },
            headers={
                "List-Unsubscribe-Post": "List-Unsubscribe=One-Click",
                "List-Unsubscribe": "<mailto:unsubscribe@example.com>",
            },
            merge_headers={
                "test+to1@anymail.dev": {
                    "List-Unsubscribe": "<https://example.com/a/>",
                },
                "test+to2@anymail.dev": {
                    "List-Unsubscribe": "<https://example.com/b/>",
                },
            },
        )
        message.from_email = None  # use template sender
        message.attach("attachment1.txt", "Here is some\ntext", "text/plain")

        message.send()
        # Unisender Go always queues:
        self.assertEqual(message.anymail_status.status, {"queued"})
        recipient_status = message.anymail_status.recipients
        self.assertEqual(recipient_status["test+to1@anymail.dev"].status, "queued")
        self.assertEqual(recipient_status["test+to2@anymail.dev"].status, "queued")
        self.assertRegex(recipient_status["test+to1@anymail.dev"].message_id, r".+")
        self.assertRegex(recipient_status["test+to2@anymail.dev"].message_id, r".+")
        # Anymail generates unique message_id for each recipient:
        self.assertNotEqual(
            recipient_status["test+to1@anymail.dev"].message_id,
            recipient_status["test+to2@anymail.dev"].message_id,
        )

    @override_settings(ANYMAIL_UNISENDER_GO_API_KEY="Hey, that's not an API key!")
    def test_invalid_api_key(self):
        # Make sure the exception message includes Unisender Go's response:
        with self.assertRaisesMessage(AnymailAPIError, "Can not decode key"):
            self.message.send()