Esempio n. 1
0
 def test_recipients_selection(self):
     ml = factories.MailingFactory()
     factories.RecipientFactory(mailing=ml)
     factories.RecipientFactory(mailing=ml)
     factories.RecipientFactory(mailing=ml)
     factories.RecipientFactory(mailing=ml)
     filter = MailingSender.make_queue_filter()
     self.assertEqual(4, MailingRecipient.find(filter).count())
Esempio n. 2
0
    def test_customization_with_custom_fields(self):
        recipient = factories.RecipientFactory()


        customizer = MailCustomizer(recipient)
        self.assertEquals(customizer._do_customization(recipient.mailing.body, recipient.contact_data),
                          'This is a very simple mailing.')
Esempio n. 3
0
    def test_customize_message_encoding(self):
        mailing = factories.MailingFactory(
            header="""Content-Transfer-Encoding: 7bit
Content-Type: multipart/alternative; boundary="===============2840728917476054151=="
Subject: Great news!
From: Mailing Sender <*****@*****.**>
To: <*****@*****.**>
Date: Wed, 05 Jun 2013 06:05:56 -0000
""",
            body="""
This is a multi-part message in MIME format.
--===============2840728917476054151==
Content-Type: text/plain; charset="iso-8859-1"
MIME-Version: 1.0
Content-Transfer-Encoding: quoted-printable

This is a very simple mailing. I'm happy.
--===============2840728917476054151==
Content-Type: text/html; charset="iso-8859-1"
MIME-Version: 1.0
Content-Transfer-Encoding: quoted-printable

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html><head>
<META http-equiv=3DContent-Type content=3D"text/html; charset=3Diso-8859-1">
</head>
<body>
This is <strong> a very simple</strong> <u>mailing</u>. =
I'm happy! Nothing else to say...
</body></html>

--===============2840728917476054151==--
"""
        )
        recipient = factories.RecipientFactory(mailing=mailing)

        customizer = MailCustomizer(recipient)
        fullpath = os.path.join(customizer.temp_path, MailCustomizer.make_file_name(recipient.mailing.id, recipient.id))
        if os.path.exists(fullpath):
            os.remove(fullpath)

        self.assertFalse(os.path.exists(fullpath))

        customizer._run_customizer()

        self.assertTrue(os.path.exists(fullpath))
        parser = email.parser.Parser()
        message = parser.parse(file(fullpath, 'rt'), headersonly = False)
        assert(isinstance(message, email.message.Message))
        self.assertTrue(message.is_multipart())
        self.assertEquals("multipart/alternative", message.get_content_type())
        self.assertEquals("text/plain", message.get_payload(i=0).get_content_type())
        self.assertEquals("text/html", message.get_payload(i=1).get_content_type())
        self.assertEquals(message.get_payload(i=0).get_payload(decode=True), "This is a very simple mailing. I'm happy.")
        self.assertIn("This is <strong> a very simple</strong> <u>mailing</u>. I'm happy! ", message.get_payload(i=1).get_payload(decode=True))
Esempio n. 4
0
    def test_rotate_encryption_in_tracking_links(self):
        mailing = factories.MailingFactory(tracking_url='http://tracking.net/')
        recipient = factories.RecipientFactory(mailing=mailing, tracking_id="TRACKING_ID")

        customizer = MailCustomizer(recipient, read_tracking=False, click_tracking=True, url_encoding='base64')
        content = '<p>Please <a href="http://www.mydomain.com/the_page?p=parameter">click here</a></p>'
        new_content = customizer._do_customization(
            body=content,
            contact_data=customizer.make_contact_data_dict(recipient),
            is_html=True
        )
        self.assertEquals(
            # '<p>Please <a href="http://tracking.net/c/?o=http://www.mydomain.com/the_page?p=parameter">click here</a></p>',
            '<p>Please <a href="http://tracking.net/c/TRACKING_ID/?c=b64&o=aHR0cDovL3d3dy5teWRvbWFpbi5jb20vdGhlX3BhZ2U_cD1wYXJhbWV0ZXI'
            '&t=aHR0cDovL3d3dy5teWRvbWFpbi5jb20vdGhlX3BhZ2U_cD1wYXJhbWV0ZXI">click here</a></p>',
            new_content)
Esempio n. 5
0
    def test_dkim(self):
        privkey = self._get_dkim_privkey()
        mailing = factories.MailingFactory(dkim={'selector': 'mail', 'domain': 'unittest.cloud-mailing.net', 'privkey':privkey})
        recipient = factories.RecipientFactory(mailing=mailing)

        message_str = self._customize(recipient)

        self.assertNotIn(b"\r\n", message_str)

        parser = email.parser.Parser()
        message = parser.parsestr(message_str, headersonly=False)
        assert (isinstance(message, email.message.Message))
        self.assertTrue('DKIM-Signature' in message)
        # print message['DKIM-Signature']

        self.assertTrue(dkim.verify(message_str, dnsfunc=self._get_txt))
Esempio n. 6
0
    def test_clicks_tracking(self):
        mailing = factories.MailingFactory(tracking_url='http://tracking.net/')
        recipient = factories.RecipientFactory(mailing=mailing, tracking_id="TRACKING_ID")

        customizer = MailCustomizer(recipient, read_tracking=False, click_tracking=True)
        content = '<p>Please <a href="http://www.mydomain.com/the_page?p=parameter">click here</a></p>'
        new_content = customizer._do_customization(
            body=content,
            contact_data=customizer.make_contact_data_dict(recipient),
            is_html=True
        )
        self.assertEquals(
            # '<p>Please <a href="http://tracking.net/c/?o=http://www.mydomain.com/the_page?p=parameter">click here</a></p>',
            '<p>Please <a href="http://tracking.net/c/TRACKING_ID/?o=http%3A//www.mydomain.com/the_page%3Fp%3Dparameter'
                    '&t=http%3A//www.mydomain.com/the_page%3Fp%3Dparameter">click here</a></p>',
            new_content)
Esempio n. 7
0
    def test_dkim_and_feedback_loop(self):
        privkey = self._get_dkim_privkey()
        mailing = factories.MailingFactory(dkim={'selector': 'mail', 'domain': 'unittest.cloud-mailing.net', 'privkey':privkey},
                                           feedback_loop={'dkim': {'selector': 'mail', 'domain': 'unittest.cloud-mailing.net', 'privkey':privkey},
                                                          'sender_id': 'CloudMailing'})
        recipient = factories.RecipientFactory(mailing=mailing)

        message_str = self._customize(recipient)

        self.assertNotIn(b"\r\n", message_str)

        parser = email.parser.Parser()
        message = parser.parsestr(message_str, headersonly=False)
        assert (isinstance(message, email.message.Message))
        self.assertTrue('Feedback-ID' in message)
        self.assertEqual(2, len(message.get_all('DKIM-Signature')))

        d = dkim.DKIM(message_str)
        self.assertTrue(d.verify(0, dnsfunc=self._get_txt))
        self.assertTrue(d.verify(1, dnsfunc=self._get_txt))
Esempio n. 8
0
    def test_feedback_loop(self):
        privkey = self._get_dkim_privkey()
        mailing = factories.MailingFactory(feedback_loop={'dkim': {'selector': 'mail', 'domain': 'unittest.cloud-mailing.net', 'privkey':privkey},
                                                          'sender_id': 'CloudMailing'},
                                           domain_name='cloud-mailing.net')
        recipient = factories.RecipientFactory(mailing=mailing)

        message_str = self._customize(recipient)

        self.assertNotIn(b"\r\n", message_str)

        parser = email.parser.Parser()
        message = parser.parsestr(message_str, headersonly=False)
        assert (isinstance(message, email.message.Message))
        self.assertTrue('Feedback-ID' in message)
        self.assertTrue('DKIM-Signature' in message)
        # print message['Feedback-ID']
        self.assertEqual('%d:cloud-mailing.net:%s:CloudMailing' % (mailing.id, mailing.type), message['Feedback-ID'])

        self.assertTrue(dkim.verify(message_str, dnsfunc=self._get_txt))
Esempio n. 9
0
    def test_clicks_tracking_with_customized_links(self):
        mailing = factories.MailingFactory(tracking_url='http://tr.net/')
        recipient = factories.RecipientFactory(mailing=mailing,
                                               tracking_id="TRACKING_ID",
                                               contact_data={
                                                   'email': '*****@*****.**',
                                                   'id': 123
                                               })

        customizer = MailCustomizer(recipient, read_tracking=False, click_tracking=True)
        content = '<p>Please <a href="http://my.com/the_page?id={{ id }}">click here</a></p>'
        new_content = customizer._do_customization(
            body=content,
            contact_data=customizer.make_contact_data_dict(recipient),
            is_html=True
        )
        self.assertEquals(
            '<p>Please <a href="http://tr.net/c/TRACKING_ID/?o=http%3A//my.com/the_page%3Fid%3D%7B%7B%20id%20%7D%7D'
                    '&t=http%3A//my.com/the_page%3Fid%3D123">click here</a></p>',
            new_content)
Esempio n. 10
0
    def test_customize_message(self):
        mailing = factories.MailingFactory()
        recipient = factories.RecipientFactory(mailing=mailing)

        customizer = MailCustomizer(recipient)
        fullpath = os.path.join(customizer.temp_path, MailCustomizer.make_file_name(recipient.mailing.id, recipient.id))
        if os.path.exists(fullpath):
            os.remove(fullpath)

        self.assertFalse(os.path.exists(fullpath))

        customizer._run_customizer()

        self.assertTrue(os.path.exists(fullpath))
        # print file(fullpath, 'rt').read()
        parser = email.parser.Parser()
        message = parser.parse(file(fullpath, 'rt'), headersonly = False)
        assert(isinstance(message, email.message.Message))
        self.assertFalse(message.is_multipart())
        self.assertTrue('Date' in message)
        self.assertEquals('This is a very simple mailing.', message.get_payload())
Esempio n. 11
0
    def test_customize_simple_message_with_recipient_attachment(self):
        recipient = factories.RecipientFactory(
            contact_data={
                'email': '*****@*****.**',
                'custom': 'very simple',
                'attachments': [
                    {
                        'filename': "export.csv",
                        'data': base64.b64encode("col1;col2;col3\nval1;val2;val3\n"),
                        'content-type': 'text/plain',
                        'charset': 'us-ascii',
                    },
                ]
            }
        )
        #factories.MailingContentFactory(mailing=recipient.mailing)
        #print recipient.mailing.content

        customizer = MailCustomizer(recipient)
        fullpath = os.path.join(customizer.temp_path, MailCustomizer.make_file_name(recipient.mailing.id, recipient.id))
        if os.path.exists(fullpath):
            os.remove(fullpath)

        self.assertFalse(os.path.exists(fullpath))

        customizer._run_customizer()

        self.assertTrue(os.path.exists(fullpath))
        parser = email.parser.Parser()
        message = parser.parse(file(fullpath, 'rt'), headersonly = False)
        assert(isinstance(message, email.message.Message))
        self.assertTrue(message.is_multipart())
        # print
        # print message.as_string()
        self.assertEquals(message.get_payload(i=0).get_payload(), 'This is a very simple mailing.')
        self.assertEquals(message.get_payload(i=1).get_payload(), 'col1;col2;col3\nval1;val2;val3\n')
Esempio n. 12
0
    def test_customize_mixed_and_alternative_and_related_message_with_recipient_attachment(self):
        recipient = factories.RecipientFactory(
            mailing = factories.MailingFactory(
                header="""Content-Transfer-Encoding: 7bit
Content-Type: multipart/mixed; boundary="===============0000000000000000000=="
Subject: Great news!
From: Mailing Sender <*****@*****.**>
To: <*****@*****.**>
Date: Wed, 05 Jun 2013 06:05:56 -0000
""",
                body="""
This is a multi-part message in MIME format.
--===============0000000000000000000==
Content-Type: multipart/alternative; boundary="===============1111111111111111111=="

--===============1111111111111111111==
Content-Type: text/plain; charset="us-ascii"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit

This is a very simple mailing.
--===============1111111111111111111==
Content-Type: multipart/related; boundary="===============2222222222222222222=="

This is a multi-part message in MIME format.
--===============2222222222222222222==
Content-Type: text/html; charset="us-ascii"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit

<html><head></head>
<body>
This is <strong> a very simple</strong> <u>mailing</u>.
Nothing else to say...
<img id="Image 2"src="cid:[email protected]"
                 height="45" width="130" border="0">
</body></html>
--===============2222222222222222222==
Content-Type: image/jpeg;
 name="akema_logo_signatures.jpg"
Content-Transfer-Encoding: base64
Content-ID: <*****@*****.**>
Content-Disposition: inline;
 filename="akema_logo_signatures.jpg"

/9j/4AAQSkZJRgABAQEASABIAAD/4QESRXhpZgAATU0AKgAAAAgABgEaAAUAAAABAAAAVgEb
AAUAAAABAAAAXgEoAAMAAAABAAIAAAExAAIAAAASAAAAZgEyAAIAAAAUAAAAeIdpAAQAAAAB
AAAAjAAAANAAAABIAAAAAQAAAEgAAAABUGFpbnQuTkVUIHYzLjUuMTAAMjAxMjoxMjoxMSAx

--===============2222222222222222222==--

--===============1111111111111111111==--

--===============0000000000000000000==
Content-Type: text/plain; charset="us-ascii"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment; filename="common.txt"

This is an attachment common for all recipients.
Nothing else to say...

--===============0000000000000000000==--

"""
            ),
            contact_data={
                'email': '*****@*****.**',
                'custom': 'very simple',
                'attachments': [
                    {
                        'filename': "export.csv",
                        'data': base64.b64encode("col1;col2;col3\nval1;val2;val3\n"),
                        'content-type': 'text/plain',
                        'charset': 'us-ascii',
                    },
                ]
            }
        )

        customizer = MailCustomizer(recipient)
        fullpath = os.path.join(customizer.temp_path, MailCustomizer.make_file_name(recipient.mailing.id, recipient.id))
        if os.path.exists(fullpath):
            os.remove(fullpath)

        self.assertFalse(os.path.exists(fullpath))

        customizer._run_customizer()

        self.assertTrue(os.path.exists(fullpath))
        parser = email.parser.Parser()
        message = parser.parse(file(fullpath, 'rt'), headersonly = False)
        assert(isinstance(message, email.message.Message))
        # print
        # print message.as_string()
        self.assertTrue(message.is_multipart())
        self.assertEquals("multipart/mixed",       message.get_content_type())
        self.assertEquals("multipart/alternative", message.get_payload(i=0).get_content_type())
        self.assertEquals("text/plain",            message.get_payload(i=0).get_payload(i=0).get_content_type())
        self.assertEquals("multipart/related",     message.get_payload(i=0).get_payload(i=1).get_content_type())
        self.assertEquals('This is a very simple mailing.', message.get_payload(i=0).get_payload(i=0).get_payload())
        self.assertIn("This is <strong> a very simple</strong> <u>mailing</u>.", message.get_payload(i=0).get_payload(i=1).get_payload(i=0).get_payload())
        self.assertIn("This is an attachment", message.get_payload(i=1).get_payload())
        self.assertEquals(message.get_payload(i=2).get_payload(), 'col1;col2;col3\nval1;val2;val3\n')
Esempio n. 13
0
    def test_customize_alternative_message_with_recipient_attachment(self):
        recipient = factories.RecipientFactory(
            mailing = factories.MailingFactory(
                header="""Content-Transfer-Encoding: 7bit
Content-Type: multipart/alternative; boundary="===============2840728917476054151=="
Subject: Great news!
From: Mailing Sender <*****@*****.**>
To: <*****@*****.**>
Date: Wed, 05 Jun 2013 06:05:56 -0000
""",
                body="""
This is a multi-part message in MIME format.
--===============2840728917476054151==
Content-Type: text/plain; charset="us-ascii"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit

This is a very simple mailing.
--===============2840728917476054151==
Content-Type: text/html; charset="us-ascii"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit

<html><head></head>
<body>
This is <strong> a very simple</strong> <u>mailing</u>.
Nothing else to say...

--===============2840728917476054151==--
"""
            ),
            contact_data={
                'email': '*****@*****.**',
                'custom': 'very simple',
                'attachments': [
                    {
                        'filename': "export.csv",
                        'data': base64.b64encode("col1;col2;col3\nval1;val2;val3\n"),
                        'content-type': 'text/plain',
                        'charset': 'us-ascii',
                    },
                ]
            }
        )

        customizer = MailCustomizer(recipient)
        fullpath = os.path.join(customizer.temp_path, MailCustomizer.make_file_name(recipient.mailing.id, recipient.id))
        if os.path.exists(fullpath):
            os.remove(fullpath)

        self.assertFalse(os.path.exists(fullpath))

        customizer._run_customizer()

        self.assertTrue(os.path.exists(fullpath))
        parser = email.parser.Parser()
        message = parser.parse(file(fullpath, 'rt'), headersonly = False)
        assert(isinstance(message, email.message.Message))
        # print
        # print message.as_string()
        self.assertTrue(message.is_multipart())
        self.assertEquals("multipart/mixed", message.get_content_type())
        self.assertEquals("multipart/alternative", message.get_payload(i=0).get_content_type())
        self.assertEquals(message.get_payload(i=0).get_payload(i=0).get_payload(), 'This is a very simple mailing.')
        self.assertIn("This is <strong> a very simple</strong> <u>mailing</u>.", message.get_payload(i=0).get_payload(i=1).get_payload())
        self.assertEquals(message.get_payload(i=1).get_payload(), 'col1;col2;col3\nval1;val2;val3\n')