Skip to content

Commit 81681bb

Browse files
authored
Merge pull request #581 from open-craft/sync-open-release/palm.master-20230828-1693180991
Sync opencraft-release/palm.1 with Upstream 20230828-1693180991
2 parents 0e0bf04 + 6f9fc23 commit 81681bb

File tree

6 files changed

+331
-18
lines changed

6 files changed

+331
-18
lines changed
Lines changed: 141 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,141 @@
1+
""" Mocked data for testing """
2+
3+
mfe_context_data_keys = {
4+
'contextData',
5+
'registrationFields',
6+
'optionalFields'
7+
}
8+
9+
mock_mfe_context_data = {
10+
'context_data': {
11+
'currentProvider': 'edX',
12+
'platformName': 'edX',
13+
'providers': [
14+
{
15+
'id': 'oa2-facebook',
16+
'name': 'Facebook',
17+
'iconClass': 'fa-facebook',
18+
'iconImage': None,
19+
'skipHintedLogin': False,
20+
'skipRegistrationForm': False,
21+
'loginUrl': 'https://facebook.com/login',
22+
'registerUrl': 'https://facebook.com/register'
23+
},
24+
{
25+
'id': 'oa2-google-oauth2',
26+
'name': 'Google',
27+
'iconClass': 'fa-google-plus',
28+
'iconImage': None,
29+
'skipHintedLogin': False,
30+
'skipRegistrationForm': False,
31+
'loginUrl': 'https://google.com/login',
32+
'registerUrl': 'https://google.com/register'
33+
}
34+
],
35+
'secondaryProviders': [],
36+
'finishAuthUrl': 'https://edx.com/auth/finish',
37+
'errorMessage': None,
38+
'registerFormSubmitButtonText': 'Create Account',
39+
'autoSubmitRegForm': False,
40+
'syncLearnerProfileData': False,
41+
'countryCode': '',
42+
'pipeline_user_details': {
43+
'username': 'test123',
44+
'email': 'test123@edx.com',
45+
'fullname': 'Test Test',
46+
'first_name': 'Test',
47+
'last_name': 'Test'
48+
}
49+
},
50+
'registration_fields': {},
51+
'optional_fields': {
52+
'extended_profile': []
53+
}
54+
}
55+
56+
mock_default_mfe_context_data = {
57+
'context_data': {
58+
'currentProvider': None,
59+
'platformName': 'édX',
60+
'providers': [],
61+
'secondaryProviders': [],
62+
'finishAuthUrl': None,
63+
'errorMessage': None,
64+
'registerFormSubmitButtonText': 'Create Account',
65+
'autoSubmitRegForm': False,
66+
'syncLearnerProfileData': False,
67+
'countryCode': '',
68+
'pipeline_user_details': {}
69+
},
70+
'registration_fields': {},
71+
'optional_fields': {
72+
'extended_profile': []
73+
}
74+
}
75+
76+
expected_mfe_context_data = {
77+
'contextData': {
78+
'currentProvider': 'edX',
79+
'platformName': 'edX',
80+
'providers': [
81+
{
82+
'id': 'oa2-facebook',
83+
'name': 'Facebook',
84+
'iconClass': 'fa-facebook',
85+
'iconImage': None,
86+
'skipHintedLogin': False,
87+
'skipRegistrationForm': False,
88+
'loginUrl': 'https://facebook.com/login',
89+
'registerUrl': 'https://facebook.com/register'
90+
},
91+
{
92+
'id': 'oa2-google-oauth2',
93+
'name': 'Google',
94+
'iconClass': 'fa-google-plus',
95+
'iconImage': None,
96+
'skipHintedLogin': False,
97+
'skipRegistrationForm': False,
98+
'loginUrl': 'https://google.com/login',
99+
'registerUrl': 'https://google.com/register'
100+
}
101+
],
102+
'secondaryProviders': [],
103+
'finishAuthUrl': 'https://edx.com/auth/finish',
104+
'errorMessage': None,
105+
'registerFormSubmitButtonText': 'Create Account',
106+
'autoSubmitRegForm': False,
107+
'syncLearnerProfileData': False,
108+
'countryCode': '',
109+
'pipelineUserDetails': {
110+
'username': 'test123',
111+
'email': 'test123@edx.com',
112+
'name': 'Test Test',
113+
'firstName': 'Test',
114+
'lastName': 'Test'
115+
}
116+
},
117+
'registrationFields': {},
118+
'optionalFields': {
119+
'extended_profile': []
120+
}
121+
}
122+
123+
default_expected_mfe_context_data = {
124+
'contextData': {
125+
'currentProvider': None,
126+
'platformName': 'édX',
127+
'providers': [],
128+
'secondaryProviders': [],
129+
'finishAuthUrl': None,
130+
'errorMessage': None,
131+
'registerFormSubmitButtonText': 'Create Account',
132+
'autoSubmitRegForm': False,
133+
'syncLearnerProfileData': False,
134+
'countryCode': '',
135+
'pipelineUserDetails': {}
136+
},
137+
'registrationFields': {},
138+
'optionalFields': {
139+
'extended_profile': []
140+
}
141+
}
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
"""Tests for serializers for the MFE Context"""
2+
3+
from django.test import TestCase
4+
5+
from openedx.core.djangoapps.user_authn.api.tests.test_data import (
6+
mock_mfe_context_data,
7+
expected_mfe_context_data,
8+
mock_default_mfe_context_data,
9+
default_expected_mfe_context_data,
10+
)
11+
from openedx.core.djangoapps.user_authn.serializers import MFEContextSerializer
12+
13+
14+
class TestMFEContextSerializer(TestCase):
15+
"""
16+
High-level unit tests for MFEContextSerializer
17+
"""
18+
19+
def test_mfe_context_serializer(self):
20+
"""
21+
Test MFEContextSerializer with mock data that serializes data correctly
22+
"""
23+
24+
output_data = MFEContextSerializer(
25+
mock_mfe_context_data
26+
).data
27+
28+
self.assertDictEqual(
29+
output_data,
30+
expected_mfe_context_data
31+
)
32+
33+
def test_mfe_context_serializer_default_response(self):
34+
"""
35+
Test MFEContextSerializer with default data
36+
"""
37+
serialized_data = MFEContextSerializer(
38+
mock_default_mfe_context_data
39+
).data
40+
41+
self.assertDictEqual(
42+
serialized_data,
43+
default_expected_mfe_context_data
44+
)

openedx/core/djangoapps/user_authn/api/tests/test_views.py

Lines changed: 57 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,10 @@
1616
from common.djangoapps.student.tests.factories import UserFactory
1717
from common.djangoapps.third_party_auth import pipeline
1818
from common.djangoapps.third_party_auth.tests.testutil import ThirdPartyAuthTestMixin, simulate_running_pipeline
19-
from openedx.core.djangoapps.site_configuration.tests.test_util import with_site_configuration
2019
from openedx.core.djangoapps.geoinfo.api import country_code_from_ip
20+
from openedx.core.djangoapps.site_configuration.tests.test_util import with_site_configuration
2121
from openedx.core.djangoapps.user_api.tests.test_views import UserAPITestCase
22+
from openedx.core.djangoapps.user_authn.api.tests.test_data import mfe_context_data_keys
2223
from openedx.core.djangolib.testing.utils import skip_unless_lms
2324

2425

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

4648
# Several third party auth providers are created for these tests:
4749
self.configure_google_provider(enabled=True, visible=True)
@@ -93,21 +95,34 @@ def get_context(self, params=None, current_provider=None, backend_name=None, add
9395
"""
9496
Returns the MFE context
9597
"""
98+
99+
if add_user_details:
100+
self.pipeline_user_details.update(
101+
{
102+
'username': None,
103+
'email': 'test@test.com',
104+
'name': None,
105+
'firstName': None,
106+
'lastName': None
107+
}
108+
)
109+
96110
return {
97-
'context_data': {
111+
'contextData': {
98112
'currentProvider': current_provider,
99113
'platformName': settings.PLATFORM_NAME,
100114
'providers': self.get_provider_data(params) if params else [],
101115
'secondaryProviders': [],
102116
'finishAuthUrl': pipeline.get_complete_url(backend_name) if backend_name else None,
103117
'errorMessage': None,
104118
'registerFormSubmitButtonText': 'Create Account',
119+
'autoSubmitRegForm': False,
105120
'syncLearnerProfileData': False,
106-
'pipeline_user_details': {'email': 'test@test.com'} if add_user_details else {},
107-
'countryCode': self.country_code
121+
'countryCode': self.country_code,
122+
'pipelineUserDetails': self.pipeline_user_details,
108123
},
109-
'registration_fields': {},
110-
'optional_fields': {
124+
'registrationFields': {},
125+
'optionalFields': {
111126
'extended_profile': [],
112127
},
113128
}
@@ -182,7 +197,7 @@ def test_tpa_hint(self):
182197
})
183198

184199
response = self.client.get(self.url, self.query_params)
185-
assert response.data['context_data']['providers'] == provider_data
200+
assert response.data['contextData']['providers'] == provider_data
186201

187202
def test_user_country_code(self):
188203
"""
@@ -191,7 +206,7 @@ def test_user_country_code(self):
191206
response = self.client.get(self.url, self.query_params)
192207

193208
assert response.status_code == 200
194-
assert response.data['context_data']['countryCode'] == self.country_code
209+
assert response.data['contextData']['countryCode'] == self.country_code
195210

196211
@override_settings(
197212
ENABLE_DYNAMIC_REGISTRATION_FIELDS=True,
@@ -205,7 +220,7 @@ def test_required_fields_not_configured(self):
205220
self.query_params.update({'is_register_page': True})
206221
response = self.client.get(self.url, self.query_params)
207222
assert response.status_code == status.HTTP_200_OK
208-
assert response.data['registration_fields']['fields'] == {}
223+
assert response.data['registrationFields']['fields'] == {}
209224

210225
@with_site_configuration(
211226
configuration={
@@ -223,8 +238,9 @@ def test_required_field_order(self):
223238
"""
224239
self.query_params.update({'is_register_page': True})
225240
response = self.client.get(self.url, self.query_params)
241+
226242
assert response.status_code == status.HTTP_200_OK
227-
assert list(response.data['registration_fields']['fields'].keys()) == ['first_name', 'last_name', 'state']
243+
assert list(response.data['registrationFields']['fields'].keys()) == ['first_name', 'last_name', 'state']
228244

229245
@override_settings(
230246
ENABLE_DYNAMIC_REGISTRATION_FIELDS=True,
@@ -248,7 +264,7 @@ def test_optional_field_has_no_description(self):
248264
self.query_params.update({'is_register_page': True})
249265
response = self.client.get(self.url, self.query_params)
250266
assert response.status_code == status.HTTP_200_OK
251-
assert response.data['optional_fields']['fields'] == expected_response
267+
assert response.data['optionalFields']['fields'] == expected_response
252268

253269
@with_site_configuration(
254270
configuration={
@@ -282,8 +298,9 @@ def test_configurable_select_option_fields(self):
282298
}
283299
self.query_params.update({'is_register_page': True})
284300
response = self.client.get(self.url, self.query_params)
301+
285302
assert response.status_code == status.HTTP_200_OK
286-
assert response.data['optional_fields']['fields'] == expected_response
303+
assert response.data['optionalFields']['fields'] == expected_response
287304

288305
@with_site_configuration(
289306
configuration={
@@ -302,7 +319,7 @@ def test_optional_field_order(self):
302319
self.query_params.update({'is_register_page': True})
303320
response = self.client.get(self.url, self.query_params)
304321
assert response.status_code == status.HTTP_200_OK
305-
assert list(response.data['optional_fields']['fields'].keys()) == ['specialty', 'goals']
322+
assert list(response.data['optionalFields']['fields'].keys()) == ['specialty', 'goals']
306323

307324
@with_site_configuration(
308325
configuration={
@@ -322,7 +339,7 @@ def test_field_not_available_in_extended_profile_config(self):
322339
self.query_params.update({'is_register_page': True})
323340
response = self.client.get(self.url, self.query_params)
324341
assert response.status_code == status.HTTP_200_OK
325-
assert list(response.data['registration_fields']['fields'].keys()) == ['specialty']
342+
assert list(response.data['registrationFields']['fields'].keys()) == ['specialty']
326343

327344
@override_settings(
328345
ENABLE_DYNAMIC_REGISTRATION_FIELDS=True,
@@ -333,9 +350,34 @@ def test_response_structure(self):
333350
Test that API return valid response dictionary with both required and optional fields
334351
"""
335352
response = self.client.get(self.url, self.query_params)
336-
337353
assert response.data == self.get_context()
338354

355+
def test_mfe_context_api_serialized_response(self):
356+
"""
357+
Test MFE Context API serialized response
358+
"""
359+
response = self.client.get(self.url, self.query_params)
360+
self.assertEqual(response.status_code, status.HTTP_200_OK)
361+
362+
params = {
363+
'next': self.query_params['next']
364+
}
365+
366+
self.assertEqual(
367+
response.data,
368+
self.get_context(params)
369+
)
370+
371+
def test_mfe_context_api_response_keys(self):
372+
"""
373+
Test MFE Context API response keys
374+
"""
375+
response = self.client.get(self.url, self.query_params)
376+
self.assertEqual(response.status_code, status.HTTP_200_OK)
377+
378+
response_keys = set(response.data.keys())
379+
self.assertSetEqual(response_keys, mfe_context_data_keys)
380+
339381

340382
@skip_unless_lms
341383
class SendAccountActivationEmail(UserAPITestCase):

openedx/core/djangoapps/user_authn/api/views.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
from common.djangoapps.student.views import compose_and_send_activation_email
1616
from openedx.core.djangoapps.site_configuration import helpers as configuration_helpers
1717
from openedx.core.djangoapps.user_authn.api.helper import RegistrationFieldsContext
18+
from openedx.core.djangoapps.user_authn.serializers import MFEContextSerializer
1819
from openedx.core.djangoapps.user_authn.views.utils import get_mfe_context
1920

2021

@@ -65,6 +66,7 @@ def get(self, request, **kwargs): # lint-amnesty, pylint: disable=unused-argume
6566
context['registration_fields'].update({
6667
'fields': registration_fields,
6768
})
69+
6870
optional_fields = RegistrationFieldsContext('optional').get_fields()
6971
if optional_fields:
7072
context['optional_fields'].update({
@@ -74,7 +76,9 @@ def get(self, request, **kwargs): # lint-amnesty, pylint: disable=unused-argume
7476

7577
return Response(
7678
status=status.HTTP_200_OK,
77-
data=context
79+
data=MFEContextSerializer(
80+
context
81+
).data
7882
)
7983

8084

0 commit comments

Comments
 (0)