From 424e1f5b3c707f11548570c724c50bf626a36926 Mon Sep 17 00:00:00 2001 From: Awais Date: Wed, 3 Jun 2015 15:16:03 +0500 Subject: [PATCH] ECOM-1572 implementing code to new branch. --- .../verify_student/tests/test_views.py | 193 ++++++++++-------- lms/djangoapps/verify_student/views.py | 26 ++- .../emails/reverification_processed.txt | 53 ++--- 3 files changed, 146 insertions(+), 126 deletions(-) diff --git a/lms/djangoapps/verify_student/tests/test_views.py b/lms/djangoapps/verify_student/tests/test_views.py index 265d736c04..cabfa9c632 100644 --- a/lms/djangoapps/verify_student/tests/test_views.py +++ b/lms/djangoapps/verify_student/tests/test_views.py @@ -20,15 +20,17 @@ from django.core.urlresolvers import reverse from django.core.exceptions import ObjectDoesNotExist from django.core import mail from django.test import TestCase -from django.test.client import Client +from django.test.client import Client, RequestFactory from django.test.utils import override_settings from django.utils import timezone from opaque_keys.edx.locations import SlashSeparatedCourseKey from opaque_keys.edx.locator import CourseLocator +from opaque_keys.edx.keys import UsageKey from course_modes.models import CourseMode from course_modes.tests.factories import CourseModeFactory +from courseware.url_helpers import get_redirect_url from commerce.tests import TEST_PAYMENT_DATA, TEST_API_URL, TEST_API_SIGNING_KEY from embargo.test_utils import restrict_course from microsite_configuration import microsite @@ -1891,6 +1893,7 @@ class TestEmailMessageWithCustomICRVBlock(ModuleStoreTestCase): self.course_key = SlashSeparatedCourseKey("Robot", "999", "Test_Course") self.course = CourseFactory.create(org='Robot', number='999', display_name='Test Course') self.due_date = datetime(2015, 6, 22, tzinfo=pytz.UTC) + self.allowed_attempts = 1 # Create the course modes for mode in ('audit', 'honor', 'verified'): @@ -1906,7 +1909,7 @@ class TestEmailMessageWithCustomICRVBlock(ModuleStoreTestCase): parent=vertical, category='edx-reverification-block', display_name='Test Verification Block', - metadata={'attempts': 3, 'due': self.due_date} + metadata={'attempts': self.allowed_attempts, 'due': self.due_date} ) self.section_location = section.location @@ -1940,73 +1943,148 @@ class TestEmailMessageWithCustomICRVBlock(ModuleStoreTestCase): status='submitted' ) self.attempt = SoftwareSecurePhotoVerification.objects.filter(user=self.user) + location_id = VerificationStatus.get_location_id(self.attempt) + usage_key = UsageKey.from_string(location_id) + redirect_url = get_redirect_url(self.course_key, usage_key.replace(course_key=self.course_key)) + self.request = RequestFactory().get('/url') + self.course_link = self.request.build_absolute_uri(redirect_url) def test_approved_email_message(self): - """ - Test email message for approved photo verification. - """ + subject, body = _compose_message_reverification_email( - self.course.id, self.user.id, self.reverification_location, "approved", True + self.course.id, self.user.id, self.reverification_location, "approved", self.request ) self.assertIn( - "Your verification for course {course_name} and assessment {assessment} has been passed.".format( - course_name=self.course.display_name_with_default, - assessment=self.assessment + "We have successfully verified your identity for the {assessment} " + "assessment in the {course_name} course.".format( + assessment=self.assessment, + course_name=self.course.display_name_with_default ), body ) + + self.check_courseware_link_exists(body) self.assertIn("Re-verification Status", subject) def test_denied_email_message_with_valid_due_date_and_attempts_allowed(self): - __, body = _compose_message_reverification_email( - self.course.id, self.user.id, self.reverification_location, "denied", True + subject, body = _compose_message_reverification_email( + self.course.id, self.user.id, self.reverification_location, "denied", self.request ) self.assertIn( - "Your verification for course {course_name} and assessment {assessment} has failed.".format( + "We could not verify your identity for the {assessment} assessment " + "in the {course_name} course. You have used " + "{used_attempts} out of {allowed_attempts} attempts to " + "verify your identity.".format( course_name=self.course.display_name_with_default, - assessment=self.assessment + assessment=self.assessment, + used_attempts=1, + allowed_attempts=self.allowed_attempts + 1 ), body ) - self.assertIn("Assessment closes on {due_date}".format(due_date=get_default_time_display(self.due_date)), body) - self.assertIn("Click on link below to re-verify", body) self.assertIn( - "https://{}{}".format( - microsite.get_value('SITE_NAME', 'localhost'), self.re_verification_link + "You must verify your identity before the assessment " + "closes on {due_date}".format( + due_date=get_default_time_display(self.due_date) ), body ) + reverify_link = self.request.build_absolute_uri(self.re_verification_link) + self.assertIn( + "To try to verify your identity again, select the following link:", + body + ) + + self.assertIn(reverify_link, body) + self.assertIn("Re-verification Status", subject) + + def test_denied_email_message_with_due_date_and_no_attempts(self): + """ Denied email message if due date is still open but user has no + attempts available. + """ + + VerificationStatus.add_verification_status( + checkpoint=self.check_point, + user=self.user, + status='submitted' + ) + + __, body = _compose_message_reverification_email( + self.course.id, self.user.id, self.reverification_location, "denied", self.request + ) + + self.assertIn( + "We could not verify your identity for the {assessment} assessment " + "in the {course_name} course. You have used " + "{used_attempts} out of {allowed_attempts} attempts to " + "verify your identity, and verification is no longer " + "possible".format( + course_name=self.course.display_name_with_default, + assessment=self.assessment, + used_attempts=2, + allowed_attempts=self.allowed_attempts + 1 + ), + body + ) + + self.check_courseware_link_exists(body) def test_denied_email_message_with_close_verification_dates(self): + # Due date given and expired return_value = datetime(2016, 1, 1, tzinfo=timezone.utc) with patch.object(timezone, 'now', return_value=return_value): __, body = _compose_message_reverification_email( - self.course.id, self.user.id, self.reverification_location, "denied", True + self.course.id, self.user.id, self.reverification_location, "denied", self.request ) self.assertIn( - "Your verification for course {course_name} and assessment {assessment} has failed.".format( + "We could not verify your identity for the {assessment} assessment " + "in the {course_name} course. You have used " + "{used_attempts} out of {allowed_attempts} attempts to " + "verify your identity, and verification is no longer " + "possible".format( course_name=self.course.display_name_with_default, - assessment=self.assessment + assessment=self.assessment, + used_attempts=1, + allowed_attempts=self.allowed_attempts + 1 ), body ) - self.assertIn("Assessment date has passed and retake not allowed", body) - def test_check_num_queries(self): # Get the re-verification block to check the call made - with check_mongo_calls(2): + with check_mongo_calls(1): ver_block = modulestore().get_item(self.reverification.location) # Expect that the verification block is fetched self.assertIsNotNone(ver_block) + def check_courseware_link_exists(self, body): + """Checking courseware url and signature information of EDX""" + self.assertIn( + "To go to the courseware, select the following link:", + body + ) + self.assertIn( + "{course_link}".format( + course_link=self.course_link + ), + body + ) + + self.assertIn("Thanks,", body) + self.assertIn( + "The {platform_name} team".format( + platform_name=settings.PLATFORM_NAME + ), + body + ) + class TestEmailMessageWithDefaultICRVBlock(ModuleStoreTestCase): """ @@ -2059,6 +2137,7 @@ class TestEmailMessageWithDefaultICRVBlock(ModuleStoreTestCase): ) self.check_point.add_verification_attempt(SoftwareSecurePhotoVerification.objects.create(user=self.user)) self.attempt = SoftwareSecurePhotoVerification.objects.filter(user=self.user) + self.request = RequestFactory().get('/url') def test_denied_email_message_with_no_attempt_allowed(self): @@ -2069,73 +2148,25 @@ class TestEmailMessageWithDefaultICRVBlock(ModuleStoreTestCase): ) __, body = _compose_message_reverification_email( - self.course.id, self.user.id, self.reverification_location, "denied", True + self.course.id, self.user.id, self.reverification_location, "denied", self.request ) self.assertIn( - "Your verification for course {course_name} and assessment {assessment} has failed.".format( + "We could not verify your identity for the {assessment} assessment " + "in the {course_name} course. You have used " + "{used_attempts} out of {allowed_attempts} attempts to " + "verify your identity, and verification is no longer " + "possible".format( course_name=self.course.display_name_with_default, - assessment=self.assessment - ), - body - ) - - self.assertIn("You have reached your allowed attempts limit. No more retakes allowed.", body) - - def test_due_date(self): - self.reverification.due = datetime.now() - self.reverification.save() - - VerificationStatus.add_verification_status( - checkpoint=self.check_point, - user=self.user, - status='submitted' - ) - __, body = _compose_message_reverification_email( - self.course.id, self.user.id, self.reverification_location, "denied", True - ) - - self.assertIn( - "Your verification for course {course_name} and assessment {assessment} has failed.".format( - course_name=self.course.display_name_with_default, - assessment=self.assessment - ), - body - ) - - self.assertIn("You have reached your allowed attempts limit. No more retakes allowed.", body) - - def test_denied_email_message_with_no_due_date(self): - - VerificationStatus.add_verification_status( - checkpoint=self.check_point, - user=self.user, - status='error' - ) - - __, body = _compose_message_reverification_email( - self.course.id, self.user.id, self.reverification_location, "denied", True - ) - - self.assertIn( - "Your verification for course {course_name} and assessment {assessment} has failed.".format( - course_name=self.course.display_name_with_default, - assessment=self.assessment - ), - body - ) - - self.assertIn("Assessment is open and you have 1 attempt(s) remaining.", body) - self.assertIn("Click on link below to re-verify", body) - self.assertIn( - "https://{}{}".format( - microsite.get_value('SITE_NAME', 'localhost'), self.re_verification_link + assessment=self.assessment, + used_attempts=1, + allowed_attempts=1 ), body ) def test_error_on_compose_email(self): resp = _compose_message_reverification_email( - self.course.id, self.user.id, u'i4x://edX/DemoX/edx-reverification-block/invalid_location', "denied", True + self.course.id, self.user.id, self.reverification_location, "denied", True ) self.assertIsNone(resp) diff --git a/lms/djangoapps/verify_student/views.py b/lms/djangoapps/verify_student/views.py index 26a7392c66..0345b39954 100644 --- a/lms/djangoapps/verify_student/views.py +++ b/lms/djangoapps/verify_student/views.py @@ -858,7 +858,7 @@ def submit_photos_for_verification(request): def _compose_message_reverification_email( - course_key, user_id, related_assessment_location, status, is_secure + course_key, user_id, related_assessment_location, status, request ): # pylint: disable=invalid-name """ Compose subject and message for photo reverification email. @@ -885,14 +885,13 @@ def _compose_message_reverification_email( context = { "status": status, "course_name": course.display_name_with_default, - "assessment": reverification_block.related_assessment, - "courseware_url": redirect_url + "assessment": reverification_block.related_assessment } # Allowed attempts is 1 if not set on verification block - allowed_attempts = 1 if reverification_block.attempts == 0 else reverification_block.attempts - user_attempts = VerificationStatus.get_user_attempts(user_id, course_key, related_assessment_location) - left_attempts = allowed_attempts - user_attempts + allowed_attempts = reverification_block.attempts + 1 + used_attempts = VerificationStatus.get_user_attempts(user_id, course_key, related_assessment_location) + left_attempts = allowed_attempts - used_attempts is_attempt_allowed = left_attempts > 0 verification_open = True if reverification_block.due: @@ -902,9 +901,11 @@ def _compose_message_reverification_email( context["is_attempt_allowed"] = is_attempt_allowed context["verification_open"] = verification_open context["due_date"] = get_default_time_display(reverification_block.due) - context["is_secure"] = is_secure - context["site"] = microsite.get_value('SITE_NAME', 'localhost') - context['platform_name'] = microsite.get_value('platform_name', settings.PLATFORM_NAME), + + context['platform_name'] = settings.PLATFORM_NAME + context["used_attempts"] = used_attempts + context["allowed_attempts"] = allowed_attempts + context["support_link"] = microsite.get_value('email_from_address', settings.CONTACT_EMAIL) re_verification_link = reverse( 'verify_student_incourse_reverify', @@ -913,7 +914,10 @@ def _compose_message_reverification_email( related_assessment_location ) ) - context["reverify_link"] = re_verification_link + + context["course_link"] = request.build_absolute_uri(redirect_url) + context["reverify_link"] = request.build_absolute_uri(re_verification_link) + message = render_to_string('emails/reverification_processed.txt', context) log.info( "Sending email to User_Id=%s. Attempts left for this user are %s. " @@ -1030,7 +1034,7 @@ def results_callback(request): related_assessment_location = checkpoints[0].checkpoint_location subject, message = _compose_message_reverification_email( - course_key, user_id, related_assessment_location, status, request.is_secure() + course_key, user_id, related_assessment_location, status, request ) _send_email(user_id, subject, message) diff --git a/lms/templates/emails/reverification_processed.txt b/lms/templates/emails/reverification_processed.txt index 762b2b9268..217df1d7ff 100644 --- a/lms/templates/emails/reverification_processed.txt +++ b/lms/templates/emails/reverification_processed.txt @@ -1,43 +1,28 @@ <%namespace file="../main.html" import="stanford_theme_enabled" /> <%! from django.utils.translation import ugettext as _ %> % if status == "approved": - ${_("Your verification for course {course_name} and assessment {assessment} " - "has been passed." - ).format(course_name=course_name, assessment=assessment)} +${_("We have successfully verified your identity for the {assessment} assessment in the {course_name} course." +).format(course_name=course_name, assessment=assessment)} -%else: - ${_("Your verification for course {course_name} and assessment {assessment} " - "has failed." - ).format(course_name=course_name, assessment=assessment)} +% elif is_attempt_allowed and verification_open: # if attempts are allowed and verification is still open. +${_("We could not verify your identity for the {assessment} assessment in the {course_name} course. You have used {used_attempts} out of {allowed_attempts} attempts to verify your identity." +).format(course_name=course_name, assessment=assessment, used_attempts=used_attempts, allowed_attempts=allowed_attempts)} +%if due_date: +${_("You must verify your identity before the assessment closes on {due_date}.").format(due_date=due_date)} +%endif - % if not is_attempt_allowed: - ${_("You have reached your allowed attempts limit. No more retakes allowed.")} - % elif not verification_open: - ${_("Assessment date has passed and retake not allowed.")} - % else: - % if due_date: - ${_("Assessment closes on {due_date}.".format(due_date=due_date))} - % else: - ${_("Assessment is open and you have {left_attempts} attempt(s) remaining.".format(left_attempts=left_attempts))} - % endif +${_("To try to verify your identity again, select the following link:")} +${reverify_link} - ${_("Click on link below to re-verify:")} - % if is_secure: - https://${ site }${ reverify_link } - % else: - http://${ site }${ reverify_link } - % endif +% elif not is_attempt_allowed or not verification_open: # if attempts are not allowed or verification window is closed +${_("We could not verify your identity for the {assessment} assessment in the {course_name} course. You have used {used_attempts} out of {allowed_attempts} attempts to verify your identity, and verification is no longer possible." +).format(course_name=course_name, assessment=assessment, used_attempts=used_attempts, allowed_attempts=allowed_attempts)} +%endif - % endif -% endif +${_("To go to the courseware, select the following link:")} +${course_link} - ${_("Click on link below to go to the courseware:")} - % if is_secure: - https://${ site }${ courseware_url } - % else: - http://${ site }${ courseware_url } - % endif +${_("If you have any questions, you can contact student support at {support_link}.").format(support_link=support_link)} - - -${_("The {platform_name} Team.").format(platform_name=platform_name)} +${_("Thanks,")} +${_("The {platform_name} team").format(platform_name=platform_name)}