From 537ae9fcea979c023b25d0e4dc2c30cc7b9b49a2 Mon Sep 17 00:00:00 2001 From: alangsto <46360176+alangsto@users.noreply.github.com> Date: Mon, 15 Nov 2021 14:43:04 -0500 Subject: [PATCH] fix: latest IDV expiration date should be returned (#29320) The lack of ordering for a django query that grabbed verification records is blocking learners with multiple SSO records from taking proctored exams. All IDV records should be sorted by a key first, and then the correct expiration date can be determined. --- lms/djangoapps/verify_student/services.py | 10 ++++++---- .../verify_student/tests/test_services.py | 18 +++++++++++++++++- 2 files changed, 23 insertions(+), 5 deletions(-) diff --git a/lms/djangoapps/verify_student/services.py b/lms/djangoapps/verify_student/services.py index 768162f587..7059102152 100644 --- a/lms/djangoapps/verify_student/services.py +++ b/lms/djangoapps/verify_student/services.py @@ -116,15 +116,17 @@ class IDVerificationService: 'status__in': statuses, } - photo_id_verifications = SoftwareSecurePhotoVerification.objects.filter(**filter_kwargs) - sso_id_verifications = SSOVerification.objects.filter(**filter_kwargs) - manual_id_verifications = ManualVerification.objects.filter(**filter_kwargs) + sort_by = 'updated_at' + + photo_id_verifications = SoftwareSecurePhotoVerification.objects.filter(**filter_kwargs).order_by('-' + sort_by) + sso_id_verifications = SSOVerification.objects.filter(**filter_kwargs).order_by('-' + sort_by) + manual_id_verifications = ManualVerification.objects.filter(**filter_kwargs).order_by('-' + sort_by) attempt = most_recent_verification( photo_id_verifications, sso_id_verifications, manual_id_verifications, - 'updated_at' + sort_by ) return attempt and attempt.expiration_datetime diff --git a/lms/djangoapps/verify_student/tests/test_services.py b/lms/djangoapps/verify_student/tests/test_services.py index eeeca1f5e6..bf83f1e9ef 100644 --- a/lms/djangoapps/verify_student/tests/test_services.py +++ b/lms/djangoapps/verify_student/tests/test_services.py @@ -2,7 +2,7 @@ Tests for the service classes in verify_student. """ -from datetime import datetime, timedelta +from datetime import datetime, timedelta, timezone from unittest.mock import patch import ddt @@ -140,6 +140,22 @@ class TestIDVerificationService(ModuleStoreTestCase): expected_path = f'{settings.ACCOUNT_MICROFRONTEND_URL}/id-verification' assert path == (expected_path + '?course_id=course-v1%3AedX%2BDemoX%2BDemo_Course') + def test_get_expiration_datetime(self): + """ + Test that the latest expiration datetime is returned if there are multiple records + """ + user_a = UserFactory.create() + + SSOVerification.objects.create( + user=user_a, status='approved', expiration_date=datetime(2021, 11, 12, 0, 0, tzinfo=timezone.utc) + ) + newer_record = SSOVerification.objects.create( + user=user_a, status='approved', expiration_date=datetime(2022, 1, 12, 0, 0, tzinfo=timezone.utc) + ) + + expiration_datetime = IDVerificationService.get_expiration_datetime(user_a, ['approved']) + assert expiration_datetime == newer_record.expiration_datetime + @patch.dict(settings.VERIFY_STUDENT, FAKE_SETTINGS) @ddt.ddt