Commit 5f32f93d authored by Titouan Soulard's avatar Titouan Soulard

erp5_action_information_api: add tests for hyperdocument and action

parent 0ae5b5ec
......@@ -127,7 +127,7 @@ class ActionInformationAPI(XMLObject):
request_content_type = request.getHeader("content-type")
if request_content_type and request_content_type != "application/json":
raise NotImplementedError("Cannot server Content-Type {}".format(request_content_type))
raise NotImplementedError("Cannot serve Content-Type {}".format(request_content_type))
response.setHeader("Content-Type", "application/json")
......@@ -146,7 +146,7 @@ class ActionInformationAPI(XMLObject):
found_action = ""
for schema_url in actions:
if schema_url == request_schema:
if schema_url in request_schema:
found_action = actions[schema_url]
break
......
......@@ -53,6 +53,24 @@
</tuple>
</value>
</item>
<item>
<key> <string>_count</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAI=</string> </persistent>
</value>
</item>
<item>
<key> <string>_mt_index</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAM=</string> </persistent>
</value>
</item>
<item>
<key> <string>_tree</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAQ=</string> </persistent>
</value>
</item>
<item>
<key> <string>description</string> </key>
<value>
......@@ -70,4 +88,26 @@
</dictionary>
</pickle>
</record>
<record id="2" aka="AAAAAAAAAAI=">
<pickle>
<global name="Length" module="BTrees.Length"/>
</pickle>
<pickle> <int>0</int> </pickle>
</record>
<record id="3" aka="AAAAAAAAAAM=">
<pickle>
<global name="OOBTree" module="BTrees.OOBTree"/>
</pickle>
<pickle>
<none/>
</pickle>
</record>
<record id="4" aka="AAAAAAAAAAQ=">
<pickle>
<global name="OOBTree" module="BTrees.OOBTree"/>
</pickle>
<pickle>
<none/>
</pickle>
</record>
</ZopeData>
import json
base_url = portal.portal_callables.absolute_url().strip()
from AccessControl import getSecurityManager
u = getSecurityManager().getUser()
context.log(u.getUserName())
base_url_absolute = portal.portal_callables.absolute_url().strip()
base_url_relative = portal.portal_callables.getPath().strip()
raw_action_list = portal.portal_catalog(
portal_type="Action Information",
......@@ -12,17 +18,16 @@ action_dict = {}
for item in raw_action_list:
# XXX: for now, expects reference to be the same as action URL
callable_url = base_url + "/" + str(item.getProperty("reference"))
request_schema = callable_url + "/getInputJSONSchema"
action_url = "/" + str(item.getProperty("reference"))
links.append({
"$schemaRequest": request_schema,
"$schemaResponse": callable_url + "/getOutputJSONSchema",
"$schemaRequest": base_url_absolute + action_url + "/getInputJSONSchema",
"$schemaResponse": base_url_absolute + action_url + "/getOutputJSONSchema",
"method": "POST",
"url": url
})
action_dict[request_schema] = item
action_dict[base_url_relative + action_url + "/getInputJSONSchema"] = item
hyperdocument = json.dumps({ "links": links }, indent=2).encode()
......
......@@ -52,6 +52,14 @@
<key> <string>_params</string> </key>
<value> <string>portal, action_filter, url</string> </value>
</item>
<item>
<key> <string>_proxy_roles</string> </key>
<value>
<tuple>
<string>Manager</string>
</tuple>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>ActionInformationAPI_api_slap</string> </value>
......
##############################################################################
#
# Copyright (c) 2002-2023 Nexedi SA and Contributors. All Rights Reserved.
#
# WARNING: This program as such is intended to be used by professional
# programmers who take the whole responsibility of assessing all potential
# consequences resulting from its eventual inadequacies and bugs
# End users who are looking for a ready-to-use solution with commercial
# guarantees and support are strongly adviced to contract a Free Software
# Service Company
#
# This program is Free Software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#
##############################################################################
import httplib
import io
import json
import ssl
import urlparse
from Products.ERP5Type.tests.ERP5TypeTestCase import ERP5TypeTestCase
from Products.ERP5Type.tests.utils import createZODBPythonScript
class TestActionInformationAPI(ERP5TypeTestCase):
"""
A Sample Test Class
"""
def afterSetUp(self):
"""
This is ran before anything, used to set the environment
"""
self.portal = self.getPortalObject()
self.current_id = self.portal.portal_ids.generateNewId(
id_group=repr(("reference", "test_action_information_api")),
default=1
)
object_api_category = self.portal.portal_categories.action_type["object_api"]
object_api_name = "test_cedric_api"
if not object_api_name in object_api_category:
object_api_category.newContent(
portal_type="Category",
title=object_api_name,
id=object_api_name,
)
self.object_api_value = object_api_category[object_api_name]
self.tic()
self.commit()
ai_type = self.portal.portal_catalog(
portal_type="Action Information",
action_type__uid=self.portal.portal_categories.action_type.object_api_type.getUid(),
reference="api_slap",
)[0]
self.web_service = self.portal.portal_web_services.newContent(
portal_type="Action Information API",
)
self.web_service.edit(
api_type=ai_type.getRelativeUrl(),
action_reference=self.object_api_value.getRelativeUrl(),
)
self.tic()
self.commit()
portal_type_name = "Person"
portal_type = self.portal.portal_types[portal_type_name]
action_id = "Person_updateEmail"
action_script = "Person_updateEmail_script"
action = portal_type.get(action_id, None)
if not action:
action = portal_type.newContent(
portal_type="Action Information",
id=action_id,
)
action.edit(
title=action_id,
reference=action_id,
action="string:${object_url}/" + action_script,
action_type=self.object_api_value.getRelativeUrl(),
float_index=7.0,
)
self.tic()
self.commit()
script = createZODBPythonScript(
self.portal.portal_skins.custom,
action_script,
"data",
"""
if data is None:
return {}
email = data["email"]
if email is None:
return {}
context.setDefaultEmailUrlString(email)
return {"status": 200}""")
script.manage_proxy(roles=["Manager"])
self.tic()
self.commit()
def test_hyperdocument(self):
base_url = self.portal.portal_callables.absolute_url()
endpoint_url = self.web_service.absolute_url() + "/api"
endpoint_scheme, endpoint_netloc, _, _, _ = urlparse.urlsplit(endpoint_url)
expected_document = """{
"links": [
{
"url": "%s",
"$schemaResponse": "%s/Person_updateEmail/getOutputJSONSchema",
"method": "POST",
"$schemaRequest": "%s/Person_updateEmail/getInputJSONSchema"
}
]
}""" % (endpoint_url, base_url, base_url)
self.login()
if endpoint_scheme == "https":
connection = httplib.HTTPSConnection(endpoint_netloc, context=ssl._create_unverified_context(), timeout=10)
else:
connection = httplib.HTTPConnection(endpoint_netloc, timeout=10)
connection.request(
method="GET",
url=endpoint_url
)
response = connection.getresponse()
response_body = response.read()
connection.close()
self.assertEqual(response_body, expected_document)
def test_update(self):
person = self.portal.person_module.newContent(
id="%s_person" % self.current_id,
portal_type="Person",
title=self.current_id,
)
person.setDefaultEmailUrlString("alice@wonder.land")
self.tic()
self.commit()
self.login()
response = self.publish(
self.web_service.getPath() + "/api",
request_method="POST",
stdin=io.BytesIO(
json.dumps({
"$schemaDocument": self.portal.portal_callables.absolute_url() + "/Person_updateEmail/getInputJSONSchema",
"reference": "%s_person" % self.current_id,
"email": "alice@looking.glass"
}).encode()
),
env={"CONTENT_TYPE": "application/json"},
user="ERP5TypeTestCase"
)
self.assertEqual(response.getBody(), json.dumps({ "status": 200 }, indent=2))
self.assertEqual(response.getStatus(), 200)
self.assertEqual(person.getDefaultEmailUrlString(), "alice@looking.glass")
......@@ -2,112 +2,101 @@
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="Category" module="erp5.portal_type"/>
<global name="Test Component" module="erp5.portal_type"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>_Add_portal_content_Permission</string> </key>
<value>
<tuple>
<string>Assignor</string>
<string>Manager</string>
</tuple>
</value>
</item>
<item>
<key> <string>_Add_portal_folders_Permission</string> </key>
<value>
<tuple>
<string>Assignor</string>
<string>Manager</string>
</tuple>
</value>
<key> <string>default_reference</string> </key>
<value> <string>testActionInformationAPI</string> </value>
</item>
<item>
<key> <string>_Copy_or_Move_Permission</string> </key>
<key> <string>description</string> </key>
<value>
<tuple>
<string>Assignor</string>
<string>Manager</string>
</tuple>
<none/>
</value>
</item>
<item>
<key> <string>_Delete_objects_Permission</string> </key>
<value>
<tuple>
<string>Assignor</string>
<string>Manager</string>
</tuple>
</value>
<key> <string>id</string> </key>
<value> <string>test.erp5.testActionInformationAPI</string> </value>
</item>
<item>
<key> <string>_Modify_portal_content_Permission</string> </key>
<key> <string>sid</string> </key>
<value>
<tuple>
<string>Assignee</string>
<string>Assignor</string>
<string>Manager</string>
<string>Owner</string>
</tuple>
<none/>
</value>
</item>
<item>
<key> <string>_count</string> </key>
<key> <string>text_content_error_message</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAI=</string> </persistent>
<tuple/>
</value>
</item>
<item>
<key> <string>_mt_index</string> </key>
<key> <string>text_content_warning_message</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAM=</string> </persistent>
<tuple/>
</value>
</item>
<item>
<key> <string>_tree</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAQ=</string> </persistent>
</value>
<key> <string>version</string> </key>
<value> <string>erp5</string> </value>
</item>
<item>
<key> <string>description</string> </key>
<key> <string>workflow_history</string> </key>
<value>
<none/>
<persistent> <string encoding="base64">AAAAAAAAAAI=</string> </persistent>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>object_api_type</string> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string>object_api_type</string> </value>
</item>
</dictionary>
</pickle>
</record>
<record id="2" aka="AAAAAAAAAAI=">
<pickle>
<global name="Length" module="BTrees.Length"/>
</pickle>
<pickle> <int>0</int> </pickle>
</record>
<record id="3" aka="AAAAAAAAAAM=">
<pickle>
<global name="OOBTree" module="BTrees.OOBTree"/>
<global name="PersistentMapping" module="Persistence.mapping"/>
</pickle>
<pickle>
<none/>
<dictionary>
<item>
<key> <string>data</string> </key>
<value>
<dictionary>
<item>
<key> <string>component_validation_workflow</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAM=</string> </persistent>
</value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</pickle>
</record>
<record id="4" aka="AAAAAAAAAAQ=">
<record id="3" aka="AAAAAAAAAAM=">
<pickle>
<global name="OOBTree" module="BTrees.OOBTree"/>
<global name="WorkflowHistoryList" module="Products.ERP5Type.Workflow"/>
</pickle>
<pickle>
<none/>
<dictionary>
<item>
<key> <string>_log</string> </key>
<value>
<list>
<dictionary>
<item>
<key> <string>action</string> </key>
<value> <string>validate</string> </value>
</item>
<item>
<key> <string>validation_state</string> </key>
<value> <string>validated</string> </value>
</item>
</dictionary>
</list>
</value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
portal_categories/action_reference
portal_categories/action_type/object_api
portal_categories/action_type/object_api_type
portal_categories/api_type
\ No newline at end of file
test.erp5.testActionInformationAPI
\ No newline at end of file
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment