From 9507a0a3f31c652561b6799d70f030a7bb725c64 Mon Sep 17 00:00:00 2001 From: Varsha Menon Date: Tue, 17 Dec 2024 16:41:48 -0500 Subject: [PATCH] fix: change course mode to course enrollment to calculate audit trial expired --- learning_assistant/api.py | 31 ++++++++++++------------- learning_assistant/views.py | 4 ++-- tests/test_api.py | 45 +++++++++++++++---------------------- 3 files changed, 36 insertions(+), 44 deletions(-) diff --git a/learning_assistant/api.py b/learning_assistant/api.py index 3f1ff5c..baa2ad2 100644 --- a/learning_assistant/api.py +++ b/learning_assistant/api.py @@ -3,7 +3,7 @@ """ import datetime import logging -from datetime import datetime, timedelta +from datetime import date, datetime, timedelta from django.conf import settings from django.contrib.auth import get_user_model @@ -12,11 +12,6 @@ from jinja2 import BaseLoader, Environment from opaque_keys import InvalidKeyError -try: - from common.djangoapps.course_modes.models import CourseMode -except ImportError: - CourseMode = None - from learning_assistant.constants import ACCEPTED_CATEGORY_TYPES, CATEGORY_TYPE_MAP from learning_assistant.data import LearningAssistantAuditTrialData, LearningAssistantCourseEnabledData from learning_assistant.models import ( @@ -307,19 +302,25 @@ def get_or_create_audit_trial(user): ) -def audit_trial_is_expired(audit_trial_data, courserun_key): - """ - Given a user (User), get or create the corresponding LearningAssistantAuditTrial trial object. +def audit_trial_is_expired(enrollment, audit_trial_data): """ - course_mode = CourseMode.objects.get(course=courserun_key) + Given an enrollment and audit_trial_data, return whether the audit trial is expired as a boolean. + + Arguments: + * enrollment (CourseEnrollment): the user course enrollment + * audit_trial_data (LearningAssistantAuditTrialData): the data related to the audit trial - upgrade_deadline = course_mode.expiration_datetime() + Returns: + * audit_trial_is_expired (boolean): whether the audit trial is expired + """ + upgrade_deadline = enrollment.upgrade_deadline + today = date.today() # If the upgrade deadline has passed, return True for expired. Upgrade deadline is an optional attribute of a - # CourseMode, so if it's None, then do not return True. - days_until_upgrade_deadline = datetime.now() - upgrade_deadline if upgrade_deadline else None - if days_until_upgrade_deadline is not None and days_until_upgrade_deadline >= timedelta(days=0): + # CourseEnrollment, so if it's None, then do not return True. + days_until_upgrade_deadline = (today - upgrade_deadline.date()).days if upgrade_deadline else None + if days_until_upgrade_deadline is not None and days_until_upgrade_deadline >= 0: return True # If the user's trial is past its expiry date, return True for expired. Else, return False. - return audit_trial_data is None or audit_trial_data.expiration_date <= datetime.now() + return audit_trial_data is None or audit_trial_data.expiration_date.date() <= today diff --git a/learning_assistant/views.py b/learning_assistant/views.py index 87d5713..77eda79 100644 --- a/learning_assistant/views.py +++ b/learning_assistant/views.py @@ -156,7 +156,7 @@ def post(self, request, course_run_id): # next message. Otherwise, return 403 elif enrollment_mode in CourseMode.UPSELL_TO_VERIFIED_MODES: # AUDIT, HONOR audit_trial = get_or_create_audit_trial(request.user) - is_user_audit_trial_expired = audit_trial_is_expired(audit_trial, courserun_key) + is_user_audit_trial_expired = audit_trial_is_expired(enrollment_object, audit_trial) if is_user_audit_trial_expired: return Response( status=http_status.HTTP_403_FORBIDDEN, @@ -383,7 +383,7 @@ def get(self, request, course_run_id): has_trial_access = ( enrollment_mode in valid_trial_access_modes and audit_trial - and not audit_trial_is_expired(audit_trial, courserun_key) + and not audit_trial_is_expired(enrollment_object, audit_trial) ) if ( diff --git a/tests/test_api.py b/tests/test_api.py index 3937856..0623201 100644 --- a/tests/test_api.py +++ b/tests/test_api.py @@ -599,12 +599,9 @@ def setUp(self): self.upgrade_deadline = datetime.now() + timedelta(days=1) # 1 day from now @freeze_time('2024-01-01') - @patch('learning_assistant.api.CourseMode') - def test_upgrade_deadline_expired(self, mock_course_mode): - - mock_mode = MagicMock() - mock_mode.expiration_datetime.return_value = datetime.now() - timedelta(days=1) # yesterday - mock_course_mode.objects.get.return_value = mock_mode + def test_upgrade_deadline_expired(self): + mock_enrollment = MagicMock() + mock_enrollment.upgrade_deadline = datetime.now() - timedelta(days=1) # yesterday start_date = datetime.now() audit_trial_data = LearningAssistantAuditTrialData( @@ -613,17 +610,15 @@ def test_upgrade_deadline_expired(self, mock_course_mode): expiration_date=start_date + timedelta(days=settings.LEARNING_ASSISTANT_AUDIT_TRIAL_LENGTH_DAYS), ) - self.assertEqual(audit_trial_is_expired(audit_trial_data, self.course_key), True) + self.assertEqual(audit_trial_is_expired(mock_enrollment, audit_trial_data), True) @freeze_time('2024-01-01') - @patch('learning_assistant.api.CourseMode') - def test_upgrade_deadline_none(self, mock_course_mode): + def test_upgrade_deadline_none(self): - mock_mode = MagicMock() - mock_mode.expiration_datetime.return_value = None - mock_course_mode.objects.get.return_value = mock_mode + mock_enrollment = MagicMock() + mock_enrollment.upgrade_deadline = None - # Verify that the audit trial data is considered when determing whether an audit trial is expired and not the + # Verify that the audit trial data is considered when determining whether an audit trial is expired and not the # upgrade deadline. start_date = datetime.now() audit_trial_data = LearningAssistantAuditTrialData( @@ -632,7 +627,7 @@ def test_upgrade_deadline_none(self, mock_course_mode): expiration_date=start_date + timedelta(days=settings.LEARNING_ASSISTANT_AUDIT_TRIAL_LENGTH_DAYS), ) - self.assertEqual(audit_trial_is_expired(audit_trial_data, self.course_key), False) + self.assertEqual(audit_trial_is_expired(mock_enrollment, audit_trial_data), False) start_date = datetime.now() - timedelta(days=settings.LEARNING_ASSISTANT_AUDIT_TRIAL_LENGTH_DAYS + 1) audit_trial_data = LearningAssistantAuditTrialData( @@ -641,7 +636,7 @@ def test_upgrade_deadline_none(self, mock_course_mode): expiration_date=start_date + timedelta(days=settings.LEARNING_ASSISTANT_AUDIT_TRIAL_LENGTH_DAYS), ) - self.assertEqual(audit_trial_is_expired(audit_trial_data, self.course_key), True) + self.assertEqual(audit_trial_is_expired(mock_enrollment, audit_trial_data), True) @ddt.data( # exactly the trial deadline @@ -650,11 +645,9 @@ def test_upgrade_deadline_none(self, mock_course_mode): datetime(year=2024, month=1, day=1) - timedelta(days=settings.LEARNING_ASSISTANT_AUDIT_TRIAL_LENGTH_DAYS + 1), ) @freeze_time('2024-01-01') - @patch('learning_assistant.api.CourseMode') - def test_audit_trial_expired(self, start_date, mock_course_mode): - mock_mode = MagicMock() - mock_mode.expiration_datetime.return_value = datetime.now() + timedelta(days=1) # tomorrow - mock_course_mode.objects.get.return_value = mock_mode + def test_audit_trial_expired(self, start_date): + mock_enrollment = MagicMock() + mock_enrollment.upgrade_deadline = datetime.now() + timedelta(days=1) # tomorrow audit_trial_data = LearningAssistantAuditTrialData( user_id=self.user.id, @@ -662,14 +655,12 @@ def test_audit_trial_expired(self, start_date, mock_course_mode): expiration_date=get_audit_trial_expiration_date(start_date), ) - self.assertEqual(audit_trial_is_expired(audit_trial_data, self.upgrade_deadline), True) + self.assertEqual(audit_trial_is_expired(mock_enrollment, audit_trial_data), True) @freeze_time('2024-01-01') - @patch('learning_assistant.api.CourseMode') - def test_audit_trial_unexpired(self, mock_course_mode): - mock_mode = MagicMock() - mock_mode.expiration_datetime.return_value = datetime.now() + timedelta(days=1) # tomorrow - mock_course_mode.objects.get.return_value = mock_mode + def test_audit_trial_unexpired(self): + mock_enrollment = MagicMock() + mock_enrollment.upgrade_deadline = datetime.now() + timedelta(days=1) # tomorrow start_date = datetime.now() - timedelta(days=settings.LEARNING_ASSISTANT_AUDIT_TRIAL_LENGTH_DAYS - 1) audit_trial_data = LearningAssistantAuditTrialData( @@ -678,4 +669,4 @@ def test_audit_trial_unexpired(self, mock_course_mode): expiration_date=get_audit_trial_expiration_date(start_date), ) - self.assertEqual(audit_trial_is_expired(audit_trial_data, self.upgrade_deadline), False) + self.assertEqual(audit_trial_is_expired(mock_enrollment, audit_trial_data), False)