From 3e40deefbaed088f7fda42bb3d44fa53f215ae39 Mon Sep 17 00:00:00 2001 From: Mikel Larreategi Date: Thu, 12 Sep 2024 14:32:53 +0200 Subject: [PATCH 01/13] add a failing test --- .../restapi/tests/test_serializer_summary.py | 47 +++++++++++++++++++ 1 file changed, 47 insertions(+) diff --git a/src/plone/restapi/tests/test_serializer_summary.py b/src/plone/restapi/tests/test_serializer_summary.py index 16b54f7b0c..fbc8862c1e 100644 --- a/src/plone/restapi/tests/test_serializer_summary.py +++ b/src/plone/restapi/tests/test_serializer_summary.py @@ -1,16 +1,23 @@ +from datetime import datetime +from datetime import timedelta from DateTime import DateTime from plone.app.contentlisting.interfaces import IContentListingObject +from plone.app.event.dx.traverser import OccurrenceTraverser from plone.app.testing import popGlobalRegistry from plone.app.testing import pushGlobalRegistry from plone.dexterity.utils import createContentInContainer +from plone.event.interfaces import IEvent +from plone.event.interfaces import IEventRecurrence from plone.restapi.interfaces import ISerializeToJsonSummary from plone.restapi.testing import PLONE_RESTAPI_DX_INTEGRATION_TESTING from plone.restapi.testing import register_static_uuid_utility from Products.CMFCore.utils import getToolByName from zope.component import getMultiAdapter from zope.component.hooks import getSite +from zope.interface import alsoProvides import Missing +import transaction import unittest @@ -203,3 +210,43 @@ def test_dx_type_summary(self): }, summary, ) + +class TestSummarySerializerswithRecurrenceObjects(unittest.TestCase): + layer = PLONE_RESTAPI_DX_INTEGRATION_TESTING + + def setUp(self): + self.portal = self.layer["portal"] + self.request = self.layer["request"] + + pushGlobalRegistry(getSite()) + register_static_uuid_utility(prefix="c6dcbd55ab2746e199cd4ed458") + + behaviors = self.portal.portal_types.DXTestDocument.behaviors + behaviors = behaviors + ('plone.eventbasic', 'plone.eventrecurrence',) + self.portal.portal_types.DXTestDocument.behaviors = behaviors + + self.event = createContentInContainer( + self.portal, + "DXTestDocument", + id="doc1", + title="Lorem Ipsum event", + description="Description event", + start=datetime.now(), + end=datetime.now() + timedelta(hours=1), + recurrence="RRULE:FREQ=DAILY;COUNT=3" # see https://github.com/plone/plone.app.event/blob/master/plone/app/event/tests/base_setup.py + ) + + alsoProvides(self.event, IEvent) + alsoProvides(self.event, IEventRecurrence) + + def tearDown(self): + popGlobalRegistry(getSite()) + + def test_dx_event_with_recurrence(self): + tomorrow = datetime.now() + timedelta(days=1) + tomorrow_str = tomorrow.strftime('%Y-%m-%d') + ot = OccurrenceTraverser(self.event, self.request) + ocurrence = ot.publishTraverse(self.request, tomorrow_str) + summary = getMultiAdapter((ocurrence, self.request), ISerializeToJsonSummary)() + + self.assertEqual(summary, {}) From 40389dec5f2ce03ee6c6c505a0b762a25331ce8d Mon Sep 17 00:00:00 2001 From: Mikel Larreategi Date: Thu, 12 Sep 2024 14:33:35 +0200 Subject: [PATCH 02/13] add a check for objects that are not able to be adapted to IContentListing --- src/plone/restapi/serializer/summary.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/plone/restapi/serializer/summary.py b/src/plone/restapi/serializer/summary.py index a18ed98a8c..8b8c36dc93 100644 --- a/src/plone/restapi/serializer/summary.py +++ b/src/plone/restapi/serializer/summary.py @@ -83,7 +83,10 @@ def __init__(self, context, request): self.blocklisted_attributes = metadata["blocklisted_attributes"] def __call__(self): - obj = IContentListingObject(self.context) + try: + obj = IContentListingObject(self.context) + except TypeError: + return {} summary = {} for field in self.metadata_fields(): From 2c729f873255c4e8e835cfd47fe1c7c2be566ea4 Mon Sep 17 00:00:00 2001 From: Mikel Larreategi Date: Thu, 12 Sep 2024 14:34:50 +0200 Subject: [PATCH 03/13] changelog --- news/1810.bugfix | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 news/1810.bugfix diff --git a/news/1810.bugfix b/news/1810.bugfix new file mode 100644 index 0000000000..af19b61056 --- /dev/null +++ b/news/1810.bugfix @@ -0,0 +1,2 @@ +Safely convert objects to IContentListingObject +[erral] From b1526efcda3cf361636adfefa161f8f1749a2686 Mon Sep 17 00:00:00 2001 From: Mikel Larreategi Date: Thu, 12 Sep 2024 14:37:18 +0200 Subject: [PATCH 04/13] run black --- .../restapi/tests/test_serializer_summary.py | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/src/plone/restapi/tests/test_serializer_summary.py b/src/plone/restapi/tests/test_serializer_summary.py index fbc8862c1e..e0ad823555 100644 --- a/src/plone/restapi/tests/test_serializer_summary.py +++ b/src/plone/restapi/tests/test_serializer_summary.py @@ -211,8 +211,9 @@ def test_dx_type_summary(self): summary, ) + class TestSummarySerializerswithRecurrenceObjects(unittest.TestCase): - layer = PLONE_RESTAPI_DX_INTEGRATION_TESTING + layer = PLONE_RESTAPI_DX_INTEGRATION_TESTING def setUp(self): self.portal = self.layer["portal"] @@ -220,9 +221,12 @@ def setUp(self): pushGlobalRegistry(getSite()) register_static_uuid_utility(prefix="c6dcbd55ab2746e199cd4ed458") - + behaviors = self.portal.portal_types.DXTestDocument.behaviors - behaviors = behaviors + ('plone.eventbasic', 'plone.eventrecurrence',) + behaviors = behaviors + ( + "plone.eventbasic", + "plone.eventrecurrence", + ) self.portal.portal_types.DXTestDocument.behaviors = behaviors self.event = createContentInContainer( @@ -233,7 +237,7 @@ def setUp(self): description="Description event", start=datetime.now(), end=datetime.now() + timedelta(hours=1), - recurrence="RRULE:FREQ=DAILY;COUNT=3" # see https://github.com/plone/plone.app.event/blob/master/plone/app/event/tests/base_setup.py + recurrence="RRULE:FREQ=DAILY;COUNT=3", # see https://github.com/plone/plone.app.event/blob/master/plone/app/event/tests/base_setup.py ) alsoProvides(self.event, IEvent) @@ -244,9 +248,9 @@ def tearDown(self): def test_dx_event_with_recurrence(self): tomorrow = datetime.now() + timedelta(days=1) - tomorrow_str = tomorrow.strftime('%Y-%m-%d') + tomorrow_str = tomorrow.strftime("%Y-%m-%d") ot = OccurrenceTraverser(self.event, self.request) ocurrence = ot.publishTraverse(self.request, tomorrow_str) summary = getMultiAdapter((ocurrence, self.request), ISerializeToJsonSummary)() - + self.assertEqual(summary, {}) From 512967b3c221f385e61845e5b2477a6743059aa4 Mon Sep 17 00:00:00 2001 From: Mikel Larreategi Date: Thu, 12 Sep 2024 14:37:38 +0200 Subject: [PATCH 05/13] run flake8 --- src/plone/restapi/tests/test_serializer_summary.py | 1 - 1 file changed, 1 deletion(-) diff --git a/src/plone/restapi/tests/test_serializer_summary.py b/src/plone/restapi/tests/test_serializer_summary.py index e0ad823555..36296d78c8 100644 --- a/src/plone/restapi/tests/test_serializer_summary.py +++ b/src/plone/restapi/tests/test_serializer_summary.py @@ -17,7 +17,6 @@ from zope.interface import alsoProvides import Missing -import transaction import unittest From f84de7c2b95f4344f970ac9723d5c982776582fe Mon Sep 17 00:00:00 2001 From: Mikel Larreategi Date: Thu, 12 Sep 2024 15:11:33 +0200 Subject: [PATCH 06/13] test that Ocurrence serialization returns correct data --- src/plone/restapi/tests/test_serializer_summary.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/plone/restapi/tests/test_serializer_summary.py b/src/plone/restapi/tests/test_serializer_summary.py index 36296d78c8..2736b4040b 100644 --- a/src/plone/restapi/tests/test_serializer_summary.py +++ b/src/plone/restapi/tests/test_serializer_summary.py @@ -252,4 +252,5 @@ def test_dx_event_with_recurrence(self): ocurrence = ot.publishTraverse(self.request, tomorrow_str) summary = getMultiAdapter((ocurrence, self.request), ISerializeToJsonSummary)() - self.assertEqual(summary, {}) + self.assertEqual(summary["start"], tomorrow_str) + self.assertEqual(summary["Title"], ocurrence.Title()) From 2646197da87a87a3d5e59a57223c960d3ee4f374 Mon Sep 17 00:00:00 2001 From: Mikel Larreategi Date: Thu, 12 Sep 2024 15:12:12 +0200 Subject: [PATCH 07/13] changelog --- news/1809.feature | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 news/1809.feature diff --git a/news/1809.feature b/news/1809.feature new file mode 100644 index 0000000000..ae905f0068 --- /dev/null +++ b/news/1809.feature @@ -0,0 +1,2 @@ +Test that recurrence serialization provides correct data +[erral] From e08431ed8f524030cca1fdd4086fdb1e4e621a14 Mon Sep 17 00:00:00 2001 From: Mikel Larreategi Date: Thu, 10 Oct 2024 17:12:12 +0200 Subject: [PATCH 08/13] conditional tests --- src/plone/restapi/serializer/summary.py | 5 +--- .../restapi/tests/test_serializer_summary.py | 26 ++++++++++++++++++- 2 files changed, 26 insertions(+), 5 deletions(-) diff --git a/src/plone/restapi/serializer/summary.py b/src/plone/restapi/serializer/summary.py index 8b8c36dc93..a18ed98a8c 100644 --- a/src/plone/restapi/serializer/summary.py +++ b/src/plone/restapi/serializer/summary.py @@ -83,10 +83,7 @@ def __init__(self, context, request): self.blocklisted_attributes = metadata["blocklisted_attributes"] def __call__(self): - try: - obj = IContentListingObject(self.context) - except TypeError: - return {} + obj = IContentListingObject(self.context) summary = {} for field in self.metadata_fields(): diff --git a/src/plone/restapi/tests/test_serializer_summary.py b/src/plone/restapi/tests/test_serializer_summary.py index 2736b4040b..05d0a864ba 100644 --- a/src/plone/restapi/tests/test_serializer_summary.py +++ b/src/plone/restapi/tests/test_serializer_summary.py @@ -18,6 +18,13 @@ import Missing import unittest +import pkg_resources + + +try: + from plone.app.event.adapters import OccurrenceContentListingObject +except ImportError: + OccurrenceContentListingObject = None class TestSummarySerializers(unittest.TestCase): @@ -245,7 +252,24 @@ def setUp(self): def tearDown(self): popGlobalRegistry(getSite()) - def test_dx_event_with_recurrence(self): + @unittest.skipIf( + OccurrenceContentListingObject is not None, + "this test needs a plone.app.event version that does not include a IContentListingObject adapter", + ) + def test_dx_event_with_recurrence_old_version(self): + tomorrow = datetime.now() + timedelta(days=1) + tomorrow_str = tomorrow.strftime("%Y-%m-%d") + ot = OccurrenceTraverser(self.event, self.request) + ocurrence = ot.publishTraverse(self.request, tomorrow_str) + + with self.assertRaises(TypeError): + getMultiAdapter((ocurrence, self.request), ISerializeToJsonSummary)() + + @unittest.skipIf( + OccurrenceContentListingObject is None, + "this test needs a plone.app.event version that includes a IContentListingObject adapter", + ) + def test_dx_event_with_recurrence_new_version(self): tomorrow = datetime.now() + timedelta(days=1) tomorrow_str = tomorrow.strftime("%Y-%m-%d") ot = OccurrenceTraverser(self.event, self.request) From 3f7efa63bfe2ebcb4f88a58b5310bfaa3c320940 Mon Sep 17 00:00:00 2001 From: Mikel Larreategi Date: Thu, 10 Oct 2024 17:13:50 +0200 Subject: [PATCH 09/13] lint --- .python-version | 2 +- src/plone/restapi/tests/test_serializer_summary.py | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/.python-version b/.python-version index e4fba21835..a7f6449fc8 100644 --- a/.python-version +++ b/.python-version @@ -1 +1 @@ -3.12 +restapi-3.9 diff --git a/src/plone/restapi/tests/test_serializer_summary.py b/src/plone/restapi/tests/test_serializer_summary.py index 05d0a864ba..7945792419 100644 --- a/src/plone/restapi/tests/test_serializer_summary.py +++ b/src/plone/restapi/tests/test_serializer_summary.py @@ -18,7 +18,6 @@ import Missing import unittest -import pkg_resources try: From c8b66010358534562b64cce92b69955ca12c1105 Mon Sep 17 00:00:00 2001 From: Mikel Larreategi Date: Thu, 10 Oct 2024 17:14:42 +0200 Subject: [PATCH 10/13] restore --- .python-version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.python-version b/.python-version index a7f6449fc8..bd28b9c5c2 100644 --- a/.python-version +++ b/.python-version @@ -1 +1 @@ -restapi-3.9 +3.9 From 2603b07a6a74ab07ec89be67b5ef4c553cba5206 Mon Sep 17 00:00:00 2001 From: Mikel Larreategi Date: Thu, 10 Oct 2024 17:15:11 +0200 Subject: [PATCH 11/13] changelog --- news/1810.bugfix | 2 -- 1 file changed, 2 deletions(-) delete mode 100644 news/1810.bugfix diff --git a/news/1810.bugfix b/news/1810.bugfix deleted file mode 100644 index af19b61056..0000000000 --- a/news/1810.bugfix +++ /dev/null @@ -1,2 +0,0 @@ -Safely convert objects to IContentListingObject -[erral] From 4d84fc022abc5d1a537a3c1b64089951a7152d6f Mon Sep 17 00:00:00 2001 From: Mikel Larreategi Date: Thu, 10 Oct 2024 17:15:31 +0200 Subject: [PATCH 12/13] restore --- .python-version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.python-version b/.python-version index bd28b9c5c2..e4fba21835 100644 --- a/.python-version +++ b/.python-version @@ -1 +1 @@ -3.9 +3.12 From d81800f550c4c2c309e5042eff93e1506e70ba00 Mon Sep 17 00:00:00 2001 From: Mikel Larreategi Date: Sun, 20 Oct 2024 18:29:14 +0200 Subject: [PATCH 13/13] rename changelog file --- news/{1809.feature => 1809.internal} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename news/{1809.feature => 1809.internal} (100%) diff --git a/news/1809.feature b/news/1809.internal similarity index 100% rename from news/1809.feature rename to news/1809.internal