diff --git a/lms/djangoapps/learner_home/mock_data.json b/lms/djangoapps/learner_home/mock_data.json index 5519b07579..058e5a6729 100644 --- a/lms/djangoapps/learner_home/mock_data.json +++ b/lms/djangoapps/learner_home/mock_data.json @@ -49,7 +49,8 @@ "course": { "courseName": "Course Name 0", "bannerImgSrc": "/asset-v1:edX+DemoX+Demo_Course+type@asset+block@images_course_image.jpg", - "courseNumber": "course-number0" + "courseNumber": "course-number0", + "socialShareUrl": "edx.com/courses/my-course-url/marketing/about" }, "programs": { "relatedPrograms": [ @@ -124,7 +125,8 @@ "course": { "courseName": "Course Name 1", "bannerImgSrc": "/asset-v1:edX+DemoX+Demo_Course+type@asset+block@images_course_image.jpg", - "courseNumber": "course-number1" + "courseNumber": "course-number1", + "socialShareUrl": "edx.com/courses/my-course-url/marketing/about" }, "programs": { "relatedPrograms": [ @@ -187,7 +189,8 @@ "course": { "courseName": "Course Name 2", "bannerImgSrc": "/asset-v1:edX+DemoX+Demo_Course+type@asset+block@images_course_image.jpg", - "courseNumber": "course-number2" + "courseNumber": "course-number2", + "socialShareUrl": "edx.com/courses/my-course-url/marketing/about" }, "programs": { "relatedPrograms": [] @@ -242,7 +245,8 @@ "course": { "courseName": "Course Name 3", "bannerImgSrc": "/asset-v1:edX+DemoX+Demo_Course+type@asset+block@images_course_image.jpg", - "courseNumber": "course-number3" + "courseNumber": "course-number3", + "socialShareUrl": "edx.com/courses/my-course-url/marketing/about" }, "programs": { "relatedPrograms": [ @@ -317,7 +321,8 @@ "course": { "courseName": "Course Name 4", "bannerImgSrc": "/asset-v1:edX+DemoX+Demo_Course+type@asset+block@images_course_image.jpg", - "courseNumber": "course-number4" + "courseNumber": "course-number4", + "socialShareUrl": "edx.com/courses/my-course-url/marketing/about" }, "programs": { "relatedPrograms": [ @@ -380,7 +385,8 @@ "course": { "courseName": "Course Name 5", "bannerImgSrc": "/asset-v1:edX+DemoX+Demo_Course+type@asset+block@images_course_image.jpg", - "courseNumber": "course-number5" + "courseNumber": "course-number5", + "socialShareUrl": "edx.com/courses/my-course-url/marketing/about" }, "programs": { "relatedPrograms": [] @@ -435,7 +441,8 @@ "course": { "courseName": "Course Name 6", "bannerImgSrc": "/asset-v1:edX+DemoX+Demo_Course+type@asset+block@images_course_image.jpg", - "courseNumber": "course-number6" + "courseNumber": "course-number6", + "socialShareUrl": "edx.com/courses/my-course-url/marketing/about" }, "programs": { "relatedPrograms": [ @@ -510,7 +517,8 @@ "course": { "courseName": "Course Name 7", "bannerImgSrc": "/asset-v1:edX+DemoX+Demo_Course+type@asset+block@images_course_image.jpg", - "courseNumber": "course-number7" + "courseNumber": "course-number7", + "socialShareUrl": "edx.com/courses/my-course-url/marketing/about" }, "programs": { "relatedPrograms": [ @@ -573,7 +581,8 @@ "course": { "courseName": "Course Name 8", "bannerImgSrc": "/asset-v1:edX+DemoX+Demo_Course+type@asset+block@images_course_image.jpg", - "courseNumber": "course-number8" + "courseNumber": "course-number8", + "socialShareUrl": "edx.com/courses/my-course-url/marketing/about" }, "programs": { "relatedPrograms": [] @@ -628,7 +637,8 @@ "course": { "courseName": "Course Name 9", "bannerImgSrc": "/asset-v1:edX+DemoX+Demo_Course+type@asset+block@images_course_image.jpg", - "courseNumber": "course-number9" + "courseNumber": "course-number9", + "socialShareUrl": "edx.com/courses/my-course-url/marketing/about" }, "programs": { "relatedPrograms": [ @@ -706,7 +716,8 @@ "course": { "courseName": "Course Name 10", "bannerImgSrc": "/asset-v1:edX+DemoX+Demo_Course+type@asset+block@images_course_image.jpg", - "courseNumber": "course-number10" + "courseNumber": "course-number10", + "socialShareUrl": "edx.com/courses/my-course-url/marketing/about" }, "programs": { "relatedPrograms": [ @@ -772,7 +783,8 @@ "course": { "courseName": "Course Name 11", "bannerImgSrc": "/asset-v1:edX+DemoX+Demo_Course+type@asset+block@images_course_image.jpg", - "courseNumber": "course-number11" + "courseNumber": "course-number11", + "socialShareUrl": "edx.com/courses/my-course-url/marketing/about" }, "programs": { "relatedPrograms": [] @@ -834,7 +846,8 @@ "course": { "courseName": "Course Name 12", "bannerImgSrc": "/asset-v1:edX+DemoX+Demo_Course+type@asset+block@images_course_image.jpg", - "courseNumber": "course-number12" + "courseNumber": "course-number12", + "socialShareUrl": "edx.com/courses/my-course-url/marketing/about" }, "programs": { "relatedPrograms": [ @@ -917,7 +930,8 @@ "course": { "courseName": "Course Name 13", "bannerImgSrc": "/asset-v1:edX+DemoX+Demo_Course+type@asset+block@images_course_image.jpg", - "courseNumber": "course-number13" + "courseNumber": "course-number13", + "socialShareUrl": "edx.com/courses/my-course-url/marketing/about" }, "programs": { "relatedPrograms": [ @@ -980,7 +994,8 @@ "course": { "courseName": "Course Name 14", "bannerImgSrc": "/asset-v1:edX+DemoX+Demo_Course+type@asset+block@images_course_image.jpg", - "courseNumber": "course-number14" + "courseNumber": "course-number14", + "socialShareUrl": "edx.com/courses/my-course-url/marketing/about" }, "programs": { "relatedPrograms": [] @@ -1035,7 +1050,8 @@ "course": { "courseName": "Course Name 15", "bannerImgSrc": "/asset-v1:edX+DemoX+Demo_Course+type@asset+block@images_course_image.jpg", - "courseNumber": "course-number15" + "courseNumber": "course-number15", + "socialShareUrl": "edx.com/courses/my-course-url/marketing/about" }, "programs": { "relatedPrograms": [ @@ -1110,7 +1126,8 @@ "course": { "courseName": "Course Name 16", "bannerImgSrc": "/asset-v1:edX+DemoX+Demo_Course+type@asset+block@images_course_image.jpg", - "courseNumber": "course-number16" + "courseNumber": "course-number16", + "socialShareUrl": "edx.com/courses/my-course-url/marketing/about" }, "programs": { "relatedPrograms": [ @@ -1173,7 +1190,8 @@ "course": { "courseName": "Course Name 17", "bannerImgSrc": "/asset-v1:edX+DemoX+Demo_Course+type@asset+block@images_course_image.jpg", - "courseNumber": "course-number17" + "courseNumber": "course-number17", + "socialShareUrl": "edx.com/courses/my-course-url/marketing/about" }, "programs": { "relatedPrograms": [] @@ -1228,7 +1246,8 @@ "course": { "courseName": "Course Name 18", "bannerImgSrc": "/asset-v1:edX+DemoX+Demo_Course+type@asset+block@images_course_image.jpg", - "courseNumber": "course-number18" + "courseNumber": "course-number18", + "socialShareUrl": "edx.com/courses/my-course-url/marketing/about" }, "programs": { "relatedPrograms": [ @@ -1303,7 +1322,8 @@ "course": { "courseName": "Course Name 19", "bannerImgSrc": "/asset-v1:edX+DemoX+Demo_Course+type@asset+block@images_course_image.jpg", - "courseNumber": "course-number19" + "courseNumber": "course-number19", + "socialShareUrl": "edx.com/courses/my-course-url/marketing/about" }, "programs": { "relatedPrograms": [ @@ -1366,7 +1386,8 @@ "course": { "courseName": "Course Name 20", "bannerImgSrc": "/asset-v1:edX+DemoX+Demo_Course+type@asset+block@images_course_image.jpg", - "courseNumber": "course-number20" + "courseNumber": "course-number20", + "socialShareUrl": "edx.com/courses/my-course-url/marketing/about" }, "programs": { "relatedPrograms": [] @@ -1421,7 +1442,8 @@ "course": { "courseName": "Course Name 21", "bannerImgSrc": "/asset-v1:edX+DemoX+Demo_Course+type@asset+block@images_course_image.jpg", - "courseNumber": "course-number21" + "courseNumber": "course-number21", + "socialShareUrl": "edx.com/courses/my-course-url/marketing/about" }, "programs": { "relatedPrograms": [ @@ -1496,7 +1518,8 @@ "course": { "courseName": "Course Name 22", "bannerImgSrc": "/asset-v1:edX+DemoX+Demo_Course+type@asset+block@images_course_image.jpg", - "courseNumber": "course-number22" + "courseNumber": "course-number22", + "socialShareUrl": "edx.com/courses/my-course-url/marketing/about" }, "programs": { "relatedPrograms": [ @@ -1559,7 +1582,8 @@ "course": { "courseName": "Course Name 23", "bannerImgSrc": "/asset-v1:edX+DemoX+Demo_Course+type@asset+block@images_course_image.jpg", - "courseNumber": "course-number23" + "courseNumber": "course-number23", + "socialShareUrl": "edx.com/courses/my-course-url/marketing/about" }, "programs": { "relatedPrograms": [] @@ -1648,7 +1672,8 @@ "course": { "courseName": "Course Name 24", "bannerImgSrc": "/asset-v1:edX+DemoX+Demo_Course+type@asset+block@images_course_image.jpg", - "courseNumber": "course-number24" + "courseNumber": "course-number24", + "socialShareUrl": "edx.com/courses/my-course-url/marketing/about" }, "programs": { "relatedPrograms": [ @@ -1753,7 +1778,8 @@ "course": { "courseName": "Course Name 25", "bannerImgSrc": "/asset-v1:edX+DemoX+Demo_Course+type@asset+block@images_course_image.jpg", - "courseNumber": "course-number25" + "courseNumber": "course-number25", + "socialShareUrl": "edx.com/courses/my-course-url/marketing/about" }, "programs": { "relatedPrograms": [ @@ -1850,7 +1876,8 @@ "course": { "courseName": "Course Name 26", "bannerImgSrc": "/asset-v1:edX+DemoX+Demo_Course+type@asset+block@images_course_image.jpg", - "courseNumber": "course-number26" + "courseNumber": "course-number26", + "socialShareUrl": "edx.com/courses/my-course-url/marketing/about" }, "programs": { "relatedPrograms": [] @@ -1939,7 +1966,8 @@ "course": { "courseName": "Course Name 27", "bannerImgSrc": "/asset-v1:edX+DemoX+Demo_Course+type@asset+block@images_course_image.jpg", - "courseNumber": "course-number27" + "courseNumber": "course-number27", + "socialShareUrl": "edx.com/courses/my-course-url/marketing/about" }, "programs": { "relatedPrograms": [ @@ -2022,7 +2050,8 @@ "course": { "courseName": "Course Name 28", "bannerImgSrc": "/asset-v1:edX+DemoX+Demo_Course+type@asset+block@images_course_image.jpg", - "courseNumber": "course-number28" + "courseNumber": "course-number28", + "socialShareUrl": "edx.com/courses/my-course-url/marketing/about" }, "programs": { "relatedPrograms": [ @@ -2093,7 +2122,8 @@ "course": { "courseName": "Course Name 29", "bannerImgSrc": "/asset-v1:edX+DemoX+Demo_Course+type@asset+block@images_course_image.jpg", - "courseNumber": "course-number29" + "courseNumber": "course-number29", + "socialShareUrl": "edx.com/courses/my-course-url/marketing/about" }, "programs": { "relatedPrograms": [] @@ -2156,7 +2186,8 @@ "course": { "courseName": "Course Name 30", "bannerImgSrc": "/asset-v1:edX+DemoX+Demo_Course+type@asset+block@images_course_image.jpg", - "courseNumber": "course-number30" + "courseNumber": "course-number30", + "socialShareUrl": "edx.com/courses/my-course-url/marketing/about" }, "programs": { "relatedPrograms": [ @@ -2239,7 +2270,8 @@ "course": { "courseName": "Course Name 31", "bannerImgSrc": "/asset-v1:edX+DemoX+Demo_Course+type@asset+block@images_course_image.jpg", - "courseNumber": "course-number31" + "courseNumber": "course-number31", + "socialShareUrl": "edx.com/courses/my-course-url/marketing/about" }, "programs": { "relatedPrograms": [ @@ -2318,7 +2350,8 @@ "course": { "courseNumber": "course-number100", "courseName": "Course Name 100", - "bannerImgSrc": "/asset-v1:edX+DemoX+Demo_Course+type@asset+block@images_course_image.jpg" + "bannerImgSrc": "/asset-v1:edX+DemoX+Demo_Course+type@asset+block@images_course_image.jpg", + "socialShareUrl": "edx.com/courses/my-course-url/marketing/about" }, "programs": { "relatedPrograms": [ @@ -2407,7 +2440,8 @@ "course": { "courseNumber": "course-number101", "courseName": "Course Name 101", - "bannerImgSrc": "/asset-v1:edX+DemoX+Demo_Course+type@asset+block@images_course_image.jpg" + "bannerImgSrc": "/asset-v1:edX+DemoX+Demo_Course+type@asset+block@images_course_image.jpg", + "socialShareUrl": "edx.com/courses/my-course-url/marketing/about" }, "programs": { "relatedPrograms": [ @@ -2484,7 +2518,8 @@ "course": { "courseNumber": "course-number102", "courseName": "Course Name 102", - "bannerImgSrc": "/asset-v1:edX+DemoX+Demo_Course+type@asset+block@images_course_image.jpg" + "bannerImgSrc": "/asset-v1:edX+DemoX+Demo_Course+type@asset+block@images_course_image.jpg", + "socialShareUrl": "edx.com/courses/my-course-url/marketing/about" }, "programs": { "relatedPrograms": [] @@ -2527,7 +2562,8 @@ "course": { "courseNumber": "course-number103", "courseName": "Course Name 103", - "bannerImgSrc": "/asset-v1:edX+DemoX+Demo_Course+type@asset+block@images_course_image.jpg" + "bannerImgSrc": "/asset-v1:edX+DemoX+Demo_Course+type@asset+block@images_course_image.jpg", + "socialShareUrl": "edx.com/courses/my-course-url/marketing/about" }, "programs": { "relatedPrograms": [ @@ -2567,6 +2603,16 @@ "billingEmail": "billing@email.com", "courseSearchUrl": "edx.com/course-search" }, + "socialShareSettings": { + "facebook": { + "isEnabled": true, + "utmParams": "utm_medium=social&utm_campaign=social-sharing-db&utm_source=facebook" + }, + "twitter": { + "isEnabled": true, + "utmParams": "utm_medium=social&utm_campaign=social-sharing-db&utm_source=twitter" + } + }, "suggestedCourses": [ { "bannerImgSrc": "https://prod-discovery.edx-cdn.org/media/programs/banner_images/9a310b98-8f27-439e-be85-12d6460245c9-f2efca129273.small.jpg", diff --git a/lms/djangoapps/learner_home/serializers.py b/lms/djangoapps/learner_home/serializers.py index 7d49792f81..527aaff4a4 100644 --- a/lms/djangoapps/learner_home/serializers.py +++ b/lms/djangoapps/learner_home/serializers.py @@ -39,6 +39,21 @@ class PlatformSettingsSerializer(serializers.Serializer): courseSearchUrl = serializers.URLField() +class SocialMediaSiteSettingsSerializer(serializers.Serializer): + """Social media sharing config for a particular website""" + + isEnabled = serializers.BooleanField(source="is_enabled") + socialBrand = serializers.CharField(source="brand") + utmParams = serializers.CharField(source="utm_params") + + +class SocialShareSettingsSerializer(serializers.Serializer): + """Serializer for social media sharing config""" + + facebook = SocialMediaSiteSettingsSerializer() + twitter = SocialMediaSiteSettingsSerializer() + + class CourseProviderSerializer(serializers.Serializer): """Info about a course provider (institution/business) from a CourseOverview""" @@ -51,6 +66,10 @@ class CourseSerializer(serializers.Serializer): bannerImgSrc = serializers.URLField(source="image_urls.small") courseName = serializers.CharField(source="display_name_with_default") courseNumber = serializers.CharField(source="display_number_with_default") + socialShareUrl = serializers.SerializerMethodField() + + def get_socialShareUrl(self, instance): + return self.context.get("course_share_urls", {}).get(instance.id) class CourseRunSerializer(serializers.Serializer): @@ -546,6 +565,7 @@ class LearnerDashboardSerializer(serializers.Serializer): enterpriseDashboard = EnterpriseDashboardSerializer(allow_null=True) platformSettings = PlatformSettingsSerializer() courses = serializers.SerializerMethodField() + socialShareSettings = SocialShareSettingsSerializer() suggestedCourses = serializers.ListField( child=SuggestedCourseSerializer(), allow_empty=True ) diff --git a/lms/djangoapps/learner_home/test_serializers.py b/lms/djangoapps/learner_home/test_serializers.py index f530f2e90d..071563f4ee 100644 --- a/lms/djangoapps/learner_home/test_serializers.py +++ b/lms/djangoapps/learner_home/test_serializers.py @@ -43,6 +43,8 @@ from lms.djangoapps.learner_home.serializers import ( ProgramsSerializer, LearnerDashboardSerializer, RelatedProgramSerializer, + SocialMediaSiteSettingsSerializer, + SocialShareSettingsSerializer, SuggestedCourseSerializer, UnfulfilledEntitlementSerializer, ) @@ -161,16 +163,26 @@ class TestCourseProviderSerializer(LearnerDashboardBaseTest): class TestCourseSerializer(LearnerDashboardBaseTest): """Tests for the CourseSerializer""" + def create_test_context(self, course_id): + return { + "course_share_urls": { + course_id: random_url() + } + } + def test_happy_path(self): test_enrollment = self.create_test_enrollment() + course_id = test_enrollment.course_overview.id + test_context = self.create_test_context(course_id) input_data = test_enrollment.course_overview - output_data = CourseSerializer(input_data).data + output_data = CourseSerializer(input_data, context=test_context).data assert output_data == { "bannerImgSrc": test_enrollment.course_overview.banner_image_url, "courseName": test_enrollment.course_overview.display_name_with_default, "courseNumber": test_enrollment.course_overview.display_number_with_default, + "socialShareUrl": test_context['course_share_urls'][course_id] } @@ -1095,6 +1107,54 @@ class TestEnterpriseDashboardSerializer(TestCase): ) +class TestSocialMediaSettingsSiteSerializer(TestCase): + """ Tests for the SocialMediaSiteSettingsSerializer """ + + @classmethod + def generate_test_social_media_settings(cls): + return { + "is_enabled": random_bool(), + "brand": random_string(), + "utm_params": random_string(), + } + + def test_structure(self): + """Test that nothing breaks and the output fields look correct""" + input_data = self.generate_test_social_media_settings() + + output_data = SocialMediaSiteSettingsSerializer(input_data).data + + expected_keys = [ + "isEnabled", + "socialBrand", + "utmParams", + ] + self.assertEqual(output_data.keys(), set(expected_keys)) + + +class TestSocialShareSettingsSerializer(TestCase): + """ Tests for the SocialShareSettingsSerializer """ + + @classmethod + def generate_test_social_share_settings(cls): + return { + "twitter": TestSocialMediaSettingsSiteSerializer.generate_test_social_media_settings(), + "facebook": TestSocialMediaSettingsSiteSerializer.generate_test_social_media_settings() + } + + def test_structure(self): + """Test that nothing breaks and the output fields look correct""" + input_data = self.generate_test_social_share_settings() + + output_data = SocialShareSettingsSerializer(input_data).data + + expected_keys = [ + "twitter", + "facebook" + ] + self.assertEqual(output_data.keys(), set(expected_keys)) + + class TestLearnerDashboardSerializer(LearnerDashboardBaseTest): """High-level tests for Learner Dashboard serialization""" @@ -1186,6 +1246,7 @@ class TestLearnerDashboardSerializer(LearnerDashboardBaseTest): "platformSettings": None, "enrollments": [], "unfulfilledEntitlements": [], + "socialShareSettings": None, "suggestedCourses": [], } output_data = LearnerDashboardSerializer(input_data).data @@ -1197,6 +1258,7 @@ class TestLearnerDashboardSerializer(LearnerDashboardBaseTest): "enterpriseDashboard": None, "platformSettings": None, "courses": [], + "socialShareSettings": None, "suggestedCourses": [], }, ) @@ -1216,6 +1278,7 @@ class TestLearnerDashboardSerializer(LearnerDashboardBaseTest): "platformSettings": None, "enrollments": enrollments, "unfulfilledEntitlements": [], + "socialShareSettings": None, "suggestedCourses": [], } @@ -1243,6 +1306,7 @@ class TestLearnerDashboardSerializer(LearnerDashboardBaseTest): "platformSettings": None, "enrollments": enrollments, "unfulfilledEntitlements": unfulfilled_entitlements, + "socialShareSettings": None, "suggestedCourses": [], } @@ -1277,6 +1341,7 @@ class TestLearnerDashboardSerializer(LearnerDashboardBaseTest): "platformSettings": None, "enrollments": [], "unfulfilledEntitlements": [], + "socialShareSettings": None, "suggestedCourses": suggested_courses, } output_data = LearnerDashboardSerializer(input_data).data @@ -1288,6 +1353,9 @@ class TestLearnerDashboardSerializer(LearnerDashboardBaseTest): @mock.patch( "lms.djangoapps.learner_home.serializers.SuggestedCourseSerializer.to_representation" ) + @mock.patch( + "lms.djangoapps.learner_home.serializers.SocialShareSettingsSerializer.to_representation" + ) @mock.patch( "lms.djangoapps.learner_home.serializers.UnfulfilledEntitlementSerializer.data" ) @@ -1310,6 +1378,7 @@ class TestLearnerDashboardSerializer(LearnerDashboardBaseTest): mock_platform_settings_serializer, mock_learner_enrollment_serializer, mock_entitlement_serializer, + mock_social_settings_serializer, mock_suggestions_serializer, ): mock_email_confirmation_serializer.return_value = ( @@ -1325,6 +1394,7 @@ class TestLearnerDashboardSerializer(LearnerDashboardBaseTest): mock_learner_enrollment_serializer ) mock_entitlement_serializer.return_value = mock_entitlement_serializer + mock_social_settings_serializer.return_value = mock_social_settings_serializer mock_suggestions_serializer.return_value = mock_suggestions_serializer input_data = { @@ -1333,6 +1403,7 @@ class TestLearnerDashboardSerializer(LearnerDashboardBaseTest): "platformSettings": {}, "enrollments": [{}], "unfulfilledEntitlements": [{}], + "socialShareSettings": {}, "suggestedCourses": [{}], } output_data = LearnerDashboardSerializer(input_data).data @@ -1347,6 +1418,7 @@ class TestLearnerDashboardSerializer(LearnerDashboardBaseTest): mock_learner_enrollment_serializer, mock_entitlement_serializer, ], + "socialShareSettings": mock_social_settings_serializer, "suggestedCourses": [mock_suggestions_serializer], }, ) diff --git a/lms/djangoapps/learner_home/test_views.py b/lms/djangoapps/learner_home/test_views.py index 996549b12b..99874f9ee8 100644 --- a/lms/djangoapps/learner_home/test_views.py +++ b/lms/djangoapps/learner_home/test_views.py @@ -2,7 +2,7 @@ from contextlib import contextmanager import json -from unittest import mock, TestCase +from unittest import mock from unittest.mock import Mock, patch from urllib.parse import urlencode from uuid import uuid4 @@ -11,6 +11,7 @@ import ddt from django.conf import settings from django.urls import reverse, reverse_lazy from django.utils import timezone +from django.test import TestCase, override_settings from edx_toggles.toggles.testutils import override_waffle_flag from opaque_keys.edx.keys import CourseKey from rest_framework.test import APITestCase @@ -22,8 +23,9 @@ from common.djangoapps.student.tests.factories import ( CourseEnrollmentFactory, UserFactory, ) +from common.djangoapps.util.course import get_encoded_course_sharing_utm_params from lms.djangoapps.bulk_email.models import Optout -from lms.djangoapps.learner_home.test_utils import create_test_enrollment +from lms.djangoapps.learner_home.test_utils import create_test_enrollment, random_string from lms.djangoapps.learner_home.views import ( get_course_overviews_for_pseudo_sessions, get_course_programs, @@ -34,6 +36,8 @@ from lms.djangoapps.learner_home.views import ( get_suggested_courses, get_user_account_confirmation_info, get_entitlements, + get_social_share_settings, + get_course_share_urls, ) from lms.djangoapps.learner_home.test_serializers import random_url from openedx.core.djangoapps.catalog.tests.factories import ( @@ -420,6 +424,69 @@ class TestGetEnterpriseCustomer(TestCase): assert result is mock_get_from_session.return_value +class TestGetSocialShareSettings(TestCase): + """ Tests for get_social_share_settings """ + + def test_get_social_share_settings(self): + share_settings = { + "DASHBOARD_FACEBOOK": True, + "FACEBOOK_BRAND": random_string(), + "DASHBOARD_TWITTER": True, + "TWITTER_BRAND": random_string(), + } + + utm_sources = get_encoded_course_sharing_utm_params() + with override_settings(SOCIAL_SHARING_SETTINGS=share_settings): + social_share_settings = get_social_share_settings() + + assert social_share_settings == { + "facebook": { + "is_enabled": True, + "brand": share_settings["FACEBOOK_BRAND"], + "utm_params": utm_sources.get("facebook") + }, + "twitter": { + "is_enabled": True, + "brand": share_settings["TWITTER_BRAND"], + "utm_params": utm_sources.get("twitter") + } + } + + @patch('lms.djangoapps.learner_home.views.get_encoded_course_sharing_utm_params') + def test_social_share_settings__empty(self, mock_get_utm_params): + share_settings = {} + mock_get_utm_params.return_value = {} + + with override_settings(SOCIAL_SHARING_SETTINGS=share_settings): + social_share_settings = get_social_share_settings() + + assert social_share_settings == { + "facebook": { + "is_enabled": False, + "brand": "edX.org", + "utm_params": None + }, + "twitter": { + "is_enabled": False, + "brand": "edX.org", + "utm_params": None + } + } + + +class TestGetCourseShareUrls(TestCase): + """ Tests for get_course_share_urls """ + + @patch('lms.djangoapps.learner_home.views.get_link_for_about_page') + def test_get_course_share_urls(self, mock_about_page_link): + enrollments = CourseEnrollmentFactory.create_batch(3) + course_share_urls = get_course_share_urls(enrollments) + assert course_share_urls == { + course_enrollment.course_id: mock_about_page_link(course_enrollment.course) + for course_enrollment in enrollments + } + + class BaseTestDashboardView(SharedModuleStoreTestCase, APITestCase): """Base class for test setup""" @@ -498,6 +565,7 @@ class TestDashboardView(BaseTestDashboardView): "enterpriseDashboard", "platformSettings", "courses", + "socialShareSettings", "suggestedCourses", ] ) diff --git a/lms/djangoapps/learner_home/views.py b/lms/djangoapps/learner_home/views.py index 970fa66cdf..7ff61cf02e 100644 --- a/lms/djangoapps/learner_home/views.py +++ b/lms/djangoapps/learner_home/views.py @@ -5,6 +5,10 @@ import logging from django.conf import settings from django.contrib.auth import get_user_model from django.core.exceptions import MultipleObjectsReturned +from common.djangoapps.util.course import ( + get_encoded_course_sharing_utm_params, + get_link_for_about_page, +) from edx_django_utils import monitoring as monitoring_utils from opaque_keys.edx.keys import CourseKey from rest_framework.exceptions import PermissionDenied, NotFound @@ -296,6 +300,39 @@ def get_suggested_courses(): ) +def get_social_share_settings(): + """Config around social media sharing campaigns""" + + share_settings = configuration_helpers.get_value( + "SOCIAL_SHARING_SETTINGS", getattr(settings, "SOCIAL_SHARING_SETTINGS", {}) + ) + + utm_sources = get_encoded_course_sharing_utm_params() + + default_brand = "edX.org" + + return { + "facebook": { + "is_enabled": share_settings.get("DASHBOARD_FACEBOOK", False), + "brand": share_settings.get("FACEBOOK_BRAND", default_brand), + "utm_params": utm_sources.get("facebook"), + }, + "twitter": { + "is_enabled": share_settings.get("DASHBOARD_TWITTER", False), + "brand": share_settings.get("TWITTER_BRAND", default_brand), + "utm_params": utm_sources.get("twitter"), + }, + } + + +def get_course_share_urls(course_enrollments): + """Get course URLs for sharing on social media""" + return { + course_enrollment.course_id: get_link_for_about_page(course_enrollment.course) + for course_enrollment in course_enrollments + } + + class InitializeView(RetrieveAPIView): # pylint: disable=unused-argument """List of courses a user is enrolled in or entitled to""" @@ -381,12 +418,17 @@ class InitializeView(RetrieveAPIView): # pylint: disable=unused-argument # Get suggested courses suggested_courses = get_suggested_courses().get("courses", []) + # Get social media sharing config + social_share_settings = get_social_share_settings() + course_share_urls = get_course_share_urls(course_enrollments) + learner_dash_data = { "emailConfirmation": email_confirmation, "enterpriseDashboard": enterprise_customer, "platformSettings": get_platform_settings(), "enrollments": course_enrollments, "unfulfilledEntitlements": unfulfilled_entitlements, + "socialShareSettings": social_share_settings, "suggestedCourses": suggested_courses, } @@ -397,6 +439,7 @@ class InitializeView(RetrieveAPIView): # pylint: disable=unused-argument "course_optouts": course_optouts, "course_access_checks": course_access_checks, "resume_course_urls": resume_button_urls, + "course_share_urls": course_share_urls, "show_email_settings_for": show_email_settings_for, "fulfilled_entitlements": fulfilled_entitlements_by_course_key, "course_entitlement_available_sessions": course_entitlement_available_sessions,