Skip to content

Commit

Permalink
Move context to notification
Browse files Browse the repository at this point in the history
  • Loading branch information
Kevin Etienne committed Mar 13, 2015
1 parent e2387e6 commit ee064bc
Show file tree
Hide file tree
Showing 4 changed files with 44 additions and 32 deletions.
2 changes: 1 addition & 1 deletion user_management/api/tests/test_views.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
User = get_user_model()
TEST_SERVER = 'http://testserver'
SEND_METHOD = 'user_management.utils.notifications.incuna_mail.send'
EMAIL_CONTEXT = 'user_management.models.mixins.EmailVerifyUserMethodsMixin.email_context'
EMAIL_CONTEXT = 'user_management.utils.notifications.email_context'


class GetAuthTokenTest(APIRequestTestCase):
Expand Down
22 changes: 3 additions & 19 deletions user_management/models/mixins.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,9 @@
from django.contrib.auth.models import BaseUserManager
from django.contrib.auth.tokens import default_token_generator
from django.contrib.sites.models import Site
from django.core import checks
from django.db import models
from django.utils import timezone
from django.utils.encoding import force_bytes, python_2_unicode_compatible
from django.utils.http import urlsafe_base64_encode
from django.utils.encoding import python_2_unicode_compatible
from django.utils.translation import ugettext_lazy as _

from user_management.utils.notifications import (
Expand Down Expand Up @@ -140,38 +138,24 @@ class EmailVerifyUserMethodsMixin:
password_reset_notification = PasswordResetNotification
validation_notification = ValidationNotification

def email_context(self, site):
return {
'protocol': 'https',
'uid': urlsafe_base64_encode(force_bytes(self.pk)),
'token': default_token_generator.make_token(self),
'site': site,
}

def send_validation_email(self):
"""Send a validation email to the user's email address."""
if not self.email_verification_required:
raise ValueError(_('Cannot validate already active user.'))

site = Site.objects.get_current()
email_subject = _('{domain} account validate'.format(domain=site.domain))

notification = self.validation_notification(
user=self,
email_subject=email_subject,
context=self.email_context(site),
site=site,
)
notification.notify()

def send_password_reset(self):
"""Send a password reset to the user's email address."""
site = Site.objects.get_current()
email_subject = _('{domain} password reset'.format(domain=site.domain))

notification = self.password_reset_notification(
user=self,
email_subject=email_subject,
context=self.email_context(site),
site=site,
)
notification.notify()

Expand Down
16 changes: 10 additions & 6 deletions user_management/models/tests/test_models.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,16 @@
from django.utils import six, timezone
from django.utils.encoding import force_bytes
from django.utils.http import urlsafe_base64_encode
from mock import patch
from mock import Mock, patch

from user_management.models.tests import utils
from user_management.utils.notifications import email_context
from . import models
from .factories import UserFactory
from .. import mixins


EMAIL_CONTEXT = 'user_management.utils.notifications.email_context'
SEND_METHOD = 'user_management.utils.notifications.incuna_mail.send'

skip_if_checks_unavailable = unittest.skipIf(
Expand Down Expand Up @@ -179,18 +181,20 @@ def test_save(self):
self.assertTrue(user.email_verification_required)

def test_email_context(self):
site = Site.objects.get_current()
user = self.model()
uid = urlsafe_base64_encode(force_bytes(user.pk))

notification = Mock()
notification.user = user

with patch.object(default_token_generator, 'make_token') as make_token:
context = user.email_context(site)
context = email_context(notification)

expected_context = {
'protocol': 'https',
'uid': uid,
'token': make_token(),
'site': site,
'site': notification.site,
}
self.assertEqual(context, expected_context)

Expand All @@ -199,7 +203,7 @@ def test_send_validation_email(self):
site = Site.objects.get_current()
user = self.model(email='email@email.email')

with patch.object(user, 'email_context') as get_context:
with patch(EMAIL_CONTEXT) as get_context:
get_context.return_value = context
with patch(SEND_METHOD) as send:
user.send_validation_email()
Expand Down Expand Up @@ -291,7 +295,7 @@ def test_send_password_reset_email(self):
site = Site.objects.get_current()
user = self.model(email='email@email.email')

with patch.object(user, 'email_context') as get_context:
with patch(EMAIL_CONTEXT) as get_context:
get_context.return_value = context
with patch(SEND_METHOD) as send:
user.send_password_reset()
Expand Down
36 changes: 30 additions & 6 deletions user_management/utils/notifications.py
Original file line number Diff line number Diff line change
@@ -1,30 +1,54 @@
import incuna_mail
from django.contrib.auth.tokens import default_token_generator
from django.utils.encoding import force_bytes
from django.utils.http import urlsafe_base64_encode
from django.utils.translation import ugettext_lazy as _
from pigeon.notification import Notification


def email_context(notification):
return {
'protocol': 'https',
'uid': urlsafe_base64_encode(force_bytes(notification.user.pk)),
'token': default_token_generator.make_token(notification.user),
'site': notification.site,
}


def email_handler(notification):
"""Send a notification by email."""
incuna_mail.send(
to=notification.user.email,
subject=notification.email_subject,
template_name=notification.text_email_template,
html_template_name=notification.html_email_template,
context=notification.context,
context=email_context(notification),
)


class NotificationBase(Notification):
"""Base notification class defining an `email_handler`."""
handlers = (email_handler,)
def password_reset_email_handler(notification):
"""Password reset email handler."""
subject = _('{domain} password reset'.format(domain=notification.site.domain))
notification.email_subject = subject
email_handler(notification)


def validation_email_handler(notification):
"""Validation email handler."""
subject = _('{domain} account validate'.format(domain=notification.site.domain))
notification.email_subject = subject
email_handler(notification)


class PasswordResetNotification(NotificationBase):
class PasswordResetNotification(Notification):
"""`PasswordResetNotification` defines text and html email templates."""
handlers = (password_reset_email_handler,)
text_email_template = 'user_management/password_reset_email.txt'
html_email_template = 'user_management/password_reset_email.html'


class ValidationNotification(NotificationBase):
class ValidationNotification(Notification):
"""`ValidationNotification` defines text and html email templates."""
handlers = (validation_email_handler,)
text_email_template = 'user_management/account_validation_email.txt'
html_email_template = 'user_management/account_validation_email.html'

0 comments on commit ee064bc

Please sign in to comment.