diff --git a/publik_django_templatetags/publik/templatetags/publik.py b/publik_django_templatetags/publik/templatetags/publik.py index 07eaaf3..e853fca 100644 --- a/publik_django_templatetags/publik/templatetags/publik.py +++ b/publik_django_templatetags/publik/templatetags/publik.py @@ -51,7 +51,10 @@ def getlist(mapping, key): @register.filter(name='list') def as_list(obj): - return list(obj) + try: + return list(obj) + except TypeError: + return [] @register.filter diff --git a/publik_django_templatetags/wcs/templatetags/wcs.py b/publik_django_templatetags/wcs/templatetags/wcs.py index d8b1586..f7e277e 100644 --- a/publik_django_templatetags/wcs/templatetags/wcs.py +++ b/publik_django_templatetags/wcs/templatetags/wcs.py @@ -26,116 +26,183 @@ def objects(cards, slug): @register.filter def with_custom_view(queryset, custom_view_id): - return queryset.with_custom_view(custom_view_id) + try: + return queryset.with_custom_view(custom_view_id) + except AttributeError: + return None @register.filter def get_full(queryset): - return queryset.get_full() + try: + return queryset.get_full() + except AttributeError: + return None @register.filter def include_fields(queryset): - return queryset.include_fields() + try: + return queryset.include_fields() + except AttributeError: + return None @register.filter def include_evolution(queryset): - return queryset.include_evolution() + try: + return queryset.include_evolution() + except AttributeError: + return None @register.filter def include_roles(queryset): - return queryset.include_roles() + try: + return queryset.include_roles() + except AttributeError: + return None @register.filter def include_submission(queryset): - return queryset.include_submission() + try: + return queryset.include_submission() + except AttributeError: + return None @register.filter def include_workflow(queryset): - return queryset.include_workflow() + try: + return queryset.include_workflow() + except AttributeError: + return None @register.filter def include_workflow_data(queryset): - return queryset.include_workflow_data() + try: + return queryset.include_workflow_data() + except AttributeError: + return None @register.filter def access_control(queryset, user): - return queryset.access_control(user) + try: + return queryset.access_control(user) + except AttributeError: + return None @register.filter def count(queryset): - if queryset is None: + try: + return queryset.count + except AttributeError: return 0 - return queryset.count @register.filter def filter_by(queryset, attribute): - return queryset.filter_by(attribute) + try: + return queryset.filter_by(attribute) + except AttributeError: + return None @register.filter def filter_value(queryset, value): - return queryset.apply_filter_value(value) + try: + return queryset.apply_filter_value(value) + except AttributeError: + return None @register.filter def filter_by_internal_id(queryset, internal_id): - return queryset.filter_by_internal_id(internal_id) + try: + return queryset.filter_by_internal_id(internal_id) + except AttributeError: + return None @register.filter def filter_by_number(queryset, number): - return queryset.filter_by_number(number) + try: + return queryset.filter_by_number(number) + except AttributeError: + return None @register.filter def filter_by_user(queryset, user): - return queryset.filter_by_user(user) + try: + return queryset.filter_by_user(user) + except AttributeError: + return None @register.filter def filter_by_status(queryset, status): - return queryset.filter_by_status(status) + try: + return queryset.filter_by_status(status) + except AttributeError: + return None @register.filter(name='equal') def eq(queryset): - return queryset.apply_eq() + try: + return queryset.apply_eq() + except AttributeError: + return None @register.filter(name='not_equal') def ne(queryset): - return queryset.apply_ne() + try: + return queryset.apply_ne() + except AttributeError: + return None @register.filter(name='less_than') def lt(queryset): - return queryset.apply_lt() + try: + return queryset.apply_lt() + except AttributeError: + return None @register.filter(name='less_than_or_equal') def lte(queryset): - return queryset.apply_lte() + try: + return queryset.apply_lte() + except AttributeError: + return None @register.filter(name='greater_than') def gt(queryset): - return queryset.apply_gt() + try: + return queryset.apply_gt() + except AttributeError: + return None @register.filter(name='greater_than_or_equal') def gte(queryset): - return queryset.apply_gte() + try: + return queryset.apply_gte() + except AttributeError: + return None @register.filter def order_by(queryset, attribute): - return queryset.order_by(attribute) + try: + return queryset.order_by(attribute) + except AttributeError: + return None diff --git a/tests/test_wcs.py b/tests/test_wcs.py index fa8a0b7..f9d1fd4 100644 --- a/tests/test_wcs.py +++ b/tests/test_wcs.py @@ -134,6 +134,12 @@ def test_with_custom_view(mock_send, context, nocache): t.render(context) assert mock_send.call_args_list == [] # unknown, not evaluated + mock_send.reset_mock() + context['foobar'] = None + t = Template('{{ foobar|with_custom_view:"foobar"|list }}') + t.render(context) + assert mock_send.call_args_list == [] + @mock.patch('requests.Session.send', side_effect=mocked_requests_send) def test_full(mock_send, context, nocache): @@ -145,6 +151,12 @@ def test_full(mock_send, context, nocache): t.render(context) assert 'full=on&' in mock_send.call_args_list[0][0][0].url + mock_send.reset_mock() + context['foobar'] = None + t = Template('{{ foobar|get_full|list }}') + t.render(context) + assert mock_send.call_args_list == [] + @mock.patch('requests.Session.send', side_effect=mocked_requests_send) def test_include_filters(mock_send, context, nocache): @@ -159,6 +171,12 @@ def test_include_filters(mock_send, context, nocache): t.render(context) assert '%s=on&' % param in mock_send.call_args_list[0][0][0].url + mock_send.reset_mock() + context['foobar'] = None + t = Template('{{ foobar|%s|list }}' % _filter) + t.render(context) + assert mock_send.call_args_list == [] + @mock.patch('requests.Session.send', side_effect=mocked_requests_send) def test_errors(mock_send, context, nocache): @@ -243,6 +261,12 @@ def test_access_control(mock_send, context, nocache): assert 'NameID' not in mock_send.call_args_list[0][0][0].url assert 'email=foo%40example.net&' in mock_send.call_args_list[0][0][0].url + mock_send.reset_mock() + context['foobar'] = None + t = Template('{{ foobar|access_control:request.user|list }}') + t.render(context) + assert mock_send.call_args_list == [] + @mock.patch('requests.Session.send', side_effect=mocked_requests_send) def test_count(mock_send, context, nocache): @@ -294,6 +318,7 @@ def test_filter(mock_send, context, nocache): t.render(context) assert 'filter-foo=&' in mock_send.call_args_list[0][0][0].url + context['foobar'] = None for filter_op, api_op in OPERATORS: mock_send.reset_mock() t = Template('{{ cards|objects:"foo"|filter_by:"foo"|%s|filter_value:"bar"|list }}' % filter_op) @@ -301,6 +326,21 @@ def test_filter(mock_send, context, nocache): assert 'filter-foo=bar&' in mock_send.call_args_list[0][0][0].url assert 'filter-foo-operator=%s&' % api_op in mock_send.call_args_list[0][0][0].url + mock_send.reset_mock() + t = Template('{{ foobar|%s }}' % filter_op) + t.render(context) + assert mock_send.call_args_list == [] + + mock_send.reset_mock() + t = Template('{{ foobar|filter_by:"foo"|list }}') + t.render(context) + assert mock_send.call_args_list == [] + + mock_send.reset_mock() + t = Template('{{ foobar|filter_value:"foo"|list }}') + t.render(context) + assert mock_send.call_args_list == [] + @mock.patch('requests.Session.send', side_effect=mocked_requests_send) def test_filter_by_internal_id(mock_send, context, nocache): @@ -333,6 +373,12 @@ def test_filter_by_internal_id(mock_send, context, nocache): assert 'filter-internal-id=42&' in mock_send.call_args_list[0][0][0].url assert 'filter-internal-id-operator=%s&' % api_op in mock_send.call_args_list[0][0][0].url + mock_send.reset_mock() + context['foobar'] = None + t = Template('{{ foobar|filter_by_internal_id:"42"|list }}') + t.render(context) + assert mock_send.call_args_list == [] + @mock.patch('requests.Session.send', side_effect=mocked_requests_send) def test_filter_by_number(mock_send, context, nocache): @@ -364,6 +410,12 @@ def test_filter_by_number(mock_send, context, nocache): # not for this filter assert 'filter-number-operator=%s&' % api_op not in mock_send.call_args_list[0][0][0].url + mock_send.reset_mock() + context['foobar'] = None + t = Template('{{ foobar|filter_by_number:"42"|list }}') + t.render(context) + assert mock_send.call_args_list == [] + @mock.patch('requests.Session.send', side_effect=mocked_requests_send) def test_filter_by_user(mock_send, context, nocache): @@ -399,6 +451,12 @@ def test_filter_by_user(mock_send, context, nocache): # not for this filter assert 'filter-user-uuid-operator=%s&' % api_op not in mock_send.call_args_list[0][0][0].url + mock_send.reset_mock() + context['foobar'] = None + t = Template('{{ foobar|filter_by_user:request.user|list }}') + t.render(context) + assert mock_send.call_args_list == [] + @mock.patch('requests.Session.send', side_effect=mocked_requests_send) def test_filter_by_status(mock_send, context, nocache): @@ -436,6 +494,12 @@ def test_filter_by_status(mock_send, context, nocache): else: assert 'filter-operator=%s&' % api_op not in mock_send.call_args_list[0][0][0].url + mock_send.reset_mock() + context['foobar'] = None + t = Template('{{ foobar|filter_by_status:"foobar"|list }}') + t.render(context) + assert mock_send.call_args_list == [] + @mock.patch('requests.Session.send', side_effect=mocked_requests_send) def test_getlist(mock_send, context, nocache): @@ -489,3 +553,9 @@ def test_order_by(mock_send, context, nocache): t = Template('{% for v in cards|objects:"foo"|order_by:""|order_by:"bar" %}{{ v }},{% endfor %}') t.render(context) assert 'order_by=bar' in mock_send.call_args_list[0][0][0].url + + mock_send.reset_mock() + context['foobar'] = None + t = Template('{{ foobar|order_by:"foo" }}') + t.render(context) + assert mock_send.call_args_list == []