Skip to content

Commit

Permalink
fix: nits
Browse files Browse the repository at this point in the history
  • Loading branch information
AfaqShuaib09 committed Jul 14, 2023
1 parent 8be6461 commit e540265
Show file tree
Hide file tree
Showing 2 changed files with 81 additions and 61 deletions.
54 changes: 23 additions & 31 deletions course_discovery/apps/course_metadata/emails.py
Original file line number Diff line number Diff line change
Expand Up @@ -168,36 +168,6 @@ def send_email_to_legal(course_run, template_name, subject, context=None):
send_email(template_name, subject, to_users, _('legal team'), context=context, course_run=course_run)


def send_email_to_watchers(course, template_name, subject, context=None):
""" Send a specific email template to all watchers for a course.
Arguments:
course (Object): Course object
template_name (str): path to template without filename extension
subject (str): subject line for the email
context (dict): additional context for the template
"""
to_users = course.watchers
txt_template = f'{template_name}.txt'
html_template = f'{template_name}.html'
template = get_template(txt_template)
plain_content = template.render(context)
template = get_template(html_template)
html_content = template.render(context)

email_msg = EmailMultiAlternatives(
subject, plain_content, settings.PUBLISHER_FROM_EMAIL, to_users
)
email_msg.attach_alternative(html_content, 'text/html')

try:
email_msg.send()
except Exception as exc: # pylint: disable=broad-except
logger.exception(
f'Failed to send email notification with subject "{subject}" to users {to_users}. Error: {exc}'
)


def send_email_to_project_coordinator(course_run, template_name, subject, context=None):
""" Send a specific email template to the project coordinator for a course run.
Expand Down Expand Up @@ -254,6 +224,11 @@ def send_email_for_legal_review(course_run):
def send_email_for_course_url(course, course_run_publish_date, course_run_status):
"""
Send email to the watchers of the course when the course run is scheduled or published.
Arguments:
course (Object): Course object
course_run_publish_date (datetime): Course run publish date
course_run_status (str): Course run status
"""
subject = _('Course URL for {title}').format(title=course.title)
context = {
Expand All @@ -264,8 +239,25 @@ def send_email_for_course_url(course, course_run_publish_date, course_run_status
'course_marketing_url': course.marketing_url,
'course_preview_url': f'{course.partner.marketing_site_url_root}/preview/{course.active_url_slug}',
}
to_users = course.watchers
txt_template = 'course_metadata/email/watchers_course_url.txt'
html_template = 'course_metadata/email/watchers_course_url.html'
template = get_template(txt_template)
plain_content = template.render(context)
template = get_template(html_template)
html_content = template.render(context)

send_email_to_watchers(course, 'course_metadata/email/watchers_course_url', subject, context=context)
email_msg = EmailMultiAlternatives(
subject, plain_content, settings.PUBLISHER_FROM_EMAIL, to_users
)
email_msg.attach_alternative(html_content, 'text/html')

try:
email_msg.send()
except Exception as exc: # pylint: disable=broad-except
logger.exception(
f'Failed to send email notification with subject "{subject}" to users {to_users}. Error: {exc}'
)


def send_email_for_internal_review(course_run):
Expand Down
88 changes: 58 additions & 30 deletions course_discovery/apps/course_metadata/tests/test_models.py
Original file line number Diff line number Diff line change
Expand Up @@ -960,53 +960,81 @@ def test_reviewed_with_go_live_date(self, when, published, mock_email):
assert mock_email.call_count == 1

@ddt.data(
(None, False),
(datetime.datetime.now(pytz.UTC) + datetime.timedelta(days=10), False),
(datetime.datetime.now(pytz.UTC) - datetime.timedelta(days=10), True),
datetime.datetime.now(pytz.UTC) - datetime.timedelta(days=10),
datetime.datetime.now(pytz.UTC) - datetime.timedelta(days=20),
)
@ddt.unpack
@mock.patch('course_discovery.apps.course_metadata.emails.send_email_for_reviewed')
@mock.patch('course_discovery.apps.course_metadata.emails.send_email_for_course_url')
def test_reviewed_with_go_live_date_along_with_watchers_email(
self, when, published, mock_course_url_email, mock_email
def test_reviewed_with_go_live_date_along_with_watchers_email_when_course_is_published(
self, when, mock_course_url_email, mock_email
):
"""
Test that watchers are emailed when a course is reviewed and has a go live date
Test that watchers are emailed when a course is published
"""
draft = factories.CourseRunFactory(
draft_course_run = factories.CourseRunFactory(
draft=True,
go_live_date=when,
announcement=None,
)
end = when + datetime.timedelta(days=50) if when else None
if end: # Both end and enrollment_end need to be in the future or else runs will be set to unpublished
draft.end = end
draft.enrollment_end = end
draft.course.draft = True
draft.course.watchers = [
draft_course_run.end = end
draft_course_run.enrollment_end = end
draft_course_run.course.draft = True
draft_course_run.course.watchers = [
'[email protected]',
]
draft.course.save()
draft_course_run.course.save()

# force this prop to be cached, to catch any errors if we assume .official_version is valid after creation
assert draft.official_version is None
assert draft_course_run.official_version is None

draft.status = CourseRunStatus.Reviewed
draft.save()
draft.refresh_from_db()
official_version = CourseRun.objects.get(key=draft.key)
draft_course_run.status = CourseRunStatus.Reviewed
draft_course_run.save()
draft_course_run.refresh_from_db()
official_version = CourseRun.objects.get(key=draft_course_run.key)

for run in [draft, official_version]:
if published:
assert run.status == CourseRunStatus.Published
assert run.announcement is not None
assert mock_course_url_email.call_count == 1
assert mock_email.call_count == 0
else:
assert run.status == CourseRunStatus.Reviewed
assert run.announcement is None
assert mock_email.call_count == 1
assert mock_course_url_email.call_count == 1
for run in [draft_course_run, official_version]:
assert run.status == CourseRunStatus.Published
assert run.announcement is not None
assert mock_course_url_email.call_count == 1
assert mock_email.call_count == 0

@ddt.data(None, datetime.datetime.now(pytz.UTC) + datetime.timedelta(days=10))
@mock.patch('course_discovery.apps.course_metadata.emails.send_email_for_reviewed')
@mock.patch('course_discovery.apps.course_metadata.emails.send_email_for_course_url')
def test_reviewed_with_go_live_date_along_with_watchers_email_when_course_run_is_scheduled(
self, when, mock_course_url_email, mock_email
):
"""
Test that watchers are emailed when a course is reviewed
"""
draft_course_run = factories.CourseRunFactory(
draft=True,
go_live_date=when,
announcement=None,
)
end = when + datetime.timedelta(days=50) if when else None
if end: # Both end and enrollment_end need to be in the future or else runs will be set to unpublished
draft_course_run.end = end
draft_course_run.enrollment_end = end
draft_course_run.course.draft = True
draft_course_run.course.watchers = [
'[email protected]',
]
draft_course_run.course.save()

assert draft_course_run.official_version is None

draft_course_run.status = CourseRunStatus.Reviewed
draft_course_run.save()
draft_course_run.refresh_from_db()
official_version = CourseRun.objects.get(key=draft_course_run.key)

for run in [draft_course_run, official_version]:
assert run.status == CourseRunStatus.Reviewed
assert run.announcement is None
assert mock_email.call_count == 1
assert mock_course_url_email.call_count == 1

def test_publish_ignores_draft_input(self):
draft = factories.CourseRunFactory(status=CourseRunStatus.Unpublished, draft=True)
Expand Down

0 comments on commit e540265

Please sign in to comment.