Skip to content
Snippets Groups Projects
Commit 62143651 authored by stephensanchez's avatar stephensanchez
Browse files

Create new API endpoint for email optin

Updating the design of the email opt in end point.

Updating API call based on new Org Model.
parent 19f737d5
No related branches found
No related tags found
No related merge requests found
......@@ -5,11 +5,16 @@ but does NOT include basic account information such as username, password, and
email address.
"""
import datetime
from django.conf import settings
from django.db import IntegrityError
import logging
from pytz import UTC
from user_api.models import User, UserProfile, UserPreference
from user_api.models import User, UserProfile, UserPreference, UserOrgTag
from user_api.helpers import intercept_errors
log = logging.getLogger(__name__)
class ProfileRequestError(Exception):
""" The request to the API was not valid. """
......@@ -155,3 +160,45 @@ def update_preferences(username, **kwargs):
else:
for key, value in kwargs.iteritems():
UserPreference.set_preference(user, key, value)
@intercept_errors(ProfileInternalError, ignore_errors=[ProfileRequestError])
def update_email_opt_in(username, org, optin):
"""Updates a user's preference for receiving org-wide emails.
Sets a User Org Tag defining the choice to opt in or opt out of organization-wide
emails.
Args:
username (str): The user to set a preference for.
org (str): The org is used to determine the organization this setting is related to.
optin (boolean): True if the user is choosing to receive emails for this organization. If the user is not
the correct age to receive emails, email-optin is set to False regardless.
Returns:
None
Raises:
ProfileUserNotFound: Raised when the username specified is not associated with a user.
"""
try:
user = User.objects.get(username=username)
except User.DoesNotExist:
raise ProfileUserNotFound
profile = UserProfile.objects.get(user=user)
of_age = (
profile.year_of_birth is None or # If year of birth is not set, we assume user is of age.
datetime.datetime.now(UTC).year - profile.year_of_birth >= # pylint: disable=maybe-no-member
getattr(settings, 'EMAIL_OPTIN_MINIMUM_AGE', 13)
)
try:
preference, _ = UserOrgTag.objects.get_or_create(
user=user, org=org, key='email-optin'
)
preference.value = str(optin and of_age)
preference.save()
except IntegrityError as err:
log.warn(u"Could not update organization wide preference due to IntegrityError: {}".format(err.message))
# -*- coding: utf-8 -*-
""" Tests for the profile API. """
from django.contrib.auth.models import User
from django.test import TestCase
import ddt
from django.test.utils import override_settings
from nose.tools import raises
from dateutil.parser import parse as parse_datetime
from xmodule.modulestore.tests.factories import CourseFactory
import datetime
from user_api.api import account as account_api
from user_api.api import profile as profile_api
from user_api.models import UserProfile
from user_api.models import UserProfile, UserOrgTag
@ddt.ddt
......@@ -94,6 +98,84 @@ class ProfileApiTest(TestCase):
preferences = profile_api.preference_info(self.USERNAME)
self.assertEqual(preferences['preference_key'], 'preference_value')
@ddt.data(
# Check that a 27 year old can opt-in
(27, True, u"True"),
# Check that a 32-year old can opt-out
(32, False, u"False"),
# Check that someone 13 years old can opt-in
(13, True, u"True"),
# Check that someone 12 years old cannot opt-in
(12, True, u"False")
)
@ddt.unpack
@override_settings(EMAIL_OPTIN_MINIMUM_AGE=13)
def test_update_email_optin(self, age, option, expected_result):
# Create the course and account.
course = CourseFactory.create()
account_api.create_account(self.USERNAME, self.PASSWORD, self.EMAIL)
# Set year of birth
user = User.objects.get(username=self.USERNAME)
profile = UserProfile.objects.get(user=user)
year_of_birth = datetime.datetime.now().year - age # pylint: disable=maybe-no-member
profile.year_of_birth = year_of_birth
profile.save()
profile_api.update_email_opt_in(self.USERNAME, course.id.org, option)
result_obj = UserOrgTag.objects.get(user=user, org=course.id.org, key='email-optin')
self.assertEqual(result_obj.value, expected_result)
def test_update_email_optin_no_age_set(self):
# Test that the API still works if no age is specified.
# Create the course and account.
course = CourseFactory.create()
account_api.create_account(self.USERNAME, self.PASSWORD, self.EMAIL)
user = User.objects.get(username=self.USERNAME)
profile_api.update_email_opt_in(self.USERNAME, course.id.org, True)
result_obj = UserOrgTag.objects.get(user=user, org=course.id.org, key='email-optin')
self.assertEqual(result_obj.value, u"True")
@ddt.data(
# Check that a 27 year old can opt-in, then out.
(27, True, False, u"False"),
# Check that a 32-year old can opt-out, then in.
(32, False, True, u"True"),
# Check that someone 13 years old can opt-in, then out.
(13, True, False, u"False"),
# Check that someone 12 years old cannot opt-in, then explicitly out.
(12, True, False, u"False")
)
@ddt.unpack
@override_settings(EMAIL_OPTIN_MINIMUM_AGE=13)
def test_change_email_optin(self, age, option, second_option, expected_result):
# Create the course and account.
course = CourseFactory.create()
account_api.create_account(self.USERNAME, self.PASSWORD, self.EMAIL)
# Set year of birth
user = User.objects.get(username=self.USERNAME)
profile = UserProfile.objects.get(user=user)
year_of_birth = datetime.datetime.now().year - age # pylint: disable=maybe-no-member
profile.year_of_birth = year_of_birth
profile.save()
profile_api.update_email_opt_in(self.USERNAME, course.id.org, option)
profile_api.update_email_opt_in(self.USERNAME, course.id.org, second_option)
result_obj = UserOrgTag.objects.get(user=user, org=course.id.org, key='email-optin')
self.assertEqual(result_obj.value, expected_result)
@raises(profile_api.ProfileUserNotFound)
def test_retrieve_and_update_preference_info_no_user(self):
preferences = profile_api.preference_info(self.USERNAME)
......
......@@ -1365,6 +1365,10 @@ BULK_EMAIL_LOG_SENT_EMAILS = False
# parallel, and what the SES rate is.
BULK_EMAIL_RETRY_DELAY_BETWEEN_SENDS = 0.02
############################# Email Opt In ####################################
# Minimum age for organization-wide email opt in
EMAIL_OPTIN_MINIMUM_AGE = 13
############################## Video ##########################################
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment