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
</item>
<item>
<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>
<key> <string>id</string> </key>
......
......@@ -377,7 +377,11 @@ def renderForm(form, response_dict):\n
for field in form.get_fields_in_group(group[\'goid\']):\n
# field_list.append((field.id, renderRawField(field)))\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
# for field_group in field.form.get_groups():\n
# traversed_document.log("Field group: " + field_group)\n
......@@ -658,6 +662,7 @@ elif (mode == \'root\') or (mode == \'traverse\'):\n
\n
# Include properties in document JSON\n
# XXX Extract from renderer form?\n
"""\n
for group in renderer_form.Form_getGroupTitleAndId():\n
for field in renderer_form.get_fields_in_group(group[\'goid\']):\n
field_id = field.id\n
......@@ -671,6 +676,7 @@ elif (mode == \'root\') or (mode == \'traverse\'):\n
# Serialize DateTime\n
property_value = property_value.rfc822()\n
result_dict[property_name] = property_value \n
"""\n
\n
##############\n
# XXX Custom slapos code\n
......@@ -797,7 +803,9 @@ elif mode == \'search\':\n
# else:\n
\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
\n
for sql_document in sql_list:\n
......@@ -844,7 +852,7 @@ return json.dumps(result_dict, indent=2)\n
</item>
<item>
<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>
<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 @@
\n
return gadget.jio_allDocs({\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
.push(function (result) {\n
var result_list = [],\n
......@@ -355,7 +356,7 @@
</item>
<item>
<key> <string>actor</string> </key>
<value> <string>super_sven</string> </value>
<value> <string>romain</string> </value>
</item>
<item>
<key> <string>comment</string> </key>
......@@ -369,7 +370,7 @@
</item>
<item>
<key> <string>serial</string> </key>
<value> <string>940.1897.57739.49578</string> </value>
<value> <string>940.11553.26313.55261</string> </value>
</item>
<item>
<key> <string>state</string> </key>
......@@ -387,7 +388,7 @@
</tuple>
<state>
<tuple>
<float>1420236486.36</float>
<float>1425475569.42</float>
<string>GMT</string>
</tuple>
</state>
......
......@@ -80,7 +80,7 @@ else:\n
response.setHeader("X-Content-Type-Options", "nosniff")\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
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
response.setHeader(\'Content-Type\', \'text/html\')\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