Commit c2c28029 authored by Romain Courteaud's avatar Romain Courteaud

[erp5_hal_json_style] Do not generate link for empty value, as it will not be clickable in UI

Tests: do not depend on previous test executions.
parent 082712a1
...@@ -1814,72 +1814,74 @@ def calculateHateoas(is_portal=None, is_site_root=None, traversed_document=None, ...@@ -1814,72 +1814,74 @@ def calculateHateoas(is_portal=None, is_site_root=None, traversed_document=None,
key='field_%s_%s' % (editable_field.id, brain_uid)) key='field_%s_%s' % (editable_field.id, brain_uid))
# By default, we won't be generating views in the URL # Do not generate link for empty value, as it will not be clickable in UI
url_parameter_dict = None if default_field_value not in ('', None):
if select in url_column_dict: # By default, we won't be generating views in the URL
# Check if we get URL parameters using listbox field `url_columns` url_parameter_dict = None
try: if select in url_column_dict:
url_column_method = getattr(brain, url_column_dict[select]) # Check if we get URL parameters using listbox field `url_columns`
# Result of `url_column_method` must be a dictionary in the format try:
# {'command': <command_name, ex: 'raw', 'push_history'>, url_column_method = getattr(brain, url_column_dict[select])
# 'options': {'url': <Absolute URL>, 'jio_key': <Relative URL of object>, 'view': <id of the view>}} # Result of `url_column_method` must be a dictionary in the format
url_parameter_dict = url_column_method(url_dict=True, # {'command': <command_name, ex: 'raw', 'push_history'>,
brain=brain, # 'options': {'url': <Absolute URL>, 'jio_key': <Relative URL of object>, 'view': <id of the view>}}
selection=catalog_kw['selection'], url_parameter_dict = url_column_method(url_dict=True,
selection_name=catalog_kw['selection_name'], brain=brain,
column_id=select) selection=catalog_kw['selection'],
except AttributeError as e: selection_name=catalog_kw['selection_name'],
# In case the URL method is invalid or empty, we expect to have no link column_id=select)
# for the column to maintain compatibility with old UI, hence we create except AttributeError as e:
# an empty url_parameter_dict for these cases. # In case the URL method is invalid or empty, we expect to have no link
url_parameter_dict = {} # for the column to maintain compatibility with old UI, hence we create
if url_column_dict[select]: # an empty url_parameter_dict for these cases.
log("Invalid URL method {!s} on column {}".format(url_column_dict[select], select), level=800) url_parameter_dict = {}
if url_column_dict[select]:
elif getattr(brain, 'getListItemUrlDict', None) is not None: log("Invalid URL method {!s} on column {}".format(url_column_dict[select], select), level=800)
# Check if we can get URL result from the brain
try: elif getattr(brain, 'getListItemUrlDict', None) is not None:
url_parameter_dict = brain.getListItemUrlDict( # Check if we can get URL result from the brain
select, result_index, catalog_kw['selection_name'] try:
) url_parameter_dict = brain.getListItemUrlDict(
except (ConflictError, RuntimeError): select, result_index, catalog_kw['selection_name']
raise )
except: except (ConflictError, RuntimeError):
log('could not evaluate the url method getListItemUrlDict with %r' % brain, raise
level=800) except:
log('could not evaluate the url method getListItemUrlDict with %r' % brain,
if isinstance(url_parameter_dict, dict): level=800)
# We need to put URL into rendered field so just ensure it is a dict
if not isinstance(contents_item[select], dict): if isinstance(url_parameter_dict, dict):
contents_item[select] = { # We need to put URL into rendered field so just ensure it is a dict
'default': contents_item[select], if not isinstance(contents_item[select], dict):
} contents_item[select] = {
# We should be generating view if there is extra params for view in 'default': contents_item[select],
# view_kw. These parameters are required to create url at hateoas side
# using the URL template as necessary
if 'view_kw' not in url_parameter_dict:
contents_item[select]['url_value'] = url_parameter_dict
else:
# Get extra parameters either from url_result_dict or from brain
extra_url_param_dict = url_parameter_dict['view_kw'].get('extra_param_json', {})
url_template_id = 'traverse_generator'
if extra_url_param_dict:
url_template_id = 'traverse_generator_action'
# Explicity populate url_value dict. This way we can ensure that whatever been
# sent via url_parameter_dict goes directly in url_value dict
contents_item[select]['url_value'] = {}
contents_item[select]['url_value']['command'] = url_parameter_dict['command']
contents_item[select]['url_value']['options'] = url_parameter_dict['options']
# Generate `view` to be used to construct URL
contents_item[select]['url_value']['options']['view'] = url_template_dict[url_template_id] % {
"root_url": site_root.absolute_url(),
"script_id": script.id,
"relative_url": url_parameter_dict['view_kw']['jio_key'].replace("/", "%2F"),
"view": url_parameter_dict['view_kw']['view'],
"extra_param_json": urlsafe_b64encode(
json.dumps(ensureSerializable(extra_url_param_dict)))
} }
# We should be generating view if there is extra params for view in
# view_kw. These parameters are required to create url at hateoas side
# using the URL template as necessary
if 'view_kw' not in url_parameter_dict:
contents_item[select]['url_value'] = url_parameter_dict
else:
# Get extra parameters either from url_result_dict or from brain
extra_url_param_dict = url_parameter_dict['view_kw'].get('extra_param_json', {})
url_template_id = 'traverse_generator'
if extra_url_param_dict:
url_template_id = 'traverse_generator_action'
# Explicity populate url_value dict. This way we can ensure that whatever been
# sent via url_parameter_dict goes directly in url_value dict
contents_item[select]['url_value'] = {}
contents_item[select]['url_value']['command'] = url_parameter_dict['command']
contents_item[select]['url_value']['options'] = url_parameter_dict['options']
# Generate `view` to be used to construct URL
contents_item[select]['url_value']['options']['view'] = url_template_dict[url_template_id] % {
"root_url": site_root.absolute_url(),
"script_id": script.id,
"relative_url": url_parameter_dict['view_kw']['jio_key'].replace("/", "%2F"),
"view": url_parameter_dict['view_kw']['view'],
"extra_param_json": urlsafe_b64encode(
json.dumps(ensureSerializable(extra_url_param_dict)))
}
# endfor select # endfor select
contents_list.append(contents_item) contents_list.append(contents_item)
......
...@@ -66,9 +66,10 @@ def simulate(script_id, params_string, code_string): ...@@ -66,9 +66,10 @@ def simulate(script_id, params_string, code_string):
return decorated return decorated
return upperWrap return upperWrap
def wipeFolder(folder): def wipeFolder(folder, commit=True):
folder.deleteContent(list(folder.objectIds())) folder.deleteContent(list(folder.objectIds()))
transaction.commit() if commit:
transaction.commit()
def createIndexedDocument(quantity=1): def createIndexedDocument(quantity=1):
"""Create `quantity` Foo document(s) in Foo module and pass it as `document(_list)` argument into the wrapped function.""" """Create `quantity` Foo document(s) in Foo module and pass it as `document(_list)` argument into the wrapped function."""
...@@ -136,6 +137,8 @@ from Products.ERP5Type.tests.ERP5TypeTestCase import ERP5TypeTestCase ...@@ -136,6 +137,8 @@ from Products.ERP5Type.tests.ERP5TypeTestCase import ERP5TypeTestCase
class ERP5HALJSONStyleSkinsMixin(ERP5TypeTestCase): class ERP5HALJSONStyleSkinsMixin(ERP5TypeTestCase):
def afterSetUp(self): def afterSetUp(self):
self.login() self.login()
wipeFolder(self.portal.foo_module, commit=False)
def beforeTearDown(self): def beforeTearDown(self):
transaction.abort() transaction.abort()
...@@ -1384,6 +1387,7 @@ return '%s/Base_viewMetadata?reset:int=1' % context.getRelativeUrl() ...@@ -1384,6 +1387,7 @@ return '%s/Base_viewMetadata?reset:int=1' % context.getRelativeUrl()
""") """)
@changeSkin('Hal') @changeSkin('Hal')
def test_getHateoasDocument_listbox_check_url_column_different_view(self): def test_getHateoasDocument_listbox_check_url_column_different_view(self):
self._makeDocument()
# pass custom list method which expect input arguments # pass custom list method which expect input arguments
self.portal.foo_module.FooModule_viewFooList.listbox.ListBox_setPropertyList( self.portal.foo_module.FooModule_viewFooList.listbox.ListBox_setPropertyList(
field_url_columns = ['modification_date | Base_getUrl',]) field_url_columns = ['modification_date | Base_getUrl',])
...@@ -1466,9 +1470,6 @@ return url ...@@ -1466,9 +1470,6 @@ return url
'return "http://example.org/bar"') 'return "http://example.org/bar"')
@simulate('Base_getRequestHeader', '*args, **kwargs', @simulate('Base_getRequestHeader', '*args, **kwargs',
'return "application/hal+json"') 'return "application/hal+json"')
@simulate('Test_listProducts', '*args, **kwargs', """
return context.getPortalObject().foo_module.contentValues()
""")
@simulate('Base_getUrl', 'url_dict=False, *args, **kwargs', """ @simulate('Base_getUrl', 'url_dict=False, *args, **kwargs', """
url = "https://officejs.com" url = "https://officejs.com"
if url_dict: if url_dict:
...@@ -1481,6 +1482,7 @@ return url ...@@ -1481,6 +1482,7 @@ return url
""") """)
@changeSkin('Hal') @changeSkin('Hal')
def test_getHateoasDocument_listbox_check_url_column_absolute_url_without_field_rendering(self): def test_getHateoasDocument_listbox_check_url_column_absolute_url_without_field_rendering(self):
self._makeDocument()
# pass custom list method which expect input arguments # pass custom list method which expect input arguments
self.portal.foo_module.FooModule_viewFooList.listbox.ListBox_setPropertyList( self.portal.foo_module.FooModule_viewFooList.listbox.ListBox_setPropertyList(
field_url_columns = ['title | Base_getUrl',]) field_url_columns = ['title | Base_getUrl',])
...@@ -1489,7 +1491,8 @@ return url ...@@ -1489,7 +1491,8 @@ return url
result = self.portal.web_site_module.hateoas.ERP5Document_getHateoas( result = self.portal.web_site_module.hateoas.ERP5Document_getHateoas(
REQUEST=fake_request, REQUEST=fake_request,
mode="search", mode="search",
list_method='Test_listProducts', list_method='contentValues',
relative_url='foo_module',
select_list=['id', 'title', 'creation_date', 'modification_date'], select_list=['id', 'title', 'creation_date', 'modification_date'],
form_relative_url='portal_skins/erp5_ui_test/FooModule_viewFooList/listbox') form_relative_url='portal_skins/erp5_ui_test/FooModule_viewFooList/listbox')
result_dict = json.loads(result) result_dict = json.loads(result)
...@@ -1519,11 +1522,9 @@ return url ...@@ -1519,11 +1522,9 @@ return url
'return "http://example.org/bar"') 'return "http://example.org/bar"')
@simulate('Base_getRequestHeader', '*args, **kwargs', @simulate('Base_getRequestHeader', '*args, **kwargs',
'return "application/hal+json"') 'return "application/hal+json"')
@simulate('Test_listProducts', '*args, **kwargs', """
return context.getPortalObject().foo_module.contentValues()
""")
@changeSkin('Hal') @changeSkin('Hal')
def test_getHateoasDocument_listbox_check_url_column_no_url(self): def test_getHateoasDocument_listbox_check_url_column_no_url(self):
self._makeDocument()
# pass custom list method which expect input arguments # pass custom list method which expect input arguments
self.portal.foo_module.FooModule_viewFooList.listbox.ListBox_setPropertyList( self.portal.foo_module.FooModule_viewFooList.listbox.ListBox_setPropertyList(
field_url_columns = ['title|',]) field_url_columns = ['title|',])
...@@ -1532,7 +1533,8 @@ return context.getPortalObject().foo_module.contentValues() ...@@ -1532,7 +1533,8 @@ return context.getPortalObject().foo_module.contentValues()
result = self.portal.web_site_module.hateoas.ERP5Document_getHateoas( result = self.portal.web_site_module.hateoas.ERP5Document_getHateoas(
REQUEST=fake_request, REQUEST=fake_request,
mode="search", mode="search",
list_method='Test_listProducts', list_method='contentValues',
relative_url='foo_module',
select_list=['id', 'title', 'creation_date', 'modification_date'], select_list=['id', 'title', 'creation_date', 'modification_date'],
form_relative_url='portal_skins/erp5_ui_test/FooModule_viewFooList/listbox') form_relative_url='portal_skins/erp5_ui_test/FooModule_viewFooList/listbox')
result_dict = json.loads(result) result_dict = json.loads(result)
...@@ -1554,9 +1556,6 @@ return context.getPortalObject().foo_module.contentValues() ...@@ -1554,9 +1556,6 @@ return context.getPortalObject().foo_module.contentValues()
'return "http://example.org/bar"') 'return "http://example.org/bar"')
@simulate('Base_getRequestHeader', '*args, **kwargs', @simulate('Base_getRequestHeader', '*args, **kwargs',
'return "application/hal+json"') 'return "application/hal+json"')
@simulate('Test_listProducts', '*args, **kwargs', """
return context.getPortalObject().foo_module.contentValues()
""")
@simulate('Base_getUrl', 'url_dict=False, *args, **kwargs', """ @simulate('Base_getUrl', 'url_dict=False, *args, **kwargs', """
url = "https://officejs.com" url = "https://officejs.com"
if url_dict: if url_dict:
...@@ -1570,6 +1569,7 @@ return url ...@@ -1570,6 +1569,7 @@ return url
""") """)
@changeSkin('Hal') @changeSkin('Hal')
def test_getHateoasDocument_listbox_check_url_column_option_parameters(self): def test_getHateoasDocument_listbox_check_url_column_option_parameters(self):
self._makeDocument()
# pass custom list method which expect input arguments # pass custom list method which expect input arguments
self.portal.foo_module.FooModule_viewFooList.listbox.ListBox_setPropertyList( self.portal.foo_module.FooModule_viewFooList.listbox.ListBox_setPropertyList(
field_url_columns = ['title | Base_getUrl',]) field_url_columns = ['title | Base_getUrl',])
...@@ -1578,7 +1578,8 @@ return url ...@@ -1578,7 +1578,8 @@ return url
result = self.portal.web_site_module.hateoas.ERP5Document_getHateoas( result = self.portal.web_site_module.hateoas.ERP5Document_getHateoas(
REQUEST=fake_request, REQUEST=fake_request,
mode="search", mode="search",
list_method='Test_listProducts', list_method='contentValues',
relative_url='foo_module',
select_list=['id', 'title', 'creation_date', 'modification_date'], select_list=['id', 'title', 'creation_date', 'modification_date'],
form_relative_url='portal_skins/erp5_ui_test/FooModule_viewFooList/listbox') form_relative_url='portal_skins/erp5_ui_test/FooModule_viewFooList/listbox')
result_dict = json.loads(result) result_dict = json.loads(result)
......
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