diff --git a/lms/djangoapps/verify_student/api.py b/lms/djangoapps/verify_student/api.py index c974fa0c8e5f..034a6002f954 100644 --- a/lms/djangoapps/verify_student/api.py +++ b/lms/djangoapps/verify_student/api.py @@ -5,6 +5,7 @@ from django.utils.translation import gettext as _ from lms.djangoapps.verify_student.emails import send_verification_approved_email +from lms.djangoapps.verify_student.models import VerificationAttempt from lms.djangoapps.verify_student.tasks import send_verification_status_email @@ -33,3 +34,42 @@ def send_approval_email(attempt): else: email_context = {'user': attempt.user, 'expiration_datetime': expiration_datetime.strftime("%m/%d/%Y")} send_verification_approved_email(context=email_context) + + +def create_verification_attempt(user, name, status, expiration_datetime=None): + """ + Create a verification attempt. + + Args: + user (User): the user (usually a learner) performing the verfication attempt + name (string): the name of the user + status (string): the initial status of the verification attempt + expiration_datetime (datetime, optional): When the verification attempt expires. Defaults to None. + + Returns: + VerificationAttempt (VerificationAttempt): The created VerificationAttempt instance + """ + verification_attempt = VerificationAttempt.objects.create( + user=user, + name=name, + status=status, + expiration_datetime=expiration_datetime, + ) + + return verification_attempt.id + + +def update_verification_status(attempt_id, status): + """ + Update the VerificationAttempt status. + + Arguments: + * id (str): the verification attempt id + * status (str): the new status + + Returns: + * None + """ + attempt = VerificationAttempt.objects.get(id=attempt_id) + attempt.status = status + attempt.save() diff --git a/lms/djangoapps/verify_student/management/commands/approve_id_verifications.py b/lms/djangoapps/verify_student/management/commands/approve_id_verifications.py index b87b2eee4559..6d505618bcb3 100644 --- a/lms/djangoapps/verify_student/management/commands/approve_id_verifications.py +++ b/lms/djangoapps/verify_student/management/commands/approve_id_verifications.py @@ -8,7 +8,7 @@ import time from pprint import pformat -from django.contrib.auth.models import User # lint-amnesty, pylint: disable=imported-auth-user +from django.contrib.auth.models import User # lint-amnesty, pylint: disable=imported-auth-user, unused-import from django.core.management.base import BaseCommand, CommandError from lms.djangoapps.verify_student.api import send_approval_email diff --git a/lms/djangoapps/verify_student/tests/test_api.py b/lms/djangoapps/verify_student/tests/test_api.py index acdebaa70c1c..4f5f42aedc04 100644 --- a/lms/djangoapps/verify_student/tests/test_api.py +++ b/lms/djangoapps/verify_student/tests/test_api.py @@ -3,14 +3,20 @@ """ from unittest.mock import patch +from datetime import datetime, timezone 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 +from lms.djangoapps.verify_student.api import ( + create_verification_attempt, + send_approval_email, + update_verification_status, +) +from lms.djangoapps.verify_student.models import SoftwareSecurePhotoVerification, VerificationAttempt +from lms.djangoapps.verify_student.statuses import VerificationAttemptStatus @ddt.ddt @@ -18,6 +24,7 @@ class TestSendApprovalEmail(TestCase): """ Test cases for the send_approval_email API method. """ + def setUp(self): super().setUp() @@ -41,3 +48,77 @@ 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) + + +@ddt.ddt +class CreateVerificationAttempt(TestCase): + """ + Test cases for the send_approval_email API method. + """ + + def setUp(self): + super().setUp() + + self.user = UserFactory.create() + self.attempt = VerificationAttempt( + user=self.user, + name='Tester McTest', + status=VerificationAttemptStatus.created, + expiration_datetime=datetime(2024, 12, 31, tzinfo=timezone.utc) + ) + self.attempt.save() + + def test_create_verification_attempt(self): + expected_id = 2 + self.assertEqual( + create_verification_attempt( + user=self.user, + name='Tester McTest', + status=VerificationAttemptStatus.created, + expiration_datetime=datetime(2024, 12, 31, tzinfo=timezone.utc) + ), + expected_id + ) + verification_attempt = VerificationAttempt.objects.get(id=expected_id) + + self.assertEqual(verification_attempt.user, self.user) + self.assertEqual(verification_attempt.name, 'Tester McTest') + self.assertEqual(verification_attempt.status, VerificationAttemptStatus.created) + self.assertEqual(verification_attempt.expiration_datetime, datetime(2024, 12, 31, tzinfo=timezone.utc)) + + +@ddt.ddt +class UpdateVerificationStatus(TestCase): + """ + Test cases for the update_verification_status API method. + """ + + def setUp(self): + super().setUp() + + self.user= UserFactory.create() + self.attempt= VerificationAttempt( + user=self.user, + name='Tester McTest', + status=VerificationAttemptStatus.created, + expiration_datetime=datetime(2024, 12, 31, tzinfo=timezone.utc) + ) + self.attempt.save() + + @ddt.data( + VerificationAttemptStatus.pending, + VerificationAttemptStatus.approved, + VerificationAttemptStatus.denied, + ) + def test_update_verification_status(self, to_status): + update_verification_status(attempt_id=self.attempt.id, status=to_status) + + verification_attempt = VerificationAttempt.objects.get(id=self.attempt.id) + + # These are fields whose values should not change as a result of this update. + self.assertEqual(verification_attempt.user, self.user) + self.assertEqual(verification_attempt.name, 'Tester McTest') + self.assertEqual(verification_attempt.expiration_datetime, datetime(2024, 12, 31, tzinfo=timezone.utc)) + + # This field's value should change as a result of this update. + self.assertEqual(verification_attempt.status, to_status)