Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add audit_trial_length_days attribute to ChatSummaryView response. #143

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions CHANGELOG.rst
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,12 @@ Change Log
Unreleased
**********

4.6.0 - 2025-12-10
******************
* Add an audit_trial_length_days attribute to the response returned by the ChatSummaryView, representing the
number of days in an audit trial as currently configured. It does not necessarily represent the number of days in the
learner's current trial.

4.5.0 - 2024-12-04
******************
* Add local setup to readme
Expand Down
2 changes: 1 addition & 1 deletion learning_assistant/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,6 @@
Plugin for a learning assistant backend, intended for use within edx-platform.
"""

__version__ = '4.5.0'
__version__ = '4.6.0'

default_app_config = 'learning_assistant.apps.LearningAssistantConfig' # pylint: disable=invalid-name
13 changes: 2 additions & 11 deletions learning_assistant/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
traverse_block_pre_order,
)
from learning_assistant.text_utils import html_to_text
from learning_assistant.utils import get_audit_trial_length_days

log = logging.getLogger(__name__)
User = get_user_model()
Expand Down Expand Up @@ -247,17 +248,7 @@ def get_audit_trial_expiration_date(start_date):
Returns:
* expiration_date (datetime): the expiration date of the audit trial
"""
default_trial_length_days = 14

trial_length_days = getattr(settings, 'LEARNING_ASSISTANT_AUDIT_TRIAL_LENGTH_DAYS', default_trial_length_days)

if trial_length_days is None:
trial_length_days = default_trial_length_days

# If LEARNING_ASSISTANT_AUDIT_TRIAL_LENGTH_DAYS is set to a negative number, assume it should be 0.
# pylint: disable=consider-using-max-builtin
if trial_length_days < 0:
trial_length_days = 0
trial_length_days = get_audit_trial_length_days()

expiration_datetime = start_date + timedelta(days=trial_length_days)
return expiration_datetime
Expand Down
25 changes: 25 additions & 0 deletions learning_assistant/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -112,3 +112,28 @@ def user_role_is_staff(role):
* bool: whether the user's role is that of a staff member
"""
return role in ('staff', 'instructor')


def get_audit_trial_length_days():
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice idea to move this!

"""
Return the length of an audit trial in days.

Arguments:
* None

Returns:
* int: the length of an audit trial in days
"""
default_trial_length_days = 14

trial_length_days = getattr(settings, 'LEARNING_ASSISTANT_AUDIT_TRIAL_LENGTH_DAYS', default_trial_length_days)

if trial_length_days is None:
trial_length_days = default_trial_length_days

# If LEARNING_ASSISTANT_AUDIT_TRIAL_LENGTH_DAYS is set to a negative number, assume it should be 0.
# pylint: disable=consider-using-max-builtin
if trial_length_days < 0:
trial_length_days = 0

return trial_length_days
11 changes: 7 additions & 4 deletions learning_assistant/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@
from learning_assistant.models import LearningAssistantMessage
from learning_assistant.serializers import MessageSerializer
from learning_assistant.toggles import chat_history_enabled
from learning_assistant.utils import get_chat_response, user_role_is_staff
from learning_assistant.utils import get_audit_trial_length_days, get_chat_response, user_role_is_staff

log = logging.getLogger(__name__)

Expand Down Expand Up @@ -335,10 +335,11 @@ def get(self, request, course_run_id):
"timestamp": "2024-12-02T15:04:40.084584Z"
}
],
"trial": {
"audit_trial": {
"start_date": "2024-12-02T14:59:16.148236Z",
"expiration_date": "2024-12-16T14:59:16.148236Z"
}
"expiration_date": "2024-12-26T14:59:16.148236Z",
},
"audit_trial_length_days": 14
}
"""
try:
Expand Down Expand Up @@ -409,4 +410,6 @@ def get(self, request, course_run_id):

data['audit_trial'] = trial_data

data['audit_trial_length_days'] = get_audit_trial_length_days()

return Response(status=http_status.HTTP_200_OK, data=data)
26 changes: 14 additions & 12 deletions tests/test_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -492,22 +492,24 @@ class GetAuditTrialExpirationDateTests(TestCase):
Test suite for get_audit_trial_expiration_date.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice updates to tests!

"""
@ddt.data(
(datetime(2024, 1, 1, 0, 0, 0), datetime(2024, 1, 15, 0, 0, 0), None),
(datetime(2024, 1, 18, 0, 0, 0), datetime(2024, 2, 1, 0, 0, 0), None),
(datetime(2024, 1, 1, 0, 0, 0), datetime(2024, 1, 2, 0, 0, 0), 1),
(datetime(2024, 1, 18, 0, 0, 0), datetime(2024, 1, 19, 0, 0, 0), 1),
(datetime(2024, 1, 1, 0, 0, 0), datetime(2024, 1, 8, 0, 0, 0), 7),
(datetime(2024, 1, 18, 0, 0, 0), datetime(2024, 1, 25, 0, 0, 0), 7),
(datetime(2024, 1, 1, 0, 0, 0), datetime(2024, 1, 15, 0, 0, 0), 14),
(datetime(2024, 1, 18, 0, 0, 0), datetime(2024, 2, 1, 0, 0, 0), 14),
(datetime(2024, 1, 1, 0, 0, 0), datetime(2024, 1, 1, 0, 0, 0), -1),
(datetime(2024, 1, 18, 0, 0, 0), datetime(2024, 1, 18, 0, 0, 0), -1),
(datetime(2024, 1, 1, 0, 0, 0), datetime(2024, 1, 1, 0, 0, 0), 0),
(datetime(2024, 1, 18, 0, 0, 0), datetime(2024, 1, 18, 0, 0, 0), 0),
(datetime(2024, 1, 1, 0, 0, 0), datetime(2024, 1, 4, 0, 0, 0), 3),
(datetime(2024, 1, 18, 0, 0, 0), datetime(2024, 1, 21, 0, 0, 0), 3),
)
@ddt.unpack
def test_expiration_date(self, start_date, expected_expiration_date, trial_length_days):
with override_settings(LEARNING_ASSISTANT_AUDIT_TRIAL_LENGTH_DAYS=trial_length_days):
expiration_date = get_audit_trial_expiration_date(start_date)
self.assertEqual(expected_expiration_date, expiration_date)
@patch('learning_assistant.api.get_audit_trial_length_days')
def test_expiration_date(
self, start_date,
expected_expiration_date,
trial_length_days,
mock_get_audit_trial_length_days
):
mock_get_audit_trial_length_days.return_value = trial_length_days
expiration_date = get_audit_trial_expiration_date(start_date)
self.assertEqual(expected_expiration_date, expiration_date)


class GetAuditTrialTests(TestCase):
Expand Down
31 changes: 30 additions & 1 deletion tests/test_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,12 @@
from django.test import TestCase, override_settings
from requests.exceptions import ConnectTimeout

from learning_assistant.utils import get_chat_response, get_reduced_message_list, user_role_is_staff
from learning_assistant.utils import (
get_audit_trial_length_days,
get_chat_response,
get_reduced_message_list,
user_role_is_staff,
)


@ddt.ddt
Expand Down Expand Up @@ -145,3 +150,27 @@ class UserRoleIsStaffTests(TestCase):
@ddt.unpack
def test_user_role_is_staff(self, role, expected_value):
self.assertEqual(user_role_is_staff(role), expected_value)


@ddt.ddt
class GetAuditTrialLengthDaysTests(TestCase):
"""
Tests for the get_audit_trial_length_days helper function.
"""
@ddt.data(
(None, 14),
(0, 0),
(-7, 0),
(7, 7),
(14, 14),
(28, 28),
)
@ddt.unpack
def test_get_audit_trial_length_days_with_value(self, setting_value, expected_value):
with patch.object(settings, 'LEARNING_ASSISTANT_AUDIT_TRIAL_LENGTH_DAYS', setting_value):
self.assertEqual(get_audit_trial_length_days(), expected_value)

@override_settings()
def test_get_audit_trial_length_days_no_setting(self):
del settings.LEARNING_ASSISTANT_AUDIT_TRIAL_LENGTH_DAYS
self.assertEqual(get_audit_trial_length_days(), 14)
18 changes: 18 additions & 0 deletions tests/test_views.py
Original file line number Diff line number Diff line change
Expand Up @@ -495,12 +495,14 @@ def test_invalid_course_id(self, mock_course_key):
['verified', 'credit', 'no-id', 'audit', None], # course mode
[True, False], # trial available
[True, False], # trial expired
[7, 14], # trial length
)
)
@ddt.unpack
@patch('learning_assistant.views.audit_trial_is_expired')
@patch('learning_assistant.views.chat_history_enabled')
@patch('learning_assistant.views.learning_assistant_enabled')
@patch('learning_assistant.views.get_audit_trial_length_days')
@patch('learning_assistant.views.get_user_role')
@patch('learning_assistant.views.CourseEnrollment')
@patch('learning_assistant.views.CourseMode')
Expand All @@ -512,9 +514,11 @@ def test_chat_summary_with_access_instructor(
course_mode_mock_value,
trial_available,
audit_trial_is_expired_mock_value,
audit_trial_length_days_mock_value,
mock_mode,
mock_enrollment,
mock_get_user_role,
mock_get_audit_trial_length_days,
mock_learning_assistant_enabled,
mock_chat_history_enabled,
mock_audit_trial_is_expired,
Expand Down Expand Up @@ -555,6 +559,7 @@ def test_chat_summary_with_access_instructor(

# Set up audit trial data.
mock_audit_trial_is_expired.return_value = audit_trial_is_expired_mock_value
mock_get_audit_trial_length_days.return_value = audit_trial_length_days_mock_value

trial_start_date = datetime(2024, 1, 1, 0, 0, 0)
if trial_available:
Expand Down Expand Up @@ -594,6 +599,7 @@ def test_chat_summary_with_access_instructor(
expected_trial_data['expiration_date'] = trial_start_date + timedelta(days=14)

self.assertEqual(response.data['audit_trial'], expected_trial_data)
self.assertEqual(response.data['audit_trial_length_days'], audit_trial_length_days_mock_value)

@ddt.data(
*product(
Expand All @@ -603,12 +609,14 @@ def test_chat_summary_with_access_instructor(
['verified', 'credit', 'no-id'], # course mode
[True, False], # trial available
[True, False], # trial expired
[7, 14], # trial length
)
)
@ddt.unpack
@patch('learning_assistant.views.audit_trial_is_expired')
@patch('learning_assistant.views.chat_history_enabled')
@patch('learning_assistant.views.learning_assistant_enabled')
@patch('learning_assistant.views.get_audit_trial_length_days')
@patch('learning_assistant.views.get_user_role')
@patch('learning_assistant.views.CourseEnrollment')
@patch('learning_assistant.views.CourseMode')
Expand All @@ -620,9 +628,11 @@ def test_chat_summary_with_full_access_student(
course_mode_mock_value,
trial_available,
audit_trial_is_expired_mock_value,
audit_trial_length_days_mock_value,
mock_mode,
mock_enrollment,
mock_get_user_role,
mock_get_audit_trial_length_days,
mock_learning_assistant_enabled,
mock_chat_history_enabled,
mock_audit_trial_is_expired,
Expand Down Expand Up @@ -663,6 +673,7 @@ def test_chat_summary_with_full_access_student(

# Set up audit trial data.
mock_audit_trial_is_expired.return_value = audit_trial_is_expired_mock_value
mock_get_audit_trial_length_days.return_value = audit_trial_length_days_mock_value

trial_start_date = datetime(2024, 1, 1, 0, 0, 0)
if trial_available:
Expand Down Expand Up @@ -702,6 +713,7 @@ def test_chat_summary_with_full_access_student(
expected_trial_data['expiration_date'] = trial_start_date + timedelta(days=14)

self.assertEqual(response.data['audit_trial'], expected_trial_data)
self.assertEqual(response.data['audit_trial_length_days'], audit_trial_length_days_mock_value)

@ddt.data(
*product(
Expand All @@ -711,12 +723,14 @@ def test_chat_summary_with_full_access_student(
['audit'], # course mode
[True, False], # trial available
[True, False], # trial expired
[7, 14], # trial length
)
)
@ddt.unpack
@patch('learning_assistant.views.audit_trial_is_expired')
@patch('learning_assistant.views.chat_history_enabled')
@patch('learning_assistant.views.learning_assistant_enabled')
@patch('learning_assistant.views.get_audit_trial_length_days')
@patch('learning_assistant.views.get_user_role')
@patch('learning_assistant.views.CourseEnrollment')
@patch('learning_assistant.views.CourseMode')
Expand All @@ -728,9 +742,11 @@ def test_chat_summary_with_trial_access_student(
course_mode_mock_value,
trial_available,
audit_trial_is_expired_mock_value,
audit_trial_length_days_mock_value,
mock_mode,
mock_enrollment,
mock_get_user_role,
mock_get_audit_trial_length_days,
mock_learning_assistant_enabled,
mock_chat_history_enabled,
mock_audit_trial_is_expired,
Expand Down Expand Up @@ -771,6 +787,7 @@ def test_chat_summary_with_trial_access_student(

# Set up audit trial data.
mock_audit_trial_is_expired.return_value = audit_trial_is_expired_mock_value
mock_get_audit_trial_length_days.return_value = audit_trial_length_days_mock_value

trial_start_date = datetime(2024, 1, 1, 0, 0, 0)
if trial_available:
Expand Down Expand Up @@ -810,3 +827,4 @@ def test_chat_summary_with_trial_access_student(
expected_trial_data['expiration_date'] = trial_start_date + timedelta(days=14)

self.assertEqual(response.data['audit_trial'], expected_trial_data)
self.assertEqual(response.data['audit_trial_length_days'], audit_trial_length_days_mock_value)
Loading