Commit 6f2270f9 authored by Tomáš Peterka's avatar Tomáš Peterka

[hal_json_style] Unittest exotic results of search method

parent 6cf2326c
...@@ -12,10 +12,13 @@ Only in mode == 'search' ...@@ -12,10 +12,13 @@ Only in mode == 'search'
:param query: :param query:
:param select_list: :param select_list:
:param limit: :param limit:
:param form_relative_url: {str} relative URL of a form FIELD issuing the search (listbox/relation field...)
Only in mode == 'form' Only in mode == 'form'
:param form: :param form:
Only in mode == 'traverse'
TBD. TBD.
""" """
from ZTUtils import make_query from ZTUtils import make_query
...@@ -143,11 +146,7 @@ def getRealRelativeUrl(document): ...@@ -143,11 +146,7 @@ def getRealRelativeUrl(document):
def getFormRelativeUrl(form): def getFormRelativeUrl(form):
return portal.portal_catalog( return portal.portal_catalog(
portal_type=ComplexQuery( portal_type=("ERP5 Form", "ERP5 Report"),
Query(portal_type="ERP5 Form"),
Query(portal_type="ERP5 Report"),
logical_operator='or'
),
uid=form.getUid(), uid=form.getUid(),
id=form.getId(), id=form.getId(),
limit=1, limit=1,
...@@ -1174,11 +1173,9 @@ def calculateHateoas(is_portal=None, is_site_root=None, traversed_document=None, ...@@ -1174,11 +1173,9 @@ def calculateHateoas(is_portal=None, is_site_root=None, traversed_document=None,
if action_dict: if action_dict:
result_dict['_actions'] = action_dict result_dict['_actions'] = action_dict
elif mode == 'search': elif mode == 'search':
################################################# #################################################
# Portal catalog search # Portal catalog search
# #
# Possible call arguments example: # Possible call arguments example:
# form_relative_url: portal_skins/erp5_web/WebSite_view/listbox # form_relative_url: portal_skins/erp5_web/WebSite_view/listbox
...@@ -1407,6 +1404,7 @@ def calculateHateoas(is_portal=None, is_site_root=None, traversed_document=None, ...@@ -1407,6 +1404,7 @@ def calculateHateoas(is_portal=None, is_site_root=None, traversed_document=None,
listbox_form, listbox_form,
value=default_field_value, value=default_field_value,
key='field_%s_%s' % (editable_field_dict[select].id, contents_uid)) key='field_%s_%s' % (editable_field_dict[select].id, contents_uid))
REQUEST.other.pop('cell', None) REQUEST.other.pop('cell', None)
else: else:
...@@ -1414,13 +1412,14 @@ def calculateHateoas(is_portal=None, is_site_root=None, traversed_document=None, ...@@ -1414,13 +1412,14 @@ def calculateHateoas(is_portal=None, is_site_root=None, traversed_document=None,
# value by resolving value in the correct order. The code is copy&pasted # value by resolving value in the correct order. The code is copy&pasted
# from ListBoxRendererLine.getValueList because it is universal # from ListBoxRendererLine.getValueList because it is universal
contents_value = None contents_value = None
if "." in select:
select = select[select.rindex('.') + 1:]
if len(select) == 0: if not isinstance(select, (str, unicode)) or len(select) == 0:
context.log('There is an empty column name in {!s}!'.format(select_list), level=200) context.log('There is an invalid column name in {!s}!'.format(select_list), level=200)
continue continue
if "." in select:
select = select[select.rindex('.') + 1:]
# 1. resolve attribute on a raw object (all wrappers removed) using # 1. resolve attribute on a raw object (all wrappers removed) using
# lowest-level secure getattr method given object type # lowest-level secure getattr method given object type
raw_search_result = search_result raw_search_result = search_result
...@@ -1470,7 +1469,9 @@ def calculateHateoas(is_portal=None, is_site_root=None, traversed_document=None, ...@@ -1470,7 +1469,9 @@ def calculateHateoas(is_portal=None, is_site_root=None, traversed_document=None,
has_brain_param = False has_brain_param = False
if hasattr(contents_value, "params"): if hasattr(contents_value, "params"):
has_mandatory_param = any(map(lambda param: '=' not in param and '*' not in param, has_mandatory_param = any(map(lambda param: '=' not in param and '*' not in param,
contents_value.params().split(","))) contents_value.params().split(","))) \
if contents_value.params() \
else False # because any([]) == True
has_brain_param = "brain" in contents_value.params() has_brain_param = "brain" in contents_value.params()
try: try:
if has_mandatory_param: if has_mandatory_param:
......
...@@ -66,14 +66,26 @@ def simulate(script_id, params_string, code_string): ...@@ -66,14 +66,26 @@ def simulate(script_id, params_string, code_string):
return decorated return decorated
return upperWrap return upperWrap
def createIndexedDocument(): def wipeFolder(folder):
"""Create a Foo document inside Foo module and pass it as "document" argument into wrapped function.""" folder.deleteContent(list(folder.objectIds()))
transaction.commit()
def createIndexedDocument(quantity=1):
"""Create `quantity` Foo document(s) in Foo module and pass it as `document(_list)` argument into the wrapped function."""
def decorator(func): def decorator(func):
def wrapped(self, *args, **kwargs): def wrapped(self, *args, **kwargs):
wipeFolder(self.portal.foo_module)
if quantity <= 1:
kwargs.update(document=self._makeDocument()) kwargs.update(document=self._makeDocument())
else:
kwargs.update(document_list=[self._makeDocument() for _ in range(quantity)])
self.portal.portal_caches.clearAllCache() self.portal.portal_caches.clearAllCache()
self.tic() self.tic()
try:
return func(self, *args, **kwargs) return func(self, *args, **kwargs)
finally:
wipeFolder(self.portal.foo_module)
self.tic() # unindex
return wrapped return wrapped
return decorator return decorator
...@@ -1074,6 +1086,82 @@ class TestERP5Document_getHateoas_mode_search(ERP5HALJSONStyleSkinsMixin): ...@@ -1074,6 +1086,82 @@ class TestERP5Document_getHateoas_mode_search(ERP5HALJSONStyleSkinsMixin):
mode="search", mode="search",
default_param_json='eyJcdTAwZWEiOiAiXHUwMGU4In0=') default_param_json='eyJcdTAwZWEiOiAiXHUwMGU4In0=')
@simulate('Base_getRequestUrl', '*args, **kwargs', 'return "http://example.org/bar"')
@simulate('Base_getRequestHeader', '*args, **kwargs', 'return "application/hal+json"')
@simulate('Test_listObjects', '*args, **kwargs', """
from Products.PythonScripts.standard import Object
return [Object(debit_price=1000.00, credit_price=100.00),
Object(debit_price=10.00, credit_price=0.00)]
""")
@simulate('Test_listProducts', '*args, **kwargs', """
return context.getPortalObject().foo_module.values()
""")
@simulate('Test_listCatalog', '*args, **kwargs', """
return context.getPortalObject().portal_catalog(portal_type='Foo', sort_on=[('id', 'ASC')])
""")
@createIndexedDocument(quantity=2)
@changeSkin('Hal')
def test_getHateoas_exotic_search_results(self, document_list):
"""Test that ingestion of `list_method` result does not fail.
The only limit for the result of `list_method` is that it should be an iterable.
Practically, because we code in python, it can be any object.
"""
fake_request = do_fake_request("GET")
result = self.portal.web_site_module.hateoas.ERP5Document_getHateoas(
REQUEST=fake_request,
mode="search",
local_roles=["Assignor", "Assignee"],
list_method='Test_listObjects',
select_list=['credit_price', 'debit_price']
)
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(len(result_dict['_embedded']['contents']), 2)
self.assertEqual(result_dict['_embedded']['contents'][0]['debit_price'], 1000.0)
self.assertEqual(result_dict['_embedded']['contents'][0]['credit_price'], 100.0)
self.assertEqual(result_dict['_embedded']['contents'][1]['debit_price'], 10.0)
self.assertEqual(result_dict['_embedded']['contents'][1]['credit_price'], 0.0)
# Render a Document using Form Field template (only for field 'id')
result = self.portal.web_site_module.hateoas.ERP5Document_getHateoas(
REQUEST=fake_request,
mode="search",
local_roles=["Assignor", "Assignee"],
list_method='Test_listProducts',
select_list=['id'],
form_relative_url='portal_skins/erp5_ui_test/FooModule_viewFooList/listbox'
)
result_dict = json.loads(result)
self.assertEqual(2, len(result_dict['_embedded']['contents']))
self.assertIn("field_listbox", result_dict['_embedded']['contents'][0]['id']['key'])
self.assertEqual("StringField", result_dict['_embedded']['contents'][0]['id']['type'])
self.assertEqual(document_list[0].getId(), result_dict['_embedded']['contents'][0]['id']['default'])
self.assertIn("field_listbox", result_dict['_embedded']['contents'][1]['id']['key'])
self.assertEqual("StringField", result_dict['_embedded']['contents'][1]['id']['type'])
self.assertEqual(document_list[1].getId(), result_dict['_embedded']['contents'][1]['id']['default'])
# Test rendering without form template of attribute, getterm and a script
result = self.portal.web_site_module.hateoas.ERP5Document_getHateoas(
REQUEST=fake_request,
mode="search",
local_roles=["Assignor", "Assignee"],
list_method='Test_listCatalog',
select_list=['title', 'Foo_getLocalTitle', 'getTotalQuantity'] # property, Script, method
)
result_dict = json.loads(result)
self.assertEqual(len(result_dict['_embedded']['contents']), 2)
self.assertEqual(result_dict['_embedded']['contents'][0]['title'].encode('utf-8'), document_list[0].getTitle())
self.assertEqual(result_dict['_embedded']['contents'][0]['Foo_getLocalTitle'], None)
self.assertEqual(result_dict['_embedded']['contents'][0]['getTotalQuantity'], 0)
self.assertEqual(result_dict['_embedded']['contents'][1]['title'].encode('utf-8'), document_list[1].getTitle())
self.assertEqual(result_dict['_embedded']['contents'][1]['Foo_getLocalTitle'], None)
self.assertEqual(result_dict['_embedded']['contents'][1]['getTotalQuantity'], 0)
class TestERP5Document_getHateoas_mode_bulk(ERP5HALJSONStyleSkinsMixin): class TestERP5Document_getHateoas_mode_bulk(ERP5HALJSONStyleSkinsMixin):
@simulate('Base_getRequestHeader', '*args, **kwargs', @simulate('Base_getRequestHeader', '*args, **kwargs',
......
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