Skip to content

Commit a2436c4

Browse files
authored
Merge pull request #431 from Y-Note-SAS/feature-36919
feat(core): implements fields max length service
2 parents fa3032c + ed496cd commit a2436c4

5 files changed

Lines changed: 164 additions & 1 deletion

File tree

core/gql/__init__.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
# core/gql/__init__.py
2+
3+
from .max_length_constraints import MaxLengthConstraintsGQLType, build_max_length_constraints
4+
5+
__all__ = ['MaxLengthConstraintsGQLType', 'build_max_length_constraints']

core/gql/max_length_constraints.py

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
# core/gql/max_length_constraints.py
2+
3+
from graphene.types.generic import GenericScalar
4+
import graphene
5+
from django.apps import apps
6+
7+
try:
8+
from insuree.models import Insuree
9+
except ImportError:
10+
Insuree = None
11+
12+
13+
def get_model(model_name):
14+
"""Récupère un modèle à partir de son nom."""
15+
try:
16+
return apps.get_model('core', model_name)
17+
except LookupError:
18+
return None
19+
20+
21+
MAX_LENGTH_CONSTRAINTS_FIELDS = {
22+
"admin": {
23+
"user": {
24+
"username": ("User", "username"),
25+
"lastName": ("InteractiveUser", "last_name"),
26+
"otherNames": ("InteractiveUser", "other_names"),
27+
"phone": ("InteractiveUser", "phone"),
28+
"email": ("InteractiveUser", "email"),
29+
},
30+
},
31+
}
32+
33+
if Insuree:
34+
MAX_LENGTH_CONSTRAINTS_FIELDS["insuree"] = {
35+
"insuree": {
36+
"uuid": (Insuree, "uuid"),
37+
"chfId": (Insuree, "chf_id"),
38+
"lastName": (Insuree, "last_name"),
39+
"otherNames": (Insuree, "other_names"),
40+
"marital": (Insuree, "marital"),
41+
"passport": (Insuree, "passport"),
42+
"phone": (Insuree, "phone"),
43+
"email": (Insuree, "email"),
44+
"currentAddress": (Insuree, "current_address"),
45+
"geolocation": (Insuree, "geolocation"),
46+
"status": (Insuree, "status"),
47+
},
48+
}
49+
50+
51+
def build_max_length_constraints():
52+
constraints = {}
53+
54+
for module_name, forms in MAX_LENGTH_CONSTRAINTS_FIELDS.items():
55+
module_constraints = {}
56+
57+
for form_name, fields in forms.items():
58+
form_constraints = {}
59+
60+
for field_name, (model_or_name, model_field_name) in fields.items():
61+
if isinstance(model_or_name, str):
62+
model = get_model(model_or_name)
63+
if model is None:
64+
continue
65+
else:
66+
model = model_or_name
67+
68+
try:
69+
field = model._meta.get_field(model_field_name)
70+
if field.max_length:
71+
form_constraints[field_name] = field.max_length
72+
except Exception:
73+
continue
74+
75+
if form_constraints:
76+
module_constraints[form_name] = form_constraints
77+
78+
if module_constraints:
79+
constraints[module_name] = module_constraints
80+
81+
return constraints
82+
83+
84+
class MaxLengthConstraintsGQLType(graphene.ObjectType):
85+
"""
86+
Returns max_length constraints used by the frontend to enforce field length
87+
limits in supported forms.
88+
"""
89+
constraints = GenericScalar()
90+
91+
@staticmethod
92+
def resolve_constraints(root, info):
93+
return build_max_length_constraints()

core/gql_queries.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,8 @@
1616
from core.apps import CoreConfig
1717
from django.utils.translation import gettext as _
1818
from django.core.exceptions import PermissionDenied
19-
19+
from graphene.types.generic import GenericScalar
20+
from .gql import MaxLengthConstraintsGQLType, build_max_length_constraints
2021
from .utils import prefix_filterset
2122

2223
class OfficerGQLType(DjangoObjectType):

core/schema.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@
6969
PermissionOpenImisGQLType,
7070
ModulePermissionGQLType,
7171
CustomFilterOptionGQLType,
72+
MaxLengthConstraintsGQLType,
7273
)
7374
from core.utils import ( # noqa: 401
7475
ExtendedConnection,
@@ -758,6 +759,8 @@ class Query(graphene.ObjectType):
758759
ModuleConfigurationGQLType, validity=graphene.String(), layer=graphene.String()
759760
)
760761

762+
max_length_constraints = graphene.Field(MaxLengthConstraintsGQLType)
763+
761764
user_obligatory_fields = GenericScalar()
762765
eo_obligatory_fields = GenericScalar()
763766

@@ -968,6 +971,9 @@ def resolve_validate_username(self, info, **kwargs):
968971
else:
969972
return True
970973

974+
def resolve_max_length_constraints(self, info):
975+
return MaxLengthConstraintsGQLType()
976+
971977
def resolve_validate_user_email(self, info, **kwargs):
972978
if not info.context.user.has_perms(CoreConfig.gql_query_users_perms):
973979
raise PermissionDenied(_("unauthorized"))

core/tests/test_gql_queries.py

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
from django.test import TestCase
2+
3+
from core.gql.max_length_constraints import build_max_length_constraints
4+
5+
try:
6+
from insuree.models import Insuree
7+
except ImportError:
8+
Insuree = None
9+
10+
11+
class MaxLengthConstraintsTestCase(TestCase):
12+
def test_build_max_length_constraints_returns_supported_admin_user_fields(self):
13+
constraints = build_max_length_constraints()
14+
15+
self.assertIn("admin", constraints)
16+
self.assertIn("user", constraints["admin"])
17+
self.assertEqual(
18+
constraints["admin"]["user"],
19+
{
20+
"username": 50,
21+
"lastName": 100,
22+
"otherNames": 100,
23+
"phone": 50,
24+
"email": 200,
25+
},
26+
)
27+
28+
def test_build_max_length_constraints_excludes_uncontrolled_models(self):
29+
constraints = build_max_length_constraints()
30+
31+
self.assertNotIn("logentry", constraints)
32+
self.assertNotIn("session", constraints)
33+
self.assertNotIn("historicalinteractiveuser", constraints)
34+
35+
def test_build_max_length_constraints_returns_insuree_fields_when_available(self):
36+
if not Insuree:
37+
self.skipTest("Insuree module is not installed")
38+
39+
constraints = build_max_length_constraints()
40+
41+
self.assertIn("insuree", constraints)
42+
self.assertIn("insuree", constraints["insuree"])
43+
self.assertEqual(
44+
constraints["insuree"]["insuree"],
45+
{
46+
"uuid": 36,
47+
"chfId": 50,
48+
"lastName": 100,
49+
"otherNames": 100,
50+
"marital": 1,
51+
"passport": 25,
52+
"phone": 50,
53+
"email": 100,
54+
"currentAddress": 200,
55+
"geolocation": 250,
56+
"status": 2,
57+
},
58+
)

0 commit comments

Comments
 (0)