Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Get with payload #125

Draft
wants to merge 11 commits into
base: main
Choose a base branch
from
Draft
1 change: 1 addition & 0 deletions plone-5.2.x.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,4 @@
extends =
https://dist.plone.org/release/5.2.14/versions.cfg
base.cfg

4 changes: 4 additions & 0 deletions src/plone/rest/demo.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,10 @@ def render(self):

class Get(BaseService):
def data(self):
if self.request.form and self.request.form.get("query"):
# the query parameter is a json-encoded query string and needs to be parsed as json
self.request.form["query"] = json.loads(self.request.form.get("query"))
return {"method": "GET", "id": self.context.id, "body": self.request.form}
return {"method": "GET", "id": self.context.id}


Expand Down
137 changes: 137 additions & 0 deletions src/plone/rest/tests/test_dexterity.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,9 @@
from zope.component import getUtility
from zope.intid.interfaces import IIntIds

import json
import os
import urllib
import requests
import transaction
import unittest
Expand Down Expand Up @@ -40,6 +42,141 @@ def test_dexterity_document_get(self):
self.assertEqual("doc1", response.json().get("id"))
self.assertEqual("GET", response.json().get("method"))

def test_dexterity_document_get_with_urlencoded_params(self):
params = {
"query": [
{
"i": "Title",
"o": "plone.app.querystring.operation.string.is",
"v": "Welcome to Plone",
},
{
"i": "path",
"o": "plone.app.querystring.operation.string.path",
"v": "/news",
},
],
"sort_on": "sortable_title",
"sort_order": "reverse",
"limit": "10",
"fullobjects": "False",
"b_start": "0",
"b_size": "2",
}
params = urllib.parse.urlencode(params, doseq=True)
response = requests.get(
self.document.absolute_url(),
headers={"Accept": "application/json"},
params=params,
auth=(SITE_OWNER_NAME, SITE_OWNER_PASSWORD),
)
self.assertEqual(200, response.status_code)
self.assertEqual(u"doc1", response.json().get("id"))
self.assertEqual(u"GET", response.json().get("method"))
self.assertEqual(
{
"body": {
"b_size": "2",
"b_start": "0",
"fullobjects": "False",
"limit": "10",
"query": [
{
"i": "Title",
"o": "plone.app.querystring.operation.string.is",
"v": "Welcome to Plone",
},
{
"i": "path",
"o": "plone.app.querystring.operation.string.path",
"v": "/news",
},
],
"sort_on": "sortable_title",
"sort_order": "reverse",
},
"id": "doc1",
"method": "GET",
},
response.json(),
)

def test_dexterity_document_get_with_payload(self):
# Encoding querystrings with arrays AND nested structures is a non-trivial use case, see for instance:
#
# https://github.com/sindresorhus/query-string/blob/main/readme.md#nesting
#
# There is no standardized way to deal with this, and most options in the wild have certain limitations and edge cases.
#
# Therefore we call json.dumps() on the query parameter only.
#
# This means that in the endpoint code, you have to convert the 'query' parameter querystring from a string to a dict:
#
# self.request.form['query'] = json.loads(self.request.form.get("query"))
#
# After this conversion you will have a Python dict with the query parameters.

payload = {
"query": json.dumps(
[
{
"i": "Title",
"o": "plone.app.querystring.operation.string.is",
"v": "Welcome to Plone",
},
{
"i": "path",
"o": "plone.app.querystring.operation.string.path",
"v": "/news",
},
]
),
"sort_on": "sortable_title",
"sort_order": "reverse",
"limit": "10",
"fullobjects": "False",
"b_start": "0",
"b_size": "2",
}

response = requests.get(
self.document.absolute_url(),
headers={"Accept": "application/json"},
params=payload,
auth=(SITE_OWNER_NAME, SITE_OWNER_PASSWORD),
)
self.assertEqual(200, response.status_code)
self.assertEqual(u"doc1", response.json().get("id"))
self.assertEqual(u"GET", response.json().get("method"))

self.assertEqual(
{
"body": {
"b_size": "2",
"b_start": "0",
"fullobjects": "False",
"limit": "10",
"query": [
{
"i": "Title",
"o": "plone.app.querystring.operation.string.is",
"v": "Welcome to Plone",
},
{
"i": "path",
"o": "plone.app.querystring.operation.string.path",
"v": "/news",
},
],
"sort_on": "sortable_title",
"sort_order": "reverse",
},
"id": "doc1",
"method": "GET",
},
response.json(),
)

def test_dexterity_document_post(self):
response = requests.post(
self.document.absolute_url(),
Expand Down
Loading