Merge pull request #34875 from openedx/michaelroytman/COSMO-310-idv-approval-email-in-command
Send IDV approval email in approve_id_verifications management command
This commit is contained in:
@@ -0,0 +1,35 @@
|
||||
"""
|
||||
API module.
|
||||
"""
|
||||
from django.conf import settings
|
||||
from django.utils.translation import gettext as _
|
||||
|
||||
from lms.djangoapps.verify_student.emails import send_verification_approved_email
|
||||
from lms.djangoapps.verify_student.tasks import send_verification_status_email
|
||||
|
||||
|
||||
def send_approval_email(attempt):
|
||||
"""
|
||||
Send an approval email to the learner associated with the IDV attempt.
|
||||
"""
|
||||
verification_status_email_vars = {
|
||||
'platform_name': settings.PLATFORM_NAME,
|
||||
}
|
||||
|
||||
expiration_datetime = attempt.expiration_datetime.date()
|
||||
if settings.VERIFY_STUDENT.get('USE_DJANGO_MAIL'):
|
||||
verification_status_email_vars['expiration_datetime'] = expiration_datetime.strftime("%m/%d/%Y")
|
||||
verification_status_email_vars['full_name'] = attempt.user.profile.name
|
||||
subject = _("Your {platform_name} ID verification was approved!").format(
|
||||
platform_name=settings.PLATFORM_NAME
|
||||
)
|
||||
context = {
|
||||
'subject': subject,
|
||||
'template': 'emails/passed_verification_email.txt',
|
||||
'email': attempt.user.email,
|
||||
'email_vars': verification_status_email_vars
|
||||
}
|
||||
send_verification_status_email.delay(context)
|
||||
else:
|
||||
email_context = {'user': attempt.user, 'expiration_datetime': expiration_datetime.strftime("%m/%d/%Y")}
|
||||
send_verification_approved_email(context=email_context)
|
||||
|
||||
@@ -11,6 +11,7 @@ from pprint import pformat
|
||||
from django.contrib.auth.models import User # lint-amnesty, pylint: disable=imported-auth-user
|
||||
from django.core.management.base import BaseCommand, CommandError
|
||||
|
||||
from lms.djangoapps.verify_student.api import send_approval_email
|
||||
from lms.djangoapps.verify_student.models import SoftwareSecurePhotoVerification
|
||||
from lms.djangoapps.verify_student.utils import earliest_allowed_verification_date
|
||||
|
||||
@@ -125,8 +126,8 @@ class Command(BaseCommand):
|
||||
|
||||
def _approve_id_verifications(self, user_ids):
|
||||
"""
|
||||
This command manually approves ID verification attempts for a provided set of learners whose ID verification
|
||||
attempt is in the submitted or must_retry state.
|
||||
This method manually approves ID verification attempts for a provided set of user IDs so long as the attempt
|
||||
is in the submitted or must_retry state. This method also send an IDV approval email to the user.
|
||||
|
||||
Arguments:
|
||||
user_ids (list): user IDs of the users whose ID verification attempt should be manually approved
|
||||
@@ -148,5 +149,6 @@ class Command(BaseCommand):
|
||||
|
||||
for verification in existing_id_verifications:
|
||||
verification.approve(service='idv_verifications command')
|
||||
send_approval_email(verification)
|
||||
|
||||
return list(failed_user_ids)
|
||||
|
||||
@@ -8,6 +8,7 @@ import os
|
||||
import tempfile
|
||||
|
||||
import pytest
|
||||
from django.core import mail
|
||||
from django.core.management import CommandError, call_command
|
||||
from django.test import TestCase
|
||||
from testfixtures import LogCapture
|
||||
@@ -70,6 +71,35 @@ class TestApproveIDVerificationsCommand(TestCase):
|
||||
|
||||
assert SoftwareSecurePhotoVerification.objects.filter(status='approved').count() == 3
|
||||
|
||||
@ddt.data('submitted', 'must_retry')
|
||||
def test_approve_id_verifications_email(self, status):
|
||||
"""
|
||||
Tests that the approve_id_verifications management command correctly sends approval emails.
|
||||
"""
|
||||
# Create SoftwareSecurePhotoVerification instances for the users.
|
||||
for user in [self.user1_profile, self.user2_profile]:
|
||||
SoftwareSecurePhotoVerification.objects.create(
|
||||
user=user.user,
|
||||
name=user.name,
|
||||
status=status,
|
||||
)
|
||||
SoftwareSecurePhotoVerification.objects.create(
|
||||
user=self.user3_profile.user,
|
||||
name=self.user3_profile.name,
|
||||
status='denied',
|
||||
)
|
||||
|
||||
call_command('approve_id_verifications', self.tmp_file_path)
|
||||
|
||||
assert len(mail.outbox) == 2
|
||||
|
||||
# All three emails should have equal expiration dates, so just pick one from an attempt.
|
||||
expiration_date = SoftwareSecurePhotoVerification.objects.first().expiration_datetime
|
||||
for email in mail.outbox:
|
||||
assert email.subject == 'Your édX ID verification was approved!'
|
||||
assert 'Your édX ID verification photos have been approved' in email.body
|
||||
assert expiration_date.strftime("%m/%d/%Y") in email.body
|
||||
|
||||
def test_user_does_not_exist_log(self):
|
||||
"""
|
||||
Tests that the approve_id_verifications management command logs an error when an invalid user ID is
|
||||
|
||||
43
lms/djangoapps/verify_student/tests/test_api.py
Normal file
43
lms/djangoapps/verify_student/tests/test_api.py
Normal file
@@ -0,0 +1,43 @@
|
||||
"""
|
||||
Tests of API module.
|
||||
"""
|
||||
from unittest.mock import patch
|
||||
|
||||
import ddt
|
||||
from django.conf import settings
|
||||
from django.core import mail
|
||||
from django.test import TestCase
|
||||
|
||||
from common.djangoapps.student.tests.factories import UserFactory
|
||||
from lms.djangoapps.verify_student.api import send_approval_email
|
||||
from lms.djangoapps.verify_student.models import SoftwareSecurePhotoVerification
|
||||
|
||||
|
||||
@ddt.ddt
|
||||
class TestSendApprovalEmail(TestCase):
|
||||
"""
|
||||
Test cases for the send_approval_email API method.
|
||||
"""
|
||||
def setUp(self):
|
||||
super().setUp()
|
||||
|
||||
self.user = UserFactory.create()
|
||||
self.attempt = SoftwareSecurePhotoVerification(
|
||||
status="submitted",
|
||||
user=self.user
|
||||
)
|
||||
self.attempt.save()
|
||||
|
||||
def _assert_verification_approved_email(self, expiration_date):
|
||||
"""Check that a verification approved email was sent."""
|
||||
assert len(mail.outbox) == 1
|
||||
email = mail.outbox[0]
|
||||
assert email.subject == 'Your édX ID verification was approved!'
|
||||
assert 'Your édX ID verification photos have been approved' in email.body
|
||||
assert expiration_date.strftime("%m/%d/%Y") in email.body
|
||||
|
||||
@ddt.data(True, False)
|
||||
def test_send_approval(self, use_ace):
|
||||
with patch.dict(settings.VERIFY_STUDENT, {'USE_DJANGO_MAIL': use_ace}):
|
||||
send_approval_email(self.attempt)
|
||||
self._assert_verification_approved_email(self.attempt.expiration_datetime)
|
||||
@@ -36,7 +36,8 @@ from common.djangoapps.util.db import outer_atomic
|
||||
from common.djangoapps.util.json_request import JsonResponse
|
||||
from common.djangoapps.util.views import require_global_staff
|
||||
from lms.djangoapps.commerce.utils import EcommerceService, is_account_activation_requirement_disabled
|
||||
from lms.djangoapps.verify_student.emails import send_verification_approved_email, send_verification_confirmation_email
|
||||
from lms.djangoapps.verify_student.api import send_approval_email
|
||||
from lms.djangoapps.verify_student.emails import send_verification_confirmation_email
|
||||
from lms.djangoapps.verify_student.image import InvalidImageData, decode_image_data
|
||||
from lms.djangoapps.verify_student.models import SoftwareSecurePhotoVerification, VerificationDeadline
|
||||
from lms.djangoapps.verify_student.tasks import send_verification_status_email
|
||||
@@ -1117,24 +1118,7 @@ def results_callback(request): # lint-amnesty, pylint: disable=too-many-stateme
|
||||
log.info("[COSMO-184] Approved verification for receipt_id={receipt_id}.".format(receipt_id=receipt_id))
|
||||
attempt.approve()
|
||||
|
||||
expiration_datetime = attempt.expiration_datetime.date()
|
||||
if settings.VERIFY_STUDENT.get('USE_DJANGO_MAIL'):
|
||||
verification_status_email_vars['expiration_datetime'] = expiration_datetime.strftime("%m/%d/%Y")
|
||||
verification_status_email_vars['full_name'] = user.profile.name
|
||||
subject = _("Your {platform_name} ID verification was approved!").format(
|
||||
platform_name=settings.PLATFORM_NAME
|
||||
)
|
||||
context = {
|
||||
'subject': subject,
|
||||
'template': 'emails/passed_verification_email.txt',
|
||||
'email': user.email,
|
||||
'email_vars': verification_status_email_vars
|
||||
}
|
||||
send_verification_status_email.delay(context)
|
||||
else:
|
||||
email_context = {'user': user, 'expiration_datetime': expiration_datetime.strftime("%m/%d/%Y")}
|
||||
send_verification_approved_email(context=email_context)
|
||||
|
||||
send_approval_email(attempt)
|
||||
elif result == "FAIL":
|
||||
log.debug("Denying verification for %s", receipt_id)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user