From 7426601f1709d12747a3477b15c550e30afc6e5f Mon Sep 17 00:00:00 2001 From: Mikel Larreategi Date: Thu, 12 Sep 2024 15:10:00 +0200 Subject: [PATCH 1/5] provide an IContentListingObject adapter --- news/410.feature | 2 ++ plone/app/event/adapters.py | 5 +++++ plone/app/event/configure.zcml | 7 +++++++ 3 files changed, 14 insertions(+) create mode 100644 news/410.feature create mode 100644 plone/app/event/adapters.py diff --git a/news/410.feature b/news/410.feature new file mode 100644 index 00000000..1ad25924 --- /dev/null +++ b/news/410.feature @@ -0,0 +1,2 @@ +Provide an IContentListingObject adapter +[erral] diff --git a/plone/app/event/adapters.py b/plone/app/event/adapters.py new file mode 100644 index 00000000..2149dac4 --- /dev/null +++ b/plone/app/event/adapters.py @@ -0,0 +1,5 @@ +from plone.app.contentlisting.realobject import RealContentListingObject + + +class OcurrenceContentListingObject(RealContentListingObject): + pass diff --git a/plone/app/event/configure.zcml b/plone/app/event/configure.zcml index e546895c..f19c0d05 100644 --- a/plone/app/event/configure.zcml +++ b/plone/app/event/configure.zcml @@ -67,4 +67,11 @@ name="plone.app.event" /> + + + From b2844f1121f98f611a4907efa58ceb476b854e01 Mon Sep 17 00:00:00 2001 From: Mikel Larreategi Date: Thu, 10 Oct 2024 16:50:40 +0200 Subject: [PATCH 2/5] tests for content listing support --- plone/app/event/adapters.py | 19 +++++++- plone/app/event/configure.zcml | 2 +- plone/app/event/tests/test_recurrence.py | 57 +++++++++++++++++++++++- 3 files changed, 75 insertions(+), 3 deletions(-) diff --git a/plone/app/event/adapters.py b/plone/app/event/adapters.py index 2149dac4..dc661691 100644 --- a/plone/app/event/adapters.py +++ b/plone/app/event/adapters.py @@ -1,5 +1,22 @@ from plone.app.contentlisting.realobject import RealContentListingObject +from plone.app.contentlisting.interfaces import IContentListingObject +from zope.interface import implementer +@implementer(IContentListingObject) class OcurrenceContentListingObject(RealContentListingObject): - pass + + def __getattr__(self, name): + """We'll override getattr so that we can defer name lookups to + the real underlying objects without knowing the names of all + attributes. + """ + if name.startswith("_"): + raise AttributeError(name) + obj = self.getObject() + # we need to override the behavior of RealContentListingObject + # because Ocurrence objects rely on acquisition to show their title + # and other attributes + if hasattr(obj, name): + return getattr(obj, name) + raise AttributeError(name) diff --git a/plone/app/event/configure.zcml b/plone/app/event/configure.zcml index f19c0d05..273d58c9 100644 --- a/plone/app/event/configure.zcml +++ b/plone/app/event/configure.zcml @@ -70,7 +70,7 @@ diff --git a/plone/app/event/tests/test_recurrence.py b/plone/app/event/tests/test_recurrence.py index 21e5a1cd..3c8d25d5 100644 --- a/plone/app/event/tests/test_recurrence.py +++ b/plone/app/event/tests/test_recurrence.py @@ -1,6 +1,6 @@ from OFS.SimpleItem import SimpleItem from plone.app.event.base import get_events -from plone.app.event.base import RET_MODE_ACCESSORS +from plone.app.event.base import RET_MODE_ACCESSORS, RET_MODE_OBJECTS from plone.app.event.dx.traverser import OccurrenceTraverser from plone.app.event.recurrence import Occurrence from plone.app.event.testing import PAEvent_INTEGRATION_TESTING @@ -11,6 +11,7 @@ from plone.app.event.testing import set_timezone from plone.app.event.tests.base_setup import AbstractSampleDataEvents from plone.app.event.tests.base_setup import patched_now +from plone.app.contentlisting.interfaces import IContentListingObject from plone.app.testing import setRoles from plone.app.testing import TEST_USER_ID from plone.app.testing import TEST_USER_PASSWORD @@ -352,3 +353,57 @@ def test_recurrence_occurrences_with_range_start_and_end(self): # Subsequent ones are IOccurrence objects self.assertTrue(IOccurrence.providedBy(result[1])) + + +class TestRecurrenceContentListingSupport(unittest.TestCase): + """test that content listing objects are correctly serialized in plone.app.contentlisting objects""" + + layer = PAEventDX_INTEGRATION_TESTING + + def setUp(self): + self.portal = self.layer["portal"] + self.request = self.layer["request"] + + set_browserlayer(self.request) + set_env_timezone(TZNAME) + set_timezone(TZNAME) + + now = patched_now() + + yesterday = now - datetime.timedelta(days=1) + + setRoles(self.portal, TEST_USER_ID, ["Manager"]) + self.daily = createContentInContainer( + self.portal, + "plone.app.event.dx.event", + id="daily", + title="Daily Event", + start=now, + end=now + datetime.timedelta(hours=1), + location="Vienna", + recurrence="RRULE:FREQ=DAILY;COUNT=4", + ) + + def test_recurrence_objects_adapted_to_content_listing_objects(self): + res = get_events(self.portal, ret_mode=RET_MODE_OBJECTS, expand=True) + + self.assertEqual(len(res), 4) + + first_item = res[0] + second_item = res[1] + + first_content_listing_object = IContentListingObject(first_item) + second_content_listing_object = IContentListingObject(second_item) + + self.assertEqual(first_content_listing_object.Title(), first_item.Title()) + self.assertEqual(second_content_listing_object.Title(), second_item.Title()) + + self.assertEqual(first_content_listing_object.start, first_item.start) + self.assertEqual(second_content_listing_object.start, second_item.start) + + self.assertEqual(first_content_listing_object.end, first_item.end) + self.assertEqual(second_content_listing_object.end, second_item.end) + + self.assertTrue( + first_content_listing_object.start < second_content_listing_object.start + ) From a0820a904e15a76d8304f5737d5b9c6e685a779d Mon Sep 17 00:00:00 2001 From: Mikel Larreategi Date: Thu, 10 Oct 2024 16:54:28 +0200 Subject: [PATCH 3/5] lint --- plone/app/event/tests/test_recurrence.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/plone/app/event/tests/test_recurrence.py b/plone/app/event/tests/test_recurrence.py index 3c8d25d5..d34a4b78 100644 --- a/plone/app/event/tests/test_recurrence.py +++ b/plone/app/event/tests/test_recurrence.py @@ -370,8 +370,6 @@ def setUp(self): now = patched_now() - yesterday = now - datetime.timedelta(days=1) - setRoles(self.portal, TEST_USER_ID, ["Manager"]) self.daily = createContentInContainer( self.portal, From 919e92ff80ec8650e9ce7f3196d76b7034657995 Mon Sep 17 00:00:00 2001 From: Mikel Larreategi Date: Thu, 10 Oct 2024 16:54:56 +0200 Subject: [PATCH 4/5] lint --- plone/app/event/adapters.py | 4 ++-- plone/app/event/configure.zcml | 2 +- plone/app/event/tests/test_recurrence.py | 5 +++-- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/plone/app/event/adapters.py b/plone/app/event/adapters.py index dc661691..4f3745c2 100644 --- a/plone/app/event/adapters.py +++ b/plone/app/event/adapters.py @@ -1,10 +1,10 @@ -from plone.app.contentlisting.realobject import RealContentListingObject from plone.app.contentlisting.interfaces import IContentListingObject +from plone.app.contentlisting.realobject import RealContentListingObject from zope.interface import implementer @implementer(IContentListingObject) -class OcurrenceContentListingObject(RealContentListingObject): +class OccurrenceContentListingObject(RealContentListingObject): def __getattr__(self, name): """We'll override getattr so that we can defer name lookups to diff --git a/plone/app/event/configure.zcml b/plone/app/event/configure.zcml index 273d58c9..edf0399a 100644 --- a/plone/app/event/configure.zcml +++ b/plone/app/event/configure.zcml @@ -69,7 +69,7 @@ diff --git a/plone/app/event/tests/test_recurrence.py b/plone/app/event/tests/test_recurrence.py index d34a4b78..34451906 100644 --- a/plone/app/event/tests/test_recurrence.py +++ b/plone/app/event/tests/test_recurrence.py @@ -1,6 +1,8 @@ from OFS.SimpleItem import SimpleItem +from plone.app.contentlisting.interfaces import IContentListingObject from plone.app.event.base import get_events -from plone.app.event.base import RET_MODE_ACCESSORS, RET_MODE_OBJECTS +from plone.app.event.base import RET_MODE_ACCESSORS +from plone.app.event.base import RET_MODE_OBJECTS from plone.app.event.dx.traverser import OccurrenceTraverser from plone.app.event.recurrence import Occurrence from plone.app.event.testing import PAEvent_INTEGRATION_TESTING @@ -11,7 +13,6 @@ from plone.app.event.testing import set_timezone from plone.app.event.tests.base_setup import AbstractSampleDataEvents from plone.app.event.tests.base_setup import patched_now -from plone.app.contentlisting.interfaces import IContentListingObject from plone.app.testing import setRoles from plone.app.testing import TEST_USER_ID from plone.app.testing import TEST_USER_PASSWORD From f1a14587db5a5f3289ff641f97e046d9bbe4db73 Mon Sep 17 00:00:00 2001 From: Mikel Larreategi Date: Thu, 10 Oct 2024 16:55:17 +0200 Subject: [PATCH 5/5] lint --- plone/app/event/adapters.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plone/app/event/adapters.py b/plone/app/event/adapters.py index 4f3745c2..95278b3a 100644 --- a/plone/app/event/adapters.py +++ b/plone/app/event/adapters.py @@ -15,7 +15,7 @@ def __getattr__(self, name): raise AttributeError(name) obj = self.getObject() # we need to override the behavior of RealContentListingObject - # because Ocurrence objects rely on acquisition to show their title + # because Occurrence objects rely on acquisition to show their title # and other attributes if hasattr(obj, name): return getattr(obj, name)