Skip to content

Commit

Permalink
feat: added endpoint for context needed for recommendations experiment (
Browse files Browse the repository at this point in the history
openedx#32645)

* feat: added endpoint for context needed for recommendations experiment

* chore: Removed unnecessary decorator
  • Loading branch information
JodyBaileyy authored Jul 4, 2023
1 parent ac5b087 commit 02084fa
Show file tree
Hide file tree
Showing 5 changed files with 108 additions and 0 deletions.
6 changes: 6 additions & 0 deletions lms/djangoapps/learner_recommendations/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,12 @@ class AboutPageRecommendationsSerializer(serializers.Serializer):
)


class RecommendationsContextSerializer(serializers.Serializer):
"""Serializer for recommendations context"""

countryCode = serializers.CharField(allow_blank=True)


class CrossProductRecommendationsSerializer(serializers.Serializer):
"""
Cross product recommendation courses for course about page
Expand Down
37 changes: 37 additions & 0 deletions lms/djangoapps/learner_recommendations/tests/test_serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

from lms.djangoapps.learner_recommendations.serializers import (
DashboardRecommendationsSerializer,
RecommendationsContextSerializer,
CrossProductRecommendationsSerializer,
CrossProductAndAmplitudeRecommendationsSerializer,
AmplitudeRecommendationsSerializer
Expand Down Expand Up @@ -91,6 +92,42 @@ def test_happy_path(self):
)


class TestRecommendationsContextSerializer(TestCase):
"""Tests for RecommendationsContextSerializer"""

def test_successful_serialization(self):
"""Test that context data serializes correctly"""

serialized_data = RecommendationsContextSerializer(
{
"countryCode": "US",
}
).data

self.assertDictEqual(
serialized_data,
{
"countryCode": "US",
},
)

def test_empty_response_serialization(self):
"""Test that an empty response serializes correctly"""

serialized_data = RecommendationsContextSerializer(
{
"countryCode": "",
}
).data

self.assertDictEqual(
serialized_data,
{
"countryCode": "",
},
)


class TestCrossProductRecommendationsSerializers(TestCase):
"""
Tests for the CrossProductRecommendationsSerializer,
Expand Down
30 changes: 30 additions & 0 deletions lms/djangoapps/learner_recommendations/tests/test_views.py
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,36 @@ def test_successful_response(
assert segment_mock.call_args[0][1] == "edx.bi.user.recommendations.viewed"


class TestRecommendationsContextView(APITestCase):
"""Unit tests for the Recommendations Context View"""

def setUp(self):
super().setUp()
self.user = UserFactory()
self.password = "test"
self.url = reverse_lazy("learner_recommendations:recommendations_context")

@mock.patch("lms.djangoapps.learner_recommendations.views.country_code_from_ip")
def test_successful_response(self, country_code_from_ip_mock):
"""Test that country code gets sent back when authenticated"""

country_code_from_ip_mock.return_value = "za"
self.client.login(username=self.user.username, password=self.password)

response = self.client.get(self.url)
response_data = json.loads(response.content)

self.assertEqual(response_data["countryCode"], "za")

def test_unauthenticated_response(self):
"""
Test that a 401 is sent back if an anauthenticated user calls endpoint
"""
response = self.client.get(self.url)

self.assertEqual(response.status_code, 401)


class TestCrossProductRecommendationsView(APITestCase):
"""Unit tests for the Cross Product Recommendations View"""

Expand Down
3 changes: 3 additions & 0 deletions lms/djangoapps/learner_recommendations/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,4 +25,7 @@
re_path(r"^courses/$",
views.DashboardRecommendationsApiView.as_view(),
name="courses"),
re_path(r'^recommendations_context/$',
views.RecommendationsContextView.as_view(),
name='recommendations_context'),
]
32 changes: 32 additions & 0 deletions lms/djangoapps/learner_recommendations/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
from lms.djangoapps.learner_recommendations.serializers import (
AboutPageRecommendationsSerializer,
DashboardRecommendationsSerializer,
RecommendationsContextSerializer,
CrossProductAndAmplitudeRecommendationsSerializer,
CrossProductRecommendationsSerializer,
AmplitudeRecommendationsSerializer,
Expand Down Expand Up @@ -195,6 +196,37 @@ def get(self, request, course_id):
)


class RecommendationsContextView(APIView):
"""
*Example Request*
GET /api/learner_recommendations/recommendations_context/
"""

authentication_classes = (
JwtAuthentication,
SessionAuthenticationAllowInactiveUser,
)
permission_classes = (IsAuthenticated, NotJwtRestrictedApplication)

def get(self, request):
"""
Returns the context needed for the recommendations experiment:
- Country Code
"""
ip_address = get_client_ip(request)[0]
country_code = country_code_from_ip(ip_address)

return Response(
RecommendationsContextSerializer(
{
"countryCode": country_code,
}
).data,
status=200,
)


class ProductRecommendationsView(APIView):
"""
**Example Request**
Expand Down

0 comments on commit 02084fa

Please sign in to comment.