feat: replace learning_assistant_launch_url with learning_assistant_enabled in courseware API
This commit replaces the learning_assistant_launch_url field of the CoursewareInformation view of the courseware API with a learning_assistant_enabled field. learning_assistant_enabled is a boolean that represents whether the Xpert Learning Assistant is enabled for the requesting user, based on the associated CourseWaffleFlag. This change is necessary because we are no longer leveraging the Learning Assistant LTI tool.
This commit is contained in:
@@ -114,7 +114,7 @@ class CourseInfoSerializer(serializers.Serializer): # pylint: disable=abstract-
|
||||
linkedin_add_to_profile_url = serializers.URLField()
|
||||
is_integrity_signature_enabled = serializers.BooleanField()
|
||||
user_needs_integrity_signature = serializers.BooleanField()
|
||||
learning_assistant_launch_url = serializers.CharField()
|
||||
learning_assistant_enabled = serializers.BooleanField()
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
"""
|
||||
|
||||
@@ -11,13 +11,10 @@ import ddt
|
||||
from completion.test_utils import CompletionWaffleTestMixin, submit_completions_for_testing
|
||||
from django.conf import settings
|
||||
from django.contrib.auth import get_user_model
|
||||
from django.test import override_settings
|
||||
from django.test.client import RequestFactory
|
||||
|
||||
from edx_django_utils.cache import TieredCache
|
||||
from edx_toggles.toggles.testutils import override_waffle_flag
|
||||
from lti_consumer.data import Lti1p3LaunchData
|
||||
from lti_consumer.models import LtiConfiguration
|
||||
from xmodule.data import CertificatesDisplayBehaviors
|
||||
from xmodule.modulestore.django import modulestore
|
||||
from xmodule.modulestore.tests.django_utils import SharedModuleStoreTestCase
|
||||
@@ -434,109 +431,16 @@ class CourseApiTestViews(BaseCoursewareTests, MasqueradeMixin):
|
||||
assert courseware_data['can_access_proctored_exams'] == result
|
||||
|
||||
@override_waffle_flag(COURSEWARE_LEARNING_ASSISTANT, active=False)
|
||||
def test_learning_assistant_launch_url_disabled_waffle_flag(self):
|
||||
def test_learning_assistant_enabled_disabled_waffle_flag(self):
|
||||
response = self.client.get(self.url)
|
||||
launch_url = response.json()['learning_assistant_launch_url']
|
||||
assert launch_url is None
|
||||
learning_assistant_enabled = response.json()['learning_assistant_enabled']
|
||||
self.assertFalse(learning_assistant_enabled)
|
||||
|
||||
@override_waffle_flag(COURSEWARE_LEARNING_ASSISTANT, active=True)
|
||||
@override_settings(LEARNING_ASSISTANT_CONFIG_ID=None)
|
||||
def test_learning_assistant_launch_no_config(self):
|
||||
def test_learning_assistant_enabled_enabled_waffle_flag(self):
|
||||
response = self.client.get(self.url)
|
||||
launch_url = response.json()['learning_assistant_launch_url']
|
||||
assert launch_url is None
|
||||
|
||||
@override_waffle_flag(COURSEWARE_LEARNING_ASSISTANT, active=True)
|
||||
def test_learning_assistant_launch_1p1(self):
|
||||
test_config = LtiConfiguration.objects.create(
|
||||
config_id=1,
|
||||
version='lti_1p1'
|
||||
)
|
||||
with override_settings(LEARNING_ASSISTANT_CONFIG_ID=test_config.id):
|
||||
response = self.client.get(self.url)
|
||||
launch_url = response.json()['learning_assistant_launch_url']
|
||||
assert launch_url is None
|
||||
|
||||
@override_waffle_flag(COURSEWARE_LEARNING_ASSISTANT, active=True)
|
||||
def test_learning_assistant_launch_not_staff_unverified(self):
|
||||
test_config = LtiConfiguration.objects.create(
|
||||
config_id=1,
|
||||
version='lti_1p3'
|
||||
)
|
||||
with override_settings(LEARNING_ASSISTANT_CONFIG_ID=test_config.id):
|
||||
self.user.is_staff = False
|
||||
self.user.save()
|
||||
CourseEnrollment.enroll(self.user, self.course.id, 'audit')
|
||||
response = self.client.get(self.url)
|
||||
launch_url = response.json()['learning_assistant_launch_url']
|
||||
assert launch_url is None
|
||||
|
||||
@ddt.data(
|
||||
'verified',
|
||||
'professional',
|
||||
'masters',
|
||||
'executive-education',
|
||||
'paid-executive-education',
|
||||
'paid-bootcamp'
|
||||
)
|
||||
@mock.patch('openedx.core.djangoapps.courseware_api.utils.get_lti_1p3_launch_start_url')
|
||||
@override_waffle_flag(COURSEWARE_LEARNING_ASSISTANT, active=True)
|
||||
def test_learning_assistant_launch_url(self, enrollment_mode, mock_lti_launch):
|
||||
test_config = LtiConfiguration.objects.create(
|
||||
config_id=1,
|
||||
version='lti_1p3'
|
||||
)
|
||||
with override_settings(LEARNING_ASSISTANT_CONFIG_ID=test_config.id):
|
||||
self.user.is_staff = False
|
||||
self.user.save()
|
||||
CourseEnrollment.enroll(self.user, self.course.id, enrollment_mode)
|
||||
|
||||
expected_url = 'https://testlaunch.org'
|
||||
mock_lti_launch.return_value = expected_url
|
||||
|
||||
response = self.client.get(self.url)
|
||||
launch_url = response.json()['learning_assistant_launch_url']
|
||||
assert launch_url == expected_url
|
||||
|
||||
expected_launch_data = Lti1p3LaunchData(
|
||||
user_id=self.user.id,
|
||||
user_role='student',
|
||||
email=self.user.email,
|
||||
config_id=1,
|
||||
resource_link_id='-'.join(['1', str(self.course.id)]),
|
||||
context_id=str(self.course.id),
|
||||
context_type=['course_offering'],
|
||||
context_title=self.course.display_name
|
||||
)
|
||||
mock_lti_launch.assert_called_with(expected_launch_data)
|
||||
|
||||
@mock.patch('openedx.core.djangoapps.courseware_api.utils.get_lti_1p3_launch_start_url')
|
||||
@override_waffle_flag(COURSEWARE_LEARNING_ASSISTANT, active=True)
|
||||
def test_learning_assistant_launch_url_instructor(self, mock_lti_launch):
|
||||
self.client.login(username='instructor', password='foo')
|
||||
test_config = LtiConfiguration.objects.create(
|
||||
config_id=1,
|
||||
version='lti_1p3'
|
||||
)
|
||||
with override_settings(LEARNING_ASSISTANT_CONFIG_ID=test_config.id):
|
||||
expected_url = 'https://testlaunch.org'
|
||||
mock_lti_launch.return_value = expected_url
|
||||
|
||||
response = self.client.get(self.url)
|
||||
launch_url = response.json()['learning_assistant_launch_url']
|
||||
assert launch_url == expected_url
|
||||
|
||||
expected_launch_data = Lti1p3LaunchData(
|
||||
user_id=self.instructor.id,
|
||||
user_role='instructor',
|
||||
email=self.instructor.email,
|
||||
config_id=1,
|
||||
resource_link_id='-'.join(['1', str(self.course.id)]),
|
||||
context_id=str(self.course.id),
|
||||
context_type=['course_offering'],
|
||||
context_title=self.course.display_name
|
||||
)
|
||||
mock_lti_launch.assert_called_with(expected_launch_data)
|
||||
learning_assistant_enabled = response.json()['learning_assistant_enabled']
|
||||
self.assertTrue(learning_assistant_enabled)
|
||||
|
||||
|
||||
@ddt.ddt
|
||||
|
||||
@@ -3,15 +3,9 @@ Courseware API Mixins.
|
||||
"""
|
||||
|
||||
from babel.numbers import get_currency_symbol
|
||||
from django.conf import settings
|
||||
|
||||
from lti_consumer.api import get_lti_1p3_launch_start_url
|
||||
from lti_consumer.data import Lti1p3LaunchData
|
||||
from lti_consumer.models import LtiConfiguration
|
||||
|
||||
from common.djangoapps.course_modes.models import CourseMode
|
||||
from common.djangoapps.student.models import CourseEnrollmentCelebration, UserCelebration
|
||||
from lms.djangoapps.courseware.access import get_user_role
|
||||
from lms.djangoapps.courseware.utils import can_show_verified_upgrade, verified_upgrade_deadline_link
|
||||
from openedx.features.course_duration_limits.access import get_user_course_expiration_date
|
||||
from openedx.features.discounts.applicability import can_show_streak_discount_coupon
|
||||
@@ -72,41 +66,3 @@ def serialize_upgrade_info(user, course_overview, enrollment):
|
||||
'sku': mode.sku,
|
||||
'upgrade_url': verified_upgrade_deadline_link(user, course_overview),
|
||||
}
|
||||
|
||||
|
||||
def get_learning_assistant_launch_url(user, course_key, enrollment_object, overview):
|
||||
"""
|
||||
Return the launch URL for an LTI based learning assistant
|
||||
"""
|
||||
config_id = getattr(settings, 'LEARNING_ASSISTANT_CONFIG_ID', None)
|
||||
if not config_id:
|
||||
return None
|
||||
|
||||
try:
|
||||
lti_config = LtiConfiguration.objects.get(config_id=config_id)
|
||||
except LtiConfiguration.DoesNotExist:
|
||||
return None
|
||||
|
||||
if lti_config.version != 'lti_1p3':
|
||||
return None
|
||||
|
||||
user_role = get_user_role(user, course_key)
|
||||
if (
|
||||
(enrollment_object and enrollment_object.mode not in CourseMode.VERIFIED_MODES)
|
||||
and (user_role != 'staff' or user_role != 'instructor')
|
||||
):
|
||||
return None
|
||||
|
||||
launch_data = Lti1p3LaunchData(
|
||||
user_id=user.id,
|
||||
user_role=user_role,
|
||||
email=user.email,
|
||||
config_id=config_id,
|
||||
resource_link_id='-'.join([str(config_id), str(course_key)]),
|
||||
context_id=str(course_key),
|
||||
context_type=['course_offering'],
|
||||
context_title=overview.display_name
|
||||
)
|
||||
|
||||
lti_url = get_lti_1p3_launch_start_url(launch_data)
|
||||
return lti_url
|
||||
|
||||
@@ -47,7 +47,7 @@ from lms.djangoapps.gating.api import get_entrance_exam_score, get_entrance_exam
|
||||
from lms.djangoapps.grades.api import CourseGradeFactory
|
||||
from lms.djangoapps.verify_student.services import IDVerificationService
|
||||
from openedx.core.djangoapps.agreements.api import get_integrity_signature
|
||||
from openedx.core.djangoapps.courseware_api.utils import get_celebrations_dict, get_learning_assistant_launch_url
|
||||
from openedx.core.djangoapps.courseware_api.utils import get_celebrations_dict
|
||||
from openedx.core.djangoapps.programs.utils import ProgramProgressMeter
|
||||
from openedx.core.lib.api.authentication import BearerAuthenticationAllowInactiveUser
|
||||
from openedx.core.lib.api.view_utils import DeveloperErrorViewMixin
|
||||
@@ -360,19 +360,11 @@ class CoursewareMeta:
|
||||
return enrollment_active and CourseMode.is_eligible_for_certificate(enrollment_mode)
|
||||
|
||||
@property
|
||||
def learning_assistant_launch_url(self):
|
||||
def learning_assistant_enabled(self):
|
||||
"""
|
||||
Returns a URL for the learning assistant LTI launch if applicable, otherwise None
|
||||
Returns a boolean representing whether the requesting user should have access to the Xpert Learning Assistant.
|
||||
"""
|
||||
if learning_assistant_is_active(self.course_key):
|
||||
lti_url = get_learning_assistant_launch_url(
|
||||
self.effective_user,
|
||||
self.course_key,
|
||||
self.enrollment_object,
|
||||
self.overview,
|
||||
)
|
||||
return lti_url
|
||||
return None
|
||||
return learning_assistant_is_active(self.course_key)
|
||||
|
||||
|
||||
class CoursewareInformation(RetrieveAPIView):
|
||||
@@ -463,7 +455,7 @@ class CoursewareInformation(RetrieveAPIView):
|
||||
verified mode. Will update to reverify URL if necessary.
|
||||
* linkedin_add_to_profile_url: URL to add the effective user's certificate to a LinkedIn Profile.
|
||||
* user_needs_integrity_signature: Whether the user needs to sign the integrity agreement for the course
|
||||
* learning_assistant_launch_url: URL for the LTI launch of a learning assistant
|
||||
* learning_assistant_enabled: Whether the Xpert Learning Assistant is enabled for the requesting user
|
||||
|
||||
**Parameters:**
|
||||
|
||||
|
||||
Reference in New Issue
Block a user