From d457c18a03379f51dbb18e1ab3ae5e616d626594 Mon Sep 17 00:00:00 2001 From: Mauro Amico Date: Tue, 9 Jul 2024 12:30:31 +0200 Subject: [PATCH 1/8] fix: get schemata definied in the context --- src/plone/restapi/types/utils.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plone/restapi/types/utils.py b/src/plone/restapi/types/utils.py index e146f9b99..650aa625f 100644 --- a/src/plone/restapi/types/utils.py +++ b/src/plone/restapi/types/utils.py @@ -229,7 +229,7 @@ def get_jsonschema_for_fti(fti, context, request, excluded_fields=None): fieldsets = () additional_schemata = () else: - additional_schemata = tuple(getAdditionalSchemata(portal_type=fti.id)) + additional_schemata = tuple(getAdditionalSchemata(context=context)) fieldsets = get_fieldsets(context, request, schema, additional_schemata) # Build JSON schema properties From 3afabc5fde58253cad3c5b073e187bf63bff08a2 Mon Sep 17 00:00:00 2001 From: Mauro Amico Date: Sun, 14 Jul 2024 22:56:48 +0200 Subject: [PATCH 2/8] fti vs. context --- src/plone/restapi/types/utils.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/plone/restapi/types/utils.py b/src/plone/restapi/types/utils.py index 650aa625f..3cd18a18d 100644 --- a/src/plone/restapi/types/utils.py +++ b/src/plone/restapi/types/utils.py @@ -229,7 +229,10 @@ def get_jsonschema_for_fti(fti, context, request, excluded_fields=None): fieldsets = () additional_schemata = () else: - additional_schemata = tuple(getAdditionalSchemata(context=context)) + if fti.id == context.portal_type: + additional_schemata = tuple(getAdditionalSchemata(context=context)) + else: + additional_schemata = tuple(getAdditionalSchemata(portal_type=fti.id)) fieldsets = get_fieldsets(context, request, schema, additional_schemata) # Build JSON schema properties From 72f213533048a0c194ccf4450abaddc948a51924 Mon Sep 17 00:00:00 2001 From: Mauro Amico Date: Sun, 14 Jul 2024 23:45:40 +0200 Subject: [PATCH 3/8] fix docutils requirement --- plone-6.0.x.cfg | 1 + 1 file changed, 1 insertion(+) diff --git a/plone-6.0.x.cfg b/plone-6.0.x.cfg index 5c418ddfe..d7cf8db36 100644 --- a/plone-6.0.x.cfg +++ b/plone-6.0.x.cfg @@ -20,3 +20,4 @@ robotframework-assertion-engine = 2.0.0 robotframework-debuglibrary = 2.3.0 robotframework-pythonlibcore = 4.2.0 grpcio-tools = 1.59.0 +docutils = 0.21.2 From 58e9fd24d6225ed56fd9b403a6a80581bab81582 Mon Sep 17 00:00:00 2001 From: Mauro Amico Date: Mon, 15 Jul 2024 07:48:31 +0200 Subject: [PATCH 4/8] Update plone-6.0.x.cfg Co-authored-by: Steve Piercy --- plone-6.0.x.cfg | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plone-6.0.x.cfg b/plone-6.0.x.cfg index d7cf8db36..0e6006c1f 100644 --- a/plone-6.0.x.cfg +++ b/plone-6.0.x.cfg @@ -20,4 +20,4 @@ robotframework-assertion-engine = 2.0.0 robotframework-debuglibrary = 2.3.0 robotframework-pythonlibcore = 4.2.0 grpcio-tools = 1.59.0 -docutils = 0.21.2 +readme_renderer <= 43.0 From a683f97831a96a0edebd0028b553860fa122cb2a Mon Sep 17 00:00:00 2001 From: Mauro Amico Date: Mon, 15 Jul 2024 07:51:44 +0200 Subject: [PATCH 5/8] Update plone-6.0.x.cfg --- plone-6.0.x.cfg | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plone-6.0.x.cfg b/plone-6.0.x.cfg index 0e6006c1f..3f8e21c26 100644 --- a/plone-6.0.x.cfg +++ b/plone-6.0.x.cfg @@ -20,4 +20,4 @@ robotframework-assertion-engine = 2.0.0 robotframework-debuglibrary = 2.3.0 robotframework-pythonlibcore = 4.2.0 grpcio-tools = 1.59.0 -readme_renderer <= 43.0 +readme_renderer = 43.0 From 055a495c56a55849e9800edf30b2077b6b5cca57 Mon Sep 17 00:00:00 2001 From: Mauro Amico Date: Thu, 10 Oct 2024 00:34:29 +0200 Subject: [PATCH 6/8] tests --- news/1796.bugfix | 2 ++ src/plone/restapi/testing.zcml | 2 ++ src/plone/restapi/tests/dxtypes.py | 23 +++++++++++++++++++++++ src/plone/restapi/tests/test_types.py | 26 ++++++++++++++++++++++++++ 4 files changed, 53 insertions(+) create mode 100644 news/1796.bugfix diff --git a/news/1796.bugfix b/news/1796.bugfix new file mode 100644 index 000000000..83f56af82 --- /dev/null +++ b/news/1796.bugfix @@ -0,0 +1,2 @@ +Fix getting schemata for behaviors defined in the context +[mamico] diff --git a/src/plone/restapi/testing.zcml b/src/plone/restapi/testing.zcml index d1cd9a2db..4ec899bcf 100644 --- a/src/plone/restapi/testing.zcml +++ b/src/plone/restapi/testing.zcml @@ -33,4 +33,6 @@ provides=".tests.dxtypes.ITestAnnotationsBehavior" /> + + diff --git a/src/plone/restapi/tests/dxtypes.py b/src/plone/restapi/tests/dxtypes.py index b3632d41d..d1e76b04d 100644 --- a/src/plone/restapi/tests/dxtypes.py +++ b/src/plone/restapi/tests/dxtypes.py @@ -6,7 +6,10 @@ from plone.autoform.directives import read_permission from plone.autoform.directives import write_permission from plone.autoform.interfaces import IFormFieldProvider +from plone.behavior.interfaces import IBehavior +from plone.dexterity.behavior import DexterityBehaviorAssignable from plone.dexterity.content import Item +from plone.dexterity.interfaces import IDexterityContent from plone.namedfile import field as namedfile from plone.restapi.tests.helpers import ascii_token from plone.supermodel import model @@ -17,6 +20,8 @@ from z3c.relationfield.schema import RelationChoice from z3c.relationfield.schema import RelationList from zope import schema +from zope.component import adapter +from zope.component import queryUtility from zope.interface import directlyProvides from zope.interface import implementer from zope.interface import Invalid @@ -317,3 +322,21 @@ class ITestBehavior(model.Schema): @provider(IFormFieldProvider) class ITestAnnotationsBehavior(model.Schema): test_annotations_behavior_field = schema.TextLine(required=False) + + +class IInstanceBehaviorAssignableContent(IDexterityContent): + """Marks dexterity content to be extensible by instance behaviors.""" + + +@adapter(IInstanceBehaviorAssignableContent) +class DexterityInstanceBehaviorAssignable(DexterityBehaviorAssignable): + """Per instance specification of plone.behavior behaviors. + - add tests.restapi.test_behavior + - remove plone.dublincore + """ + + def enumerateBehaviors(self): + for behavior in super().enumerateBehaviors(): + if behavior.name not in ["plone.dublincore"]: + yield behavior + yield queryUtility(IBehavior, name="tests.restapi.test_behavior") diff --git a/src/plone/restapi/tests/test_types.py b/src/plone/restapi/tests/test_types.py index a19186ca0..7014e247c 100644 --- a/src/plone/restapi/tests/test_types.py +++ b/src/plone/restapi/tests/test_types.py @@ -4,7 +4,9 @@ from plone.app.textfield import RichText from plone.autoform import directives as form from plone.dexterity.fti import DexterityFTI +from plone.dexterity.utils import createContentInContainer from plone.restapi.testing import PLONE_RESTAPI_DX_INTEGRATION_TESTING +from plone.restapi.tests.dxtypes import IInstanceBehaviorAssignableContent from plone.restapi.types.interfaces import IJsonSchemaProvider from plone.restapi.types.utils import get_fieldsets from plone.restapi.types.utils import get_jsonschema_for_fti @@ -18,6 +20,7 @@ from z3c.form.browser.text import TextWidget from zope import schema from zope.component import getMultiAdapter +from zope.interface import alsoProvides from zope.interface import provider from zope.schema.interfaces import IContextAwareDefaultFactory from zope.schema.vocabulary import SimpleTerm @@ -129,6 +132,29 @@ def test_get_jsonschema_for_portal_type(self): ) self.assertNotIn("title", list(jsonschema["properties"])) + def test_get_jsonschema_for_instance(self): + portal = self.portal + request = self.request + ttool = getToolByName(portal, "portal_types") + obj = createContentInContainer( + portal, + "Document", + id="doc", + title="Document", + ) + jsonschema = get_jsonschema_for_fti(ttool["Document"], obj, request) + behaviors = [field["behavior"] for field in jsonschema["properties"].values()] + self.assertIn("plone.dublincore", behaviors) + self.assertNotIn("tests.restapi.test_behavior", behaviors) + + # this testing adapter contextually add `test_behavior` and remove + # `dublincore` + alsoProvides(obj, IInstanceBehaviorAssignableContent) + jsonschema = get_jsonschema_for_fti(ttool["Document"], obj, request) + behaviors = [field["behavior"] for field in jsonschema["properties"].values()] + self.assertNotIn("plone.dublincore", behaviors) + self.assertIn("tests.restapi.test_behavior", behaviors) + class TestTaggedValuesJsonSchemaUtils(TestCase): From 6600296a9e9e5cb2ce16aa400537836fec8df7d2 Mon Sep 17 00:00:00 2001 From: Mauro Amico Date: Thu, 10 Oct 2024 00:50:30 +0200 Subject: [PATCH 7/8] revert --- plone-6.0.x.cfg | 1 - 1 file changed, 1 deletion(-) diff --git a/plone-6.0.x.cfg b/plone-6.0.x.cfg index 3936ef3c1..26373fac8 100644 --- a/plone-6.0.x.cfg +++ b/plone-6.0.x.cfg @@ -22,4 +22,3 @@ robotframework-assertion-engine = 2.0.0 robotframework-debuglibrary = 2.3.0 robotframework-pythonlibcore = 4.2.0 grpcio-tools = 1.59.0 -readme_renderer = 43.0 From 59de4a4f3cf342e394098e7d3d501ac04c1915e2 Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Wed, 9 Oct 2024 16:35:08 -0700 Subject: [PATCH 8/8] Apply suggestions from code review --- news/1796.bugfix | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/news/1796.bugfix b/news/1796.bugfix index 83f56af82..f5635497e 100644 --- a/news/1796.bugfix +++ b/news/1796.bugfix @@ -1,2 +1 @@ -Fix getting schemata for behaviors defined in the context -[mamico] +Get schemata for behaviors defined in the context. @mamico