Project

General

Profile

Download (6.05 KB) Statistics
| Branch: | Tag: | Revision:

root / tests / test_emailing.py @ f46f80e4

1
import pytest
2
from uuid import uuid4
3
import os
4
import re
5
import urllib
6
import mock
7

    
8
from django.core.urlresolvers import reverse
9
from django.core import mail, signing
10
from django.utils import timezone
11
from django.core.files.storage import DefaultStorage
12
from django.utils.text import slugify
13

    
14
from corbo.models import Category, Announce, Subscription, Broadcast
15
from corbo.models import channel_choices
16

    
17
pytestmark = pytest.mark.django_db
18

    
19
CATEGORIES = (u'Alerts', u'News')
20

    
21

    
22
@pytest.fixture
23
def categories():
24
    categories = []
25
    for category in CATEGORIES:
26
        c, created = Category.objects.get_or_create(name=category, slug=slugify(category))
27
        categories.append(c)
28
    return categories
29

    
30

    
31
@pytest.fixture
32
def announces():
33
    announces = []
34
    for category in Category.objects.all():
35
        a = Announce.objects.create(category=category, title='Announce 1',
36
                                    publication_time=timezone.now(),
37
                                    text='<h2>Announce 1</h2>')
38
        Broadcast.objects.create(announce=a)
39
        announces.append(a)
40
        a = Announce.objects.create(category=category, title='Announce 2',
41
                                    publication_time=timezone.now(),
42
                                    text='<h2>Announce 2</h2>')
43
        Broadcast.objects.create(announce=a)
44
        announces.append(a)
45
    return announces
46

    
47

    
48
def test_emailing_with_no_subscriptions(app, categories, announces, mailoutbox):
49
    for announce in announces:
50
        broadcast = Broadcast.objects.get(announce=announce)
51
        broadcast.send()
52
        assert not broadcast.delivery_count
53
    assert not len(mailoutbox)
54

    
55

    
56
def test_send_email(app, categories, announces, mailoutbox):
57
    for category in categories:
58
        uuid = uuid4()
59
        Subscription.objects.create(category=category,
60
                                    identifier='%s@example.net' % uuid, uuid=uuid)
61
    for i, announce in enumerate(announces):
62
        broadcast = Broadcast.objects.get(announce=announce)
63
        broadcast.send()
64
        assert broadcast.delivery_count
65
        assert len(mailoutbox) == i+1
66

    
67

    
68
def test_check_inline_css(app, categories, announces, mailoutbox):
69
    total_sent = 0
70
    for i, announce in enumerate(announces):
71
        announce.text = '<style type="text/css">h2 {color: #F00}</style>' + announce.text
72
        announce.save()
73
        uuid = uuid4()
74
        Subscription.objects.create(category=announce.category,
75
                                    identifier='%s@example.net' % uuid, uuid=uuid)
76
        broadcast = Broadcast.objects.get(announce=announce)
77
        broadcast.send()
78
        assert broadcast.delivery_count
79
        assert len(mailoutbox) == total_sent + broadcast.delivery_count
80
        total_sent += broadcast.delivery_count
81
        assert 'h2 style="color:#F00"' in mailoutbox[i].html
82

    
83

    
84
@mock.patch('emails.utils.requests.get')
85
def test_check_inline_images(mocked_get, app, categories, announces, mailoutbox):
86
    storage = DefaultStorage()
87
    media_path = os.path.join(os.path.dirname(__file__), 'media')
88
    image_name = 'logo.png'
89
    image_name = storage.save(image_name, file(os.path.join(media_path, image_name)))
90
    total_sent = 0
91
    for i, announce in enumerate(announces):
92
        img_src = "/media/%s" % image_name
93
        announce.text = announce.text + '<img src="%s" />' % img_src
94
        announce.save()
95
        uuid = uuid4()
96
        Subscription.objects.create(category=announce.category,
97
                                    identifier='%s@example.net' % uuid, uuid=uuid)
98
        broadcast = Broadcast.objects.get(announce=announce)
99
        mocked_get.return_value = mock.Mock(status_code=200,
100
                                            headers={'content-type': 'image/png'},
101
                                            content=storage.open(image_name).read())
102
        broadcast.send()
103
        assert broadcast.delivery_count
104

    
105
        assert len(mailoutbox) == total_sent + broadcast.delivery_count
106
        attachments = [a['filename'] for a in mailoutbox[0].attachments.as_dict()]
107
        assert image_name in attachments
108
        assert 'cid:%s' % image_name in mail.outbox[0].html_body
109
        assert 'cid:%s' % image_name in mail.outbox[0].text_body
110
        total_sent += broadcast.delivery_count
111
    storage.delete(image_name)
112

    
113

    
114
def test_unsubscription_link(app, categories, announces, custom_mailoutbox):
115
    unsubscription_link_sentinel = ''
116
    subscriptions_number = 3
117
    scheme = 'mailto:'
118
    for category in categories:
119
        for i in xrange(subscriptions_number):
120
            uuid = uuid4()
121
            uri = scheme + '%s@example.com' % uuid
122
            Subscription.objects.create(category=category, identifier=uri, uuid=str(uuid))
123

    
124
        for i, announce in enumerate(announces):
125
            if announce.category != category:
126
                continue
127
            broadcast = Broadcast.objects.get(announce=announce)
128
            broadcast.send()
129
            assert broadcast.delivery_count
130
            assert len(mail.outbox) == (i+1)*subscriptions_number
131
            assert mail.outbox[i*subscriptions_number].subject == announce.title
132

    
133
            for counter, destination in enumerate(category.subscription_set.all()):
134
                index = i*subscriptions_number+counter
135
                signature = urllib.unquote(re.findall('/unsubscribe/(.*)"', mail.outbox[index].html)[0])
136
                unsubscription_link = reverse('unsubscribe', kwargs={'unsubscription_token': signature})
137
                assert mail.outbox[index]._headers['List-Unsubscribe'] == '<http://localhost%s>' % unsubscription_link
138
                assert unsubscription_link in mail.outbox[index].html
139
                assert unsubscription_link in mail.outbox[index].text
140
                assert unsubscription_link_sentinel != unsubscription_link
141
                assert signing.loads(signature) == {
142
                    'category': announce.category.pk, 'identifier': destination.identifier}
143
                unsubscription_link_sentinel = unsubscription_link
144

    
145
                # make sure the uri schema is not in the page
146
                resp = app.get(unsubscription_link)
147
                assert scheme not in resp.content
(5-5/9)