diff --git a/bt5/erp5_hal_json_style/SkinTemplateItem/portal_skins/erp5_hal_json_style/ERP5Document_getHateoas.py b/bt5/erp5_hal_json_style/SkinTemplateItem/portal_skins/erp5_hal_json_style/ERP5Document_getHateoas.py index 03dd64821520a6401ce16fe4b6d6347e8272e8a1..06befff7a71fce50d5be7dd40e5277d5074d6c8f 100644 --- a/bt5/erp5_hal_json_style/SkinTemplateItem/portal_skins/erp5_hal_json_style/ERP5Document_getHateoas.py +++ b/bt5/erp5_hal_json_style/SkinTemplateItem/portal_skins/erp5_hal_json_style/ERP5Document_getHateoas.py @@ -1729,6 +1729,17 @@ def calculateHateoas(is_portal=None, is_site_root=None, traversed_document=None, line[select]['editable'] = False if source_field is not None and source_field_meta_type == "ListBox": + # Trigger count method if exist + # XXX No need to count if no pagination + count_method = source_field.get_value('count_method') + if count_method != "" and count_method.getMethodName() != list_method: + count_kw = dict(catalog_kw) + # Drop not needed parameters + count_kw.pop("sort_on", None) + count_kw.pop("limit", None) + count_method_result = getattr(traversed_document, count_method.getMethodName())(REQUEST=REQUEST, **count_kw) + result_dict['_embedded']['count'] = ensureSerializable(count_method_result[0][0]) + contents_stat_list = [] # in case the search was issued by listbox we can provide results of # stat_method and count_method back to the caller diff --git a/bt5/erp5_hal_json_style/TestTemplateItem/portal_components/test.erp5.testHalJsonStyle.py b/bt5/erp5_hal_json_style/TestTemplateItem/portal_components/test.erp5.testHalJsonStyle.py index bdb5b7cbed2ba8b72a2733ec0af313e3e6e306b9..7e2e19a5c88db24b4449ec86ffa5814baa7276bd 100644 --- a/bt5/erp5_hal_json_style/TestTemplateItem/portal_components/test.erp5.testHalJsonStyle.py +++ b/bt5/erp5_hal_json_style/TestTemplateItem/portal_components/test.erp5.testHalJsonStyle.py @@ -975,6 +975,8 @@ class TestERP5Document_getHateoas_mode_search(ERP5HALJSONStyleSkinsMixin): self.assertEqual(len(result_dict['_embedded']['contents']), 10) self.assertEqual(result_dict['_embedded']['contents'][0]["_links"]["self"]["href"][:12], "urn:jio:get:") + # No count if not in the listbox context currently + self.assertEqual(result_dict['_embedded'].get('count', None), None) @simulate('Base_getRequestUrl', '*args, **kwargs', 'return "http://example.org/bar"') @@ -999,6 +1001,8 @@ class TestERP5Document_getHateoas_mode_search(ERP5HALJSONStyleSkinsMixin): self.assertEqual(len(result_dict['_embedded']['contents']), 1) self.assertEqual(result_dict['_embedded']['contents'][0]["_links"]["self"]["href"][:12], "urn:jio:get:") + # No count if not in the listbox context currently + self.assertEqual(result_dict['_embedded'].get('count', None), None) # self.assertEqual(result_dict, {}, json.dumps(result_dict, indent=2)) @@ -1028,6 +1032,8 @@ class TestERP5Document_getHateoas_mode_search(ERP5HALJSONStyleSkinsMixin): 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) + # No count if not in the listbox context currently + self.assertEqual(result_dict['_embedded'].get('count', None), None) @simulate('Base_getRequestUrl', '*args, **kwargs', 'return "http://example.org/bar"') @@ -1051,6 +1057,8 @@ class TestERP5Document_getHateoas_mode_search(ERP5HALJSONStyleSkinsMixin): self.assertEqual(result_dict['_select_list'], []) self.assertEqual(len(result_dict['_embedded']['contents']), 0) + # No count if not in the listbox context currently + self.assertEqual(result_dict['_embedded'].get('count', None), None) @simulate('Base_getRequestUrl', '*args, **kwargs', 'return "http://example.org/bar"') @@ -1074,6 +1082,8 @@ class TestERP5Document_getHateoas_mode_search(ERP5HALJSONStyleSkinsMixin): self.assertEqual(result_dict['_select_list'], []) self.assertEqual(len(result_dict['_embedded']['contents']), 0) + # No count if not in the listbox context currently + self.assertEqual(result_dict['_embedded'].get('count', None), None) @simulate('Base_getRequestUrl', '*args, **kwargs', 'return "http://example.org/bar"') @@ -1114,6 +1124,9 @@ return context.getPortalObject().foo_module.contentValues() #editalble creation date is defined at proxy form self.assertEqual(result_dict['_embedded']['contents'][0]['creation_date']['type'], 'DateTimeField') self.assertEqual(result_dict['_embedded']['contents'][0]['modification_date']['type'], 'DateTimeField') + # There is a count method on this listbox + self.assertEqual(result_dict['_embedded']['count'], 0) + @simulate('Base_getRequestUrl', '*args, **kwargs', 'return "http://example.org/bar"') @simulate('Base_getRequestHeader', '*args, **kwargs', 'return "application/hal+json"') @@ -1154,6 +1167,8 @@ return context.getPortalObject().portal_catalog(portal_type='Foo', sort_on=[('id 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) + # No count if not in the listbox context currently + self.assertEqual(result_dict['_embedded'].get('count', None), None) # Render a Document using Form Field template (only for field 'id') result = self.portal.web_site_module.hateoas.ERP5Document_getHateoas( @@ -1172,6 +1187,8 @@ return context.getPortalObject().portal_catalog(portal_type='Foo', sort_on=[('id 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']) + # There is a count method on the listbox + self.assertEqual(result_dict['_embedded']['count'], 0) # Test rendering without form template of attribute, getterm and a script result = self.portal.web_site_module.hateoas.ERP5Document_getHateoas( @@ -1189,6 +1206,64 @@ return context.getPortalObject().portal_catalog(portal_type='Foo', sort_on=[('id 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) + # No count if not in the listbox context currently + self.assertEqual(result_dict['_embedded'].get('count', None), None) + + @simulate('Base_getRequestUrl', '*args, **kwargs', 'return "http://example.org/bar"') + @simulate('Base_getRequestHeader', '*args, **kwargs', 'return "application/hal+json"') + @simulate('Test_listCatalog', '*args, **kwargs', """ +return context.getPortalObject().portal_catalog(portal_type='Foo', sort_on=[('id', 'ASC')]) +""") + @simulate('Test_countCatalog', '*args, **kwargs', """ +return context.getPortalObject().portal_catalog(portal_type='Foo', sort_on=[('id', 'ASC')]) +""") + @createIndexedDocument(quantity=2) + @changeSkin('Hal') + def test_getHateoas_count_method(self, document_list): + """Test that count method also uses the query parameters. + """ + fake_request = do_fake_request("GET") + result = self.portal.web_site_module.hateoas.ERP5Document_getHateoas( + REQUEST=fake_request, + mode="search", + relative_url='foo_module', + list_method="searchFolder", + form_relative_url='portal_skins/erp5_ui_test/FooModule_viewFooList/listbox' + ) + result_dict = json.loads(result) + self.assertEqual(len(result_dict['_embedded']['contents']), 2) + self.assertEqual(result_dict['_embedded']['count'], 2) + + # Check that limiting the number of result doesn't impact count + fake_request = do_fake_request("GET") + result = self.portal.web_site_module.hateoas.ERP5Document_getHateoas( + REQUEST=fake_request, + mode="search", + relative_url='foo_module', + list_method="searchFolder", + query='portal_type:"Foo"', + limit=1, + form_relative_url='portal_skins/erp5_ui_test/FooModule_viewFooList/listbox' + ) + result_dict = json.loads(result) + # There is a count method on this listbox + self.assertEqual(len(result_dict['_embedded']['contents']), 1) + self.assertEqual(result_dict['_embedded']['count'], 2) + + # Check that query parameters are passed to the count method + fake_request = do_fake_request("GET") + result = self.portal.web_site_module.hateoas.ERP5Document_getHateoas( + REQUEST=fake_request, + mode="search", + relative_url='foo_module', + list_method="searchFolder", + query='id:"%s"' % self.portal.foo_module.contentIds()[0], + form_relative_url='portal_skins/erp5_ui_test/FooModule_viewFooList/listbox' + ) + result_dict = json.loads(result) + # There is a count method on this listbox + self.assertEqual(len(result_dict['_embedded']['contents']), 1) + self.assertEqual(result_dict['_embedded']['count'], 1) class TestERP5Person_getHateoas_mode_search(ERP5HALJSONStyleSkinsMixin): @@ -1230,6 +1305,8 @@ return context.getPortalObject().portal_catalog.searchResults(portal_type="Perso titles = [result['title'] for result in result_dict['_embedded']['contents']] # getTitle() composes title from first_name and last_name while attribute "title" remains empty self.assertIn("Benoit Mandelbrot", titles) + # No count if not in the listbox context currently + self.assertEqual(result_dict['_embedded'].get('count', None), None) result = self.portal.web_site_module.hateoas.ERP5Document_getHateoas( REQUEST=fake_request, @@ -1242,6 +1319,8 @@ return context.getPortalObject().portal_catalog.searchResults(portal_type="Perso titles = [result['title'] for result in result_dict['_embedded']['contents']] # getTitle() composes title from first_name and last_name while attribute "title" remains empty self.assertIn("Benoit Mandelbrot", titles) + # No count if not in the listbox context currently + self.assertEqual(result_dict['_embedded'].get('count', None), None) class TestERP5PDM_getHateoas_mode_search(ERP5HALJSONStyleSkinsMixin): @@ -1305,6 +1384,8 @@ return portal.portal_simulation.getInventoryList(section_uid=context.getUid()) self.assertEqual(len(result_dict['_embedded']['contents']), 1) self.assertEqual(result_dict['_embedded']['contents'][0]['total_price'], 0) self.assertEqual(result_dict['_embedded']['contents'][0]['total_quantity'],0) + # No count if not in the listbox context currently + self.assertEqual(result_dict['_embedded'].get('count', None), None) class TestERP5Document_getHateoas_mode_bulk(ERP5HALJSONStyleSkinsMixin):