feat: add eventing to personalized recommendations (#31703)

VAN-1261
This commit is contained in:
Syed Sajjad Hussain Shah
2023-02-03 16:40:22 +05:00
committed by GitHub
parent ca6272a50f
commit 284e64d1f1
7 changed files with 40 additions and 3 deletions

View File

@@ -361,6 +361,7 @@ class TestCourseRecommendationApiView(TestCase):
"is_control": False,
"amplitude_recommendations": False,
"course_key_array": self.general_recommendation_courses,
"page": "dashboard",
},
)
@@ -400,6 +401,7 @@ class TestCourseRecommendationApiView(TestCase):
"amplitude_recommendations": True,
"course_key_array": [course.get("key") for course in
self._get_filtered_courses()[:expected_recommendations]],
"page": "dashboard",
},
)

View File

@@ -385,6 +385,7 @@ class CourseRecommendationApiView(APIView):
"course_key_array": [
course["course_key"] for course in recommended_courses
],
"page": "dashboard",
},
)

View File

@@ -97,6 +97,7 @@ class CourseRecommendationApiView(APIView):
"is_control": is_control,
"amplitude_recommendations": amplitude_recommendations,
"course_key_array": [course["course_key"] for course in recommended_courses],
"page": "dashboard",
},
)

View File

@@ -24,7 +24,7 @@ class CourseImageSerializer(serializers.Serializer):
class RecommendedCourseSerializer(serializers.Serializer):
"""Serializer for a recommended course from the recommendation engine"""
key = serializers.CharField()
uuid = serializers.UUIDField()
title = serializers.CharField()
image = CourseImageSerializer()

View File

@@ -235,12 +235,13 @@ class TestAmplitudeRecommendationsView(APITestCase):
self.assertEqual(response.status_code, 404)
self.assertEqual(response.data, None)
@mock.patch("lms.djangoapps.learner_dashboard.api.v0.views.segment.track")
@mock.patch(
"lms.djangoapps.learner_recommendations.views.get_amplitude_course_recommendations"
)
@mock.patch("lms.djangoapps.learner_recommendations.views.filter_recommended_courses")
def test_successful_response(
self, filter_recommended_courses_mock, get_amplitude_course_recommendations_mock
self, filter_recommended_courses_mock, get_amplitude_course_recommendations_mock, segment_mock,
):
"""
Verify API returns course recommendations.
@@ -252,6 +253,7 @@ class TestAmplitudeRecommendationsView(APITestCase):
True,
self.recommended_courses,
]
segment_mock.return_value = None
response = self.client.get(self.url)
response_content = json.loads(response.content)
@@ -261,3 +263,7 @@ class TestAmplitudeRecommendationsView(APITestCase):
self.assertEqual(
len(response_content.get("courses")), expected_recommendations_length
)
# Verify that the segment event was fired
assert segment_mock.call_count == 1
assert segment_mock.call_args[0][1] == "edx.bi.user.recommendations.viewed"

View File

@@ -15,6 +15,7 @@ from rest_framework.permissions import IsAuthenticated
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,
@@ -75,6 +76,27 @@ class AmplitudeRecommendationsView(APIView):
recommendations_count = 4
def _emit_recommendations_viewed_event(
self,
user_id,
is_control,
recommended_courses,
amplitude_recommendations=True,
):
"""Emits an event to track recommendation experiment views."""
segment.track(
user_id,
"edx.bi.user.recommendations.viewed",
{
"is_control": is_control,
"amplitude_recommendations": amplitude_recommendations,
"course_key_array": [
course["key"] for course in recommended_courses
],
"page": "course_about_page",
},
)
def get(self, request, course_id):
"""
Returns
@@ -105,7 +127,7 @@ class AmplitudeRecommendationsView(APIView):
ip_address = get_client_ip(request)[0]
user_country_code = country_code_from_ip(ip_address).upper()
filtered_courses = filter_recommended_courses(
request.user, course_keys, user_country_code=user_country_code, request_course=course_key,
user, course_keys, user_country_code=user_country_code, request_course=course_key,
)
for course in filtered_courses:
@@ -119,6 +141,10 @@ class AmplitudeRecommendationsView(APIView):
if len(recommended_courses) == self.recommendations_count:
break
self._emit_recommendations_viewed_event(
user.id, is_control, recommended_courses
)
return Response(
RecommendationsSerializer(
{

View File

@@ -20,6 +20,7 @@ class RecommendationsPanel extends React.Component {
window.analytics.track('edx.bi.user.recommended.course.click', {
course_key: courseKey,
is_control: this.state.isControl,
page: 'dashboard',
});
let recommendedCourses = Cookies.get(this.cookieName);