Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
141 changes: 141 additions & 0 deletions openedx/core/djangoapps/user_authn/api/tests/test_data.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,141 @@
""" Mocked data for testing """

mfe_context_data_keys = {
'contextData',
'registrationFields',
'optionalFields'
}

mock_mfe_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': []
}
}

mock_default_mfe_context_data = {
'context_data': {
'currentProvider': None,
'platformName': 'édX',
'providers': [],
'secondaryProviders': [],
'finishAuthUrl': None,
'errorMessage': None,
'registerFormSubmitButtonText': 'Create Account',
'autoSubmitRegForm': False,
'syncLearnerProfileData': False,
'countryCode': '',
'pipeline_user_details': {}
},
'registration_fields': {},
'optional_fields': {
'extended_profile': []
}
}

expected_mfe_context_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': []
}
}

default_expected_mfe_context_data = {
'contextData': {
'currentProvider': None,
'platformName': 'édX',
'providers': [],
'secondaryProviders': [],
'finishAuthUrl': None,
'errorMessage': None,
'registerFormSubmitButtonText': 'Create Account',
'autoSubmitRegForm': False,
'syncLearnerProfileData': False,
'countryCode': '',
'pipelineUserDetails': {}
},
'registrationFields': {},
'optionalFields': {
'extended_profile': []
}
}
44 changes: 44 additions & 0 deletions openedx/core/djangoapps/user_authn/api/tests/test_serializers.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
"""Tests for serializers for the MFE Context"""

from django.test import TestCase

from openedx.core.djangoapps.user_authn.api.tests.test_data import (
mock_mfe_context_data,
expected_mfe_context_data,
mock_default_mfe_context_data,
default_expected_mfe_context_data,
)
from openedx.core.djangoapps.user_authn.serializers import MFEContextSerializer


class TestMFEContextSerializer(TestCase):
"""
High-level unit tests for MFEContextSerializer
"""

def test_mfe_context_serializer(self):
"""
Test MFEContextSerializer with mock data that serializes data correctly
"""

output_data = MFEContextSerializer(
mock_mfe_context_data
).data

self.assertDictEqual(
output_data,
expected_mfe_context_data
)

def test_mfe_context_serializer_default_response(self):
"""
Test MFEContextSerializer with default data
"""
serialized_data = MFEContextSerializer(
mock_default_mfe_context_data
).data

self.assertDictEqual(
serialized_data,
default_expected_mfe_context_data
)
72 changes: 57 additions & 15 deletions openedx/core/djangoapps/user_authn/api/tests/test_views.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,10 @@
from common.djangoapps.student.tests.factories import UserFactory
from common.djangoapps.third_party_auth import pipeline
from common.djangoapps.third_party_auth.tests.testutil import ThirdPartyAuthTestMixin, simulate_running_pipeline
from openedx.core.djangoapps.site_configuration.tests.test_util import with_site_configuration
from openedx.core.djangoapps.geoinfo.api import country_code_from_ip
from openedx.core.djangoapps.site_configuration.tests.test_util import with_site_configuration
from openedx.core.djangoapps.user_api.tests.test_views import UserAPITestCase
from openedx.core.djangoapps.user_authn.api.tests.test_data import mfe_context_data_keys
from openedx.core.djangolib.testing.utils import skip_unless_lms


Expand All @@ -42,6 +43,7 @@ def setUp(self): # pylint: disable=arguments-differ
hostname = socket.gethostname()
ip_address = socket.gethostbyname(hostname)
self.country_code = country_code_from_ip(ip_address)
self.pipeline_user_details = {}

# Several third party auth providers are created for these tests:
self.configure_google_provider(enabled=True, visible=True)
Expand Down Expand Up @@ -93,21 +95,34 @@ def get_context(self, params=None, current_provider=None, backend_name=None, add
"""
Returns the MFE context
"""

if add_user_details:
self.pipeline_user_details.update(
{
'username': None,
'email': 'test@test.com',
'name': None,
'firstName': None,
'lastName': None
}
)

return {
'context_data': {
'contextData': {
'currentProvider': current_provider,
'platformName': settings.PLATFORM_NAME,
'providers': self.get_provider_data(params) if params else [],
'secondaryProviders': [],
'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': [],
},
}
Expand Down Expand Up @@ -182,7 +197,7 @@ def test_tpa_hint(self):
})

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):
"""
Expand All @@ -191,7 +206,7 @@ def test_user_country_code(self):
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,
Expand All @@ -205,7 +220,7 @@ def test_required_fields_not_configured(self):
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={
Expand All @@ -223,8 +238,9 @@ def test_required_field_order(self):
"""
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,
Expand All @@ -248,7 +264,7 @@ def test_optional_field_has_no_description(self):
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={
Expand Down Expand Up @@ -282,8 +298,9 @@ def test_configurable_select_option_fields(self):
}
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={
Expand All @@ -302,7 +319,7 @@ def test_optional_field_order(self):
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={
Expand All @@ -322,7 +339,7 @@ def test_field_not_available_in_extended_profile_config(self):
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,
Expand All @@ -333,9 +350,34 @@ def test_response_structure(self):
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()

def test_mfe_context_api_serialized_response(self):
"""
Test MFE Context API serialized response
"""
response = self.client.get(self.url, self.query_params)
self.assertEqual(response.status_code, status.HTTP_200_OK)

params = {
'next': self.query_params['next']
}

self.assertEqual(
response.data,
self.get_context(params)
)

def test_mfe_context_api_response_keys(self):
"""
Test MFE Context API response keys
"""
response = self.client.get(self.url, self.query_params)
self.assertEqual(response.status_code, status.HTTP_200_OK)

response_keys = set(response.data.keys())
self.assertSetEqual(response_keys, mfe_context_data_keys)


@skip_unless_lms
class SendAccountActivationEmail(UserAPITestCase):
Expand Down
6 changes: 5 additions & 1 deletion openedx/core/djangoapps/user_authn/api/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
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


Expand Down Expand Up @@ -65,6 +66,7 @@ def get(self, request, **kwargs): # lint-amnesty, pylint: disable=unused-argume
context['registration_fields'].update({
'fields': registration_fields,
})

optional_fields = RegistrationFieldsContext('optional').get_fields()
if optional_fields:
context['optional_fields'].update({
Expand All @@ -74,7 +76,9 @@ def get(self, request, **kwargs): # lint-amnesty, pylint: disable=unused-argume

return Response(
status=status.HTTP_200_OK,
data=context
data=MFEContextSerializer(
context
).data
)


Expand Down
Loading