Skip to content

Commit a8c5434

Browse files
Merge pull request #930 from openedx/mkeating/ENT-10753-2
fix: update serializers for field constraints
2 parents 6a12858 + 2fcbd67 commit a8c5434

File tree

4 files changed

+73
-59
lines changed

4 files changed

+73
-59
lines changed

enterprise_access/apps/api/v1/tests/test_checkout_bff_views.py

Lines changed: 4 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
EnterpriseCustomerSerializer,
2323
PriceSerializer
2424
)
25+
from enterprise_access.apps.bffs.tests.utils import default_field_constraints
2526
from enterprise_access.apps.core.constants import SYSTEM_ENTERPRISE_LEARNER_ROLE
2627
from enterprise_access.apps.customer_billing.constants import CheckoutIntentState
2728
from enterprise_access.apps.customer_billing.models import CheckoutIntent
@@ -109,14 +110,7 @@ def test_response_serializer_validation(self):
109110
'default_by_lookup_key': 'b2b_enterprise_self_service_yearly',
110111
'prices': []
111112
},
112-
'field_constraints': {
113-
'quantity': {'min': 5, 'max': 30},
114-
'enterprise_slug': {
115-
'min_length': 3,
116-
'max_length': 30,
117-
'pattern': '^[a-z0-9-]+$'
118-
}
119-
}
113+
'field_constraints': default_field_constraints
120114
}
121115

122116
# Validate using our serializer
@@ -134,14 +128,7 @@ def test_response_serializer_validation_with_intent(self):
134128
'default_by_lookup_key': 'b2b_enterprise_self_service_yearly',
135129
'prices': []
136130
},
137-
'field_constraints': {
138-
'quantity': {'min': 5, 'max': 30},
139-
'enterprise_slug': {
140-
'min_length': 3,
141-
'max_length': 30,
142-
'pattern': '^[a-z0-9-]+$'
143-
}
144-
},
131+
'field_constraints': default_field_constraints,
145132
'checkout_intent': self.mock_checkout_intent_data
146133
}
147134

@@ -159,14 +146,7 @@ def test_response_serializer_validation_null_intent(self):
159146
'default_by_lookup_key': 'b2b_enterprise_self_service_yearly',
160147
'prices': []
161148
},
162-
'field_constraints': {
163-
'quantity': {'min': 5, 'max': 30},
164-
'enterprise_slug': {
165-
'min_length': 3,
166-
'max_length': 30,
167-
'pattern': '^[a-z0-9-]+$'
168-
}
169-
},
149+
'field_constraints': default_field_constraints,
170150
'checkout_intent': None
171151
}
172152

enterprise_access/apps/bffs/checkout/serializers.py

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -60,13 +60,13 @@ class QuantityConstraintSerializer(serializers.Serializer):
6060
max = serializers.IntegerField(help_text="Maximum allowed quantity")
6161

6262

63-
class SlugConstraintSerializer(serializers.Serializer):
63+
class StringConstraintSerializer(serializers.Serializer):
6464
"""
65-
Serializer for enterprise slug constraints.
65+
Serializer for enterprise string constraints.
6666
"""
67-
min_length = serializers.IntegerField(help_text="Minimum slug length")
68-
max_length = serializers.IntegerField(help_text="Maximum slug length")
69-
pattern = serializers.CharField(help_text="Regex pattern for valid slugs")
67+
min_length = serializers.IntegerField(help_text="Minimum string length")
68+
max_length = serializers.IntegerField(help_text="Maximum string length")
69+
pattern = serializers.CharField(required=False, help_text="Regex pattern for valid ")
7070

7171

7272
class FieldConstraintsSerializer(serializers.Serializer):
@@ -77,7 +77,11 @@ class FieldConstraintsSerializer(serializers.Serializer):
7777
https://github.com/edx/frontend-app-enterprise-checkout/blob/main/src/constants.ts#L13-L39
7878
"""
7979
quantity = QuantityConstraintSerializer(help_text="Constraints for license quantity")
80-
enterprise_slug = SlugConstraintSerializer(help_text="Constraints for enterprise slug")
80+
enterprise_slug = StringConstraintSerializer(help_text="Constraints for enterprise slug")
81+
full_name = StringConstraintSerializer(help_text="Constraints for enterprise user full name")
82+
admin_email = StringConstraintSerializer(help_text="Constraints for admin email address")
83+
country = StringConstraintSerializer(help_text="Constraints for enterprise country")
84+
company_name = StringConstraintSerializer(help_text="Constraints for enterprise company name")
8185
embargoed_countries = serializers.ListField(
8286
child=serializers.CharField(max_length=2),
8387
help_text="Embargoed country codes",

enterprise_access/apps/bffs/tests/test_checkout_response_builder.py

Lines changed: 28 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
CheckoutValidationResponseBuilder
2424
)
2525
from enterprise_access.apps.bffs.checkout.serializers import CheckoutSuccessResponseSerializer
26+
from enterprise_access.apps.bffs.tests.utils import default_field_constraints
2627
from test_utils import APITest
2728

2829

@@ -68,14 +69,7 @@ def _create_minimal_valid_context(self):
6869
'default_by_lookup_key': 'subscription_licenses_yearly',
6970
'prices': []
7071
}
71-
context.field_constraints = {
72-
'quantity': {'min': 5, 'max': 30},
73-
'enterprise_slug': {
74-
'min_length': 3,
75-
'max_length': 30,
76-
'pattern': '^[a-z0-9-]+$'
77-
}
78-
}
72+
context.field_constraints = default_field_constraints
7973
return context
8074

8175
def test_build_complete_context(self):
@@ -108,15 +102,7 @@ def test_build_complete_context(self):
108102
}
109103
]
110104
}
111-
context.field_constraints = {
112-
'quantity': {'min': 5, 'max': 30},
113-
'enterprise_slug': {
114-
'min_length': 3,
115-
'max_length': 30,
116-
'pattern': '^[a-z0-9-]+$'
117-
}
118-
}
119-
105+
context.field_constraints = default_field_constraints
120106
# Create and build response
121107
builder = CheckoutContextResponseBuilder(context)
122108
builder.build()
@@ -155,9 +141,19 @@ def test_build_complete_context(self):
155141
constraints = data['field_constraints']
156142
self.assertEqual(constraints['quantity']['min'], 5)
157143
self.assertEqual(constraints['quantity']['max'], 30)
158-
self.assertEqual(constraints['enterprise_slug']['min_length'], 3)
159-
self.assertEqual(constraints['enterprise_slug']['max_length'], 30)
144+
self.assertEqual(constraints['enterprise_slug']['min_length'], 1)
145+
self.assertEqual(constraints['enterprise_slug']['max_length'], 255)
160146
self.assertEqual(constraints['enterprise_slug']['pattern'], '^[a-z0-9-]+$')
147+
self.assertEqual(constraints['full_name']['min_length'], 1)
148+
self.assertEqual(constraints['full_name']['max_length'], 150)
149+
self.assertEqual(constraints['admin_email']['min_length'], 6)
150+
self.assertEqual(constraints['admin_email']['max_length'], 253)
151+
self.assertEqual(constraints['admin_email']['pattern'], '^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$')
152+
self.assertEqual(constraints['country']['min_length'], 2)
153+
self.assertEqual(constraints['country']['max_length'], 2)
154+
self.assertEqual(constraints['country']['pattern'], '^[A-Z]{2}$')
155+
self.assertEqual(constraints['company_name']['min_length'], 1)
156+
self.assertEqual(constraints['company_name']['max_length'], 255)
161157

162158
def test_build_minimal_context(self):
163159
"""
@@ -216,14 +212,7 @@ def test_serialize_response_data(self):
216212
}
217213
]
218214
}
219-
context.field_constraints = {
220-
'quantity': {'min': 5, 'max': 30},
221-
'enterprise_slug': {
222-
'min_length': 3,
223-
'max_length': 30,
224-
'pattern': '^[a-z0-9-]+$'
225-
}
226-
}
215+
context.field_constraints = default_field_constraints
227216

228217
# Build response
229218
builder = CheckoutContextResponseBuilder(context)
@@ -263,9 +252,19 @@ def test_serialize_response_data(self):
263252
constraints = data['field_constraints']
264253
self.assertEqual(constraints['quantity']['min'], 5)
265254
self.assertEqual(constraints['quantity']['max'], 30)
266-
self.assertEqual(constraints['enterprise_slug']['min_length'], 3)
267-
self.assertEqual(constraints['enterprise_slug']['max_length'], 30)
255+
self.assertEqual(constraints['enterprise_slug']['min_length'], 1)
256+
self.assertEqual(constraints['enterprise_slug']['max_length'], 255)
268257
self.assertEqual(constraints['enterprise_slug']['pattern'], '^[a-z0-9-]+$')
258+
self.assertEqual(constraints['full_name']['min_length'], 1)
259+
self.assertEqual(constraints['full_name']['max_length'], 150)
260+
self.assertEqual(constraints['admin_email']['min_length'], 6)
261+
self.assertEqual(constraints['admin_email']['max_length'], 253)
262+
self.assertEqual(constraints['admin_email']['pattern'], '^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$')
263+
self.assertEqual(constraints['country']['min_length'], 2)
264+
self.assertEqual(constraints['country']['max_length'], 2)
265+
self.assertEqual(constraints['country']['pattern'], '^[A-Z]{2}$')
266+
self.assertEqual(constraints['company_name']['min_length'], 1)
267+
self.assertEqual(constraints['company_name']['max_length'], 255)
269268

270269
def test_serializer_validation_error(self):
271270
"""

enterprise_access/apps/bffs/tests/utils.py

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,37 @@
1111
from enterprise_access.apps.core.tests.factories import UserFactory
1212
from enterprise_access.utils import _days_from_now
1313

14+
default_field_constraints = {
15+
'quantity': {
16+
'min': 5,
17+
'max': 30
18+
},
19+
'enterprise_slug': {
20+
'min_length': 1,
21+
'max_length': 255,
22+
'pattern': '^[a-z0-9-]+$'
23+
},
24+
'full_name': {
25+
'min_length': 1,
26+
'max_length': 150
27+
},
28+
'admin_email': {
29+
'min_length': 6,
30+
'max_length': 253,
31+
'pattern': '^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$'
32+
},
33+
'country': {
34+
'min_length': 2,
35+
'max_length': 2,
36+
'pattern': '^[A-Z]{2}$'
37+
},
38+
'company_name': {
39+
'min_length': 1,
40+
'max_length': 255
41+
},
42+
'embargoed_countries': []
43+
}
44+
1445

1546
class TestHandlerContextMixin(TestCase):
1647
"""

0 commit comments

Comments
 (0)