plone.restapi/unify-expired-and-excluded-items-handling: Show expired content when GET on a folderish object, include

Victor Fernandez de Alba <jenkins-z4DKO/[email protected]> Thu, 27 Jul 2017 00:12:16 -0700 (PDT)
Newsgroups gmane.comp.web.zope.plone.cvs
Message-ID <[email protected]>
Repository: plone.restapi
Branch: refs/heads/unify-expired-and-excluded-items-handling
Date: 2017-07-27T09:12:04+02:00
Author: Victor Fernandez de Alba (sneridagh) <[email protected]>
Commit: https://github.com/plone/plone.restapi/commit/5bd97c74fba6543cba7450dc2faf106974212926

Show expired content when GET on a folderish object, include a way to display it on @search via the show_inactive parameter

Files changed:
M CHANGES.rst
M docs/source/content.rst
M docs/source/searching.rst
M src/plone/restapi/search/query.py
M src/plone/restapi/serializer/atcontent.py
M src/plone/restapi/serializer/dxcontent.py
M src/plone/restapi/serializer/site.py
M src/plone/restapi/tests/test_search.py
M src/plone/restapi/tests/test_serializer.py
M src/plone/restapi/tests/test_services_navigation.py

diff --git a/CHANGES.rst b/CHANGES.rst
index 7858f485..87a7d6e4 100644
--- a/CHANGES.rst
+++ b/CHANGES.rst
@@ -12,6 +12,10 @@ New Features:
 - Add skipped tests from @breadcrumbs and @navigation now that the expansion is in place
   [sneridagh]
 
+- Show expired content when GET on a folderish object, include a way to display
+  it on @search via the show_inactive parameter
+  [sneridagh]
+
 
 1.0a20 (2017-07-24)
 -------------------
diff --git a/docs/source/content.rst b/docs/source/content.rst
index 5595bc70..2b5b6942 100644
--- a/docs/source/content.rst
+++ b/docs/source/content.rst
@@ -337,3 +337,9 @@ A response 400 BadRequest with a message 'Content ordering is not supported by t
 
 ..  http:example:: curl httpie python-requests
     :request: _json/content_reorder.req
+
+
+Expired content
+---------------
+
+When retrieving the content items they will include all the content in the folder/site, including the expired content that might contain.
diff --git a/docs/source/searching.rst b/docs/source/searching.rst
index 91b19754..56db487d 100644
--- a/docs/source/searching.rst
+++ b/docs/source/searching.rst
@@ -121,3 +121,14 @@ You do so by specifying the ``fullobjects`` parameter:
 .. warning::
 
     Be aware that this might induce performance issues when retrieving a lot of resources. Normally the search just serializes catalog brains, but with full objects we wake up all the returned objects.
+
+
+Expired content
+---------------
+
+This endpoint will not return any expired content unless you use and set the ``show_inactive`` query to true.
+
+.. code-block:: http
+
+    GET /plone/@search?show_inactive=1 HTTP/1.1
+    Accept: application/json
diff --git a/src/plone/restapi/search/query.py b/src/plone/restapi/search/query.py
index 0282f67d..6285fd7b 100644
--- a/src/plone/restapi/search/query.py
+++ b/src/plone/restapi/search/query.py
@@ -74,6 +74,7 @@ class ZCatalogCompatibleQueryAdapter(object):
         'sort_limit': int,
         'b_start': int,
         'b_size': int,
+        'show_inactive': bool
     }
 
     def __init__(self, context, request):
diff --git a/src/plone/restapi/serializer/atcontent.py b/src/plone/restapi/serializer/atcontent.py
index 53125363..9db7d9ff 100644
--- a/src/plone/restapi/serializer/atcontent.py
+++ b/src/plone/restapi/serializer/atcontent.py
@@ -81,7 +81,8 @@ class SerializeFolderToJson(SerializeToJson):
     def _build_query(self):
         path = '/'.join(self.context.getPhysicalPath())
         query = {'path': {'depth': 1, 'query': path},
-                 'sort_on': 'getObjPositionInParent'}
+                 'sort_on': 'getObjPositionInParent',
+                 'show_inactive': True}
         return query
 
     def __call__(self, version=None):
diff --git a/src/plone/restapi/serializer/dxcontent.py b/src/plone/restapi/serializer/dxcontent.py
index 3ca280eb..bc2ae36e 100644
--- a/src/plone/restapi/serializer/dxcontent.py
+++ b/src/plone/restapi/serializer/dxcontent.py
@@ -113,7 +113,8 @@ class SerializeFolderToJson(SerializeToJson):
     def _build_query(self):
         path = '/'.join(self.context.getPhysicalPath())
         query = {'path': {'depth': 1, 'query': path},
-                 'sort_on': 'getObjPositionInParent'}
+                 'sort_on': 'getObjPositionInParent',
+                 'show_inactive': True}
         return query
 
     def __call__(self, version=None):
diff --git a/src/plone/restapi/serializer/site.py b/src/plone/restapi/serializer/site.py
index 24b8284e..4b689677 100644
--- a/src/plone/restapi/serializer/site.py
+++ b/src/plone/restapi/serializer/site.py
@@ -22,7 +22,8 @@ def __init__(self, context, request):
     def _build_query(self):
         path = '/'.join(self.context.getPhysicalPath())
         query = {'path': {'depth': 1, 'query': path},
-                 'sort_on': 'getObjPositionInParent'}
+                 'sort_on': 'getObjPositionInParent',
+                 'show_inactive': True}
         return query
 
     def __call__(self, version=None):
diff --git a/src/plone/restapi/tests/test_search.py b/src/plone/restapi/tests/test_search.py
index 916d4e1c..d1ab902d 100644
--- a/src/plone/restapi/tests/test_search.py
+++ b/src/plone/restapi/tests/test_search.py
@@ -432,3 +432,31 @@ def test_uuid_index_query(self):
             [u'/plone/folder/doc'],
             result_paths(response.json())
         )
+
+    def test_search_expired_doc_not_showing(self):
+        self.portal['doc-outside-folder'].setExpirationDate(
+            DateTime('2017/01/01'))
+        wftool = getToolByName(self.portal, 'portal_workflow')
+        wftool.doActionFor(self.portal['doc-outside-folder'], 'submit')
+        wftool.doActionFor(self.portal['doc-outside-folder'], 'publish')
+        self.portal['doc-outside-folder'].reindexObject()
+        transaction.commit()
+
+        self.api_session.auth = ('', '')
+        response = self.api_session.get('/@search')
+        response = response.json()
+        self.assertEquals(len(response['items']), 0)
+
+    def test_search_expired_doc_showing_using_show_inactive(self):
+        self.portal['doc-outside-folder'].setExpirationDate(
+            DateTime('2017/01/01'))
+        wftool = getToolByName(self.portal, 'portal_workflow')
+        wftool.doActionFor(self.portal['doc-outside-folder'], 'submit')
+        wftool.doActionFor(self.portal['doc-outside-folder'], 'publish')
+        self.portal['doc-outside-folder'].reindexObject()
+        transaction.commit()
+
+        self.api_session.auth = ('', '')
+        response = self.api_session.get('/@search?show_inactive=1')
+        response = response.json()
+        self.assertEquals(len(response['items']), 1)
diff --git a/src/plone/restapi/tests/test_serializer.py b/src/plone/restapi/tests/test_serializer.py
index bbf76142..06a9ba39 100644
--- a/src/plone/restapi/tests/test_serializer.py
+++ b/src/plone/restapi/tests/test_serializer.py
@@ -1,5 +1,6 @@
 # -*- coding: utf-8 -*-
 from DateTime import DateTime
+from plone.app.testing import logout
 from plone.app.testing import setRoles
 from plone.app.testing import TEST_USER_ID
 from plone.app.textfield.value import RichTextValue
@@ -367,3 +368,17 @@ def test_serialize_to_json_collection(self):
             ],
             self.serialize(self.portal.collection1).get('items')
         )
+
+    def test_serialize_folder_returns_expired_items(self):
+        self.portal.doc1.setExpirationDate(DateTime('2017/01/01'))
+        wftool = getToolByName(self.portal, 'portal_workflow')
+        wftool.doActionFor(self.portal.doc1, 'submit')
+        wftool.doActionFor(self.portal.doc1, 'publish')
+        self.portal.doc1.reindexObject()
+        # We test it with published content for not to fiddle with permissions
+        # and users
+        logout()
+        self.assertEqual(
+            len(self.serialize(self.portal)['items']),
+            1
+        )
diff --git a/src/plone/restapi/tests/test_services_navigation.py b/src/plone/restapi/tests/test_services_navigation.py
index a0c47213..0d7019dc 100644
--- a/src/plone/restapi/tests/test_services_navigation.py
+++ b/src/plone/restapi/tests/test_services_navigation.py
@@ -6,6 +6,8 @@
 from plone.dexterity.utils import createContentInContainer
 from plone.restapi.testing import PLONE_RESTAPI_DX_FUNCTIONAL_TESTING
 from plone.restapi.testing import RelativeSession
+from DateTime import DateTime
+from Products.CMFCore.utils import getToolByName
 
 import transaction
 import unittest
@@ -55,3 +57,18 @@ def test_navigation(self):
                 ]
             }
         )
+
+    def test_navigation_expired_items(self):
+        self.folder.setExpirationDate(DateTime('2017/01/01'))
+        wftool = getToolByName(self.portal, 'portal_workflow')
+        wftool.doActionFor(self.folder, 'submit')
+        wftool.doActionFor(self.folder, 'publish')
+        self.folder.reindexObject()
+        transaction.commit()
+
+        self.api_session.auth = ('', '')
+        response = self.api_session.get('/@navigation')
+        response = response.json()
+
+        self.assertEquals(len(response['items']), 1)
+        self.assertEquals(response['items'][0]['title'], 'Home')



------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot