plone.restapi/plone-only-login: Make workflow info expandable

Thomas Buchberger <jenkins-z4DKO/[email protected]>
Newsgroups gmane.comp.web.zope.plone.cvs
Message-ID <[email protected]>
Repository: plone.restapi
Branch: refs/heads/plone-only-login
Date: 2017-07-25T10:37:43+02:00
Author: Thomas Buchberger (buchi) <t.buchberger-/8aE7x569Db/[email protected]>
Commit: https://github.com/plone/plone.restapi/commit/848f958a1caedc1b549ba6d9db71cc36d8759773

Make workflow info expandable

Files changed:
M docs/source/_json/collection.resp
M docs/source/_json/content_get.resp
M docs/source/_json/content_post.resp
M docs/source/_json/document.resp
M docs/source/_json/event.resp
M docs/source/_json/file.resp
M docs/source/_json/folder.resp
M docs/source/_json/image.resp
M docs/source/_json/link.resp
M docs/source/_json/newsitem.resp
M src/plone/restapi/services/workflow/configure.zcml
M src/plone/restapi/services/workflow/info.py
M src/plone/restapi/tests/test_workflow.py

diff --git a/docs/source/_json/collection.resp b/docs/source/_json/collection.resp
index c0fce081..12cac672 100644
--- a/docs/source/_json/collection.resp
+++ b/docs/source/_json/collection.resp
@@ -4,6 +4,9 @@ Content-Type: application/json
 {
   "@id": "http://localhost:55001/plone/collection", 
   "@type": "Collection", 
+  "@workflow": {
+    "@id": "http://localhost:55001/plone/collection/@workflow"
+  }, 
   "UID": "SomeUUID000000000000000000000002", 
   "allow_discussion": null, 
   "contributors": [], 
diff --git a/docs/source/_json/content_get.resp b/docs/source/_json/content_get.resp
index bb605400..69c3f4b9 100644
--- a/docs/source/_json/content_get.resp
+++ b/docs/source/_json/content_get.resp
@@ -4,6 +4,9 @@ Content-Type: application/json
 {
   "@id": "http://localhost:55001/plone/folder/my-document", 
   "@type": "Document", 
+  "@workflow": {
+    "@id": "http://localhost:55001/plone/folder/my-document/@workflow"
+  }, 
   "UID": "SomeUUID000000000000000000000005", 
   "allow_discussion": null, 
   "changeNote": "", 
diff --git a/docs/source/_json/content_post.resp b/docs/source/_json/content_post.resp
index 85f0a7b6..ae35de46 100644
--- a/docs/source/_json/content_post.resp
+++ b/docs/source/_json/content_post.resp
@@ -5,6 +5,9 @@ Location: http://localhost:55001/plone/folder/my-document
 {
   "@id": "http://localhost:55001/plone/folder/my-document", 
   "@type": "Document", 
+  "@workflow": {
+    "@id": "http://localhost:55001/plone/folder/my-document/@workflow"
+  }, 
   "UID": "SomeUUID000000000000000000000005", 
   "allow_discussion": null, 
   "changeNote": "", 
diff --git a/docs/source/_json/document.resp b/docs/source/_json/document.resp
index 39c00b5b..31dfecfa 100644
--- a/docs/source/_json/document.resp
+++ b/docs/source/_json/document.resp
@@ -4,6 +4,9 @@ Content-Type: application/json
 {
   "@id": "http://localhost:55001/plone/front-page", 
   "@type": "Document", 
+  "@workflow": {
+    "@id": "http://localhost:55001/plone/front-page/@workflow"
+  }, 
   "UID": "SomeUUID000000000000000000000001", 
   "allow_discussion": null, 
   "changeNote": "", 
diff --git a/docs/source/_json/event.resp b/docs/source/_json/event.resp
index 375ca779..f2ac6eea 100644
--- a/docs/source/_json/event.resp
+++ b/docs/source/_json/event.resp
@@ -4,6 +4,9 @@ Content-Type: application/json
 {
   "@id": "http://localhost:55001/plone/event", 
   "@type": "Event", 
+  "@workflow": {
+    "@id": "http://localhost:55001/plone/event/@workflow"
+  }, 
   "UID": "SomeUUID000000000000000000000002", 
   "allow_discussion": null, 
   "attendees": [], 
diff --git a/docs/source/_json/file.resp b/docs/source/_json/file.resp
index cac96f4f..b19631d4 100644
--- a/docs/source/_json/file.resp
+++ b/docs/source/_json/file.resp
@@ -4,6 +4,9 @@ Content-Type: application/json
 {
   "@id": "http://localhost:55001/plone/file", 
   "@type": "File", 
+  "@workflow": {
+    "@id": "http://localhost:55001/plone/file/@workflow"
+  }, 
   "UID": "SomeUUID000000000000000000000002", 
   "allow_discussion": null, 
   "contributors": [], 
diff --git a/docs/source/_json/folder.resp b/docs/source/_json/folder.resp
index efb105d3..7b10cfab 100644
--- a/docs/source/_json/folder.resp
+++ b/docs/source/_json/folder.resp
@@ -4,6 +4,9 @@ Content-Type: application/json
 {
   "@id": "http://localhost:55001/plone/folder", 
   "@type": "Folder", 
+  "@workflow": {
+    "@id": "http://localhost:55001/plone/folder/@workflow"
+  }, 
   "UID": "SomeUUID000000000000000000000002", 
   "allow_discussion": null, 
   "contributors": [], 
diff --git a/docs/source/_json/image.resp b/docs/source/_json/image.resp
index d31dddc0..42b0afc0 100644
--- a/docs/source/_json/image.resp
+++ b/docs/source/_json/image.resp
@@ -4,6 +4,9 @@ Content-Type: application/json
 {
   "@id": "http://localhost:55001/plone/image", 
   "@type": "Image", 
+  "@workflow": {
+    "@id": "http://localhost:55001/plone/image/@workflow"
+  }, 
   "UID": "SomeUUID000000000000000000000002", 
   "allow_discussion": null, 
   "contributors": [], 
diff --git a/docs/source/_json/link.resp b/docs/source/_json/link.resp
index 62a13159..b7f72838 100644
--- a/docs/source/_json/link.resp
+++ b/docs/source/_json/link.resp
@@ -4,6 +4,9 @@ Content-Type: application/json
 {
   "@id": "http://localhost:55001/plone/link", 
   "@type": "Link", 
+  "@workflow": {
+    "@id": "http://localhost:55001/plone/link/@workflow"
+  }, 
   "UID": "SomeUUID000000000000000000000002", 
   "allow_discussion": null, 
   "changeNote": "", 
diff --git a/docs/source/_json/newsitem.resp b/docs/source/_json/newsitem.resp
index 8d5267f5..cde39d44 100644
--- a/docs/source/_json/newsitem.resp
+++ b/docs/source/_json/newsitem.resp
@@ -4,6 +4,9 @@ Content-Type: application/json
 {
   "@id": "http://localhost:55001/plone/newsitem", 
   "@type": "News Item", 
+  "@workflow": {
+    "@id": "http://localhost:55001/plone/newsitem/@workflow"
+  }, 
   "UID": "SomeUUID000000000000000000000002", 
   "allow_discussion": null, 
   "changeNote": "", 
diff --git a/src/plone/restapi/services/workflow/configure.zcml b/src/plone/restapi/services/workflow/configure.zcml
index 1996ff01..e26831d0 100644
--- a/src/plone/restapi/services/workflow/configure.zcml
+++ b/src/plone/restapi/services/workflow/configure.zcml
@@ -7,7 +7,7 @@
     method="GET"
     name="@workflow"
     for="Products.CMFCore.interfaces.IContentish"
-    factory=".info.WorkflowInfo"
+    factory=".info.WorkflowInfoService"
     permission="zope2.View"
     />
 
@@ -19,4 +19,6 @@
     permission="zope2.View"
     />
 
+  <adapter factory=".info.WorkflowInfo" name="workflow"/>
+
 </configure>
diff --git a/src/plone/restapi/services/workflow/info.py b/src/plone/restapi/services/workflow/info.py
index 729de85d..f2c38f72 100644
--- a/src/plone/restapi/services/workflow/info.py
+++ b/src/plone/restapi/services/workflow/info.py
@@ -1,13 +1,28 @@
 # -*- coding: utf-8 -*-
 from Products.CMFCore.utils import getToolByName
+from Products.CMFCore.interfaces._content import IWorkflowAware
+from plone.restapi.interfaces import IExpandableElement
 from plone.restapi.serializer.converters import json_compatible
 from plone.restapi.services import Service
+from zope.component import adapter
+from zope.interface import Interface
+from zope.interface import implementer
 
 
-class WorkflowInfo(Service):
-    """Get workflow information
-    """
-    def reply(self):
+@implementer(IExpandableElement)
+@adapter(IWorkflowAware, Interface)
+class WorkflowInfo(object):
+
+    def __init__(self, context, request):
+        self.context = context
+        self.request = request
+
+    def __call__(self, expand=False):
+        if not expand:
+            return {'@workflow': {
+                "@id": '{}/@workflow'.format(self.context.absolute_url()),
+            }}
+
         wftool = getToolByName(self.context, 'portal_workflow')
         history = wftool.getInfoFor(self.context, "review_history")
 
@@ -28,7 +43,15 @@ def reply(self):
                 action['review_state'],
                 self.context.portal_type)
 
-        return {
+        return {'@workflow': {
             'history': json_compatible(history),
             'transitions': transitions,
-        }
+        }}
+
+
+class WorkflowInfoService(Service):
+    """Get workflow information
+    """
+    def reply(self):
+        info = WorkflowInfo(self.context, self.request)
+        return info(expand=True)['@workflow']
diff --git a/src/plone/restapi/tests/test_workflow.py b/src/plone/restapi/tests/test_workflow.py
index e4526d35..5df39224 100644
--- a/src/plone/restapi/tests/test_workflow.py
+++ b/src/plone/restapi/tests/test_workflow.py
@@ -5,6 +5,7 @@
 from plone.app.testing import SITE_OWNER_NAME
 from plone.app.testing import SITE_OWNER_PASSWORD
 from plone.app.testing import login
+from plone.restapi.interfaces import ISerializeToJson
 from plone.restapi.testing import PLONE_RESTAPI_DX_INTEGRATION_TESTING
 from unittest import TestCase
 from zExceptions import NotFound
@@ -43,6 +44,22 @@ def test_workflow_info_includes_transitions(self):
         transitions = info['transitions']
         self.assertEqual(2, len(transitions))
 
+    def test_collapsed_workflow_info_in_content_serialization(self):
+        serializer = getMultiAdapter((self.doc1, self.request),
+                                     ISerializeToJson)
+        obj = serializer()
+        self.assertIn('@workflow', obj)
+        self.assertIn('@id', obj['@workflow'])
+
+    def test_expanded_workflow_info_in_content_serialization(self):
+        self.request.form.update({'expand': 'workflow'})
+        serializer = getMultiAdapter((self.doc1, self.request),
+                                     ISerializeToJson)
+        obj = serializer()
+        self.assertIn('@workflow', obj)
+        self.assertIn('transitions', obj['@workflow'])
+        self.assertIn('history', obj['@workflow'])
+
 
 class TestWorkflowTransition(TestCase):
 



------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.