From 9a2a455d3e81e2c72e819e0647d475239b9ffa89 Mon Sep 17 00:00:00 2001 From: Gideon Thomas Date: Thu, 2 Aug 2018 14:55:32 -0400 Subject: [PATCH] Filter entries by the presence of help types (#393) Fix #392 --- README.md | 1 + pulseapi/entries/tests/test_staff_views.py | 26 ++++++++++++++++++++++ pulseapi/entries/views.py | 8 +++++++ pulseapi/helptypes/factory.py | 14 ++++++++++++ 4 files changed, 49 insertions(+) create mode 100644 pulseapi/helptypes/factory.py diff --git a/README.md b/README.md index fc8c31f..48b6dc1 100644 --- a/README.md +++ b/README.md @@ -239,6 +239,7 @@ The schema for the payload returned is: - `?tag=` - Filter entries by a specific tag - `?issue=` - Filter entries by an issue area - `?help_type=` - Filter entries by a specific help category +- `?has_help_types=` - Filter entries by whether they have help types or not. Note that `True` or `False` is case-sensitive. - `?featured=` - Filter featured or non-featured entries - `?ordering=` - Order entries by a certain property e.g. `?ordering=title`. Prepend the property with a hyphen to get entries in descending order, e.g. `?ordering=-title` - `?moderationstate=` - Filter entries by its moderation state. This filter will only be applied if the API call was made by an authenticated user with moderation permissions diff --git a/pulseapi/entries/tests/test_staff_views.py b/pulseapi/entries/tests/test_staff_views.py index 9f148a3..24d0ae0 100644 --- a/pulseapi/entries/tests/test_staff_views.py +++ b/pulseapi/entries/tests/test_staff_views.py @@ -10,6 +10,7 @@ from rest_framework.request import Request from pulseapi.creators.models import EntryCreator from pulseapi.profiles.models import UserProfile from pulseapi.entries.models import Entry, ModerationState +from pulseapi.helptypes.factory import HelpTypeFactory from pulseapi.entries.serializers import ( EntrySerializerWithV1Creators, EntrySerializerWithCreators, @@ -152,6 +153,31 @@ class TestEntryView(PulseStaffTestCase): ) self.assertEqual(postresponse.status_code, 200) + def test_no_help_type_filter(self): + """Test filtering entries that don't have a help type""" + counter = 0 + for entry in self.entries: + if counter % 2 == 0: + help_type = HelpTypeFactory() + entry.help_types.add(help_type) + else: + entry.help_types.clear() + counter += 1 + + entries_without_help_types = Entry.objects.filter(help_types__isnull=True).count() + entries_with_help_types = Entry.objects.filter(help_types__isnull=False).count() + + url = reverse('entries-list', args=[settings.API_VERSIONS['version_2'] + '/']) + response_1 = self.client.get('{url}?has_help_types=False'.format(url=url)) + response_entries_without_help_types = json.loads(str(response_1.content, 'utf-8')) + response_2 = self.client.get('{url}?has_help_types=True'.format( + url=reverse('entries-list', args=[settings.API_VERSIONS['version_2'] + '/']), + )) + response_entries_with_help_types = json.loads(str(response_2.content, 'utf-8')) + + self.assertEqual(response_entries_without_help_types['count'], entries_without_help_types) + self.assertEqual(response_entries_with_help_types['count'], entries_with_help_types) + def test_featured_filter(self): """Entry with all content""" diff --git a/pulseapi/entries/views.py b/pulseapi/entries/views.py index a76f511..b783543 100644 --- a/pulseapi/entries/views.py +++ b/pulseapi/entries/views.py @@ -167,6 +167,11 @@ class EntryCustomFilter(filters.FilterSet): name='help_types__name', lookup_expr='iexact', ) + has_help_types = django_filters.BooleanFilter( + name='help_types', + lookup_expr='isnull', + exclude=True, + ) featured = django_filters.BooleanFilter( name='featured' ) @@ -301,6 +306,9 @@ class EntriesListView(ListCreateAPIView): - `?tag=` - Allows filtering entries by a specific tag - `?issue=` - Allows filtering entries by a specific issue - `?help_type=` - Allows filtering entries by a specific help type + - `?has_help_types=` - Filter entries by whether they have + help types or not. Note that `True` + or `False` is case-sensitive. - `?featured=True` (or False) - both capitalied. Boolean is set in admin UI - `?page=` - Page number, defaults to 1 - `?page_size=` - Number of results on a page. Defaults to 48 diff --git a/pulseapi/helptypes/factory.py b/pulseapi/helptypes/factory.py new file mode 100644 index 0000000..6086768 --- /dev/null +++ b/pulseapi/helptypes/factory.py @@ -0,0 +1,14 @@ +""" +Create fake help types for local development, tests, and Heroku's review app. +""" + +from factory import DjangoModelFactory, Faker + +from pulseapi.helptypes.models import HelpType + + +class HelpTypeFactory(DjangoModelFactory): + name = Faker('job') + + class Meta: + model = HelpType