Allow for customization of course email template at the organization level
This commit is contained in:
committed by
Douglas Hall
parent
aeb76a5bc7
commit
06fa13f4df
@@ -30,7 +30,7 @@ from opaque_keys.edx.locations import SlashSeparatedCourseKey
|
||||
from opaque_keys.edx.locator import UsageKey
|
||||
from xmodule.modulestore import ModuleStoreEnum
|
||||
|
||||
from bulk_email.models import BulkEmailFlag
|
||||
from bulk_email.models import BulkEmailFlag, CourseEmail, CourseEmailTemplate
|
||||
from course_modes.models import CourseMode
|
||||
from courseware.models import StudentModule
|
||||
from courseware.tests.factories import (
|
||||
@@ -70,6 +70,7 @@ from certificates.models import CertificateStatuses
|
||||
from openedx.core.djangoapps.course_groups.cohorts import set_course_cohort_settings
|
||||
from openedx.core.lib.xblock_utils import grade_histogram
|
||||
from openedx.core.djangoapps.site_configuration import helpers as configuration_helpers
|
||||
from openedx.core.djangoapps.site_configuration.tests.mixins import SiteMixin
|
||||
|
||||
from .test_tools import msk_from_problem_urlname
|
||||
|
||||
@@ -3558,7 +3559,7 @@ class TestEntranceExamInstructorAPIRegradeTask(SharedModuleStoreTestCase, LoginE
|
||||
|
||||
@attr(shard=1)
|
||||
@patch('bulk_email.models.html_to_text', Mock(return_value='Mocking CourseEmail.text_message', autospec=True))
|
||||
class TestInstructorSendEmail(SharedModuleStoreTestCase, LoginEnrollmentTestCase):
|
||||
class TestInstructorSendEmail(SiteMixin, SharedModuleStoreTestCase, LoginEnrollmentTestCase):
|
||||
"""
|
||||
Checks that only instructors have access to email endpoints, and that
|
||||
these endpoints are only accessible with courses that actually exist,
|
||||
@@ -3645,6 +3646,43 @@ class TestInstructorSendEmail(SharedModuleStoreTestCase, LoginEnrollmentTestCase
|
||||
})
|
||||
self.assertEqual(response.status_code, 400)
|
||||
|
||||
def test_send_email_with_site_template_and_from_addr(self):
|
||||
site_email = self.site_configuration.values.get('course_email_from_addr')
|
||||
site_template = self.site_configuration.values.get('course_email_template_name')
|
||||
CourseEmailTemplate.objects.create(name=site_template)
|
||||
url = reverse('send_email', kwargs={'course_id': self.course.id.to_deprecated_string()})
|
||||
response = self.client.post(url, self.full_test_message)
|
||||
self.assertEqual(response.status_code, 200)
|
||||
self.assertEqual(1, CourseEmail.objects.filter(
|
||||
course_id=self.course.id,
|
||||
sender=self.instructor,
|
||||
subject=self.full_test_message['subject'],
|
||||
html_message=self.full_test_message['message'],
|
||||
template_name=site_template,
|
||||
from_addr=site_email
|
||||
).count())
|
||||
|
||||
def test_send_email_with_org_template_and_from_addr(self):
|
||||
org_email = 'fake_org@example.com'
|
||||
org_template = 'fake_org_email_template'
|
||||
CourseEmailTemplate.objects.create(name=org_template)
|
||||
self.site_configuration.values.update({
|
||||
'course_email_from_addr': {self.course.id.org: org_email},
|
||||
'course_email_template_name': {self.course.id.org: org_template}
|
||||
})
|
||||
self.site_configuration.save()
|
||||
url = reverse('send_email', kwargs={'course_id': self.course.id.to_deprecated_string()})
|
||||
response = self.client.post(url, self.full_test_message)
|
||||
self.assertEqual(response.status_code, 200)
|
||||
self.assertEqual(1, CourseEmail.objects.filter(
|
||||
course_id=self.course.id,
|
||||
sender=self.instructor,
|
||||
subject=self.full_test_message['subject'],
|
||||
html_message=self.full_test_message['message'],
|
||||
template_name=org_template,
|
||||
from_addr=org_email
|
||||
).count())
|
||||
|
||||
|
||||
class MockCompletionInfo(object):
|
||||
"""Mock for get_task_completion_info"""
|
||||
|
||||
@@ -110,6 +110,7 @@ from opaque_keys.edx.locations import SlashSeparatedCourseKey
|
||||
from opaque_keys import InvalidKeyError
|
||||
from openedx.core.djangoapps.course_groups.cohorts import is_course_cohorted
|
||||
from openedx.core.djangoapps.site_configuration import helpers as configuration_helpers
|
||||
from openedx.core.djangoapps.content.course_overviews.models import CourseOverview
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
@@ -2516,7 +2517,7 @@ def send_email(request, course_id):
|
||||
- 'subject' specifies email's subject
|
||||
- 'message' specifies email's content
|
||||
"""
|
||||
course_id = SlashSeparatedCourseKey.from_deprecated_string(course_id)
|
||||
course_id = CourseKey.from_string(course_id)
|
||||
|
||||
if not BulkEmailFlag.feature_enabled(course_id):
|
||||
return HttpResponseForbidden("Email is not enabled for this course.")
|
||||
@@ -2530,8 +2531,22 @@ def send_email(request, course_id):
|
||||
#
|
||||
# If these are None (there is no site configuration enabled for the current site) than
|
||||
# the system will use normal system defaults
|
||||
template_name = configuration_helpers.get_value('course_email_template_name')
|
||||
course_overview = CourseOverview.get_from_id(course_id)
|
||||
from_addr = configuration_helpers.get_value('course_email_from_addr')
|
||||
if isinstance(from_addr, dict):
|
||||
# If course_email_from_addr is a dict, we are customizing
|
||||
# the email template for each organization that has courses
|
||||
# on the site. The dict maps from addresses by org allowing
|
||||
# us to find the correct from address to use here.
|
||||
from_addr = from_addr.get(course_overview.display_org_with_default)
|
||||
|
||||
template_name = configuration_helpers.get_value('course_email_template_name')
|
||||
if isinstance(template_name, dict):
|
||||
# If course_email_template_name is a dict, we are customizing
|
||||
# the email template for each organization that has courses
|
||||
# on the site. The dict maps template names by org allowing
|
||||
# us to find the correct template to use here.
|
||||
template_name = template_name.get(course_overview.display_org_with_default)
|
||||
|
||||
# Create the CourseEmail object. This is saved immediately, so that
|
||||
# any transaction that has been pending up to this point will also be
|
||||
|
||||
@@ -16,7 +16,9 @@ class SiteMixin(object):
|
||||
site=self.site,
|
||||
values={
|
||||
"SITE_NAME": self.site.domain,
|
||||
"course_org_filter": "fakeX",
|
||||
"course_email_from_addr": "fake@example.com",
|
||||
"course_email_template_name": "fake_email_template",
|
||||
"course_org_filter": "fakeX"
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user