fix unsubscription link computation for each destination (#16456)
This commit is contained in:
parent
2949280eec
commit
23c19695b1
|
@ -36,7 +36,7 @@ UNSUBSCRIBE_LINK_PLACEHOLDER = '##UNSUBSCRIBE_LINK_PLACEHOLDER##'
|
|||
def transform_image_src(src, **kwargs):
|
||||
return urlparse.urljoin(settings.SITE_BASE_URL, src)
|
||||
|
||||
def send_email(title, content, destinations, category_id=None):
|
||||
def send_email(title, content, destinations, category_id):
|
||||
logger = logging.getLogger(__name__)
|
||||
total_sent = 0
|
||||
handler = HTML2Text()
|
||||
|
@ -51,13 +51,15 @@ def send_email(title, content, destinations, category_id=None):
|
|||
message.transformer.apply_to_images(func=transform_image_src)
|
||||
message.transformer.load_and_transform(images_inline=True)
|
||||
message.transformer.save()
|
||||
orig_html = message.html
|
||||
|
||||
for dest in destinations:
|
||||
if category_id:
|
||||
unsubscribe_token = signing.dumps({'category': category_id,
|
||||
'identifier': dest})
|
||||
unsubscribe_link = urlparse.urljoin(settings.SITE_BASE_URL, reverse(
|
||||
'unsubscribe', kwargs={'unsubscription_token': unsubscribe_token}))
|
||||
message.html = message.html.replace(UNSUBSCRIBE_LINK_PLACEHOLDER, unsubscribe_link)
|
||||
unsubscribe_token = signing.dumps({'category': category_id,
|
||||
'identifier': dest})
|
||||
unsubscribe_link = urlparse.urljoin(settings.SITE_BASE_URL, reverse(
|
||||
'unsubscribe', kwargs={'unsubscription_token': unsubscribe_token}))
|
||||
message.html = orig_html.replace(UNSUBSCRIBE_LINK_PLACEHOLDER, unsubscribe_link)
|
||||
|
||||
handler.body_width = 0
|
||||
message.text = handler.handle(message.html)
|
||||
sent = message.send(to=dest)
|
||||
|
|
|
@ -1,6 +1,40 @@
|
|||
import pytest
|
||||
import django_webtest
|
||||
import copy
|
||||
|
||||
import django.core.mail.backends.locmem
|
||||
from django.core.mail.backends.locmem import EmailBackend as DjangoEmailBackend
|
||||
|
||||
|
||||
class MockedEmailBackend(object):
|
||||
|
||||
def create_email_backend(self, *args, **kwargs):
|
||||
class EmailBackend(DjangoEmailBackend):
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(DjangoEmailBackend, self).__init__(*args, **kwargs)
|
||||
|
||||
def send_messages(self, messages):
|
||||
new_messages = []
|
||||
for message in messages:
|
||||
new_messages.append(copy.deepcopy(message))
|
||||
return super(EmailBackend, self).send_messages(new_messages)
|
||||
|
||||
return EmailBackend
|
||||
|
||||
def __enter__(self):
|
||||
import django.core.mail.backends.locmem
|
||||
self.locmem_emailbackend = django.core.mail.backends.locmem.EmailBackend
|
||||
django.core.mail.backends.locmem.EmailBackend = self.create_email_backend()
|
||||
return self
|
||||
|
||||
def __exit__(self, *args, **kwargs):
|
||||
django.core.mail.backends.locmem.EmailBackend = self.locmem_emailbackend
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def custom_mailoutbox():
|
||||
with MockedEmailBackend() as mock:
|
||||
yield mock
|
||||
|
||||
@pytest.fixture
|
||||
def app(request):
|
||||
|
|
|
@ -111,30 +111,36 @@ def test_check_inline_images(mocked_get, app, categories, announces, mailoutbox)
|
|||
storage.delete(image_name)
|
||||
|
||||
|
||||
def test_unsubscription_link(app, categories, announces, mailoutbox):
|
||||
def test_unsubscription_link(app, categories, announces, custom_mailoutbox):
|
||||
unsubscription_link_sentinel = ''
|
||||
subscriptions_number = 3
|
||||
scheme = 'mailto:'
|
||||
for category in categories:
|
||||
uuid = uuid4()
|
||||
scheme = 'mailto:'
|
||||
uri = scheme + '%s@example.net' % uuid
|
||||
Subscription.objects.create(category=category, identifier=uri, uuid=str(uuid))
|
||||
for i in xrange(subscriptions_number):
|
||||
uuid = uuid4()
|
||||
uri = scheme + '%s@example.com' % uuid
|
||||
Subscription.objects.create(category=category, identifier=uri, uuid=str(uuid))
|
||||
|
||||
for i, announce in enumerate(announces):
|
||||
if announce.category != category:
|
||||
continue
|
||||
broadcast = Broadcast.objects.get(announce=announce)
|
||||
broadcast.send()
|
||||
assert broadcast.delivery_count
|
||||
assert len(mailoutbox) == i+1
|
||||
assert len(mail.outbox) == (i+1)*subscriptions_number
|
||||
assert mail.outbox[i*subscriptions_number].subject == announce.title
|
||||
|
||||
signature = urllib.unquote(re.findall('/unsubscribe/(.*)"', mailoutbox[i].html)[0])
|
||||
unsubscription_link = reverse('unsubscribe', kwargs={'unsubscription_token': signature})
|
||||
assert signing.loads(signature) == {
|
||||
'category': announce.category.pk, 'identifier': uri}
|
||||
assert mailoutbox[i].subject == announce.title
|
||||
assert unsubscription_link in mailoutbox[i].html
|
||||
assert unsubscription_link in mailoutbox[i].text
|
||||
assert unsubscription_link_sentinel != unsubscription_link
|
||||
# make sure the uri schema is not in the page
|
||||
resp = app.get(unsubscription_link)
|
||||
assert scheme not in resp.content
|
||||
unsubscription_link_sentinel = unsubscription_link
|
||||
for counter, destination in enumerate(category.subscription_set.all()):
|
||||
index = i*subscriptions_number+counter
|
||||
signature = urllib.unquote(re.findall('/unsubscribe/(.*)"', mail.outbox[index].html)[0])
|
||||
unsubscription_link = reverse('unsubscribe', kwargs={'unsubscription_token': signature})
|
||||
assert unsubscription_link in mail.outbox[index].html
|
||||
assert unsubscription_link in mail.outbox[index].text
|
||||
assert unsubscription_link_sentinel != unsubscription_link
|
||||
assert signing.loads(signature) == {
|
||||
'category': announce.category.pk, 'identifier': destination.identifier}
|
||||
unsubscription_link_sentinel = unsubscription_link
|
||||
|
||||
# make sure the uri schema is not in the page
|
||||
resp = app.get(unsubscription_link)
|
||||
assert scheme not in resp.content
|
||||
|
|
Reference in New Issue