def test_body_props(self): msg = AnymailInboundMessage.construct(text="Test plaintext", html="Test HTML") self.assertEqual(msg.text, "Test plaintext") self.assertEqual(msg.html, "Test HTML") # Make sure attachments don't confuse it att_text = AnymailInboundMessage.construct_attachment( 'text/plain', "text attachment") att_html = AnymailInboundMessage.construct_attachment( 'text/html', "html attachment") msg = AnymailInboundMessage.construct(text="Test plaintext", attachments=[att_text, att_html]) self.assertEqual(msg.text, "Test plaintext") self.assertIsNone( msg.html) # no html body (the html attachment doesn't count) msg = AnymailInboundMessage.construct(html="Test HTML", attachments=[att_text, att_html]) self.assertIsNone( msg.text) # no plaintext body (the text attachment doesn't count) self.assertEqual(msg.html, "Test HTML") # Default None msg = AnymailInboundMessage() self.assertIsNone(msg.text) self.assertIsNone(msg.html)
def test_address_props(self): msg = AnymailInboundMessage.construct( from_email='"Sender, Inc." <*****@*****.**>', to='First To <*****@*****.**>, [email protected]', cc='First Cc <*****@*****.**>, [email protected]', ) self.assertEqual(str(msg.from_email), '"Sender, Inc." <*****@*****.**>') self.assertEqual(msg.from_email.addr_spec, '*****@*****.**') self.assertEqual(msg.from_email.display_name, 'Sender, Inc.') self.assertEqual(msg.from_email.username, 'sender') self.assertEqual(msg.from_email.domain, 'example.com') self.assertEqual(len(msg.to), 2) self.assertEqual(msg.to[0].addr_spec, '*****@*****.**') self.assertEqual(msg.to[0].display_name, 'First To') self.assertEqual(msg.to[1].addr_spec, '*****@*****.**') self.assertEqual(msg.to[1].display_name, '') self.assertEqual(len(msg.cc), 2) self.assertEqual(msg.cc[0].address, 'First Cc <*****@*****.**>') self.assertEqual(msg.cc[1].address, '*****@*****.**') # Default None/empty lists msg = AnymailInboundMessage() self.assertIsNone(msg.from_email) self.assertEqual(msg.to, []) self.assertEqual(msg.cc, [])
def test_construct_bodies(self): # this verifies we construct the expected MIME structure; # see the `text` and `html` props (in the ConveniencePropTests below) # for an easier way to get to these fields (that works however constructed) msg = AnymailInboundMessage.construct(text="Plaintext body", html="HTML body") self.assertEqual(msg['Content-Type'], "multipart/mixed") self.assertEqual(len(msg.get_payload()), 1) related = msg.get_payload(0) self.assertEqual(related['Content-Type'], "multipart/related") self.assertEqual(len(related.get_payload()), 1) alternative = related.get_payload(0) self.assertEqual(alternative['Content-Type'], "multipart/alternative") self.assertEqual(len(alternative.get_payload()), 2) plaintext = alternative.get_payload(0) self.assertEqual(plaintext['Content-Type'], 'text/plain; charset="utf-8"') self.assertEqual(plaintext.get_content_text(), "Plaintext body") html = alternative.get_payload(1) self.assertEqual(html['Content-Type'], 'text/html; charset="utf-8"') self.assertEqual(html.get_content_text(), "HTML body")
def test_construct_headers_from_raw(self): # (note header "folding" in second Received header) msg = AnymailInboundMessage.construct( raw_headers=dedent("""\ Reply-To: [email protected] Subject: raw subject Content-Type: x-custom/custom Received: by 10.1.1.4 with SMTP id q4csp; Sun, 22 Oct 2017 00:23:22 -0700 (PDT) Received: from mail.example.com (mail.example.com. [10.10.1.9]) by mx.example.com with SMTPS id 93s8iok for <*****@*****.**>; Sun, 22 Oct 2017 00:23:21 -0700 (PDT) """), subject="Explicit subject overrides raw") self.assertEqual(msg['Reply-To'], "*****@*****.**") self.assertEqual( msg.get_all('Received'), [ "by 10.1.1.4 with SMTP id q4csp; Sun, 22 Oct 2017 00:23:22 -0700 (PDT)", "from mail.example.com (mail.example.com. [10.10.1.9])" # unfolding should have stripped newlines " by mx.example.com with SMTPS id 93s8iok for <*****@*****.**>;" " Sun, 22 Oct 2017 00:23:21 -0700 (PDT)" ]) self.assertEqual(msg.get_all('Subject'), ["Explicit subject overrides raw"]) self.assertEqual( msg.get_all('Content-Type'), ["multipart/mixed"]) # Content-Type in raw header ignored
def test_date_props(self): msg = AnymailInboundMessage.construct( headers={'Date': "Mon, 23 Oct 2017 17:50:55 -0700"}) self.assertEqual(msg.date.isoformat(), "2017-10-23T17:50:55-07:00") # Default None self.assertIsNone(AnymailInboundMessage().date)
def test_construct_attachments(self): att1 = AnymailInboundMessage.construct_attachment( 'text/csv', "One,Two\n1,2".encode('iso-8859-1'), charset="iso-8859-1", filename="test.csv") att2 = AnymailInboundMessage.construct_attachment( 'image/png', SAMPLE_IMAGE_CONTENT, filename=SAMPLE_IMAGE_FILENAME, content_id="abc123") msg = AnymailInboundMessage.construct(attachments=[att1, att2]) self.assertEqual(msg['Content-Type'], "multipart/mixed") self.assertEqual(len(msg.get_payload()), 2) # bodies (related), att1 att1_part = msg.get_payload(1) self.assertEqual(att1_part['Content-Type'], 'text/csv; name="test.csv"; charset="iso-8859-1"') self.assertEqual(att1_part['Content-Disposition'], 'attachment; filename="test.csv"') self.assertNotIn('Content-ID', att1_part) self.assertEqual(att1_part.get_content_text(), "One,Two\n1,2") related = msg.get_payload(0) self.assertEqual(len(related.get_payload()), 2) # alternatives (with no bodies in this test); att2 att2_part = related.get_payload(1) self.assertEqual(att2_part['Content-Type'], 'image/png; name="sample_image.png"') self.assertEqual(att2_part['Content-Disposition'], 'inline; filename="sample_image.png"') self.assertEqual(att2_part['Content-ID'], '<abc123>') self.assertEqual(att2_part.get_content_bytes(), SAMPLE_IMAGE_CONTENT)
def test_construct_headers_from_mapping(self): msg = AnymailInboundMessage.construct(headers={ 'Reply-To': "*****@*****.**", 'X-Test': "anything" }) self.assertEqual(msg['reply-to'], "*****@*****.**") # headers are case-insensitive self.assertEqual(msg['X-TEST'], "anything")
def make_message(self, reply_token=None, text='message body', html=None): reply_token = reply_token or make_local_part(self.conversation, self.user) return AnymailInboundMessage.construct( to='{}@example.com'.format(reply_token), text=text, html=html, )
def test_inline_attachments_prop(self): att = AnymailInboundMessage.construct_attachment( 'image/png', SAMPLE_IMAGE_CONTENT, filename=SAMPLE_IMAGE_FILENAME, content_id="abc123") msg = AnymailInboundMessage.construct(attachments=[att]) self.assertEqual(msg.inline_attachments, {'abc123': att}) # Default empty dict self.assertEqual(AnymailInboundMessage().inline_attachments, {})
def test_attachments_prop(self): att = AnymailInboundMessage.construct_attachment( 'image/png', SAMPLE_IMAGE_CONTENT, filename=SAMPLE_IMAGE_FILENAME) msg = AnymailInboundMessage.construct(attachments=[att]) self.assertEqual(msg.attachments, [att]) # Default empty list self.assertEqual(AnymailInboundMessage().attachments, [])
def test_construct_params(self): msg = AnymailInboundMessage.construct( from_email="*****@*****.**", to="*****@*****.**", cc="*****@*****.**", subject="test subject") self.assertEqual(msg['From'], "*****@*****.**") self.assertEqual(msg['To'], "*****@*****.**") self.assertEqual(msg['Cc'], "*****@*****.**") self.assertEqual(msg['Subject'], "test subject") self.assertEqual(msg.defects, []) # ensures email.message.Message.__init__ ran self.assertIsNone(msg.envelope_recipient) # ensures AnymailInboundMessage.__init__ ran
def message() -> AnymailInboundMessage: message = AnymailInboundMessage.construct( from_email="*****@*****.**", to="*****@*****.**", cc="*****@*****.**", subject="test subject", text="Test email", ) assert message.text == "Test email" assert message.from_email.address == "*****@*****.**" assert message.subject == "test subject" return message
def test_construct_headers_from_pairs(self): # allows multiple instances of a header msg = AnymailInboundMessage.construct( headers=[['Reply-To', "*****@*****.**"], ['Received', "by 10.1.1.4 with SMTP id q4csp; Sun, 22 Oct 2017 00:23:22 -0700 (PDT)"], ['Received', "from mail.example.com (mail.example.com. [10.10.1.9])" " by mx.example.com with SMTPS id 93s8iok for <*****@*****.**>;" " Sun, 22 Oct 2017 00:23:21 -0700 (PDT)"], ]) self.assertEqual(msg['Reply-To'], "*****@*****.**") self.assertEqual(msg.get_all('Received'), [ "by 10.1.1.4 with SMTP id q4csp; Sun, 22 Oct 2017 00:23:22 -0700 (PDT)", "from mail.example.com (mail.example.com. [10.10.1.9])" " by mx.example.com with SMTPS id 93s8iok for <*****@*****.**>;" " Sun, 22 Oct 2017 00:23:21 -0700 (PDT)"])