Skip to content

Commit

Permalink
Add unsubscribe from marketing email functionality
Browse files Browse the repository at this point in the history
Create UnsubscribedUser model to save unsubscribed users
Create a POST API endpoint to unsubscribe user from marketing emails
  • Loading branch information
Fahminajjar committed Mar 8, 2020
1 parent 17074fa commit 102d89f
Show file tree
Hide file tree
Showing 14 changed files with 206 additions and 0 deletions.
2 changes: 2 additions & 0 deletions cms/envs/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -1041,6 +1041,8 @@
'django_comment_common',
'edraak_misc',

'edraak_marketing_email.apps.EdraakMarketingEmailConfig',

# for course creator table
'django.contrib.admin',

Expand Down
6 changes: 6 additions & 0 deletions common/djangoapps/student/views/management.py
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,8 @@
from util.db import outer_atomic
from util.json_request import JsonResponse
from util.password_policy_validators import SecurityPolicyError, validate_password
from edraak_marketing_email.helpers import unsubscribe_from_marketing_emails


log = logging.getLogger("edx.student")

Expand Down Expand Up @@ -814,6 +816,10 @@ def create_account_with_params(request, params):
if new_user is not None:
AUDIT_LOG.info(u"Login success on new account creation - {0}".format(new_user.username))

subscribe_to_marketing_emails = params.get('marketing_consent', 'false').lower() == 'true'
if not subscribe_to_marketing_emails:
unsubscribe_from_marketing_emails(new_user)

return new_user


Expand Down
Empty file.
12 changes: 12 additions & 0 deletions lms/djangoapps/edraak_marketing_email/apps.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
"""
Configuration for the edraak_marketing_email Django application.
"""
from django.apps import AppConfig


class EdraakMarketingEmailConfig(AppConfig):
"""
Configuration class for the edraak_marketing_email Django application.
"""
name = 'edraak_marketing_email'
verbose_name = "Edraak Marketing Email"
17 changes: 17 additions & 0 deletions lms/djangoapps/edraak_marketing_email/helpers.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
from edraak_marketing_email.models import UnsubscribedUser


def unsubscribe_from_marketing_emails(user):
is_unsubscribed = UnsubscribedUser.objects.filter(user=user).exists()
if is_unsubscribed:
return

UnsubscribedUser.objects.create(user=user)


def subscribe_to_marketing_emails(user):
is_unsubscribed = UnsubscribedUser.objects.filter(user=user).exists()
if not is_unsubscribed:
return

UnsubscribedUser.objects.filter(user=user).delete()
26 changes: 26 additions & 0 deletions lms/djangoapps/edraak_marketing_email/migrations/0001_initial.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.11.18 on 2020-03-08 08:16
from __future__ import unicode_literals

from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion


class Migration(migrations.Migration):

initial = True

dependencies = [
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
]

operations = [
migrations.CreateModel(
name='UnsubscribedUser',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('user', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)),
],
),
]
Empty file.
15 changes: 15 additions & 0 deletions lms/djangoapps/edraak_marketing_email/models.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
"""
Edraak-Marketing-Email-related models.
"""
from django.db import models
from django.contrib.auth.models import User


class UnsubscribedUser(models.Model):
"""
Stores users that have opted out of receiving marketing emails.
"""
class Meta(object):
app_label = "edraak_marketing_email"

user = models.OneToOneField(User, db_index=True, on_delete=models.CASCADE)
Empty file.
72 changes: 72 additions & 0 deletions lms/djangoapps/edraak_marketing_email/tests/test_views.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
from rest_framework.test import APITestCase
from rest_framework import status
from django.urls import reverse
from student.tests.factories import UserFactory
from edraak_marketing_email.helpers import (
subscribe_to_marketing_emails,
unsubscribe_from_marketing_emails
)


class TestUnsubscribeUserAPIView(APITestCase):
"""Tests for handling edraak marketing email unsubscription"""

def setUp(self):
super(TestUnsubscribeUserAPIView, self).setUp()
self.client = self.client_class()
self.url = reverse('edraak_marketing_email:unsubscribe')

def test_user_unsubscribed_successfully(self, *args): # pylint: disable=unused-argument
user = UserFactory()

data = {
'username': user.username
}
resp = self.client.post(self.url, data, format='json')

# Expect that the request gets through successfully,
self.assertEqual(resp.status_code, status.HTTP_200_OK)

def test_already_unsubscribed_user(self, *args): # pylint: disable=unused-argument
user = UserFactory()
unsubscribe_from_marketing_emails(user)

data = {
'username': user.username
}
resp = self.client.post(self.url, data, format='json')

# Expect that the request gets through successfully,
self.assertEqual(resp.status_code, status.HTTP_200_OK)


class TestSubscribeUserAPIView(APITestCase):
"""Tests for handling edraak marketing email subscription"""

def setUp(self):
super(TestSubscribeUserAPIView, self).setUp()
self.client = self.client_class()
self.url = reverse('edraak_marketing_email:subscribe')

def test_user_subscribed_successfully(self, *args): # pylint: disable=unused-argument
user = UserFactory()

data = {
'username': user.username
}
resp = self.client.post(self.url, data, format='json')

# Expect that the request gets through successfully,
self.assertEqual(resp.status_code, status.HTTP_200_OK)

def test_already_subscribed_user(self, *args): # pylint: disable=unused-argument
user = UserFactory()
subscribe_to_marketing_emails(user)

data = {
'username': user.username
}
resp = self.client.post(self.url, data, format='json')

# Expect that the request gets through successfully,
self.assertEqual(resp.status_code, status.HTTP_200_OK)
11 changes: 11 additions & 0 deletions lms/djangoapps/edraak_marketing_email/urls.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
"""
URLs for edraak marketing email.
"""
from django.conf.urls import url
from edraak_marketing_email import views


urlpatterns = [
url(r"^marketing_email/unsubscribe$", views.UnsubscribeUserAPIView.as_view(), name="unsubscribe"),
url(r"^marketing_email/subscribe$", views.SubscribeUserAPIView.as_view(), name="subscribe"),
]
39 changes: 39 additions & 0 deletions lms/djangoapps/edraak_marketing_email/views.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
from django.contrib.auth.models import User
from django.shortcuts import get_object_or_404
from rest_framework import status
from rest_framework.response import Response
from rest_framework.views import APIView
from edraak_marketing_email.helpers import (
subscribe_to_marketing_emails,
unsubscribe_from_marketing_emails
)


class UnsubscribeUserAPIView(APIView):
"""
Unsubscribe user from marketing emails
"""
authentication_classes = []
permission_classes = []

def post(self, request, *args, **kwargs):
username = request.data.get('username')
user = get_object_or_404(User, username=username)

unsubscribe_from_marketing_emails(user)
return Response(data={}, status=status.HTTP_200_OK)


class SubscribeUserAPIView(APIView):
"""
Subscribe user to marketing emails
"""
authentication_classes = []
permission_classes = []

def post(self, request, *args, **kwargs):
username = request.data.get('username')
user = get_object_or_404(User, username=username)

subscribe_to_marketing_emails(user)
return Response(data={}, status=status.HTTP_200_OK)
2 changes: 2 additions & 0 deletions lms/envs/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -2301,6 +2301,8 @@ def _make_locale_paths(settings):
# Email marketing integration
'email_marketing.apps.EmailMarketingConfig',

'edraak_marketing_email.apps.EdraakMarketingEmailConfig',

# additional release utilities to ease automation
'release_util',

Expand Down
4 changes: 4 additions & 0 deletions lms/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,10 @@
url(r'', include('edraak_misc.urls', namespace='edraak_misc')),
]

urlpatterns += [
url(r'', include('edraak_marketing_email.urls', namespace='edraak_marketing_email')),
]

urlpatterns += [
url(r'^support/', include('support.urls')),
]
Expand Down

0 comments on commit 102d89f

Please sign in to comment.