Skip to content

Commit

Permalink
Merge branch 'master' into new
Browse files Browse the repository at this point in the history
  • Loading branch information
sneridagh committed May 20, 2016
2 parents aa0c5cf + 99d4749 commit 57faa82
Show file tree
Hide file tree
Showing 13 changed files with 54 additions and 36 deletions.
2 changes: 1 addition & 1 deletion base.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ parts =
develop = .
sources-dir = extras
auto-checkout =
# plone.rest
plone.rest
sphinxcontrib-osexample

[instance]
Expand Down
24 changes: 24 additions & 0 deletions src/plone/restapi/services/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# -*- coding: utf-8 -*-
from plone.rest import Service as RestService

import json

_no_content_marker = object()


class Service(RestService):
"""Base class for Plone REST API services
"""
content_type = 'application/json'

def render(self):
content = self.reply()
if content is not _no_content_marker:
self.request.response.setHeader("Content-Type", self.content_type)
return json.dumps(content, indent=2, sort_keys=True)

def reply(self):
"""Process the request and return a JSON serializable data structure or
the no content marker if the response body should be empty.
"""
return _no_content_marker
4 changes: 2 additions & 2 deletions src/plone/restapi/services/content/add.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@
from DateTime import DateTime
from Products.CMFPlone.utils import base_hasattr
from plone.app.content.interfaces import INameFromTitle
from plone.rest import Service
from plone.restapi.deserializer import json_body
from plone.restapi.exceptions import DeserializationError
from plone.restapi.interfaces import IDeserializeFromJson
from plone.restapi.services import Service
from random import randint
from zExceptions import BadRequest
from zope.component import queryMultiAdapter
Expand All @@ -20,7 +20,7 @@ class FolderPost(Service):
"""Creates a new content object.
"""

def render(self):
def reply(self):
data = json_body(self.request)

type_ = data.get('@type', None)
Expand Down
4 changes: 2 additions & 2 deletions src/plone/restapi/services/content/delete.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,14 @@
from Acquisition import aq_parent
from plone.app.linkintegrity.exceptions import (
LinkIntegrityNotificationException)
from plone.rest import Service
from plone.restapi.services import Service


class ContentDelete(Service):
"""Deletes a content object.
"""

def render(self):
def reply(self):

parent = aq_parent(self.context)
try:
Expand Down
4 changes: 2 additions & 2 deletions src/plone/restapi/services/content/get.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
# -*- coding: utf-8 -*-
from plone.rest import Service
from plone.restapi.interfaces import ISerializeToJson
from plone.restapi.services import Service
from zope.component import queryMultiAdapter


class ContentGet(Service):
"""Returns a serialized content object.
"""

def render(self):
def reply(self):
serializer = queryMultiAdapter((self.context, self.request),
ISerializeToJson)

Expand Down
4 changes: 2 additions & 2 deletions src/plone/restapi/services/content/update.py
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
# -*- coding: utf-8 -*-
from plone.rest import Service
from plone.restapi.exceptions import DeserializationError
from plone.restapi.interfaces import IDeserializeFromJson
from plone.restapi.services import Service
from zope.component import queryMultiAdapter


class ContentPatch(Service):
"""Updates an existing content object.
"""

def render(self):
def reply(self):
deserializer = queryMultiAdapter((self.context, self.request),
IDeserializeFromJson)
if deserializer is None:
Expand Down
4 changes: 2 additions & 2 deletions src/plone/restapi/services/registry/get.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# -*- coding: utf-8 -*-
from plone.registry.interfaces import IRegistry
from plone.rest import Service
from plone.restapi.services import Service
from zope.component import getUtility
from zope.interface import implements
from zope.publisher.interfaces import IPublishTraverse
Expand Down Expand Up @@ -28,7 +28,7 @@ def _get_record_name(self):

return self.params[0]

def render(self):
def reply(self):
registry = getUtility(IRegistry)
value = registry[self._get_record_name]
return value
4 changes: 2 additions & 2 deletions src/plone/restapi/services/registry/update.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
# -*- coding: utf-8 -*-
from plone.registry.interfaces import IRegistry
from plone.rest import Service
from plone.restapi.services import Service
from zope.component import getUtility

import json


class RegistryUpdate(Service):

def render(self):
def reply(self):
records_to_update = json.loads(self.request.get('BODY', '{}'))
registry = getUtility(IRegistry)

Expand Down
4 changes: 2 additions & 2 deletions src/plone/restapi/services/search/get.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
# -*- coding: utf-8 -*-
from plone.rest import Service
from plone.restapi.search.handler import SearchHandler
from plone.restapi.search.utils import unflatten_dotted_dict
from plone.restapi.services import Service


class SearchGet(Service):

def render(self):
def reply(self):
query = self.request.form.copy()
query = unflatten_dotted_dict(query)
return SearchHandler(self.context, self.request).search(query)
14 changes: 4 additions & 10 deletions src/plone/restapi/services/types/get.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# -*- coding: utf-8 -*-
from plone.rest import Service
from plone.restapi.services import Service
from plone.restapi.types.utils import get_jsonschema_for_portal_type

from zope.component import getUtility
Expand Down Expand Up @@ -30,12 +30,9 @@ def _get_record_name(self):

return self.params[0]

def render(self):
def reply(self):
if self.params and len(self.params) > 0:
self.request.response.setHeader(
"Content-Type",
"application/json+schema"
)
self.content_type = "application/json+schema"
try:
portal_type = self.params.pop()
return get_jsonschema_for_portal_type(
Expand All @@ -44,10 +41,7 @@ def render(self):
self.request
)
except KeyError:
self.request.response.setHeader(
"Content-Type",
"application/json"
)
self.content_type = "application/json"
self.request.response.setStatus(404)
return {
'type': 'NotFound',
Expand Down
4 changes: 2 additions & 2 deletions src/plone/restapi/services/workflow/info.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
# -*- coding: utf-8 -*-
from Products.CMFCore.utils import getToolByName
from plone.rest import Service
from plone.restapi.serializer.converters import json_compatible
from plone.restapi.services import Service


class WorkflowInfo(Service):
"""Get workflow information
"""
def render(self):
def reply(self):
wftool = getToolByName(self.context, 'portal_workflow')
history = wftool.getInfoFor(self.context, "review_history")

Expand Down
4 changes: 2 additions & 2 deletions src/plone/restapi/services/workflow/transition.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
# -*- coding: utf-8 -*-
from Products.CMFCore.WorkflowCore import WorkflowException
from Products.CMFCore.utils import getToolByName
from plone.rest import Service
from plone.restapi.deserializer import json_body
from plone.restapi.serializer.converters import json_compatible
from plone.restapi.services import Service
from zope.i18n import translate
from zope.interface import implements
from zope.publisher.interfaces import IPublishTraverse
Expand All @@ -26,7 +26,7 @@ def publishTraverse(self, request, name):
raise NotFound(self, name, request)
return self

def render(self):
def reply(self):
if self.transition is None:
self.request.response.setStatus(400)
return dict(error=dict(
Expand Down
14 changes: 7 additions & 7 deletions src/plone/restapi/tests/test_workflow.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ def setUp(self):
def test_workflow_info_includes_history(self):
wfinfo = getMultiAdapter((self.doc1, self.request),
name=u'GET_application_json_@workflow')
info = wfinfo.render()
info = wfinfo.reply()
self.assertIn('history', info)
history = info['history']
self.assertEqual(3, len(history))
Expand All @@ -37,7 +37,7 @@ def test_workflow_info_includes_history(self):
def test_workflow_info_includes_transitions(self):
wfinfo = getMultiAdapter((self.doc1, self.request),
name=u'GET_application_json_@workflow')
info = wfinfo.render()
info = wfinfo.reply()
self.assertIn('transitions', info)
transitions = info['transitions']
self.assertEqual(2, len(transitions))
Expand Down Expand Up @@ -68,15 +68,15 @@ def traverse(self, path='/plone', accept='application/json',

def test_transition_action_succeeds(self):
service = self.traverse('/plone/doc1/@workflow/publish')
res = service.render()
res = service.reply()
self.assertEqual(u'published', res[u'review_state'])
self.assertEqual(
u'published',
self.wftool.getInfoFor(self.portal.doc1, u'review_state'))

def test_calling_endpoint_without_transition_gives_400(self):
service = self.traverse('/plone/doc1/@workflow')
res = service.render()
res = service.reply()
self.assertEqual(400, self.request.response.getStatus())
self.assertEqual('Missing transition', res['error']['message'])

Expand All @@ -88,18 +88,18 @@ def test_calling_workflow_with_additional_path_segments_results_in_404(
def test_transition_with_comment(self):
self.request['BODY'] = '{"comment": "A comment"}'
service = self.traverse('/plone/doc1/@workflow/publish')
res = service.render()
res = service.reply()
self.assertEqual(u'A comment', res[u'comments'])

def test_transition_with_invalid_body(self):
self.request['BODY'] = '{"comment": "A comment", "test": "123"}'
service = self.traverse('/plone/doc1/@workflow/publish')
res = service.render()
res = service.reply()
self.assertEqual(400, self.request.response.getStatus())
self.assertEqual('Invalid body', res['error']['message'])

def test_invalid_transition_results_in_400(self):
service = self.traverse('/plone/doc1/@workflow/foo')
res = service.render()
res = service.reply()
self.assertEqual(400, self.request.response.getStatus())
self.assertEqual('WorkflowException', res['error']['type'])

0 comments on commit 57faa82

Please sign in to comment.