Skip to content

Commit

Permalink
add custom validation
Browse files Browse the repository at this point in the history
  • Loading branch information
cekk committed Jul 26, 2024
1 parent 6ae8a2f commit 0b63c80
Show file tree
Hide file tree
Showing 10 changed files with 300 additions and 17 deletions.
6 changes: 5 additions & 1 deletion src/iosanita/contenttypes/behaviors/a_chi_si_rivolge.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ class IAChiSiRivolge(model.Schema):

a_chi_si_rivolge = BlocksField(
title=_("a_chi_si_rivolge_label", default="A chi si rivolge"),
required=True,
required=False,
description=_(
"a_chi_e_rivolta_help",
default="Descrizione testuale degli utenti dell'ASL a cui è rivolto questo contenuto.",
Expand All @@ -24,6 +24,10 @@ class IAChiSiRivolge(model.Schema):
model.fieldset(
"a_chi_si_rivolge",
label=_("a_chi_si_rivolge_label", default="A chi si rivolge"),
description=_(
"a_chi_si_rivolge_fieldset_help",
default="Compila almeno uno dei due campi.",
),
fields=["a_chi_si_rivolge"],
)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
</vocabName>
<vocabIdentifier>tipologia_evento</vocabIdentifier>
<term>
<termIdentifier>evento_di_formazione</termIdentifier>
<termIdentifier>evento-di-formazione</termIdentifier>
<caption>
<langstring language="it">Evento di formazione</langstring>
</caption>
Expand All @@ -28,7 +28,7 @@
</caption>
</term>
<term>
<termIdentifier>presentazione_libro</termIdentifier>
<termIdentifier>presentazione-libro</termIdentifier>
<caption>
<langstring language="it">Presentazione libro</langstring>
</caption>
Expand All @@ -41,7 +41,7 @@
</term>
</term>
<term>
<termIdentifier>conferenza_summit</termIdentifier>
<termIdentifier>conferenza-summit</termIdentifier>
<caption>
<langstring language="it">Conferenza e Summit</langstring>
</caption>
Expand All @@ -65,17 +65,17 @@
</term>
</term>
<term>
<termIdentifier>giornata_informativa</termIdentifier>
<termIdentifier>giornata-informativa</termIdentifier>
<caption>
<langstring language="en"></langstring>
<langstring language="it">Giornata informativa</langstring>
</caption>
<term>
<termIdentifier>giornata_aperta</termIdentifier>
<termIdentifier>giornata-aperta</termIdentifier>
<caption>
<langstring language="en"></langstring>
<langstring language="it">Giornata aperta</langstring>
</caption>
</term>
</term>
</vdex>
</vdex>
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,6 @@
xmlns:zcml="http://namespaces.zope.org/zcml">

<adapter factory=".dxfields.GeolocationFieldDeserializer" />
<adapter factory=".dxcontent.DeserializeFromJson" />

</configure>
111 changes: 111 additions & 0 deletions src/iosanita/contenttypes/restapi/deserializers/dxcontent.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
from plone.restapi.deserializer.dxcontent import DeserializeFromJson as BaseDeserializer
from plone.dexterity.interfaces import IDexterityContent
from plone.restapi import _
from plone.restapi.interfaces import IDeserializeFromJson
from zope.component import adapter
from zope.interface import implementer
from iosanita.contenttypes.interfaces import IIosanitaContenttypesLayer
from zExceptions import BadRequest
from plone.restapi.deserializer import json_body
from plone import api


@implementer(IDeserializeFromJson)
@adapter(IDexterityContent, IIosanitaContenttypesLayer)
class DeserializeFromJson(BaseDeserializer):

def __call__(
self, validate_all=False, data=None, create=False, mask_validation_errors=True
):
if data is None:
data = json_body(self.request)
# iosanità validations
self.validate_data_iosanita(data=data, create=create)
# if errors:
# if mask_validation_errors:
# # Drop Python specific error classes in order to be able to better handle
# # errors on front-end
# for error in errors:
# error["error"] = "ValidationError"
# for error in errors:
# error["message"] = translate(error["message"], context=self.request)
# raise BadRequest(errors)

return super().__call__(
validate_all=validate_all,
data=data,
create=create,
mask_validation_errors=mask_validation_errors,
)

def validate_data_iosanita(self, data, create):

if not create:
portal_type = self.context.portal_type
else:
portal_type = data.get("@type", "")

self.validate_a_chi_si_rivolge(data=data, create=create)

if portal_type == "Event":
self.validate_event(data=data, create=create)

def validate_a_chi_si_rivolge(self, data, create):
if not create:
if (
"a_chi_si_rivolge" not in data
and "a_chi_si_rivolge_tassonomia" not in data
):
return
a_chi_si_rivolge = data.get("a_chi_si_rivolge", {})
a_chi_si_rivolge_tassonomia = data.get("a_chi_si_rivolge_tassonomia", [])

if self.is_empty_blocks(a_chi_si_rivolge) and not a_chi_si_rivolge_tassonomia:
msg = api.portal.translate(
_(
"a_chi_si_rivolge_validation_error",
default='Devi compilare almeno uno dei due campi di "A chi si rivolge".',
)
)
raise BadRequest(
[
{"field": "a_chi_si_rivolge", "message": msg},
{"field": "a_chi_si_rivolge_tassonomia", "message": msg},
]
)

def validate_event(self, data, create):
# validate organizzato da
if not create:
if (
"organizzato_da_esterno" not in data
and "organizzato_da_interno" not in data
):
return

organizzato_da_esterno = data.get("organizzato_da_esterno", {})
organizzato_da_interno = data.get("organizzato_da_interno", [])

if self.is_empty_blocks(organizzato_da_esterno) and not organizzato_da_interno:
msg = api.portal.translate(
_(
"organizzato_validation_error",
default="Devi compilare almeno uno dei due campi per l'organizzazione.",
)
)
raise BadRequest(
[
{"field": "organizzato_da_esterno", "message": msg},
{"field": "organizzato_da_interno", "message": msg},
]
)

def is_empty_blocks(self, blocks_field):
blocks = blocks_field.get("blocks", {})
if not blocks:
return True
blocks_data = list(blocks.values())
if len(blocks_data) == 1:
if blocks_data[0] == {"@type": "slate"}:
return True
return False
1 change: 0 additions & 1 deletion src/iosanita/contenttypes/tests/test_ct_bando.py
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,6 @@ def test_bando_required_fields(self):
"descrizione_estesa",
"come_partecipare",
"modalita_selezione",
"a_chi_si_rivolge",
# "description", is required from schema_tweaks.py but it doesn't apply in test
]
),
Expand Down
1 change: 0 additions & 1 deletion src/iosanita/contenttypes/tests/test_ct_come_fare_per.py
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,6 @@ def test_come_fare_per_required_fields(self):
sorted(resp["required"]),
sorted(
[
"a_chi_si_rivolge",
"panoramica",
"title",
# "description", is required from schema_tweaks.py but it doesn't apply in test
Expand Down
13 changes: 7 additions & 6 deletions src/iosanita/contenttypes/tests/test_ct_event.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ def setUp(self):
self.portal_url = self.portal.absolute_url()
setRoles(self.portal, TEST_USER_ID, ["Manager"])

self.request["LANGUAGE"] = "it"

self.api_session = RelativeSession(self.portal_url)
self.api_session.headers.update({"Accept": "application/json"})
self.api_session.auth = (SITE_OWNER_NAME, SITE_OWNER_PASSWORD)
Expand Down Expand Up @@ -93,14 +95,13 @@ def test_event_required_fields(self):
sorted(resp["required"]),
sorted(
[
"title",
"start",
"end",
"tipologia_evento",
"a_chi_si_rivolge",
"descrizione_estesa",
"costo",
"descrizione_estesa",
"end",
"punti_di_contatto",
"start",
"tipologia_evento",
"title",
# "description", is required from schema_tweaks.py but it doesn't apply in test
]
),
Expand Down
1 change: 0 additions & 1 deletion src/iosanita/contenttypes/tests/test_ct_servizio.py
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,6 @@ def test_servizio_required_fields(self):
"uo_correlata",
"responsabile_correlato",
"punti_di_contatto",
"a_chi_si_rivolge",
]
),
)
Expand Down
1 change: 0 additions & 1 deletion src/iosanita/contenttypes/tests/test_ct_struttura.py
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,6 @@ def test_struttura_required_fields(self):
sorted(resp["required"]),
sorted(
[
"a_chi_si_rivolge",
"come_accedere",
# "description", is required from schema_tweaks.py but it doesn't apply in test
"orari",
Expand Down
Loading

0 comments on commit 0b63c80

Please sign in to comment.