refactor: mfe_context response to serialize object keys to camelcase (#31930)

This commit is contained in:
Shahbaz Shabbir
2023-04-20 12:28:17 +05:00
committed by GitHub
parent 62e59d8ace
commit 936a236273
4 changed files with 241 additions and 15 deletions

View File

@@ -0,0 +1,137 @@
"""Tests for serializers for the MFE Context"""
from django.test import TestCase
from openedx.core.djangoapps.user_authn.serializers import MFEContextSerializer
class TestMFEContextSerializer(TestCase):
"""
High-level unit tests for MFEContextSerializer
"""
@staticmethod
def get_mock_mfe_context_data():
"""
Helper function to generate mock data for the MFE Context API view.
"""
mock_context_data = {
'context_data': {
'currentProvider': 'edX',
'platformName': 'edX',
'providers': [
{
'id': 'oa2-facebook',
'name': 'Facebook',
'iconClass': 'fa-facebook',
'iconImage': None,
'skipHintedLogin': False,
'skipRegistrationForm': False,
'loginUrl': 'https://facebook.com/login',
'registerUrl': 'https://facebook.com/register'
},
{
'id': 'oa2-google-oauth2',
'name': 'Google',
'iconClass': 'fa-google-plus',
'iconImage': None,
'skipHintedLogin': False,
'skipRegistrationForm': False,
'loginUrl': 'https://google.com/login',
'registerUrl': 'https://google.com/register'
}
],
'secondaryProviders': [],
'finishAuthUrl': 'https://edx.com/auth/finish',
'errorMessage': None,
'registerFormSubmitButtonText': 'Create Account',
'autoSubmitRegForm': False,
'syncLearnerProfileData': False,
'countryCode': '',
'pipeline_user_details': {
'username': 'test123',
'email': 'test123@edx.com',
'fullname': 'Test Test',
'first_name': 'Test',
'last_name': 'Test'
}
},
'registration_fields': {},
'optional_fields': {
'extended_profile': []
}
}
return mock_context_data
@staticmethod
def get_expected_data():
"""
Helper function to generate expected data for the MFE Context API view serializer.
"""
expected_data = {
'contextData': {
'currentProvider': 'edX',
'platformName': 'edX',
'providers': [
{
'id': 'oa2-facebook',
'name': 'Facebook',
'iconClass': 'fa-facebook',
'iconImage': None,
'skipHintedLogin': False,
'skipRegistrationForm': False,
'loginUrl': 'https://facebook.com/login',
'registerUrl': 'https://facebook.com/register'
},
{
'id': 'oa2-google-oauth2',
'name': 'Google',
'iconClass': 'fa-google-plus',
'iconImage': None,
'skipHintedLogin': False,
'skipRegistrationForm': False,
'loginUrl': 'https://google.com/login',
'registerUrl': 'https://google.com/register'
}
],
'secondaryProviders': [],
'finishAuthUrl': 'https://edx.com/auth/finish',
'errorMessage': None,
'registerFormSubmitButtonText': 'Create Account',
'autoSubmitRegForm': False,
'syncLearnerProfileData': False,
'countryCode': '',
'pipelineUserDetails': {
'username': 'test123',
'email': 'test123@edx.com',
'name': 'Test Test',
'firstName': 'Test',
'lastName': 'Test'
}
},
'registrationFields': {},
'optionalFields': {
'extended_profile': []
}
}
return expected_data
def test_mfe_context_serializer(self):
"""
Test MFEContextSerializer with mock data that serializes data correctly
"""
mfe_context_data = self.get_mock_mfe_context_data()
expected_data = self.get_expected_data()
output_data = MFEContextSerializer(
mfe_context_data
).data
self.assertDictEqual(
output_data,
expected_data
)

View File

@@ -42,6 +42,8 @@ class MFEContextViewTest(ThirdPartyAuthTestMixin, APITestCase):
hostname = socket.gethostname()
ip_address = socket.gethostbyname(hostname)
self.country_code = country_code_from_ip(ip_address)
self.pipeline_user_details = {'username': None, 'email': None, 'name': None,
'firstName': None, 'lastName': None}
# Several third party auth providers are created for these tests:
self.configure_google_provider(enabled=True, visible=True)
@@ -93,8 +95,12 @@ class MFEContextViewTest(ThirdPartyAuthTestMixin, APITestCase):
"""
Returns the MFE context
"""
if add_user_details:
self.pipeline_user_details.update({'email': 'test@test.com'})
return {
'context_data': {
'contextData': {
'currentProvider': current_provider,
'platformName': settings.PLATFORM_NAME,
'providers': self.get_provider_data(params) if params else [],
@@ -102,12 +108,13 @@ class MFEContextViewTest(ThirdPartyAuthTestMixin, APITestCase):
'finishAuthUrl': pipeline.get_complete_url(backend_name) if backend_name else None,
'errorMessage': None,
'registerFormSubmitButtonText': 'Create Account',
'autoSubmitRegForm': False,
'syncLearnerProfileData': False,
'pipeline_user_details': {'email': 'test@test.com'} if add_user_details else {},
'countryCode': self.country_code
'countryCode': self.country_code,
'pipelineUserDetails': self.pipeline_user_details,
},
'registration_fields': {},
'optional_fields': {
'registrationFields': {},
'optionalFields': {
'extended_profile': [],
},
}
@@ -182,7 +189,7 @@ class MFEContextViewTest(ThirdPartyAuthTestMixin, APITestCase):
})
response = self.client.get(self.url, self.query_params)
assert response.data['context_data']['providers'] == provider_data
assert response.data['contextData']['providers'] == provider_data
def test_user_country_code(self):
"""
@@ -191,7 +198,7 @@ class MFEContextViewTest(ThirdPartyAuthTestMixin, APITestCase):
response = self.client.get(self.url, self.query_params)
assert response.status_code == 200
assert response.data['context_data']['countryCode'] == self.country_code
assert response.data['contextData']['countryCode'] == self.country_code
@override_settings(
ENABLE_DYNAMIC_REGISTRATION_FIELDS=True,
@@ -205,7 +212,7 @@ class MFEContextViewTest(ThirdPartyAuthTestMixin, APITestCase):
self.query_params.update({'is_register_page': True})
response = self.client.get(self.url, self.query_params)
assert response.status_code == status.HTTP_200_OK
assert response.data['registration_fields']['fields'] == {}
assert response.data['registrationFields']['fields'] == {}
@with_site_configuration(
configuration={
@@ -223,8 +230,9 @@ class MFEContextViewTest(ThirdPartyAuthTestMixin, APITestCase):
"""
self.query_params.update({'is_register_page': True})
response = self.client.get(self.url, self.query_params)
assert response.status_code == status.HTTP_200_OK
assert list(response.data['registration_fields']['fields'].keys()) == ['first_name', 'last_name', 'state']
assert list(response.data['registrationFields']['fields'].keys()) == ['first_name', 'last_name', 'state']
@override_settings(
ENABLE_DYNAMIC_REGISTRATION_FIELDS=True,
@@ -248,7 +256,7 @@ class MFEContextViewTest(ThirdPartyAuthTestMixin, APITestCase):
self.query_params.update({'is_register_page': True})
response = self.client.get(self.url, self.query_params)
assert response.status_code == status.HTTP_200_OK
assert response.data['optional_fields']['fields'] == expected_response
assert response.data['optionalFields']['fields'] == expected_response
@with_site_configuration(
configuration={
@@ -282,8 +290,9 @@ class MFEContextViewTest(ThirdPartyAuthTestMixin, APITestCase):
}
self.query_params.update({'is_register_page': True})
response = self.client.get(self.url, self.query_params)
assert response.status_code == status.HTTP_200_OK
assert response.data['optional_fields']['fields'] == expected_response
assert response.data['optionalFields']['fields'] == expected_response
@with_site_configuration(
configuration={
@@ -302,7 +311,7 @@ class MFEContextViewTest(ThirdPartyAuthTestMixin, APITestCase):
self.query_params.update({'is_register_page': True})
response = self.client.get(self.url, self.query_params)
assert response.status_code == status.HTTP_200_OK
assert list(response.data['optional_fields']['fields'].keys()) == ['specialty', 'goals']
assert list(response.data['optionalFields']['fields'].keys()) == ['specialty', 'goals']
@with_site_configuration(
configuration={
@@ -322,7 +331,7 @@ class MFEContextViewTest(ThirdPartyAuthTestMixin, APITestCase):
self.query_params.update({'is_register_page': True})
response = self.client.get(self.url, self.query_params)
assert response.status_code == status.HTTP_200_OK
assert list(response.data['registration_fields']['fields'].keys()) == ['specialty']
assert list(response.data['registrationFields']['fields'].keys()) == ['specialty']
@override_settings(
ENABLE_DYNAMIC_REGISTRATION_FIELDS=True,
@@ -333,7 +342,6 @@ class MFEContextViewTest(ThirdPartyAuthTestMixin, APITestCase):
Test that API return valid response dictionary with both required and optional fields
"""
response = self.client.get(self.url, self.query_params)
assert response.data == self.get_context()

View File

@@ -15,6 +15,7 @@ from common.djangoapps.student.helpers import get_next_url_for_login_page
from common.djangoapps.student.views import compose_and_send_activation_email
from openedx.core.djangoapps.site_configuration import helpers as configuration_helpers
from openedx.core.djangoapps.user_authn.api.helper import RegistrationFieldsContext
from openedx.core.djangoapps.user_authn.serializers import MFEContextSerializer
from openedx.core.djangoapps.user_authn.views.utils import get_mfe_context
@@ -65,6 +66,7 @@ class MFEContextView(APIView):
context['registration_fields'].update({
'fields': registration_fields,
})
optional_fields = RegistrationFieldsContext('optional').get_fields()
if optional_fields:
context['optional_fields'].update({
@@ -74,7 +76,9 @@ class MFEContextView(APIView):
return Response(
status=status.HTTP_200_OK,
data=context
data=MFEContextSerializer(
context
).data
)

View File

@@ -0,0 +1,77 @@
"""
MFE Context API Serializers
"""
from rest_framework import serializers
class ProvidersSerializer(serializers.Serializer):
"""
Providers Serializers
"""
id = serializers.CharField(allow_null=True)
name = serializers.CharField(allow_null=True)
iconClass = serializers.CharField(allow_null=True)
iconImage = serializers.CharField(allow_null=True)
skipHintedLogin = serializers.BooleanField(default=False)
skipRegistrationForm = serializers.BooleanField(default=False)
loginUrl = serializers.CharField(allow_null=True)
registerUrl = serializers.CharField(allow_null=True)
class PipelineUserDetailsSerializer(serializers.Serializer):
"""
Pipeline User Details Serializers
"""
username = serializers.CharField(allow_null=True)
email = serializers.CharField(allow_null=True)
name = serializers.CharField(source='fullname', allow_null=True)
firstName = serializers.CharField(source='first_name', allow_null=True)
lastName = serializers.CharField(source='last_name', allow_null=True)
class ContextDataSerializer(serializers.Serializer):
"""
Context Data Serializers
"""
currentProvider = serializers.CharField(allow_null=True)
platformName = serializers.CharField(allow_null=True)
providers = serializers.ListField(
child=ProvidersSerializer(),
allow_null=True
)
secondaryProviders = serializers.ListField(
child=ProvidersSerializer(),
allow_null=True
)
finishAuthUrl = serializers.CharField(allow_null=True)
errorMessage = serializers.CharField(allow_null=True)
registerFormSubmitButtonText = serializers.CharField(allow_null=True)
autoSubmitRegForm = serializers.BooleanField(default=False)
syncLearnerProfileData = serializers.BooleanField(default=False)
countryCode = serializers.CharField(allow_null=True)
pipelineUserDetails = PipelineUserDetailsSerializer(source='pipeline_user_details', allow_null=True)
class MFEContextSerializer(serializers.Serializer):
"""
Serializer class to convert the keys of MFE Context Response dict object to camelCase format.
"""
contextData = ContextDataSerializer(
source='context_data',
default={}
)
registrationFields = serializers.DictField(
source='registration_fields',
default={}
)
optionalFields = serializers.DictField(
source='optional_fields',
default={
'extended_profile': []
}
)