From 9bc3b36225680f3eca12d305a1242526cb09ba83 Mon Sep 17 00:00:00 2001 From: davisagli Date: Mon, 26 Aug 2024 11:44:48 -0700 Subject: [PATCH] [fc] Repository: plone.restapi Branch: refs/heads/main Date: 2024-08-26T11:44:48-07:00 Author: Jefferson Bledsoe (JeffersonBledsoe) Commit: https://github.com/plone/plone.restapi/commit/37d02e7772b1b402ef74b8e55bc7ea4ad786d014 Include next/previous only if enabled (#1799) * Add failing test for next/ previous behaviour * Return empty dict if behaviour or toggle is disabled * Fix missing import in test * Remove bad part of test * Fix some git weirdness? * Fix implementation * changelog * skip tests that require DX site root in Plone 5.2 --------- Co-authored-by: David Glick <david@glicksoftware.com> Files changed: A news/1799.bugfix M plone-6.0.x-python3.8.cfg M plone-6.0.x.cfg M requirements-6.0.txt M src/plone/restapi/serializer/nextprev.py M src/plone/restapi/tests/http-examples/collection.resp M src/plone/restapi/tests/http-examples/collection_fullobjects.resp M src/plone/restapi/tests/http-examples/content_get.resp M src/plone/restapi/tests/http-examples/content_get_folder.resp M src/plone/restapi/tests/http-examples/content_patch_representation.resp M src/plone/restapi/tests/http-examples/content_post.resp M src/plone/restapi/tests/http-examples/event.resp M src/plone/restapi/tests/http-examples/file.resp M src/plone/restapi/tests/http-examples/folder.resp M src/plone/restapi/tests/http-examples/image.resp M src/plone/restapi/tests/http-examples/link.resp M src/plone/restapi/tests/http-examples/navroot_lang_content_get.resp M src/plone/restapi/tests/http-examples/navroot_lang_folder_get.resp M src/plone/restapi/tests/http-examples/newsitem.resp M src/plone/restapi/tests/http-examples/search_fullobjects.resp M src/plone/restapi/tests/http-examples/site_get_expand_lang_folder.resp M src/plone/restapi/tests/http-examples/site_get_expand_lang_folder_content.resp M src/plone/restapi/tests/http-examples/translated_messages_types_folder.resp M src/plone/restapi/tests/http-examples/translations_expand_get.resp M src/plone/restapi/tests/http-examples/translations_link_on_post.resp M src/plone/restapi/tests/http-examples/translations_unexpanded_get.resp M src/plone/restapi/tests/http-examples/workingcopy_baseline_get.resp M src/plone/restapi/tests/http-examples/workingcopy_wc_get.resp M src/plone/restapi/tests/test_dxcontent_serializer.py --- last_commit.txt | 89 +++++++++++++++++++++++++++++++++---------------- 1 file changed, 60 insertions(+), 29 deletions(-) diff --git a/last_commit.txt b/last_commit.txt index 7cb0970c08..2c5515e070 100644 --- a/last_commit.txt +++ b/last_commit.txt @@ -1,32 +1,63 @@ -Repository: plone.staticresources - - -Branch: refs/heads/master -Date: 2024-08-26T12:41:22+02:00 -Author: Peter Mathis (petschki) -Commit: https://github.com/plone/plone.staticresources/commit/3d79f5e0563abd76f06520e3d9ee371f0d01f7bd - -Preparing release 2.2.0a10 +Repository: plone.restapi + + +Branch: refs/heads/main +Date: 2024-08-26T11:44:48-07:00 +Author: Jefferson Bledsoe (JeffersonBledsoe) +Commit: https://github.com/plone/plone.restapi/commit/37d02e7772b1b402ef74b8e55bc7ea4ad786d014 + +Include next/previous only if enabled (#1799) + +* Add failing test for next/ previous behaviour + +* Return empty dict if behaviour or toggle is disabled + +* Fix missing import in test + +* Remove bad part of test + +* Fix some git weirdness? + +* Fix implementation + +* changelog + +* skip tests that require DX site root in Plone 5.2 + +--------- + +Co-authored-by: David Glick <david@glicksoftware.com> Files changed: -M CHANGES.rst -M setup.py -D news/349.bugfix - -b'diff --git a/CHANGES.rst b/CHANGES.rst\nindex 9b7a11e05..88cf2de5b 100644\n--- a/CHANGES.rst\n+++ b/CHANGES.rst\n@@ -8,6 +8,16 @@ Changelog\n \n .. towncrier release notes start\n \n+2.2.0a10 (2024-08-26)\n+---------------------\n+\n+Bug fixes:\n+\n+\n+- Latest `mockup=5.2.0-alpha.10`. See https://github.com/plone/mockup/releases/tag/5.2.0-alpha.10 for detailed changenotes.\n+ [petschki] (#349)\n+\n+\n 2.2.0a9 (2024-08-20)\n --------------------\n \ndiff --git a/news/349.bugfix b/news/349.bugfix\ndeleted file mode 100644\nindex 682ffec68..000000000\n--- a/news/349.bugfix\n+++ /dev/null\n@@ -1,2 +0,0 @@\n-Latest `mockup=5.2.0-alpha.10`. See https://github.com/plone/mockup/releases/tag/5.2.0-alpha.10 for detailed changenotes.\n-[petschki]\ndiff --git a/setup.py b/setup.py\nindex f9df0ba33..0d5436ff7 100644\n--- a/setup.py\n+++ b/setup.py\n@@ -11,7 +11,7 @@\n \n setup(\n name="plone.staticresources",\n- version="2.2.0a10.dev0",\n+ version="2.2.0a10",\n description="Static resources for Plone",\n long_description=long_description,\n long_description_content_type="text/x-rst",\n' - -Repository: plone.staticresources - - -Branch: refs/heads/master -Date: 2024-08-26T12:42:11+02:00 -Author: Peter Mathis (petschki) -Commit: https://github.com/plone/plone.staticresources/commit/f8da17d0b445a0cd6ba5ca52d77d8d39dea5f87a - -Back to development: 2.2.0a11 - -Files changed: -M setup.py - -b'diff --git a/setup.py b/setup.py\nindex 0d5436ff7..beac5306c 100644\n--- a/setup.py\n+++ b/setup.py\n@@ -11,7 +11,7 @@\n \n setup(\n name="plone.staticresources",\n- version="2.2.0a10",\n+ version="2.2.0a11.dev0",\n description="Static resources for Plone",\n long_description=long_description,\n long_description_content_type="text/x-rst",\n' +A news/1799.bugfix +M plone-6.0.x-python3.8.cfg +M plone-6.0.x.cfg +M requirements-6.0.txt +M src/plone/restapi/serializer/nextprev.py +M src/plone/restapi/tests/http-examples/collection.resp +M src/plone/restapi/tests/http-examples/collection_fullobjects.resp +M src/plone/restapi/tests/http-examples/content_get.resp +M src/plone/restapi/tests/http-examples/content_get_folder.resp +M src/plone/restapi/tests/http-examples/content_patch_representation.resp +M src/plone/restapi/tests/http-examples/content_post.resp +M src/plone/restapi/tests/http-examples/event.resp +M src/plone/restapi/tests/http-examples/file.resp +M src/plone/restapi/tests/http-examples/folder.resp +M src/plone/restapi/tests/http-examples/image.resp +M src/plone/restapi/tests/http-examples/link.resp +M src/plone/restapi/tests/http-examples/navroot_lang_content_get.resp +M src/plone/restapi/tests/http-examples/navroot_lang_folder_get.resp +M src/plone/restapi/tests/http-examples/newsitem.resp +M src/plone/restapi/tests/http-examples/search_fullobjects.resp +M src/plone/restapi/tests/http-examples/site_get_expand_lang_folder.resp +M src/plone/restapi/tests/http-examples/site_get_expand_lang_folder_content.resp +M src/plone/restapi/tests/http-examples/translated_messages_types_folder.resp +M src/plone/restapi/tests/http-examples/translations_expand_get.resp +M src/plone/restapi/tests/http-examples/translations_link_on_post.resp +M src/plone/restapi/tests/http-examples/translations_unexpanded_get.resp +M src/plone/restapi/tests/http-examples/workingcopy_baseline_get.resp +M src/plone/restapi/tests/http-examples/workingcopy_wc_get.resp +M src/plone/restapi/tests/test_dxcontent_serializer.py + +b'diff --git a/news/1799.bugfix b/news/1799.bugfix\nnew file mode 100644\nindex 000000000..171db7f10\n--- /dev/null\n+++ b/news/1799.bugfix\n@@ -0,0 +1,4 @@\n+Fixed Dexterity content serializer:\n+Return an empty object for `next_item` and `previous_item`\n+unless the parent has next/previous support enabled.\n+@JeffersonBledsoe, @davisagli\ndiff --git a/plone-6.0.x-python3.8.cfg b/plone-6.0.x-python3.8.cfg\nindex 9fca1a2f0..2bd12daf3 100644\n--- a/plone-6.0.x-python3.8.cfg\n+++ b/plone-6.0.x-python3.8.cfg\n@@ -1,6 +1,6 @@\n [buildout]\n extends =\n- https://dist.plone.org/release/6.0.11.1/versions.cfg\n+ https://dist.plone.org/release/6.0.12/versions.cfg\n base.cfg\n \n [instance]\ndiff --git a/plone-6.0.x.cfg b/plone-6.0.x.cfg\nindex 5172c9dda..26373fac8 100644\n--- a/plone-6.0.x.cfg\n+++ b/plone-6.0.x.cfg\n@@ -1,6 +1,6 @@\n [buildout]\n extends =\n- https://dist.plone.org/release/6.0.11.1/versions.cfg\n+ https://dist.plone.org/release/6.0.12/versions.cfg\n base.cfg\n \n [buildout:python37]\ndiff --git a/requirements-6.0.txt b/requirements-6.0.txt\nindex 2f870811b..b654a46a9 100644\n--- a/requirements-6.0.txt\n+++ b/requirements-6.0.txt\n@@ -1 +1 @@\n--r https://dist.plone.org/release/6.0.11.1/requirements.txt\n+-r https://dist.plone.org/release/6.0.12/requirements.txt\ndiff --git a/src/plone/restapi/serializer/nextprev.py b/src/plone/restapi/serializer/nextprev.py\nindex ffcd0e29f..6d11ef323 100644\n--- a/src/plone/restapi/serializer/nextprev.py\n+++ b/src/plone/restapi/serializer/nextprev.py\n@@ -1,24 +1,9 @@\n-from AccessControl import getSecurityManager\n from Acquisition import aq_inner\n from Acquisition import aq_parent\n-from plone.app.dexterity.behaviors.nextprevious import NextPreviousBase\n-from plone.registry.interfaces import IRegistry\n+from plone.app.dexterity.behaviors.nextprevious import (\n+ INextPreviousProvider,\n+)\n from plone.restapi.serializer.utils import get_portal_type_title\n-from zope.component import getUtility\n-\n-\n-class NextPreviousFixed(NextPreviousBase):\n- """\n- Based on plone.app.dexterity.behaviors.nextprevious.NextPreviousBase\n- but works for IPloneSite object\n- """\n-\n- def __init__(self, context):\n- self.context = context\n- registry = getUtility(IRegistry)\n- self.vat = registry.get("plone.types_use_view_action_in_listings", [])\n- self.security = getSecurityManager()\n- self.order = self.context.objectIds()\n \n \n class NextPrevious:\n@@ -27,11 +12,14 @@ class NextPrevious:\n def __init__(self, context):\n self.context = context\n self.parent = aq_parent(aq_inner(context))\n- self.nextprev = NextPreviousFixed(self.parent)\n+ self.nextprev = INextPreviousProvider(self.parent, None)\n+ self.enabled = self.nextprev is not None and self.nextprev.enabled\n \n @property\n def next(self):\n """return info about the next item in the container"""\n+ if not self.enabled:\n+ return {}\n if getattr(self.parent, "_ordering", "") == "unordered":\n # Unordered folder\n return {}\n@@ -49,6 +37,8 @@ def next(self):\n @property\n def previous(self):\n """return info about the previous item in the container"""\n+ if not self.enabled:\n+ return {}\n if getattr(self.parent, "_ordering", "") == "unordered":\n # Unordered folder\n return {}\ndiff --git a/src/plone/restapi/tests/http-examples/collection.resp b/src/plone/restapi/tests/http-examples/collection.resp\nindex 036a0bfd2..5a839d300 100644\n--- a/src/plone/restapi/tests/http-examples/collection.resp\n+++ b/src/plone/restapi/tests/http-examples/collection.resp\n@@ -97,13 +97,7 @@ Content-Type: application/json\n "stealable": true\n },\n "modified": "1995-07-31T17:30:00+00:00",\n- "next_item": {\n- "@id": "http://localhost:55001/plone/doc1",\n- "@type": "Document",\n- "description": "",\n- "title": "Document 1",\n- "type_title": "Page"\n- },\n+ "next_item": {},\n "parent": {\n "@id": "http://localhost:55001/plone",\n "@type": "Plone Site",\n@@ -111,13 +105,7 @@ Content-Type: application/json\n "title": "Plone site",\n "type_title": "Plone Site"\n },\n- "previous_item": {\n- "@id": "http://localhost:55001/plone/front-page",\n- "@type": "Document",\n- "description": "Congratulations! You have successfully installed Plone.",\n- "title": "Welcome to Plone",\n- "type_title": "Page"\n- },\n+ "previous_item": {},\n "query": [\n {\n "i": "portal_type",\ndiff --git a/src/plone/restapi/tests/http-examples/collection_fullobjects.resp b/src/plone/restapi/tests/http-examples/collection_fullobjects.resp\nindex 04b573bff..3836845d8 100644\n--- a/src/plone/restapi/tests/http-examples/collection_fullobjects.resp\n+++ b/src/plone/restapi/tests/http-examples/collection_fullobjects.resp\n@@ -113,13 +113,7 @@ Content-Type: application/json\n "stealable": true\n },\n "modified": "1995-07-31T17:30:00+00:00",\n- "next_item": {\n- "@id": "http://localhost:55001/plone/collection",\n- "@type": "Collection",\n- "description": "This is a collection with two documents",\n- "title": "My Collection",\n- "type_title": "Collection"\n- },\n+ "next_item": {},\n "parent": {\n "@id": "http://localhost:55001/plone",\n "@type": "Plone Site",\n@@ -195,13 +189,7 @@ Content-Type: application/json\n "stealable": true\n },\n "modified": "1995-07-31T17:30:00+00:00",\n- "next_item": {\n- "@id": "http://localhost:55001/plone/doc2",\n- "@type": "Document",\n- "description": "",\n- "title": "Document 2",\n- "type_title": "Page"\n- },\n+ "next_item": {},\n "parent": {\n "@id": "http://localhost:55001/plone",\n "@type": "Plone Site",\n@@ -209,13 +197,7 @@ Content-Type: application/json\n "title": "Plone site",\n "type_title": "Plone Site"\n },\n- "previous_item": {\n- "@id": "http://localhost:55001/plone/collection",\n- "@type": "Collection",\n- "description": "This is a collection with two documents",\n- "title": "My Collection",\n- "type_title": "Collection"\n- },\n+ "previous_item": {},\n "relatedItems": [],\n "review_state": "private",\n "rights": "",\n@@ -287,13 +269,7 @@ Content-Type: application/json\n "title": "Plone site",\n "type_title": "Plone Site"\n },\n- "previous_item": {\n- "@id": "http://localhost:55001/plone/doc1",\n- "@type": "Document",\n- "description": "",\n- "title": "Document 1",\n- "type_title": "Page"\n- },\n+ "previous_item": {},\n "relatedItems": [],\n "review_state": "private",\n "rights": "",\n@@ -317,13 +293,7 @@ Content-Type: application/json\n "stealable": true\n },\n "modified": "1995-07-31T17:30:00+00:00",\n- "next_item": {\n- "@id": "http://localhost:55001/plone/doc1",\n- "@type": "Document",\n- "description": "",\n- "title": "Document 1",\n- "type_title": "Page"\n- },\n+ "next_item": {},\n "parent": {\n "@id": "http://localhost:55001/plone",\n "@type": "Plone Site",\n@@ -331,13 +301,7 @@ Content-Type: application/json\n "title": "Plone site",\n "type_title": "Plone Site"\n },\n- "previous_item": {\n- "@id": "http://localhost:55001/plone/front-page",\n- "@type": "Document",\n- "description": "Congratulations! You have successfully installed Plone.",\n- "title": "Welcome to Plone",\n- "type_title": "Page"\n- },\n+ "previous_item": {},\n "query": [\n {\n "i": "portal_type",\ndiff --git a/src/plone/restapi/tests/http-examples/content_get.resp b/src/plone/restapi/tests/http-examples/content_get.resp\nindex 9d876dccf..ad574ee2f 100644\n--- a/src/plone/restapi/tests/http-examples/content_get.resp\n+++ b/src/plone/restapi/tests/http-examples/content_get.resp\n@@ -60,13 +60,7 @@ Content-Type: application/json\n "title": "My Folder",\n "type_title": "Folder"\n },\n- "previous_item": {\n- "@id": "http://localhost:55001/plone/folder/doc2",\n- "@type": "Document",\n- "description": "",\n- "title": "A document within a folder",\n- "type_title": "Page"\n- },\n+ "previous_item": {},\n "relatedItems": [],\n "review_state": "private",\n "rights": "",\ndiff --git a/src/plone/restapi/tests/http-examples/content_get_folder.resp b/src/plone/restapi/tests/http-examples/content_get_folder.resp\nindex c7e9f35e7..7c2915f48 100644\n--- a/src/plone/restapi/tests/http-examples/content_get_folder.resp\n+++ b/src/plone/restapi/tests/http-examples/content_get_folder.resp\n@@ -89,13 +89,7 @@ Content-Type: application/json\n "title": "Plone site",\n "type_title": "Plone Site"\n },\n- "previous_item": {\n- "@id": "http://localhost:55001/plone/front-page",\n- "@type": "Document",\n- "description": "Congratulations! You have successfully installed Plone.",\n- "title": "Welcome to Plone",\n- "type_title": "Page"\n- },\n+ "previous_item": {},\n "relatedItems": [],\n "review_state": "private",\n "rights": "",\ndiff --git a/src/plone/restapi/tests/http-examples/content_patch_representation.resp b/src/plone/restapi/tests/http-examples/content_patch_representation.resp\nindex 0003cae47..bbc788a94 100644\n--- a/src/plone/restapi/tests/http-examples/content_patch_representation.resp\n+++ b/src/plone/restapi/tests/http-examples/content_patch_representation.resp\n@@ -60,13 +60,7 @@ Content-Type: application/json\n "title": "My Folder",\n "type_title": "Folder"\n },\n- "previous_item": {\n- "@id": "http://localhost:55001/plone/folder/doc2",\n- "@type": "Document",\n- "description": "",\n- "title": "A document within a folder",\n- "type_title": "Page"\n- },\n+ "previous_item": {},\n "relatedItems": [],\n "review_state": "private",\n "rights": "",\ndiff --git a/src/plone/restapi/tests/http-examples/content_post.resp b/src/plone/restapi/tests/http-examples/content_post.resp\nindex 9cd542a49..99c1f3c4b 100644\n--- a/src/plone/restapi/tests/http-examples/content_post.resp\n+++ b/src/plone/restapi/tests/http-examples/content_post.resp\n@@ -61,13 +61,7 @@ Location: http://localhost:55001/plone/folder/my-document\n "title": "My Folder",\n "type_title": "Folder"\n },\n- "previous_item": {\n- "@id": "http://localhost:55001/plone/folder/doc2",\n- "@type": "Document",\n- "description": "",\n- "title": "A document within a folder",\n- "type_title": "Page"\n- },\n+ "previous_item": {},\n "relatedItems": [],\n "review_state": "private",\n "rights": "",\ndiff --git a/src/plone/restapi/tests/http-examples/event.resp b/src/plone/restapi/tests/http-examples/event.resp\nindex 2591e6180..7cf0051a3 100644\n--- a/src/plone/restapi/tests/http-examples/event.resp\n+++ b/src/plone/restapi/tests/http-examples/event.resp\n@@ -67,13 +67,7 @@ Content-Type: application/json\n "title": "Plone site",\n "type_title": "Plone Site"\n },\n- "previous_item": {\n- "@id": "http://localhost:55001/plone/front-page",\n- "@type": "Document",\n- "description": "Congratulations! You have successfully installed Plone.",\n- "title": "Welcome to Plone",\n- "type_title": "Page"\n- },\n+ "previous_item": {},\n "recurrence": null,\n "relatedItems": [],\n "review_state": "private",\ndiff --git a/src/plone/restapi/tests/http-examples/file.resp b/src/plone/restapi/tests/http-examples/file.resp\nindex 4b463c60f..1f2f7ad12 100644\n--- a/src/plone/restapi/tests/http-examples/file.resp\n+++ b/src/plone/restapi/tests/http-examples/file.resp\n@@ -61,13 +61,7 @@ Content-Type: application/json\n "title": "Plone site",\n "type_title": "Plone Site"\n },\n- "previous_item": {\n- "@id": "http://localhost:55001/plone/front-page",\n- "@type": "Document",\n- "description": "Congratulations! You have successfully installed Plone.",\n- "title": "Welcome to Plone",\n- "type_title": "Page"\n- },\n+ "previous_item": {},\n "relatedItems": [],\n "review_state": null,\n "rights": "",\ndiff --git a/src/plone/restapi/tests/http-examples/folder.resp b/src/plone/restapi/tests/http-examples/folder.resp\nindex 7a41f8227..ad3dd229b 100644\n--- a/src/plone/restapi/tests/http-examples/folder.resp\n+++ b/src/plone/restapi/tests/http-examples/folder.resp\n@@ -75,13 +75,7 @@ Content-Type: application/json\n "title": "Plone site",\n "type_title": "Plone Site"\n },\n- "previous_item": {\n- "@id": "http://localhost:55001/plone/front-page",\n- "@type": "Document",\n- "description": "Congratulations! You have successfully installed Plone.",\n- "title": "Welcome to Plone",\n- "type_title": "Page"\n- },\n+ "previous_item": {},\n "relatedItems": [],\n "review_state": "private",\n "rights": "",\ndiff --git a/src/plone/restapi/tests/http-examples/image.resp b/src/plone/restapi/tests/http-examples/image.resp\nindex c2e13cbd1..e459b587c 100644\n--- a/src/plone/restapi/tests/http-examples/image.resp\n+++ b/src/plone/restapi/tests/http-examples/image.resp\n@@ -120,13 +120,7 @@ Content-Type: application/json\n "title": "Plone site",\n "type_title": "Plone Site"\n },\n- "previous_item": {\n- "@id": "http://localhost:55001/plone/front-page",\n- "@type": "Document",\n- "description": "Congratulations! You have successfully installed Plone.",\n- "title": "Welcome to Plone",\n- "type_title": "Page"\n- },\n+ "previous_item": {},\n "relatedItems": [],\n "review_state": null,\n "rights": "",\ndiff --git a/src/plone/restapi/tests/http-examples/link.resp b/src/plone/restapi/tests/http-examples/link.resp\nindex 76d990359..64ac54490 100644\n--- a/src/plone/restapi/tests/http-examples/link.resp\n+++ b/src/plone/restapi/tests/http-examples/link.resp\n@@ -56,13 +56,7 @@ Content-Type: application/json\n "title": "Plone site",\n "type_title": "Plone Site"\n },\n- "previous_item": {\n- "@id": "http://localhost:55001/plone/front-page",\n- "@type": "Document",\n- "description": "Congratulations! You have successfully installed Plone.",\n- "title": "Welcome to Plone",\n- "type_title": "Page"\n- },\n+ "previous_item": {},\n "remoteUrl": "http://localhost:55001/plone",\n "review_state": "private",\n "rights": "",\ndiff --git a/src/plone/restapi/tests/http-examples/navroot_lang_content_get.resp b/src/plone/restapi/tests/http-examples/navroot_lang_content_get.resp\nindex d537815af..cfbf9e1cf 100644\n--- a/src/plone/restapi/tests/http-examples/navroot_lang_content_get.resp\n+++ b/src/plone/restapi/tests/http-examples/navroot_lang_content_get.resp\n@@ -74,13 +74,7 @@ Content-Type: application/json\n "layout": "folder_listing",\n "lock": {},\n "modified": "1995-07-31T17:30:00+00:00",\n- "next_item": {\n- "@id": "http://localhost:55001/plone/de",\n- "@type": "LRF",\n- "description": "",\n- "title": "Deutsch",\n- "type_title": "Language Root Folder"\n- },\n+ "next_item": {},\n "parent": {\n "@id": "http://localhost:55001/plone",\n "@type": "Plone Site",\ndiff --git a/src/plone/restapi/tests/http-examples/navroot_lang_folder_get.resp b/src/plone/restapi/tests/http-examples/navroot_lang_folder_get.resp\nindex 801625f6d..3932a805e 100644\n--- a/src/plone/restapi/tests/http-examples/navroot_lang_folder_get.resp\n+++ b/src/plone/restapi/tests/http-examples/navroot_lang_folder_get.resp\n@@ -74,13 +74,7 @@ Content-Type: application/json\n "layout": "folder_listing",\n "lock": {},\n "modified": "1995-07-31T17:30:00+00:00",\n- "next_item": {\n- "@id": "http://localhost:55001/plone/de",\n- "@type": "LRF",\n- "description": "",\n- "title": "Deutsch",\n- "type_title": "Language Root Folder"\n- },\n+ "next_item": {},\n "parent": {\n "@id": "http://localhost:55001/plone",\n "@type": "Plone Site",\ndiff --git a/src/plone/restapi/tests/http-examples/newsitem.resp b/src/plone/restapi/tests/http-examples/newsitem.resp\nindex e1dab847d..cab5656ca 100644\n--- a/src/plone/restapi/tests/http-examples/newsitem.resp\n+++ b/src/plone/restapi/tests/http-examples/newsitem.resp\n@@ -125,13 +125,7 @@ Content-Type: application/json\n "title": "Plone site",\n "type_title": "Plone Site"\n },\n- "previous_item": {\n- "@id": "http://localhost:55001/plone/front-page",\n- "@type": "Document",\n- "description": "Congratulations! You have successfully installed Plone.",\n- "title": "Welcome to Plone",\n- "type_title": "Page"\n- },\n+ "previous_item": {},\n "relatedItems": [],\n "review_state": "private",\n "rights": "",\ndiff --git a/src/plone/restapi/tests/http-examples/search_fullobjects.resp b/src/plone/restapi/tests/http-examples/search_fullobjects.resp\nindex 5c9fe7ebf..e74567105 100644\n--- a/src/plone/restapi/tests/http-examples/search_fullobjects.resp\n+++ b/src/plone/restapi/tests/http-examples/search_fullobjects.resp\n@@ -62,13 +62,7 @@ Content-Type: application/json\n "title": "Plone site",\n "type_title": "Plone Site"\n },\n- "previous_item": {\n- "@id": "http://localhost:55001/plone/front-page",\n- "@type": "Document",\n- "description": "Congratulations! You have successfully installed Plone.",\n- "title": "Welcome to Plone",\n- "type_title": "Page"\n- },\n+ "previous_item": {},\n "relatedItems": [],\n "review_state": "private",\n "rights": "",\ndiff --git a/src/plone/restapi/tests/http-examples/site_get_expand_lang_folder.resp b/src/plone/restapi/tests/http-examples/site_get_expand_lang_folder.resp\nindex 4d636bc25..705960dde 100644\n--- a/src/plone/restapi/tests/http-examples/site_get_expand_lang_folder.resp\n+++ b/src/plone/restapi/tests/http-examples/site_get_expand_lang_folder.resp\n@@ -91,13 +91,7 @@ Content-Type: application/json\n "layout": "folder_listing",\n "lock": {},\n "modified": "1995-07-31T17:30:00+00:00",\n- "next_item": {\n- "@id": "http://localhost:55001/plone/de",\n- "@type": "LRF",\n- "description": "",\n- "title": "Deutsch",\n- "type_title": "Language Root Folder"\n- },\n+ "next_item": {},\n "parent": {\n "@id": "http://localhost:55001/plone",\n "@type": "Plone Site",\n@@ -167,13 +161,7 @@ Content-Type: application/json\n "layout": "folder_listing",\n "lock": {},\n "modified": "1995-07-31T17:30:00+00:00",\n- "next_item": {\n- "@id": "http://localhost:55001/plone/de",\n- "@type": "LRF",\n- "description": "",\n- "title": "Deutsch",\n- "type_title": "Language Root Folder"\n- },\n+ "next_item": {},\n "parent": {\n "@id": "http://localhost:55001/plone",\n "@type": "Plone Site",\ndiff --git a/src/plone/restapi/tests/http-examples/site_get_expand_lang_folder_content.resp b/src/plone/restapi/tests/http-examples/site_get_expand_lang_folder_content.resp\nindex 9d4058231..443f2014b 100644\n--- a/src/plone/restapi/tests/http-examples/site_get_expand_lang_folder_content.resp\n+++ b/src/plone/restapi/tests/http-examples/site_get_expand_lang_folder_content.resp\n@@ -91,13 +91,7 @@ Content-Type: application/json\n "layout": "folder_listing",\n "lock": {},\n "modified": "1995-07-31T17:30:00+00:00",\n- "next_item": {\n- "@id": "http://localhost:55001/plone/de",\n- "@type": "LRF",\n- "description": "",\n- "title": "Deutsch",\n- "type_title": "Language Root Folder"\n- },\n+ "next_item": {},\n "parent": {\n "@id": "http://localhost:55001/plone",\n "@type": "Plone Site",\n@@ -161,13 +155,7 @@ Content-Type: application/json\n "title": "English",\n "type_title": "Language Root Folder"\n },\n- "previous_item": {\n- "@id": "http://localhost:55001/plone/en/assets",\n- "@type": "LIF",\n- "description": "",\n- "title": "Assets",\n- "type_title": "Language Independent Folder"\n- },\n+ "previous_item": {},\n "relatedItems": [],\n "review_state": "private",\n "rights": "",\ndiff --git a/src/plone/restapi/tests/http-examples/translated_messages_types_folder.resp b/src/plone/restapi/tests/http-examples/translated_messages_types_folder.resp\nindex 3bdf1d009..ab0702c56 100644\n--- a/src/plone/restapi/tests/http-examples/translated_messages_types_folder.resp\n+++ b/src/plone/restapi/tests/http-examples/translated_messages_types_folder.resp\n@@ -59,11 +59,11 @@ Content-Type: application/json+schema\n ],\n "layouts": [\n "album_view",\n+ "event_listing",\n "full_view",\n "listing_view",\n "summary_view",\n- "tabular_view",\n- "event_listing"\n+ "tabular_view"\n ],\n "properties": {\n "allow_discussion": {\ndiff --git a/src/plone/restapi/tests/http-examples/translations_expand_get.resp b/src/plone/restapi/tests/http-examples/translations_expand_get.resp\nindex 010dce733..fc5e677b1 100644\n--- a/src/plone/restapi/tests/http-examples/translations_expand_get.resp\n+++ b/src/plone/restapi/tests/http-examples/translations_expand_get.resp\n@@ -78,13 +78,7 @@ Content-Type: application/json\n "title": "English",\n "type_title": "Language Root Folder"\n },\n- "previous_item": {\n- "@id": "http://localhost:55001/plone/en/assets",\n- "@type": "LIF",\n- "description": "",\n- "title": "Assets",\n- "type_title": "Language Independent Folder"\n- },\n+ "previous_item": {},\n "relatedItems": [],\n "review_state": "private",\n "rights": "",\ndiff --git a/src/plone/restapi/tests/http-examples/translations_link_on_post.resp b/src/plone/restapi/tests/http-examples/translations_link_on_post.resp\nindex 798d35219..699d57edd 100644\n--- a/src/plone/restapi/tests/http-examples/translations_link_on_post.resp\n+++ b/src/plone/restapi/tests/http-examples/translations_link_on_post.resp\n@@ -67,13 +67,7 @@ Location: http://localhost:55001/plone/de/mydocument\n "title": "Deutsch",\n "type_title": "Basisordner einer Sprache"\n },\n- "previous_item": {\n- "@id": "http://localhost:55001/plone/de/assets",\n- "@type": "LIF",\n- "description": "",\n- "title": "Assets",\n- "type_title": "Sprachunabh\\u00e4ngiger Ordner"\n- },\n+ "previous_item": {},\n "relatedItems": [],\n "review_state": "private",\n "rights": "",\ndiff --git a/src/plone/restapi/tests/http-examples/translations_unexpanded_get.resp b/src/plone/restapi/tests/http-examples/translations_unexpanded_get.resp\nindex 7b0e67424..f266e4dc1 100644\n--- a/src/plone/restapi/tests/http-examples/translations_unexpanded_get.resp\n+++ b/src/plone/restapi/tests/http-examples/translations_unexpanded_get.resp\n@@ -66,13 +66,7 @@ Content-Type: application/json\n "title": "English",\n "type_title": "Language Root Folder"\n },\n- "previous_item": {\n- "@id": "http://localhost:55001/plone/en/assets",\n- "@type": "LIF",\n- "description": "",\n- "title": "Assets",\n- "type_title": "Language Independent Folder"\n- },\n+ "previous_item": {},\n "relatedItems": [],\n "review_state": "private",\n "rights": "",\ndiff --git a/src/plone/restapi/tests/http-examples/workingcopy_baseline_get.resp b/src/plone/restapi/tests/http-examples/workingcopy_baseline_get.resp\nindex 32a97febf..aea5b625d 100644\n--- a/src/plone/restapi/tests/http-examples/workingcopy_baseline_get.resp\n+++ b/src/plone/restapi/tests/http-examples/workingcopy_baseline_get.resp\n@@ -58,13 +58,7 @@ Content-Type: application/json\n "token": "0.12345678901234567-0.98765432109876543-00105A989226:1630609830.249"\n },\n "modified": "1995-07-31T17:30:00+00:00",\n- "next_item": {\n- "@id": "http://localhost:55001/plone/copy_of_document",\n- "@type": "Document",\n- "description": "",\n- "title": "Test document",\n- "type_title": "Page"\n- },\n+ "next_item": {},\n "parent": {\n "@id": "http://localhost:55001/plone",\n "@type": "Plone Site",\ndiff --git a/src/plone/restapi/tests/http-examples/workingcopy_wc_get.resp b/src/plone/restapi/tests/http-examples/workingcopy_wc_get.resp\nindex 08598e4e2..2db877143 100644\n--- a/src/plone/restapi/tests/http-examples/workingcopy_wc_get.resp\n+++ b/src/plone/restapi/tests/http-examples/workingcopy_wc_get.resp\n@@ -58,13 +58,7 @@ Content-Type: application/json\n "title": "Plone site",\n "type_title": "Plone Site"\n },\n- "previous_item": {\n- "@id": "http://localhost:55001/plone/document",\n- "@type": "Document",\n- "description": "",\n- "title": "Test document",\n- "type_title": "Page"\n- },\n+ "previous_item": {},\n "relatedItems": [],\n "review_state": "private",\n "rights": "",\ndiff --git a/src/plone/restapi/tests/test_dxcontent_serializer.py b/src/plone/restapi/tests/test_dxcontent_serializer.py\nindex 18d41cb95..789cf865f 100644\n--- a/src/plone/restapi/tests/test_dxcontent_serializer.py\n+++ b/src/plone/restapi/tests/test_dxcontent_serializer.py\n@@ -11,6 +11,8 @@\n from plone.app.testing import TEST_USER_ID\n from plone.app.textfield.interfaces import ITransformer\n from plone.app.textfield.value import RichTextValue\n+from plone.dexterity.interfaces import IDexterityFTI\n+from plone.dexterity.schema import SCHEMA_CACHE\n from plone.namedfile.file import NamedFile\n from plone.registry.interfaces import IRegistry\n from plone.restapi.interfaces import IExpandableElement\n@@ -31,6 +33,9 @@\n import json\n import unittest\n \n+HAS_PLONE_6 = getattr(\n+ import_module("Products.CMFPlone.factory"), "PLONE60MARKER", False\n+)\n HAS_PLONE_61 = getattr(\n import_module("Products.CMFPlone.factory"), "PLONE61MARKER", False\n )\n@@ -200,12 +205,42 @@ def test_get_is_folderish_in_folder(self):\n self.assertIn("is_folderish", obj)\n self.assertEqual(True, obj["is_folderish"])\n \n+ def test_enable_disable_nextprev(self):\n+ folder = api.content.create(\n+ container=self.portal,\n+ type="Folder",\n+ title="Folder with items",\n+ description="This is a folder with some documents",\n+ nextPreviousEnabled=False,\n+ )\n+ api.content.create(\n+ container=folder,\n+ type="Document",\n+ title="Item 1",\n+ description="Previous item",\n+ )\n+ doc = api.content.create(\n+ container=folder,\n+ type="Document",\n+ title="Item 2",\n+ description="Current item",\n+ )\n+ api.content.create(\n+ container=folder, type="Document", title="Item 2", description="Next item"\n+ )\n+\n+ data = self.serialize(doc)\n+\n+ self.assertEqual({}, data["previous_item"])\n+ self.assertEqual({}, data["next_item"])\n+\n def test_nextprev_no_nextprev(self):\n folder = api.content.create(\n container=self.portal,\n type="Folder",\n title="Folder with items",\n description="This is a folder with some documents",\n+ nextPreviousEnabled=True,\n )\n doc = api.content.create(\n container=folder,\n@@ -223,6 +258,7 @@ def test_nextprev_has_prev(self):\n type="Folder",\n title="Folder with items",\n description="This is a folder with some documents",\n+ nextPreviousEnabled=True,\n )\n api.content.create(\n container=folder,\n@@ -255,6 +291,7 @@ def test_nextprev_has_next(self):\n type="Folder",\n title="Folder with items",\n description="This is a folder with some documents",\n+ nextPreviousEnabled=True,\n )\n doc = api.content.create(\n container=folder,\n@@ -284,6 +321,7 @@ def test_nextprev_has_nextprev(self):\n type="Folder",\n title="Folder with items",\n description="This is a folder with some documents",\n+ nextPreviousEnabled=True,\n )\n api.content.create(\n container=folder,\n@@ -327,7 +365,16 @@ def test_nextprev_root_no_nextprev(self):\n self.assertEqual({}, data["previous_item"])\n self.assertEqual({}, data["next_item"])\n \n+ @unittest.skipUnless(HAS_PLONE_6, "Requires Dexterity-based site root")\n def test_nextprev_root_has_prev(self):\n+ fti = queryUtility(IDexterityFTI, name="Plone Site")\n+ behavior_list = [a for a in fti.behaviors]\n+ behavior_list.append("plone.nextpreviousenabled")\n+ fti.behaviors = tuple(behavior_list)\n+ # Invalidating the cache is required for the FTI to be applied\n+ # on the existing object\n+ SCHEMA_CACHE.invalidate("Plone Site")\n+\n doc = api.content.create(\n container=self.portal,\n type="Document",\n@@ -347,7 +394,16 @@ def test_nextprev_root_has_prev(self):\n )\n self.assertEqual({}, data["next_item"])\n \n+ @unittest.skipUnless(HAS_PLONE_6, "Requires Dexterity-based site root")\n def test_nextprev_root_has_next(self):\n+ fti = queryUtility(IDexterityFTI, name="Plone Site")\n+ behavior_list = [a for a in fti.behaviors]\n+ behavior_list.append("plone.nextpreviousenabled")\n+ fti.behaviors = tuple(behavior_list)\n+ # Invalidating the cache is required for the FTI to be applied\n+ # on the existing object\n+ SCHEMA_CACHE.invalidate("Plone Site")\n+\n api.content.create(\n container=self.portal,\n type="Document",\n@@ -367,7 +423,16 @@ def test_nextprev_root_has_next(self):\n data["next_item"],\n )\n \n+ @unittest.skipUnless(HAS_PLONE_6, "Requires Dexterity-based site root")\n def test_nextprev_root_has_nextprev(self):\n+ fti = queryUtility(IDexterityFTI, name="Plone Site")\n+ behavior_list = [a for a in fti.behaviors]\n+ behavior_list.append("plone.nextpreviousenabled")\n+ fti.behaviors = tuple(behavior_list)\n+ # Invalidating the cache is required for the FTI to be applied\n+ # on the existing object\n+ SCHEMA_CACHE.invalidate("Plone Site")\n+\n api.content.create(\n container=self.portal,\n type="Document",\n@@ -414,6 +479,7 @@ def test_nextprev_unordered_folder(self):\n type="Folder",\n title="Folder with items",\n description="This is a folder with some documents",\n+ nextPreviousEnabled=True,\n )\n folder.setOrdering("unordered")\n doc = api.content.create(\n'