From 3b0fa7030e88289c72b80fd54c1cb5f692346a99 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lubom=C3=ADr=20Sedl=C3=A1=C5=99?= Date: Fri, 4 Sep 2015 11:25:04 +0200 Subject: [PATCH] Fix RPM epoch filter to not crash on non-numeric values This patch also fixes the documentation to properly show the value should be an int. JIRA: PDC-997 --- pdc/apps/common/filters.py | 17 +++++++++++++++++ pdc/apps/common/renderers.py | 1 + pdc/apps/package/filters.py | 4 ++-- pdc/apps/package/tests.py | 5 +++++ 4 files changed, 25 insertions(+), 2 deletions(-) diff --git a/pdc/apps/common/filters.py b/pdc/apps/common/filters.py index a758871e..01b9acfe 100644 --- a/pdc/apps/common/filters.py +++ b/pdc/apps/common/filters.py @@ -16,6 +16,7 @@ import django_filters import django.forms.widgets as widgets from .models import Label, SigKey +from .hacks import convert_str_to_int SelectMultiple = widgets.SelectMultiple @@ -49,6 +50,22 @@ def filter(self, qs, value): return qs +class MultiIntFilter(MultiValueFilter): + """ + MultiValueFilter that reports error when input is not a number. + """ + @value_is_not_empty + def filter(self, qs, value): + # This can't actually call to parent method, as double invocation of + # @value_is_not_empty would cause the filter with empty value to be + # ignored. + value = [convert_str_to_int(val, name=self.name) for val in value] + qs = qs.filter(**{self.name + '__in': value}) + if self.distinct: + qs = qs.distinct() + return qs + + class ComposeFilterSetOptions(FilterSetOptions): def __init__(self, options=None): # HACK NOTE: diff --git a/pdc/apps/common/renderers.py b/pdc/apps/common/renderers.py index 8f0ea13a..25eede7a 100644 --- a/pdc/apps/common/renderers.py +++ b/pdc/apps/common/renderers.py @@ -176,6 +176,7 @@ def replace_url(match): 'NullableCharFilter': 'string | null', 'BooleanFilter': 'bool', 'ActiveReleasesFilter': 'bool', + 'MultiIntFilter': 'int', } LOOKUP_TYPES = { 'icontains': 'case insensitive, substring match', diff --git a/pdc/apps/package/filters.py b/pdc/apps/package/filters.py index fd1e8513..0afa663d 100644 --- a/pdc/apps/package/filters.py +++ b/pdc/apps/package/filters.py @@ -8,14 +8,14 @@ import django_filters -from pdc.apps.common.filters import MultiValueFilter, NullableCharFilter +from pdc.apps.common.filters import MultiValueFilter, MultiIntFilter, NullableCharFilter from . import models class RPMFilter(django_filters.FilterSet): name = MultiValueFilter() version = MultiValueFilter() - epoch = MultiValueFilter() + epoch = MultiIntFilter() release = MultiValueFilter() arch = MultiValueFilter() srpm_name = MultiValueFilter() diff --git a/pdc/apps/package/tests.py b/pdc/apps/package/tests.py index cb95053a..b8453865 100644 --- a/pdc/apps/package/tests.py +++ b/pdc/apps/package/tests.py @@ -154,6 +154,11 @@ def test_query_with_wrong_params(self): response = self.client.get(url + 'wrong_param/', format='json') self.assertEqual(response.status_code, status.HTTP_404_NOT_FOUND) + def test_query_with_bad_epoch(self): + url = reverse('rpms-list') + response = self.client.get(url, {'epoch': 'foo'}, format='json') + self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST) + def test_query_with_only_key(self): url = reverse('rpms-list') response = self.client.get(url + '?name', format='json')