revert: remove algolia API endpoint and unit tests from lms (#31868)

This commit is contained in:
Shahbaz Shabbir
2023-03-07 10:32:57 +05:00
committed by GitHub
parent b1880cb549
commit a99826b1ef
4 changed files with 0 additions and 203 deletions

View File

@@ -14,129 +14,6 @@ from lms.djangoapps.learner_recommendations.toggles import (
)
class TestAlgoliaCoursesSearchView(APITestCase):
"""Unit tests for the Algolia courses recommendation."""
password = "test"
view_url = reverse_lazy(
"learner_recommendations:algolia_courses",
kwargs={'course_id': 'course-v1:test+TestX+Test_Course'}
)
def setUp(self):
super().setUp()
self.user = UserFactory()
self.expected_courses_recommendation = {
"hits": [
{
"availability": ["Available now"],
"level": ["Introductory"],
"marketing_url": "https://marketing-site.com/course/monsters-anatomy-101",
"card_image_url": "https://card-site.com/course/monsters-anatomy-101",
"active_run_key": "course-v1:test+TestX+Test_Course_1",
"skills": [{"skill": "skill_1"}, {"skill": "skill_2"}],
},
{
"availability": ["Available now"],
"level": ["Intermediate"],
"marketing_url": "https://marketing-site.com/course/monsters-anatomy-101",
"card_image_url": "https://card-site.com/course/monsters-anatomy-101",
"active_run_key": "course-v1:test+TestX+Test_Course_2",
"skills": [{"skill": "skill_1"}, {"skill": "skill_2"}],
}
],
"nbHits": 2
}
def test_unauthenticated_request(self):
"""
Test unauthenticated request to Algolia courses recommendation API view.
"""
response = self.client.get(self.view_url)
self.assertEqual(response.status_code, 401)
@mock.patch(
"lms.djangoapps.learner_recommendations.views.get_course_data"
)
@mock.patch(
"lms.djangoapps.learner_recommendations.views.get_course_run_details"
)
def test_no_course_data(
self,
mocked_get_course_run_details,
mocked_get_course_data
):
"""
Verify API returns empty response if no course data found.
"""
mocked_get_course_run_details.return_value = {"course": "edX+DemoX"}
mocked_get_course_data.return_value = None
self.client.login(username=self.user.username, password=self.password)
response = self.client.get(self.view_url)
self.assertEqual(response.status_code, 200)
response_content = json.loads(response.content)
self.assertEqual(response_content.get("courses"), [])
self.assertEqual(response_content.get("count"), 0)
@mock.patch(
"lms.djangoapps.learner_recommendations.views.get_course_data"
)
@mock.patch(
"lms.djangoapps.learner_recommendations.views.get_course_run_details"
)
def test_no_course_skill_names(
self,
mocked_get_course_run_details,
mocked_get_course_data
):
"""
Verify API returns empty response if no course skill_names found.
"""
mocked_get_course_run_details.return_value = {"course": "edX+DemoX"}
mocked_get_course_data.return_value = {"level_type": "Advanced", "skill_names": []}
self.client.login(username=self.user.username, password=self.password)
response = self.client.get(self.view_url)
self.assertEqual(response.status_code, 200)
response_content = json.loads(response.content)
self.assertEqual(response_content.get("courses"), [])
self.assertEqual(response_content.get("count"), 0)
@mock.patch(
"lms.djangoapps.learner_recommendations.views.get_algolia_courses_recommendation"
)
@mock.patch(
"lms.djangoapps.learner_recommendations.views.get_course_run_details"
)
@mock.patch(
"lms.djangoapps.learner_recommendations.views.get_course_data"
)
def test_recommendations(
self,
mocked_get_course_data,
mocked_get_course_run_details,
mocked_get_algolia_courses_recommendation
):
"""
Verify API response structure.
"""
mocked_get_course_run_details.return_value = {"course": "edX+DemoX"}
mocked_get_course_data.return_value = {"level_type": "Advanced", "skill_names": ["skill_1", "skill_2"]}
mocked_get_algolia_courses_recommendation.return_value = self.expected_courses_recommendation
self.client.login(username=self.user.username, password=self.password)
response = self.client.get(self.view_url)
self.assertEqual(response.status_code, 200)
response_content = json.loads(response.content)
self.assertEqual(response_content.get("courses"), self.expected_courses_recommendation["hits"])
self.assertEqual(response_content.get("count"), self.expected_courses_recommendation["nbHits"])
@override_waffle_flag(ENABLE_COURSE_ABOUT_PAGE_RECOMMENDATIONS, active=True)
class TestAmplitudeRecommendationsView(APITestCase):
"""Unit tests for the Amplitude recommendations API"""

View File

@@ -10,9 +10,6 @@ from lms.djangoapps.learner_recommendations import views
app_name = "learner_recommendations"
urlpatterns = [
re_path(fr'^algolia/courses/{settings.COURSE_ID_PATTERN}/$',
views.AlgoliaCoursesSearchView.as_view(),
name='algolia_courses'),
re_path(fr'^amplitude/{settings.COURSE_ID_PATTERN}/$',
views.AmplitudeRecommendationsView.as_view(),
name='amplitude_recommendations'),

View File

@@ -4,7 +4,6 @@ Additional utilities for Learner Recommendations.
import logging
import requests
from algoliasearch.exceptions import RequestException, AlgoliaUnreachableHostException
from algoliasearch.search_client import SearchClient
from django.conf import settings
@@ -114,48 +113,6 @@ def _get_program_duration(weeks):
return f'{total_years} years {total_remainder_months} months'
def get_algolia_courses_recommendation(course_data):
"""
Get courses recommendation from Algolia search.
Args:
course_data (dict): Course data to create the search query.
Returns:
Response object with courses recommendation from Algolia search.
"""
algolia_client = AlgoliaClient.get_algolia_client()
search_query = " ".join(course_data["skill_names"])
searchable_course_levels = [
f"level:{course_level}"
for course_level in COURSE_LEVELS
if course_level != course_data["level_type"]
]
if algolia_client and search_query:
algolia_index = algolia_client.init_index(settings.ALGOLIA_COURSES_RECOMMENDATION_INDEX_NAME)
try:
# Algolia search filter criteria:
# - Product type: Course
# - Courses are available (enrollable)
# - Courses should not have the same course level as the current course
# - Exclude current course from the results
results = algolia_index.search(
search_query,
{
"filters": f"NOT active_run_key:'{course_data['key']}'",
"facetFilters": ["availability:Available now", "product:Course", searchable_course_levels],
"optionalWords": f"{search_query}",
}
)
return results
except (AlgoliaUnreachableHostException, RequestException) as ex:
log.warning(f"Unexpected exception while attempting to fetch courses data from Algolia: {str(ex)}")
return {}
def get_amplitude_course_recommendations(user_id, recommendation_id):
"""
Get personalized recommendations from Amplitude.

View File

@@ -16,15 +16,10 @@ from rest_framework.response import Response
from rest_framework.views import APIView
from common.djangoapps.track import segment
from openedx.core.djangoapps.catalog.utils import (
get_course_data,
get_course_run_details,
)
from openedx.core.djangoapps.geoinfo.api import country_code_from_ip
from openedx.features.enterprise_support.utils import is_enterprise_learner
from lms.djangoapps.learner_recommendations.toggles import enable_course_about_page_recommendations
from lms.djangoapps.learner_recommendations.utils import (
get_algolia_courses_recommendation,
get_amplitude_course_recommendations,
filter_recommended_courses,
)
@@ -34,35 +29,6 @@ from lms.djangoapps.learner_recommendations.serializers import RecommendationsSe
log = logging.getLogger(__name__)
class AlgoliaCoursesSearchView(APIView):
"""
**Example Request**
GET api/learner_recommendations/algolia/courses/{course_id}/
"""
authentication_classes = (JwtAuthentication, SessionAuthenticationAllowInactiveUser,)
permission_classes = (IsAuthenticated,)
def get(self, request, course_id):
""" Retrieves course recommendations from Algolia based on course skills. """
course_run_data = get_course_run_details(course_id, ["course"])
course_key_str = course_run_data.get("course", None)
# Fetching course level type and skills from discovery service.
course_data = get_course_data(course_key_str, ["level_type", "skill_names"])
# If discovery service fails to fetch data, we will not run recommendations engine.
if not course_data:
return Response({"courses": [], "count": 0}, status=200)
course_data["key"] = course_id
response = get_algolia_courses_recommendation(course_data)
return Response({"courses": response.get("hits", []), "count": response.get("nbHits", 0)}, status=200)
class AmplitudeRecommendationsView(APIView):
"""
**Example Request**