Commit 131057e4 by Alex Dusenbery

EDUCATOR-1571 | Add a CourseWaffleFlag for discussion notifications.

parent 43d6cc20
......@@ -2,7 +2,7 @@
This module contains various configuration settings via
waffle switches for the Discussions app.
"""
from openedx.core.djangoapps.waffle_utils import WaffleSwitchNamespace
from openedx.core.djangoapps.waffle_utils import CourseWaffleFlag, WaffleFlagNamespace, WaffleSwitchNamespace
# Namespace
WAFFLE_NAMESPACE = u'discussions'
......@@ -10,6 +10,12 @@ WAFFLE_NAMESPACE = u'discussions'
# Switches
FORUM_RESPONSE_NOTIFICATIONS = u'forum_response_notifications'
SEND_NOTIFICATIONS_FOR_COURSE = CourseWaffleFlag(
waffle_namespace=WaffleFlagNamespace(name=WAFFLE_NAMESPACE),
flag_name=u'send_notifications_for_course',
flag_undefined_default=False
)
def waffle():
"""
......
......@@ -4,10 +4,12 @@ Signal handlers related to discussions.
import logging
from django.dispatch import receiver
from opaque_keys.edx.keys import CourseKey
from django_comment_common import signals
from lms.djangoapps.discussion.config.waffle import waffle, FORUM_RESPONSE_NOTIFICATIONS
from lms.djangoapps.discussion.config.waffle import waffle, FORUM_RESPONSE_NOTIFICATIONS, SEND_NOTIFICATIONS_FOR_COURSE
from lms.djangoapps.discussion import tasks
from openedx.core.djangoapps.theming.helpers import get_current_site
log = logging.getLogger(__name__)
......@@ -15,11 +17,23 @@ log = logging.getLogger(__name__)
@receiver(signals.comment_created)
def send_discussion_email_notification(sender, user, post, **kwargs):
if waffle().is_enabled(FORUM_RESPONSE_NOTIFICATIONS):
send_message(post)
if not waffle().is_enabled(FORUM_RESPONSE_NOTIFICATIONS):
log.debug('Discussion: Response notifications waffle switch not enabled')
return
if not SEND_NOTIFICATIONS_FOR_COURSE.is_enabled(CourseKey.from_string(post.thread.course_id)):
log.debug('Discussion: Response notifications not enabled for this course')
return
def send_message(comment):
current_site = get_current_site()
if current_site is None:
log.debug('Discussion: No current site, not sending notification')
return
send_message(post, current_site)
def send_message(comment, site):
thread = comment.thread
context = {
'course_id': unicode(thread.course_id),
......@@ -34,5 +48,6 @@ def send_message(comment):
'thread_author_id': thread.user_id,
'thread_created_at': thread.created_at,
'thread_commentable_id': thread.commentable_id,
'site_id': site.id
}
tasks.send_ace_message.apply_async(args=[context])
......@@ -76,7 +76,7 @@ def _get_course_language(course_id):
def _build_message_context(context):
message_context = get_base_template_context(Site.objects.get_current())
message_context = get_base_template_context(Site.objects.get(id=context['site_id']))
message_context.update(context)
message_context['post_link'] = _get_thread_url(context)
return message_context
......
from django.test import TestCase
import mock
from opaque_keys.edx.keys import CourseKey
from django_comment_common import signals
from lms.djangoapps.discussion.config.waffle import waffle, FORUM_RESPONSE_NOTIFICATIONS
from lms.djangoapps.discussion.config.waffle import waffle, FORUM_RESPONSE_NOTIFICATIONS, SEND_NOTIFICATIONS_FOR_COURSE
from openedx.core.djangoapps.waffle_utils.testutils import override_waffle_flag
class SendMessageHandlerTestCase(TestCase):
def setUp(self):
self.sender = mock.Mock()
self.user = mock.Mock()
self.post = mock.Mock()
self.post.thread.course_id = 'course-v1:edX+DemoX+Demo_Course'
@mock.patch('lms.djangoapps.discussion.signals.handlers.get_current_site')
@mock.patch('lms.djangoapps.discussion.signals.handlers.send_message')
def test_comment_created_signal_sends_message(self, mock_send_message):
@override_waffle_flag(SEND_NOTIFICATIONS_FOR_COURSE, True)
def test_comment_created_signal_sends_message(self, mock_send_message, mock_get_current_site):
with waffle().override(FORUM_RESPONSE_NOTIFICATIONS):
sender = mock.Mock()
user = mock.Mock()
post = mock.Mock()
signals.comment_created.send(sender=sender, user=user, post=post)
signals.comment_created.send(sender=self.sender, user=self.user, post=self.post)
mock_send_message.assert_called_once_with(post)
mock_send_message.assert_called_once_with(self.post, mock_get_current_site.return_value)
@mock.patch('lms.djangoapps.discussion.signals.handlers.send_message')
@override_waffle_flag(SEND_NOTIFICATIONS_FOR_COURSE, True)
def test_comment_created_signal_message_not_sent_without_waffle_switch(self, mock_send_message):
with waffle().override(FORUM_RESPONSE_NOTIFICATIONS, active=False):
sender = mock.Mock()
user = mock.Mock()
post = mock.Mock()
signals.comment_created.send(sender=self.sender, user=self.user, post=self.post)
self.assertFalse(mock_send_message.called)
signals.comment_created.send(sender=sender, user=user, post=post)
@mock.patch('lms.djangoapps.discussion.signals.handlers.send_message')
def test_comment_created_signal_message_not_sent_without_course_waffle_flag(self, mock_send_message):
with waffle().override(FORUM_RESPONSE_NOTIFICATIONS, active=True):
signals.comment_created.send(sender=self.sender, user=self.user, post=self.post)
self.assertFalse(mock_send_message.called)
@mock.patch('lms.djangoapps.discussion.signals.handlers.get_current_site', return_value=None)
@mock.patch('lms.djangoapps.discussion.signals.handlers.send_message')
@override_waffle_flag(SEND_NOTIFICATIONS_FOR_COURSE, True)
def test_comment_created_signal_message_not_sent_without_site(self, mock_send_message, mock_get_current_site):
with waffle().override(FORUM_RESPONSE_NOTIFICATIONS, active=True):
signals.comment_created.send(sender=self.sender, user=self.user, post=self.post)
self.assertFalse(mock_send_message.called)
......@@ -15,9 +15,10 @@ import mock
from django_comment_common.models import ForumsConfig
from django_comment_common.signals import comment_created
from edx_ace.recipient import Recipient
from lms.djangoapps.discussion.config.waffle import waffle, FORUM_RESPONSE_NOTIFICATIONS
from lms.djangoapps.discussion.config.waffle import waffle, FORUM_RESPONSE_NOTIFICATIONS, SEND_NOTIFICATIONS_FOR_COURSE
from openedx.core.djangoapps.content.course_overviews.tests.factories import CourseOverviewFactory
from openedx.core.djangoapps.schedules.template_context import get_base_template_context
from openedx.core.djangoapps.waffle_utils.testutils import override_waffle_flag
from student.tests.factories import CourseEnrollmentFactory, UserFactory
from xmodule.modulestore.tests.django_utils import ModuleStoreTestCase
......@@ -89,6 +90,7 @@ class TaskTestCase(ModuleStoreTestCase):
config.save()
@ddt.data(True, False)
@override_waffle_flag(SEND_NOTIFICATIONS_FOR_COURSE, True)
def test_send_discussion_email_notification(self, user_subscribed):
with mock_the_things() as mocked_items:
mock_request, mock_ace_send, mock_permalink = mocked_items
......@@ -105,7 +107,7 @@ class TaskTestCase(ModuleStoreTestCase):
one_hour_ago = now - timedelta(hours=1)
thread = mock.Mock(
id=self.discussion_id,
course_id=self.course.id,
course_id=unicode(self.course.id),
created_at=one_hour_ago,
title='thread-title',
user_id=self.thread_author.id,
......@@ -121,12 +123,14 @@ class TaskTestCase(ModuleStoreTestCase):
username=self.comment_author.username
)
user = mock.Mock()
site = Site.objects.get_current()
with waffle().override(FORUM_RESPONSE_NOTIFICATIONS):
comment_created.send(sender=None, user=user, post=comment)
with mock.patch('lms.djangoapps.discussion.signals.handlers.get_current_site', return_value=site):
comment_created.send(sender=None, user=user, post=comment)
if user_subscribed:
expected_message_context = get_base_template_context(Site.objects.get_current())
expected_message_context = get_base_template_context(site)
expected_message_context.update({
'comment_author_id': self.comment_author.id,
'comment_body': 'comment-body',
......@@ -141,6 +145,7 @@ class TaskTestCase(ModuleStoreTestCase):
'thread_username': self.thread_author.username,
'thread_commentable_id': 'thread-commentable-id',
'post_link': urljoin(settings.LMS_ROOT_URL, mock_permalink.return_value),
'site_id': site.id
})
expected_recipient = Recipient(self.thread_author.username, self.thread_author.email)
actual_message = mock_ace_send.call_args_list[0][0][0]
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment