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
|
|
13
|
from corbo.models import Category, Announce, Subscription, Broadcast, transform_image_src
|
14
|
|
15
|
pytestmark = pytest.mark.django_db
|
16
|
|
17
|
CATEGORIES = ('Alerts', 'News')
|
18
|
|
19
|
|
20
|
@pytest.fixture
|
21
|
def categories():
|
22
|
categories = []
|
23
|
for category in CATEGORIES:
|
24
|
c, created = Category.objects.get_or_create(name=category)
|
25
|
categories.append(c)
|
26
|
return categories
|
27
|
|
28
|
|
29
|
@pytest.fixture
|
30
|
def announces():
|
31
|
announces = []
|
32
|
for category in Category.objects.all():
|
33
|
a = Announce.objects.create(category=category, title='Announce 1',
|
34
|
publication_time=timezone.now(),
|
35
|
text='<h2>Announce 1</h2>')
|
36
|
Broadcast.objects.create(announce=a)
|
37
|
announces.append(a)
|
38
|
a = Announce.objects.create(category=category, title='Announce 2',
|
39
|
publication_time=timezone.now(),
|
40
|
text='<h2>Announce 2</h2>')
|
41
|
Broadcast.objects.create(announce=a)
|
42
|
announces.append(a)
|
43
|
return announces
|
44
|
|
45
|
|
46
|
def test_emailing_with_no_subscriptions(app, categories, announces, mailoutbox):
|
47
|
for announce in announces:
|
48
|
broadcast = Broadcast.objects.get(announce=announce)
|
49
|
broadcast.send()
|
50
|
assert not broadcast.result
|
51
|
assert not len(mailoutbox)
|
52
|
|
53
|
|
54
|
def test_send_email(app, categories, announces, mailoutbox):
|
55
|
for category in categories:
|
56
|
uuid = uuid4()
|
57
|
Subscription.objects.create(category=category,
|
58
|
identifier='%s@example.net' % uuid, uuid=uuid)
|
59
|
for i, announce in enumerate(announces):
|
60
|
broadcast = Broadcast.objects.get(announce=announce)
|
61
|
broadcast.send()
|
62
|
assert broadcast.result
|
63
|
assert len(mailoutbox) == i+1
|
64
|
|
65
|
|
66
|
def test_check_inline_css(app, categories, announces, mailoutbox):
|
67
|
total_sent = 0
|
68
|
for i, announce in enumerate(announces):
|
69
|
announce.text = '<style type="text/css">h2 {color: #F00}</style>' + announce.text
|
70
|
announce.save()
|
71
|
uuid = uuid4()
|
72
|
Subscription.objects.create(category=announce.category,
|
73
|
identifier='%s@example.net' % uuid, uuid=uuid)
|
74
|
broadcast = Broadcast.objects.get(announce=announce)
|
75
|
broadcast.send()
|
76
|
assert broadcast.result
|
77
|
assert len(mailoutbox) == total_sent + broadcast.result
|
78
|
total_sent += broadcast.result
|
79
|
assert 'h2 style="color:#F00"' in mailoutbox[i].html
|
80
|
|
81
|
|
82
|
@mock.patch('emails.utils.requests.get')
|
83
|
def test_check_inline_images(mocked_get, app, categories, announces, mailoutbox):
|
84
|
storage = DefaultStorage()
|
85
|
media_path = os.path.join(os.path.dirname(__file__), 'media')
|
86
|
image_name = 'logo.png'
|
87
|
image_name = storage.save(image_name, file(os.path.join(media_path, image_name)))
|
88
|
total_sent = 0
|
89
|
for i, announce in enumerate(announces):
|
90
|
img_src = "/media/%s" % image_name
|
91
|
announce.text = announce.text + '<img src="%s" />' % img_src
|
92
|
announce.save()
|
93
|
uuid = uuid4()
|
94
|
Subscription.objects.create(category=announce.category,
|
95
|
identifier='%s@example.net' % uuid, uuid=uuid)
|
96
|
broadcast = Broadcast.objects.get(announce=announce)
|
97
|
broadcast.send()
|
98
|
assert broadcast.result
|
99
|
|
100
|
assert len(mailoutbox) == total_sent + broadcast.result
|
101
|
transformed_image_src = transform_image_src(img_src)
|
102
|
assert transformed_image_src in mailoutbox[i].attachments.keys()
|
103
|
assert 'cid:%s' % transformed_image_src in mailoutbox[i].html_body
|
104
|
assert 'cid:%s' % transformed_image_src in mailoutbox[i].text_body
|
105
|
total_sent += broadcast.result
|
106
|
storage.delete(image_name)
|
107
|
|
108
|
|
109
|
def test_unsubscription_link(app, categories, announces, mailoutbox):
|
110
|
unsubscription_link_sentinel = ''
|
111
|
for category in categories:
|
112
|
uuid = uuid4()
|
113
|
scheme = 'mailto:'
|
114
|
uri = scheme + '%s@example.net' % uuid
|
115
|
Subscription.objects.create(category=category, identifier=uri, uuid=str(uuid))
|
116
|
for i, announce in enumerate(announces):
|
117
|
if announce.category != category:
|
118
|
continue
|
119
|
broadcast = Broadcast.objects.get(announce=announce)
|
120
|
broadcast.send()
|
121
|
assert broadcast.result
|
122
|
assert len(mailoutbox) == i+1
|
123
|
|
124
|
signature = urllib.unquote(re.findall('/unsubscribe/(.*)"', mailoutbox[i].html)[0])
|
125
|
unsubscription_link = reverse('unsubscribe', kwargs={'unsubscription_token': signature})
|
126
|
assert signing.loads(signature) == {
|
127
|
'category': announce.category.pk, 'identifier': uri}
|
128
|
assert mailoutbox[i].subject == announce.title
|
129
|
assert unsubscription_link in mailoutbox[i].html
|
130
|
assert unsubscription_link in mailoutbox[i].text
|
131
|
assert unsubscription_link_sentinel != unsubscription_link
|
132
|
# make sure the uri schema is not in the page
|
133
|
resp = app.get(unsubscription_link)
|
134
|
assert scheme not in resp.content
|
135
|
unsubscription_link_sentinel = unsubscription_link
|