From d039c9bf5dccd4a1ea782084767cc0e91bb5d156 Mon Sep 17 00:00:00 2001 From: Benjamin Dauvergne Date: Mon, 27 Dec 2021 16:21:16 +0100 Subject: [PATCH] carddef: add custom view dynamic filter on items field (#48386) --- tests/form_pages/test_all.py | 76 ++++++++++++++++++++++++++++++++++++ wcs/carddef.py | 25 ++++++++++-- 2 files changed, 98 insertions(+), 3 deletions(-) diff --git a/tests/form_pages/test_all.py b/tests/form_pages/test_all.py index 3c37b70be..8cbb4f113 100644 --- a/tests/form_pages/test_all.py +++ b/tests/form_pages/test_all.py @@ -1,5 +1,6 @@ import hashlib import io +import itertools import json import os import re @@ -5512,6 +5513,81 @@ def test_item_field_from_custom_view_on_cards(pub): assert formdef.data_class().select()[0].data['0_structured']['item'] == 'baz' +@pytest.mark.parametrize('filter_value', ['{{ "foo,bar" }}', 'foo,bar', '{{ "foo,bar"|split:","|list }}']) +def test_items_field_from_custom_view_on_cards(pub, filter_value): + pub.role_class.wipe() + pub.custom_view_class.wipe() + + user = create_user(pub) + role = pub.role_class(name='xxx') + role.store() + user.roles = [role.id] + user.is_admin = True + user.store() + + formdef = create_formdef() + formdef.data_class().wipe() + + items = ['foo', 'bar', 'baz', 'buz'] + CardDef.wipe() + carddef = CardDef() + carddef.name = 'items' + carddef.digest_templates = {'default': '{{form_var_attr}} - {{form_var_item}}'} + carddef.workflow_roles = {'_editor': user.roles[0]} + carddef.fields = [ + fields.ItemsField(id='0', type='items', label='item', varname='item', items=items), + fields.StringField(id='1', type='string', label='string', varname='attr'), + ] + carddef.store() + carddef.data_class().wipe() + foo_bar_ids = set() + for i, (v1, v2) in enumerate([(v1, v2) for (v1, v2) in itertools.product(items, items) if v1 != v2]): + carddata = carddef.data_class()() + carddata.data = { + '0': [v1, v2], + '0_display': '%s,%s' % (v1, v2), + '1': 'attr%s' % i, + } + carddata.just_created() + carddata.store() + if {v1, v2} & {'foo', 'bar'}: + foo_bar_ids.add(str(carddata.id)) + + # create custom view + app = login(get_app(pub), username='foo', password='foo') + + # we must force the ordering to have a determinist test + resp = app.get('/backoffice/data/items/?order_by=id') + assert resp.text.count(' validation page + resp = resp.form.submit('submit') # -> submit + formdata = formdef.data_class().select()[0] + assert formdata.data['0'] in foo_bar_ids + assert formdata.data['0_structured']['text'] == 'attr0 - foo,bar' + + def test_item_field_with_disabled_items(http_requests, pub): create_user(pub) formdef = create_formdef() diff --git a/wcs/carddef.py b/wcs/carddef.py index e0f420281..d8da89cca 100644 --- a/wcs/carddef.py +++ b/wcs/carddef.py @@ -213,9 +213,28 @@ class CardDef(FormDef): order_by = custom_view.order_by criterias.extend(custom_view.get_criterias(formdef=carddef)) for criteria in criterias: - if not Template.is_template_string(criteria.value): - continue - criteria.value = WorkflowStatusItem.compute(criteria.value) + if Template.is_template_string(criteria.value): + criteria.value = WorkflowStatusItem.compute(criteria.value) + # case of items + elif ( + criteria.__class__.__name__ == 'Intersects' + and isinstance(criteria.value, list) + and len(criteria.value) == 1 + and isinstance(criteria.value[0], str) + ): + cvalue = criteria.value[0] + + if Template.is_template_string(cvalue): + publisher = get_publisher() + with publisher.complex_data(): + cvalue_evaluated = WorkflowStatusItem.compute(cvalue, allow_complex=True) + cvalue = publisher.get_cached_complex_data(cvalue_evaluated) + if isinstance(cvalue, list): + pass + elif ',' in cvalue: + cvalue = [v.strip() for v in cvalue.split(',')] + criteria.value = [item.strip() for item in cvalue] + if custom_view: view_digest_key = 'custom-view:%s' % custom_view.get_url_slug() if view_digest_key in (carddef.digest_templates or {}): -- 2.34.1