From 4d42d572b63ae9d87a451ab3594683a1daaeabb2 Mon Sep 17 00:00:00 2001 From: Titouan Soulard <titouan.soulard@rapid.space> Date: Mon, 27 Nov 2023 13:03:58 -0100 Subject: [PATCH] erp5_action_information_api: support for OpenAPI hyperdocument --- .../api_openapi.xml | 81 ------------------- .../document.erp5.ActionInformationAPI.py | 3 +- .../ActionInformationAPI_api_openapi.py | 12 +++ .../ActionInformationAPI_api_openapi.xml | 62 ++++++++++++++ .../ActionInformationAPI_api_slap.py | 2 + .../ActionInformationAPI_api_slap.xml | 2 +- .../test.erp5.testActionInformationAPI.py | 65 ++++++++++----- .../bt/template_action_path_list | 1 - .../bt/test_dependency_list | 3 +- 9 files changed, 127 insertions(+), 104 deletions(-) delete mode 100644 bt5/erp5_action_information_api/ActionTemplateItem/portal_types/Action%20Information%20API/api_openapi.xml create mode 100644 bt5/erp5_action_information_api/SkinTemplateItem/portal_skins/erp5_action_information_api/ActionInformationAPI_api_openapi.py create mode 100644 bt5/erp5_action_information_api/SkinTemplateItem/portal_skins/erp5_action_information_api/ActionInformationAPI_api_openapi.xml diff --git a/bt5/erp5_action_information_api/ActionTemplateItem/portal_types/Action%20Information%20API/api_openapi.xml b/bt5/erp5_action_information_api/ActionTemplateItem/portal_types/Action%20Information%20API/api_openapi.xml deleted file mode 100644 index 57d53660a5..0000000000 --- a/bt5/erp5_action_information_api/ActionTemplateItem/portal_types/Action%20Information%20API/api_openapi.xml +++ /dev/null @@ -1,81 +0,0 @@ -<?xml version="1.0"?> -<ZopeData> - <record id="1" aka="AAAAAAAAAAE="> - <pickle> - <global name="ActionInformation" module="Products.CMFCore.ActionInformation"/> - </pickle> - <pickle> - <dictionary> - <item> - <key> <string>action</string> </key> - <value> - <persistent> <string encoding="base64">AAAAAAAAAAI=</string> </persistent> - </value> - </item> - <item> - <key> <string>categories</string> </key> - <value> - <tuple> - <string>action_type/object_api_type</string> - </tuple> - </value> - </item> - <item> - <key> <string>category</string> </key> - <value> <string>object_api_type</string> </value> - </item> - <item> - <key> <string>condition</string> </key> - <value> <string></string> </value> - </item> - <item> - <key> <string>description</string> </key> - <value> - <none/> - </value> - </item> - <item> - <key> <string>icon</string> </key> - <value> <string></string> </value> - </item> - <item> - <key> <string>id</string> </key> - <value> <string>api_openapi</string> </value> - </item> - <item> - <key> <string>permissions</string> </key> - <value> - <tuple> - <string>View</string> - </tuple> - </value> - </item> - <item> - <key> <string>priority</string> </key> - <value> <float>1.0</float> </value> - </item> - <item> - <key> <string>title</string> </key> - <value> <string>OpenAPI</string> </value> - </item> - <item> - <key> <string>visible</string> </key> - <value> <int>1</int> </value> - </item> - </dictionary> - </pickle> - </record> - <record id="2" aka="AAAAAAAAAAI="> - <pickle> - <global name="Expression" module="Products.CMFCore.Expression"/> - </pickle> - <pickle> - <dictionary> - <item> - <key> <string>text</string> </key> - <value> <string>string:${object_url}/ActionInformationAPI_api_openapi</string> </value> - </item> - </dictionary> - </pickle> - </record> -</ZopeData> diff --git a/bt5/erp5_action_information_api/DocumentTemplateItem/portal_components/document.erp5.ActionInformationAPI.py b/bt5/erp5_action_information_api/DocumentTemplateItem/portal_components/document.erp5.ActionInformationAPI.py index e6afc29ac3..49d6088511 100644 --- a/bt5/erp5_action_information_api/DocumentTemplateItem/portal_components/document.erp5.ActionInformationAPI.py +++ b/bt5/erp5_action_information_api/DocumentTemplateItem/portal_components/document.erp5.ActionInformationAPI.py @@ -120,8 +120,7 @@ class ActionInformationAPI(XMLObject): def handleRequest(self, request): portal = self.getPortalObject() - action_filter = self.getActionReferenceValue() - (hyperdocument, actions) = self.getTypeInfo().getDefaultViewFor(self, view=self.getApiTypeReference())(portal, action_filter, request.getURL()) + (hyperdocument, actions) = self.getTypeInfo().getDefaultViewFor(self, view=self.getApiTypeReference())(self, portal, request) response = request.RESPONSE request_content_type = request.getHeader("content-type") diff --git a/bt5/erp5_action_information_api/SkinTemplateItem/portal_skins/erp5_action_information_api/ActionInformationAPI_api_openapi.py b/bt5/erp5_action_information_api/SkinTemplateItem/portal_skins/erp5_action_information_api/ActionInformationAPI_api_openapi.py new file mode 100644 index 0000000000..e688c59a52 --- /dev/null +++ b/bt5/erp5_action_information_api/SkinTemplateItem/portal_skins/erp5_action_information_api/ActionInformationAPI_api_openapi.py @@ -0,0 +1,12 @@ +import json + +schema = caller.getTypeInfo().getSchema() +schema.setdefault("servers", []).insert( + 0, { + "url": caller.absolute_url(), + "description": caller.getDescription() + }) + +hyperdocument = json.dumps(schema) + +return (hyperdocument, {}) diff --git a/bt5/erp5_action_information_api/SkinTemplateItem/portal_skins/erp5_action_information_api/ActionInformationAPI_api_openapi.xml b/bt5/erp5_action_information_api/SkinTemplateItem/portal_skins/erp5_action_information_api/ActionInformationAPI_api_openapi.xml new file mode 100644 index 0000000000..ab1a20029b --- /dev/null +++ b/bt5/erp5_action_information_api/SkinTemplateItem/portal_skins/erp5_action_information_api/ActionInformationAPI_api_openapi.xml @@ -0,0 +1,62 @@ +<?xml version="1.0"?> +<ZopeData> + <record id="1" aka="AAAAAAAAAAE="> + <pickle> + <global name="PythonScript" module="Products.PythonScripts.PythonScript"/> + </pickle> + <pickle> + <dictionary> + <item> + <key> <string>_bind_names</string> </key> + <value> + <object> + <klass> + <global name="_reconstructor" module="copy_reg"/> + </klass> + <tuple> + <global name="NameAssignments" module="Shared.DC.Scripts.Bindings"/> + <global name="object" module="__builtin__"/> + <none/> + </tuple> + <state> + <dictionary> + <item> + <key> <string>_asgns</string> </key> + <value> + <dictionary> + <item> + <key> <string>name_container</string> </key> + <value> <string>container</string> </value> + </item> + <item> + <key> <string>name_context</string> </key> + <value> <string>context</string> </value> + </item> + <item> + <key> <string>name_m_self</string> </key> + <value> <string>script</string> </value> + </item> + <item> + <key> <string>name_subpath</string> </key> + <value> <string>traverse_subpath</string> </value> + </item> + </dictionary> + </value> + </item> + </dictionary> + </state> + </object> + </value> + </item> + <item> + <key> <string>_params</string> </key> + <value> <string>caller, portal, request</string> </value> + </item> + <item> + <key> <string>id</string> </key> + <value> <string>ActionInformationAPI_api_openapi</string> </value> + </item> + </dictionary> + </pickle> + </record> +</ZopeData> diff --git a/bt5/erp5_action_information_api/SkinTemplateItem/portal_skins/erp5_action_information_api/ActionInformationAPI_api_slap.py b/bt5/erp5_action_information_api/SkinTemplateItem/portal_skins/erp5_action_information_api/ActionInformationAPI_api_slap.py index 2240568d12..353573d9d2 100644 --- a/bt5/erp5_action_information_api/SkinTemplateItem/portal_skins/erp5_action_information_api/ActionInformationAPI_api_slap.py +++ b/bt5/erp5_action_information_api/SkinTemplateItem/portal_skins/erp5_action_information_api/ActionInformationAPI_api_slap.py @@ -1,8 +1,10 @@ import json +url = request.getURL() base_url_absolute = portal.portal_callables.absolute_url().strip() base_url_relative = portal.portal_callables.getPath().strip() +action_filter = caller.getActionReferenceValue() raw_action_list = portal.portal_catalog( portal_type="Action Information", action_type__uid=action_filter.getUid() diff --git a/bt5/erp5_action_information_api/SkinTemplateItem/portal_skins/erp5_action_information_api/ActionInformationAPI_api_slap.xml b/bt5/erp5_action_information_api/SkinTemplateItem/portal_skins/erp5_action_information_api/ActionInformationAPI_api_slap.xml index 415f328562..099d637f62 100644 --- a/bt5/erp5_action_information_api/SkinTemplateItem/portal_skins/erp5_action_information_api/ActionInformationAPI_api_slap.xml +++ b/bt5/erp5_action_information_api/SkinTemplateItem/portal_skins/erp5_action_information_api/ActionInformationAPI_api_slap.xml @@ -50,7 +50,7 @@ </item> <item> <key> <string>_params</string> </key> - <value> <string>portal, action_filter, url</string> </value> + <value> <string>caller, portal, request</string> </value> </item> <item> <key> <string>id</string> </key> diff --git a/bt5/erp5_action_information_api/TestTemplateItem/portal_components/test.erp5.testActionInformationAPI.py b/bt5/erp5_action_information_api/TestTemplateItem/portal_components/test.erp5.testActionInformationAPI.py index 3890c232d0..c06ad5ae57 100644 --- a/bt5/erp5_action_information_api/TestTemplateItem/portal_components/test.erp5.testActionInformationAPI.py +++ b/bt5/erp5_action_information_api/TestTemplateItem/portal_components/test.erp5.testActionInformationAPI.py @@ -58,22 +58,6 @@ class TestActionInformationAPI(ERP5TypeTestCase): 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" @@ -113,6 +97,39 @@ return {"status": 200}""") self.tic() self.commit() + def setupAiApi(self): + 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() + + def setupOpenApi(self): + 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_openapi", + )[0] + + self.web_service = self.portal.portal_web_services.newContent( + portal_type="Pet Store Open API", + ) + self.web_service.edit( + api_type=ai_type.getRelativeUrl(), + ) + self.tic() + self.commit() + def loggedInRequest(self, path, method, content): return self.publish( self.web_service.getPath() + path, @@ -124,7 +141,9 @@ return {"status": 200}""") user="ERP5TypeTestCase" ) - def test_hyperdocument(self): + def test_hyperdocument_script(self): + self.setupAiApi() + response = self.loggedInRequest("/api", "GET", {}) response_json = json.loads(response.getBody()) @@ -133,7 +152,9 @@ return {"status": 200}""") self.assertTrue("Person_updateEmail/getInputJSONSchema" in response_json["links"][0]["$schemaRequest"]) self.assertTrue("Person_updateEmail/getOutputJSONSchema" in response_json["links"][0]["$schemaResponse"]) - def test_update(self): + def test_update_script(self): + self.setupAiApi() + person = self.portal.person_module.newContent( id="%s_person" % self.current_id, portal_type="Person", @@ -152,3 +173,11 @@ return {"status": 200}""") self.assertEqual(response.getBody(), json.dumps({ "status": 200 }, indent=2)) self.assertEqual(response.getStatus(), 200) self.assertEqual(person.getDefaultEmailUrlString(), "alice@looking.glass") + + def test_hyperdocument_openapi(self): + self.setupOpenApi() + + response = self.loggedInRequest("/api", "GET", {}) + response_json = json.loads(response.getBody()) + + self.assertEqual(response_json["openapi"], "3.0.2") diff --git a/bt5/erp5_action_information_api/bt/template_action_path_list b/bt5/erp5_action_information_api/bt/template_action_path_list index ddaa267cb7..0ad2e26bc4 100644 --- a/bt5/erp5_action_information_api/bt/template_action_path_list +++ b/bt5/erp5_action_information_api/bt/template_action_path_list @@ -1,3 +1,2 @@ -Action Information API | api_openapi Action Information API | api_slap Action Information API | view \ No newline at end of file diff --git a/bt5/erp5_action_information_api/bt/test_dependency_list b/bt5/erp5_action_information_api/bt/test_dependency_list index bff77e32d8..309a46ea44 100644 --- a/bt5/erp5_action_information_api/bt/test_dependency_list +++ b/bt5/erp5_action_information_api/bt/test_dependency_list @@ -1 +1,2 @@ -erp5_full_text_mroonga_catalog \ No newline at end of file +erp5_full_text_mroonga_catalog +erp5_open_api_ui_test \ No newline at end of file -- 2.30.9