Commit 109e616f authored by Romain Courteaud's avatar Romain Courteaud

[erp5_hal_json_style] Add unit tests

Ensure that the data format returned is stable.
By default, imit the number of documents returned by the search.
Do not return document properties outside the form rendering.
Minor bug fixes.
parent 47e57367
...@@ -76,7 +76,7 @@ return context.ERP5Document_getHateoas(\n ...@@ -76,7 +76,7 @@ return context.ERP5Document_getHateoas(\n
</item> </item>
<item> <item>
<key> <string>_params</string> </key> <key> <string>_params</string> </key>
<value> <string>REQUEST=None, response=None, view=None, mode=\'root\', query=None, select_list=None, limit=None, form=None, relative_url=None, list_method=None</string> </value> <value> <string>REQUEST=None, response=None, view=None, mode=\'root\', query=None, select_list=None, limit=10, form=None, relative_url=None, list_method=None</string> </value>
</item> </item>
<item> <item>
<key> <string>id</string> </key> <key> <string>id</string> </key>
......
...@@ -377,7 +377,11 @@ def renderForm(form, response_dict):\n ...@@ -377,7 +377,11 @@ def renderForm(form, response_dict):\n
for field in form.get_fields_in_group(group[\'goid\']):\n for field in form.get_fields_in_group(group[\'goid\']):\n
# field_list.append((field.id, renderRawField(field)))\n # field_list.append((field.id, renderRawField(field)))\n
if field.get_value("enabled"):\n if field.get_value("enabled"):\n
response_dict[field.id] = renderField(field)\n try:\n
response_dict[field.id] = renderField(field)\n
except AttributeError:\n
# Do not crash if field configuration is wrong.\n
pass\n
\n \n
# for field_group in field.form.get_groups():\n # for field_group in field.form.get_groups():\n
# traversed_document.log("Field group: " + field_group)\n # traversed_document.log("Field group: " + field_group)\n
...@@ -658,6 +662,7 @@ elif (mode == \'root\') or (mode == \'traverse\'):\n ...@@ -658,6 +662,7 @@ elif (mode == \'root\') or (mode == \'traverse\'):\n
\n \n
# Include properties in document JSON\n # Include properties in document JSON\n
# XXX Extract from renderer form?\n # XXX Extract from renderer form?\n
"""\n
for group in renderer_form.Form_getGroupTitleAndId():\n for group in renderer_form.Form_getGroupTitleAndId():\n
for field in renderer_form.get_fields_in_group(group[\'goid\']):\n for field in renderer_form.get_fields_in_group(group[\'goid\']):\n
field_id = field.id\n field_id = field.id\n
...@@ -671,6 +676,7 @@ elif (mode == \'root\') or (mode == \'traverse\'):\n ...@@ -671,6 +676,7 @@ elif (mode == \'root\') or (mode == \'traverse\'):\n
# Serialize DateTime\n # Serialize DateTime\n
property_value = property_value.rfc822()\n property_value = property_value.rfc822()\n
result_dict[property_name] = property_value \n result_dict[property_name] = property_value \n
"""\n
\n \n
##############\n ##############\n
# XXX Custom slapos code\n # XXX Custom slapos code\n
...@@ -797,7 +803,9 @@ elif mode == \'search\':\n ...@@ -797,7 +803,9 @@ elif mode == \'search\':\n
# else:\n # else:\n
\n \n
# Cast to list if only one element is provided\n # Cast to list if only one element is provided\n
if same_type(select_list, ""):\n if select_list is None:\n
select_list = []\n
elif same_type(select_list, ""):\n
select_list = [select_list]\n select_list = [select_list]\n
\n \n
for sql_document in sql_list:\n for sql_document in sql_list:\n
...@@ -844,7 +852,7 @@ return json.dumps(result_dict, indent=2)\n ...@@ -844,7 +852,7 @@ return json.dumps(result_dict, indent=2)\n
</item> </item>
<item> <item>
<key> <string>_params</string> </key> <key> <string>_params</string> </key>
<value> <string>REQUEST=None, response=None, view=None, mode=\'root\', query=None, select_list=None, limit=None, form=None, relative_url=None, restricted=0, list_method=None</string> </value> <value> <string>REQUEST=None, response=None, view=None, mode=\'root\', query=None, select_list=None, limit=10, form=None, relative_url=None, restricted=0, list_method=None</string> </value>
</item> </item>
<item> <item>
<key> <string>id</string> </key> <key> <string>id</string> </key>
......
# -*- coding: utf-8 -*-
# Copyright (c) 2002-2015 Nexedi SA and Contributors. All Rights Reserved.
import transaction
from zExceptions import Unauthorized
from Products.ERP5Type.tests.utils import createZODBPythonScript
from unittest import skip
from functools import wraps
from ZPublisher.HTTPRequest import HTTPRequest
from ZPublisher.HTTPResponse import HTTPResponse
import StringIO
import json
import urllib
def changeSkin(skin_name):
def decorator(func):
def wrapped(self, *args, **kwargs):
default_skin = self.portal.portal_skins.default_skin
self.portal.portal_skins.changeSkin(skin_name)
self.app.REQUEST.set('portal_skin', skin_name)
try:
v = func(self, *args, **kwargs)
finally:
self.portal.portal_skins.changeSkin(default_skin)
self.app.REQUEST.set('portal_skin', default_skin)
return v
return wrapped
return decorator
def simulate(script_id, params_string, code_string):
def upperWrap(f):
@wraps(f)
def decorated(self, *args, **kw):
if script_id in self.portal.portal_skins.custom.objectIds():
raise ValueError('Precondition failed: %s exists in custom' % script_id)
createZODBPythonScript(self.portal.portal_skins.custom,
script_id, params_string, code_string)
transaction.commit()
try:
result = f(self, *args, **kw)
finally:
if script_id in self.portal.portal_skins.custom.objectIds():
self.portal.portal_skins.custom.manage_delObjects(script_id)
transaction.commit()
return result
return decorated
return upperWrap
def do_fake_request(request_method, headers=None):
__version__ = "0.1"
if (headers is None):
headers = {}
env={}
env['SERVER_NAME']='bobo.server'
env['SERVER_PORT']='80'
env['REQUEST_METHOD']=request_method
env['REMOTE_ADDR']='204.183.226.81 '
env['REMOTE_HOST']='bobo.remote.host'
env['HTTP_USER_AGENT']='Bobo/%s' % __version__
env['HTTP_HOST']='127.0.0.1'
env['SERVER_SOFTWARE']='Bobo/%s' % __version__
env['SERVER_PROTOCOL']='HTTP/1.0 '
env['HTTP_ACCEPT']='image/gif, image/x-xbitmap, image/jpeg, */* '
env['SERVER_HOSTNAME']='bobo.server.host'
env['GATEWAY_INTERFACE']='CGI/1.1 '
env['SCRIPT_NAME']='Main'
env.update(headers)
return HTTPRequest(StringIO.StringIO(), env, HTTPResponse())
from Products.ERP5Type.tests.ERP5TypeTestCase import ERP5TypeTestCase
#####################################################
# Base_getRequestHeader
#####################################################
class ERP5HALJSONStyleSkinsMixin(ERP5TypeTestCase):
def afterSetUp(self):
self.login()
def beforeTearDown(self):
transaction.abort()
def generateNewId(self):
return "%sö" % self.portal.portal_ids.generateNewId(
id_group=('erp5_hal_json_style_test'))
def _makeDocument(self):
new_id = self.generateNewId()
foo = self.portal.foo_module.newContent(portal_type="Foo")
foo.edit(
title="live_test_%s" % new_id,
reference="live_test_%s" % new_id
)
return foo
class TestBase_getRequestHeader(ERP5HALJSONStyleSkinsMixin):
@changeSkin('Hal')
def test_getRequestHeader_REQUEST_disallowed(self):
self.assertRaises(
Unauthorized,
self.portal.Base_getRequestHeader,
"foo",
REQUEST={})
@changeSkin('Hal')
def test_getRequestHeader_key_error(self):
self.assertEquals(
self.portal.Base_getRequestHeader('foo'),
None
)
@changeSkin('Hal')
def test_getRequestHeader_default_value(self):
self.assertEquals(
self.portal.Base_getRequestHeader('foo', default='bar'),
'bar'
)
@skip('TODO')
def test_getRequestHeader_matching_key(self):
pass
#####################################################
# Base_getRequestUrl
#####################################################
class TestBase_getRequestUrl(ERP5HALJSONStyleSkinsMixin):
@changeSkin('Hal')
def test_getRequestUrl_REQUEST_disallowed(self):
self.assertRaises(
Unauthorized,
self.portal.Base_getRequestUrl,
REQUEST={})
@skip('TODO')
def test_getRequestUrl_matching_key(self):
pass
#####################################################
# Base_getRequestBody
#####################################################
class TestBase_getRequestBody(ERP5HALJSONStyleSkinsMixin):
@changeSkin('Hal')
def test_getRequestBody_REQUEST_disallowed(self):
self.assertRaises(
Unauthorized,
self.portal.Base_getRequestBody,
REQUEST={})
@skip('TODO')
def test_getRequestBody_matching_key(self):
pass
#####################################################
# Base_handleAcceptHeader
#####################################################
class TestBase_handleAcceptHeader(ERP5HALJSONStyleSkinsMixin):
@changeSkin('Hal')
def test_handleAcceptHeader_REQUEST_disallowed(self):
self.assertRaises(
Unauthorized,
self.portal.Base_handleAcceptHeader,
[],
REQUEST={})
@simulate('Base_getRequestHeader', '*args, **kwargs', 'return "*/*"')
@changeSkin('Hal')
def test_handleAcceptHeader_star_accept(self):
self.assertEquals(
self.portal.Base_handleAcceptHeader(['application/vnd+test',
'application/vnd+test2']),
'application/vnd+test'
)
@simulate('Base_getRequestHeader', '*args, **kwargs',
'return "application/vnd+2test"')
@changeSkin('Hal')
def test_handleAcceptHeader_matching_type(self):
self.assertEquals(
self.portal.Base_handleAcceptHeader(['application/vnd+test',
'application/vnd+2test']),
'application/vnd+2test'
)
@simulate('Base_getRequestHeader', '*args, **kwargs',
'return "application/vnd+2test"')
@changeSkin('Hal')
def test_handleAcceptHeader_non_matching_type(self):
self.assertEquals(
self.portal.Base_handleAcceptHeader(['application/vnd+test']),
None
)
class TestERP5Document_getHateoas_general(ERP5HALJSONStyleSkinsMixin):
@simulate('Base_getRequestHeader', '*args, **kwargs',
'return "application/vnd+bar"')
@changeSkin('Hal')
def test_getHateoas_wrong_ACCEPT(self):
document = self._makeDocument()
fake_request = do_fake_request("GET")
result = document.ERP5Document_getHateoas(REQUEST=fake_request)
self.assertEquals(fake_request.RESPONSE.status, 406)
self.assertEquals(result, "")
@skip('TODO')
def test_getHateoas_drop_restricted(self):
pass
@simulate('Base_getRequestHeader', '*args, **kwargs',
'return "application/hal+json"')
@changeSkin('Hal')
def test_getHateoas_unsupported_mode(self):
fake_request = do_fake_request("GET")
self.assertRaises(
NotImplementedError,
self.portal.ERP5Document_getHateoas,
REQUEST=fake_request,
mode="bar")
class TestERP5Document_getHateoas_mode_root(ERP5HALJSONStyleSkinsMixin):
@simulate('Base_getRequestHeader', '*args, **kwargs',
'return "application/hal+json"')
@changeSkin('Hal')
def test_getHateoasDocument_bad_method(self):
document = self._makeDocument()
fake_request = do_fake_request("POST")
result = document.ERP5Document_getHateoas(REQUEST=fake_request)
self.assertEquals(fake_request.RESPONSE.status, 405)
self.assertEquals(result, "")
@simulate('Base_getRequestUrl', '*args, **kwargs',
'return "http://example.org/bar"')
@simulate('Base_getRequestHeader', '*args, **kwargs',
'return "application/hal+json"')
@changeSkin('Hal')
def test_getHateoasDocument_result(self):
document = self._makeDocument()
parent = document.getParentValue()
fake_request = do_fake_request("GET")
result = document.ERP5Document_getHateoas(REQUEST=fake_request)
self.assertEquals(fake_request.RESPONSE.status, 200)
self.assertEquals(fake_request.RESPONSE.getHeader('Content-Type'),
"application/hal+json"
)
result_dict = json.loads(result)
self.assertEqual(result_dict['_links']['self'], {"href": "http://example.org/bar"})
self.assertEqual(result_dict['_links']['parent'],
{"href": "urn:jio:get:%s" % parent.getRelativeUrl(), "name": parent.getTitle()})
self.assertEqual(result_dict['_links']['view'][0]['href'],
"http://nohost/erp5/ERP5Document_getHateoas?mode=traverse&relative_url=%s&view=view" % urllib.quote_plus(document.getRelativeUrl()))
self.assertEqual(result_dict['_links']['view'][0]['title'], "View")
self.assertEqual(result_dict['_links']['view'][0]['name'], "view")
self.assertEqual(result_dict['_links']['action_object_view'][0]['href'],
"http://nohost/erp5/ERP5Document_getHateoas?mode=traverse&relative_url=%s&view=view" % urllib.quote_plus(document.getRelativeUrl()))
self.assertEqual(result_dict['_links']['action_object_view'][0]['title'], "View")
self.assertEqual(result_dict['_links']['action_object_view'][0]['name'], "view")
self.assertEqual(result_dict['_links']['action_workflow'][0]['href'],
"http://nohost/erp5/ERP5Document_getHateoas?mode=traverse&relative_url=%s&view=custom_action_no_dialog" % urllib.quote_plus(document.getRelativeUrl()))
self.assertEqual(result_dict['_links']['action_workflow'][0]['title'], "Custom Action No Dialog")
self.assertEqual(result_dict['_links']['action_workflow'][0]['name'], "custom_action_no_dialog")
self.assertEqual(result_dict['_links']['portal']['href'], 'urn:jio:get:%s' % document.getPortalObject().getId())
self.assertEqual(result_dict['_links']['portal']['name'], document.getPortalObject().getTitle())
# XXX Not so usefull results
self.assertEqual(result_dict['_links']['site_root']['href'], 'urn:jio:get:')
self.assertEqual(result_dict['_links']['site_root']['name'], document.getPortalObject().getTitle())
self.assertEqual(result_dict['_links']['action_object_new_content_action']['href'],
"http://nohost/erp5/ERP5Document_getHateoas?mode=traverse&relative_url=%s&view=create_a_document" % urllib.quote_plus(document.getRelativeUrl()))
self.assertEqual(result_dict['_links']['action_object_new_content_action']['title'], "Create a Document")
self.assertEqual(result_dict['_links']['action_object_new_content_action']['name'], "create_a_document")
self.assertEqual(result_dict['_links']['type']['href'], 'urn:jio:get:portal_types/%s' % document.getPortalType())
self.assertEqual(result_dict['_links']['type']['name'], document.getPortalType())
self.assertEqual(result_dict['title'].encode("UTF-8"), document.getTitle())
self.assertEqual(result_dict['_debug'], "root")
@simulate('Base_getRequestUrl', '*args, **kwargs',
'return "http://example.org/bar"')
@simulate('Base_getRequestHeader', '*args, **kwargs',
'return "application/hal+json"')
@changeSkin('Hal')
def test_getHateoasWebSite_result(self):
document = self.portal.web_site_module.hateoas
parent = document.getParentValue()
fake_request = do_fake_request("GET")
result = document.ERP5Document_getHateoas(REQUEST=fake_request)
self.assertEquals(fake_request.RESPONSE.status, 200)
self.assertEquals(fake_request.RESPONSE.getHeader('Content-Type'),
"application/hal+json"
)
result_dict = json.loads(result)
self.assertEqual(result_dict['_links']['self'], {"href": "http://example.org/bar"})
self.assertEqual(result_dict['_links']['parent'],
{"href": "urn:jio:get:%s" % parent.getRelativeUrl(), "name": parent.getTitle()})
self.assertEqual(result_dict['_links']['view'][0]['href'],
"http://nohost/erp5/web_site_module/hateoas/ERP5Document_getHateoas?mode=traverse&relative_url=%s&view=view" % urllib.quote_plus(document.getRelativeUrl()))
self.assertEqual(result_dict['_links']['view'][0]['title'], "View")
self.assertEqual(result_dict['_links']['view'][0]['name'], "view")
self.assertEqual(result_dict['_links']['action_object_view'][0]['href'],
"http://nohost/erp5/web_site_module/hateoas/ERP5Document_getHateoas?mode=traverse&relative_url=%s&view=view" % urllib.quote_plus(document.getRelativeUrl()))
self.assertEqual(result_dict['_links']['action_object_view'][0]['title'], "View")
self.assertEqual(result_dict['_links']['action_object_view'][0]['name'], "view")
self.assertEqual(result_dict['_links']['action_workflow'][0]['href'],
"http://nohost/erp5/web_site_module/hateoas/ERP5Document_getHateoas?mode=traverse&relative_url=%s&view=embed_action" % urllib.quote_plus(document.getRelativeUrl()))
self.assertEqual(result_dict['_links']['action_workflow'][0]['title'], "Embed")
self.assertEqual(result_dict['_links']['action_workflow'][0]['name'], "embed_action")
self.assertEqual(result_dict['_links']['portal']['href'], 'urn:jio:get:%s' % document.getPortalObject().getId())
self.assertEqual(result_dict['_links']['portal']['name'], document.getPortalObject().getTitle())
self.assertEqual(result_dict['_links']['site_root']['href'], 'urn:jio:get:web_site_module/hateoas')
self.assertEqual(result_dict['_links']['site_root']['name'], document.getTitle())
self.assertEqual(result_dict['_links']['action_object_new_content_action']['href'],
"http://nohost/erp5/web_site_module/hateoas/ERP5Document_getHateoas?mode=traverse&relative_url=%s&view=create_a_document" % urllib.quote_plus(document.getRelativeUrl()))
self.assertEqual(result_dict['_links']['action_object_new_content_action']['title'], "Create a Document")
self.assertEqual(result_dict['_links']['action_object_new_content_action']['name'], "create_a_document")
self.assertEqual(result_dict['_links']['type']['href'], 'urn:jio:get:portal_types/%s' % document.getPortalType())
self.assertEqual(result_dict['_links']['type']['name'], document.getPortalType())
self.assertEqual(result_dict['_links']['raw_search']['href'],
"http://nohost/erp5/web_site_module/hateoas/ERP5Document_getHateoas?mode=search{&query,select_list*,limit*}")
self.assertEqual(result_dict['_links']['raw_search']['templated'], True)
self.assertEqual(result_dict['_links']['raw_search']['name'], "Raw Search")
self.assertEqual(result_dict['_links']['traverse']['href'],
"http://nohost/erp5/web_site_module/hateoas/ERP5Document_getHateoas?mode=traverse{&relative_url,view}")
self.assertEqual(result_dict['_links']['traverse']['templated'], True)
self.assertEqual(result_dict['_links']['traverse']['name'], "Traverse")
self.assertEqual(result_dict['title'].encode("UTF-8"), document.getTitle())
self.assertEqual(result_dict['default_view'], "view")
self.assertEqual(result_dict['_debug'], "root")
# XXX Check 'me' links
class TestERP5Document_getHateoas_mode_traverse(ERP5HALJSONStyleSkinsMixin):
@simulate('Base_getRequestHeader', '*args, **kwargs',
'return "application/hal+json"')
@changeSkin('Hal')
def test_getHateoasDocument_bad_method(self):
document = self._makeDocument()
fake_request = do_fake_request("POST")
result = self.portal.web_site_module.hateoas.ERP5Document_getHateoas(REQUEST=fake_request, mode="traverse", relative_url=document.getRelativeUrl())
self.assertEquals(fake_request.RESPONSE.status, 405)
self.assertEquals(result, "")
@simulate('Base_getRequestUrl', '*args, **kwargs',
'return "http://example.org/bar"')
@simulate('Base_getRequestHeader', '*args, **kwargs',
'return "application/hal+json"')
@changeSkin('Hal')
def test_getHateoasDocument_no_view(self):
document = self._makeDocument()
parent = document.getParentValue()
fake_request = do_fake_request("GET")
result = self.portal.web_site_module.hateoas.ERP5Document_getHateoas(REQUEST=fake_request, mode="traverse", relative_url=document.getRelativeUrl())
self.assertEquals(fake_request.RESPONSE.status, 200)
self.assertEquals(fake_request.RESPONSE.getHeader('Content-Type'),
"application/hal+json"
)
result_dict = json.loads(result)
self.assertEqual(result_dict['_links']['self'], {"href": "http://example.org/bar"})
self.assertEqual(result_dict['_links']['parent'],
{"href": "urn:jio:get:%s" % parent.getRelativeUrl(), "name": parent.getTitle()})
self.assertEqual(result_dict['_links']['view'][0]['href'],
"http://nohost/erp5/web_site_module/hateoas/ERP5Document_getHateoas?mode=traverse&relative_url=%s&view=view" % urllib.quote_plus(document.getRelativeUrl()))
self.assertEqual(result_dict['_links']['view'][0]['title'], "View")
self.assertEqual(result_dict['_links']['view'][0]['name'], "view")
self.assertEqual(result_dict['_links']['action_object_view'][0]['href'],
"http://nohost/erp5/web_site_module/hateoas/ERP5Document_getHateoas?mode=traverse&relative_url=%s&view=view" % urllib.quote_plus(document.getRelativeUrl()))
self.assertEqual(result_dict['_links']['action_object_view'][0]['title'], "View")
self.assertEqual(result_dict['_links']['action_object_view'][0]['name'], "view")
self.assertEqual(result_dict['_links']['action_workflow'][0]['href'],
"http://nohost/erp5/web_site_module/hateoas/ERP5Document_getHateoas?mode=traverse&relative_url=%s&view=custom_action_no_dialog" % urllib.quote_plus(document.getRelativeUrl()))
self.assertEqual(result_dict['_links']['action_workflow'][0]['title'], "Custom Action No Dialog")
self.assertEqual(result_dict['_links']['action_workflow'][0]['name'], "custom_action_no_dialog")
self.assertEqual(result_dict['_links']['portal']['href'], 'urn:jio:get:%s' % document.getPortalObject().getId())
self.assertEqual(result_dict['_links']['portal']['name'], document.getPortalObject().getTitle())
self.assertEqual(result_dict['_links']['site_root']['href'], 'urn:jio:get:web_site_module/hateoas')
self.assertEqual(result_dict['_links']['site_root']['name'], self.portal.web_site_module.hateoas.getTitle())
self.assertEqual(result_dict['_links']['action_object_new_content_action']['href'],
"http://nohost/erp5/web_site_module/hateoas/ERP5Document_getHateoas?mode=traverse&relative_url=%s&view=create_a_document" % urllib.quote_plus(document.getRelativeUrl()))
self.assertEqual(result_dict['_links']['action_object_new_content_action']['title'], "Create a Document")
self.assertEqual(result_dict['_links']['action_object_new_content_action']['name'], "create_a_document")
self.assertEqual(result_dict['_links']['type']['href'], 'urn:jio:get:portal_types/%s' % document.getPortalType())
self.assertEqual(result_dict['_links']['type']['name'], document.getPortalType())
self.assertEqual(result_dict['title'].encode("UTF-8"), document.getTitle())
self.assertEqual(result_dict['_debug'], "traverse")
@simulate('Base_getRequestUrl', '*args, **kwargs',
'return "http://example.org/bar"')
@simulate('Base_getRequestHeader', '*args, **kwargs',
'return "application/hal+json"')
@changeSkin('Hal')
def test_getHateoasDocument_default_view(self):
document = self._makeDocument()
parent = document.getParentValue()
fake_request = do_fake_request("GET")
result = self.portal.web_site_module.hateoas.ERP5Document_getHateoas(REQUEST=fake_request, mode="traverse", relative_url=document.getRelativeUrl(), view="view")
self.assertEquals(fake_request.RESPONSE.status, 200)
self.assertEquals(fake_request.RESPONSE.getHeader('Content-Type'),
"application/hal+json"
)
result_dict = json.loads(result)
self.assertEqual(result_dict['_links']['self'], {"href": "http://example.org/bar"})
self.assertEqual(result_dict['_links']['parent'],
{"href": "urn:jio:get:%s" % parent.getRelativeUrl(), "name": parent.getTitle()})
self.assertEqual(result_dict['_links']['view'][0]['href'],
"http://nohost/erp5/web_site_module/hateoas/ERP5Document_getHateoas?mode=traverse&relative_url=%s&view=view" % urllib.quote_plus(document.getRelativeUrl()))
self.assertEqual(result_dict['_links']['view'][0]['title'], "View")
self.assertEqual(result_dict['_links']['view'][0]['name'], "view")
self.assertEqual(result_dict['_links']['action_object_view'][0]['href'],
"http://nohost/erp5/web_site_module/hateoas/ERP5Document_getHateoas?mode=traverse&relative_url=%s&view=view" % urllib.quote_plus(document.getRelativeUrl()))
self.assertEqual(result_dict['_links']['action_object_view'][0]['title'], "View")
self.assertEqual(result_dict['_links']['action_object_view'][0]['name'], "view")
self.assertEqual(result_dict['_links']['action_workflow'][0]['href'],
"http://nohost/erp5/web_site_module/hateoas/ERP5Document_getHateoas?mode=traverse&relative_url=%s&view=custom_action_no_dialog" % urllib.quote_plus(document.getRelativeUrl()))
self.assertEqual(result_dict['_links']['action_workflow'][0]['title'], "Custom Action No Dialog")
self.assertEqual(result_dict['_links']['action_workflow'][0]['name'], "custom_action_no_dialog")
self.assertEqual(result_dict['_links']['portal']['href'], 'urn:jio:get:%s' % document.getPortalObject().getId())
self.assertEqual(result_dict['_links']['portal']['name'], document.getPortalObject().getTitle())
self.assertEqual(result_dict['_links']['site_root']['href'], 'urn:jio:get:web_site_module/hateoas')
self.assertEqual(result_dict['_links']['site_root']['name'], self.portal.web_site_module.hateoas.getTitle())
self.assertEqual(result_dict['_links']['action_object_new_content_action']['href'],
"http://nohost/erp5/web_site_module/hateoas/ERP5Document_getHateoas?mode=traverse&relative_url=%s&view=create_a_document" % urllib.quote_plus(document.getRelativeUrl()))
self.assertEqual(result_dict['_links']['action_object_new_content_action']['title'], "Create a Document")
self.assertEqual(result_dict['_links']['action_object_new_content_action']['name'], "create_a_document")
self.assertEqual(result_dict['_links']['type']['href'], 'urn:jio:get:portal_types/%s' % document.getPortalType())
self.assertEqual(result_dict['_links']['type']['name'], document.getPortalType())
self.assertEqual(result_dict['title'].encode("UTF-8"), document.getTitle())
self.assertEqual(result_dict['_debug'], "traverse")
# Check embedded form rendering
self.assertEqual(result_dict['_embedded']['_view']['form_id']['default'], 'Foo_view')
self.assertEqual(result_dict['_embedded']['_view']['form_id']['editable'], 0)
self.assertEqual(result_dict['_embedded']['_view']['form_id']['hidden'], 1)
self.assertEqual(result_dict['_embedded']['_view']['form_id']['key'], 'form_id')
self.assertEqual(result_dict['_embedded']['_view']['form_id']['required'], 1)
self.assertEqual(result_dict['_embedded']['_view']['form_id']['type'], 'StringField')
self.assertEqual(result_dict['_embedded']['_view']['my_id']['default'], document.getId())
self.assertEqual(result_dict['_embedded']['_view']['my_id']['editable'], 1)
self.assertEqual(result_dict['_embedded']['_view']['my_id']['hidden'], 0)
self.assertEqual(result_dict['_embedded']['_view']['my_id']['key'], 'field_my_id')
self.assertEqual(result_dict['_embedded']['_view']['my_id']['required'], 1)
self.assertEqual(result_dict['_embedded']['_view']['my_id']['type'], 'StringField')
self.assertEqual(result_dict['_embedded']['_view']['my_id']['title'], 'ID')
self.assertEqual(result_dict['_embedded']['_view']['_links']['traversed_document']['href'], 'urn:jio:get:%s' % document.getRelativeUrl())
self.assertEqual(result_dict['_embedded']['_view']['_links']['traversed_document']['name'], document.getRelativeUrl())
self.assertEqual(result_dict['_embedded']['_view']['_links']['traversed_document']['title'], document.getTitle().decode("UTF-8"))
self.assertEqual(result_dict['_embedded']['_view']['_links']['self']['href'], "http://nohost/erp5/%s/Foo_view" % document.getRelativeUrl())
self.assertEqual(result_dict['_embedded']['_view']['_links']['form_definition']['href'], 'urn:jio:get:portal_skins/erp5_ui_test/Foo_view')
self.assertEqual(result_dict['_embedded']['_view']['_links']['form_definition']['name'], 'Foo_view')
self.assertEqual(result_dict['_embedded']['_view']['_actions']['put']['href'], 'http://nohost/erp5/web_site_module/hateoas/%s/Base_edit' % document.getRelativeUrl())
self.assertEqual(result_dict['_embedded']['_view']['_actions']['put']['method'], 'POST')
@simulate('Base_getRequestUrl', '*args, **kwargs',
'return "http://example.org/bar"')
@simulate('Base_getRequestHeader', '*args, **kwargs',
'return "application/hal+json"')
@changeSkin('Hal')
def test_getHateoasForm_no_view(self):
fake_request = do_fake_request("GET")
result = self.portal.web_site_module.hateoas.ERP5Document_getHateoas(REQUEST=fake_request, mode="traverse", relative_url="portal_skins/erp5_ui_test/Foo_view")
self.assertEquals(fake_request.RESPONSE.status, 200)
self.assertEquals(fake_request.RESPONSE.getHeader('Content-Type'),
"application/hal+json"
)
result_dict = json.loads(result)
self.assertEqual(result_dict['_links']['self'], {"href": "http://example.org/bar"})
self.assertEqual(result_dict['_links']['parent'],
{"href": "urn:jio:get:", "name": self.portal.getTitle()})
self.assertEqual(result_dict['_links']['view'][0]['href'],
"http://nohost/erp5/web_site_module/hateoas/ERP5Document_getHateoas?mode=traverse&relative_url=%s&view=consistency" % urllib.quote_plus("portal_skins/erp5_ui_test/Foo_view"))
self.assertEqual(result_dict['_links']['view'][0]['title'], "Consistency")
self.assertEqual(result_dict['_links']['view'][0]['name'], "consistency")
self.assertEqual(result_dict['_links']['action_object_view'][0]['href'],
"http://nohost/erp5/web_site_module/hateoas/ERP5Document_getHateoas?mode=traverse&relative_url=%s&view=consistency" % urllib.quote_plus("portal_skins/erp5_ui_test/Foo_view"))
self.assertEqual(result_dict['_links']['action_object_view'][0]['title'], "Consistency")
self.assertEqual(result_dict['_links']['action_object_view'][0]['name'], "consistency")
self.assertEqual(result_dict['_links']['portal']['href'], 'urn:jio:get:%s' % self.portal.getId())
self.assertEqual(result_dict['_links']['portal']['name'], self.portal.getTitle())
self.assertEqual(result_dict['_links']['site_root']['href'], 'urn:jio:get:web_site_module/hateoas')
self.assertEqual(result_dict['_links']['site_root']['name'], self.portal.web_site_module.hateoas.getTitle())
self.assertEqual(result_dict['_links']['type']['href'], 'urn:jio:get:portal_types/ERP5 Form')
self.assertEqual(result_dict['_links']['type']['name'], 'ERP5 Form')
self.assertEqual(result_dict['title'], 'Foo')
self.assertEqual(result_dict['pt'], 'form_view')
self.assertEqual(result_dict['action'], 'Base_edit')
self.assertEqual(result_dict['group_list'][0][0], 'left')
self.assertEqual(result_dict['group_list'][0][1][0], ['my_id', {'meta_type': 'StringField'}])
self.assertEqual(result_dict['_debug'], "traverse")
class TestERP5Document_getHateoas_mode_search(ERP5HALJSONStyleSkinsMixin):
@simulate('Base_getRequestHeader', '*args, **kwargs',
'return "application/hal+json"')
@changeSkin('Hal')
def test_getHateoasDocument_bad_method(self):
fake_request = do_fake_request("POST")
result = self.portal.web_site_module.hateoas.ERP5Document_getHateoas(REQUEST=fake_request, mode="search")
self.assertEquals(fake_request.RESPONSE.status, 405)
self.assertEquals(result, "")
@simulate('Base_getRequestUrl', '*args, **kwargs',
'return "http://example.org/bar"')
@simulate('Base_getRequestHeader', '*args, **kwargs',
'return "application/hal+json"')
@changeSkin('Hal')
def test_getHateoas_no_param(self):
fake_request = do_fake_request("GET")
result = self.portal.web_site_module.hateoas.ERP5Document_getHateoas(REQUEST=fake_request, mode="search")
self.assertEquals(fake_request.RESPONSE.status, 200)
self.assertEquals(fake_request.RESPONSE.getHeader('Content-Type'),
"application/hal+json"
)
result_dict = json.loads(result)
self.assertEqual(result_dict['_links']['self'], {"href": "http://example.org/bar"})
self.assertEqual(result_dict['_links']['portal']['href'], 'urn:jio:get:%s' % self.portal.getId())
self.assertEqual(result_dict['_links']['portal']['name'], self.portal.getTitle())
self.assertEqual(result_dict['_links']['site_root']['href'], 'urn:jio:get:web_site_module/hateoas')
self.assertEqual(result_dict['_links']['site_root']['name'], self.portal.web_site_module.hateoas.getTitle())
self.assertEqual(result_dict['_debug'], "search")
self.assertEqual(result_dict['_limit'], 10)
self.assertEqual(result_dict['_query'], None)
self.assertEqual(result_dict['_select_list'], [])
self.assertEqual(len(result_dict['_embedded']['contents']), 10)
self.assertEqual(result_dict['_embedded']['contents'][0]["_links"]["self"]["href"][:12], "urn:jio:get:")
@simulate('Base_getRequestUrl', '*args, **kwargs',
'return "http://example.org/bar"')
@simulate('Base_getRequestHeader', '*args, **kwargs',
'return "application/hal+json"')
@changeSkin('Hal')
def test_getHateoas_limit_param(self):
fake_request = do_fake_request("GET")
result = self.portal.web_site_module.hateoas.ERP5Document_getHateoas(REQUEST=fake_request, mode="search", limit=1)
self.assertEquals(fake_request.RESPONSE.status, 200)
self.assertEquals(fake_request.RESPONSE.getHeader('Content-Type'),
"application/hal+json"
)
result_dict = json.loads(result)
self.assertEqual(result_dict['_links']['self'], {"href": "http://example.org/bar"})
self.assertEqual(result_dict['_debug'], "search")
self.assertEqual(result_dict['_limit'], 1)
self.assertEqual(result_dict['_query'], None)
self.assertEqual(result_dict['_select_list'], [])
self.assertEqual(len(result_dict['_embedded']['contents']), 1)
self.assertEqual(result_dict['_embedded']['contents'][0]["_links"]["self"]["href"][:12], "urn:jio:get:")
# self.assertEqual(result_dict, {}, json.dumps(result_dict, indent=2))
@simulate('Base_getRequestUrl', '*args, **kwargs',
'return "http://example.org/bar"')
@simulate('Base_getRequestHeader', '*args, **kwargs',
'return "application/hal+json"')
@changeSkin('Hal')
def test_getHateoas_select_list_param(self):
fake_request = do_fake_request("GET")
result = self.portal.web_site_module.hateoas.ERP5Document_getHateoas(REQUEST=fake_request, mode="search", select_list=["id", "relative_url"])
self.assertEquals(fake_request.RESPONSE.status, 200)
self.assertEquals(fake_request.RESPONSE.getHeader('Content-Type'),
"application/hal+json"
)
result_dict = json.loads(result)
self.assertEqual(result_dict['_links']['self'], {"href": "http://example.org/bar"})
self.assertEqual(result_dict['_debug'], "search")
self.assertEqual(result_dict['_limit'], 10)
self.assertEqual(result_dict['_query'], None)
self.assertEqual(result_dict['_select_list'], ["id", "relative_url"])
self.assertEqual(len(result_dict['_embedded']['contents']), 10)
relative_url = result_dict['_embedded']['contents'][0]["relative_url"]
self.assertTrue(str(relative_url).endswith(result_dict['_embedded']['contents'][0]["id"]))
self.assertEqual(result_dict['_embedded']['contents'][0]["_links"]["self"]["href"], "urn:jio:get:%s" % relative_url)
@simulate('Base_getRequestUrl', '*args, **kwargs',
'return "http://example.org/bar"')
@simulate('Base_getRequestHeader', '*args, **kwargs',
'return "application/hal+json"')
@changeSkin('Hal')
def test_getHateoas_query_param(self):
fake_request = do_fake_request("GET")
result = self.portal.web_site_module.hateoas.ERP5Document_getHateoas(REQUEST=fake_request, mode="search", query="ANIMPOSSIBLECOUSCOUSVALUEFOOTOFINDINDATA")
self.assertEquals(fake_request.RESPONSE.status, 200)
self.assertEquals(fake_request.RESPONSE.getHeader('Content-Type'),
"application/hal+json"
)
result_dict = json.loads(result)
self.assertEqual(result_dict['_links']['self'], {"href": "http://example.org/bar"})
self.assertEqual(result_dict['_debug'], "search")
self.assertEqual(result_dict['_limit'], 10)
self.assertEqual(result_dict['_query'], "ANIMPOSSIBLECOUSCOUSVALUEFOOTOFINDINDATA")
self.assertEqual(result_dict['_select_list'], [])
self.assertEqual(len(result_dict['_embedded']['contents']), 0)
\ No newline at end of file
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="Test Component" module="erp5.portal_type"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>_recorded_property_dict</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAI=</string> </persistent>
</value>
</item>
<item>
<key> <string>default_reference</string> </key>
<value> <string>testHalJsonStyle</string> </value>
</item>
<item>
<key> <string>description</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>test.erp5.testHalJsonStyle</string> </value>
</item>
<item>
<key> <string>portal_type</string> </key>
<value> <string>Test Component</string> </value>
</item>
<item>
<key> <string>sid</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>text_content_error_message</string> </key>
<value>
<tuple/>
</value>
</item>
<item>
<key> <string>text_content_warning_message</string> </key>
<value>
<tuple/>
</value>
</item>
<item>
<key> <string>version</string> </key>
<value> <string>erp5</string> </value>
</item>
<item>
<key> <string>workflow_history</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAM=</string> </persistent>
</value>
</item>
</dictionary>
</pickle>
</record>
<record id="2" aka="AAAAAAAAAAI=">
<pickle>
<global name="PersistentMapping" module="Persistence.mapping"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>data</string> </key>
<value>
<dictionary/>
</value>
</item>
</dictionary>
</pickle>
</record>
<record id="3" aka="AAAAAAAAAAM=">
<pickle>
<global name="PersistentMapping" module="Persistence.mapping"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>data</string> </key>
<value>
<dictionary>
<item>
<key> <string>component_validation_workflow</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAQ=</string> </persistent>
</value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</pickle>
</record>
<record id="4" aka="AAAAAAAAAAQ=">
<pickle>
<global name="WorkflowHistoryList" module="Products.ERP5Type.patches.WorkflowTool"/>
</pickle>
<pickle>
<tuple>
<none/>
<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>
</tuple>
</pickle>
</record>
</ZopeData>
test.erp5.testHalJsonStyle
\ No newline at end of file
erp5_ui_test_core
erp5_ui_test
\ No newline at end of file
...@@ -149,7 +149,8 @@ ...@@ -149,7 +149,8 @@
\n \n
return gadget.jio_allDocs({\n return gadget.jio_allDocs({\n
"query": \'meta_type:"ERP5 Folder" AND id:"%_module"\',\n "query": \'meta_type:"ERP5 Folder" AND id:"%_module"\',\n
"select_list": ["title", "business_application_title"]\n "select_list": ["title", "business_application_title"],\n
"limit": 1000\n
})\n })\n
.push(function (result) {\n .push(function (result) {\n
var result_list = [],\n var result_list = [],\n
...@@ -355,7 +356,7 @@ ...@@ -355,7 +356,7 @@
</item> </item>
<item> <item>
<key> <string>actor</string> </key> <key> <string>actor</string> </key>
<value> <string>super_sven</string> </value> <value> <string>romain</string> </value>
</item> </item>
<item> <item>
<key> <string>comment</string> </key> <key> <string>comment</string> </key>
...@@ -369,7 +370,7 @@ ...@@ -369,7 +370,7 @@
</item> </item>
<item> <item>
<key> <string>serial</string> </key> <key> <string>serial</string> </key>
<value> <string>940.1897.57739.49578</string> </value> <value> <string>940.11553.26313.55261</string> </value>
</item> </item>
<item> <item>
<key> <string>state</string> </key> <key> <string>state</string> </key>
...@@ -387,7 +388,7 @@ ...@@ -387,7 +388,7 @@
</tuple> </tuple>
<state> <state>
<tuple> <tuple>
<float>1420236486.36</float> <float>1425475569.42</float>
<string>GMT</string> <string>GMT</string>
</tuple> </tuple>
</state> </state>
......
...@@ -80,7 +80,7 @@ else:\n ...@@ -80,7 +80,7 @@ else:\n
response.setHeader("X-Content-Type-Options", "nosniff")\n response.setHeader("X-Content-Type-Options", "nosniff")\n
\n \n
# Only fetch code (html, js, css, image) and data from this ERP5, to prevent any data leak as the web site do not control the gadget\'s code\n # Only fetch code (html, js, css, image) and data from this ERP5, to prevent any data leak as the web site do not control the gadget\'s code\n
response.setHeader("Content-Security-Policy", "default-src \'none\'; img-src \'self\' data:; media-src \'self\'; connect-src \'self\'; script-src \'self\' \'unsafe-eval\'; font-src netdna.bootstrapcdn.com; style-src \'self\' netdna.bootstrapcdn.com \'unsafe-inline\' data:; frame-src \'self\' data:")\n response.setHeader("Content-Security-Policy", "default-src \'none\'; img-src \'self\' data:; media-src \'self\'; connect-src \'self\' mail.tiolive.com; script-src \'self\' \'unsafe-eval\'; font-src netdna.bootstrapcdn.com; style-src \'self\' netdna.bootstrapcdn.com \'unsafe-inline\' data:; frame-src \'self\' data:")\n
\n \n
response.setHeader(\'Content-Type\', \'text/html\')\n response.setHeader(\'Content-Type\', \'text/html\')\n
\n \n
......
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