From d08b6c72964898c9997a62e4ab6a721f166a56ca Mon Sep 17 00:00:00 2001 From: Daniel Axtens Date: Tue, 14 Apr 2020 15:34:40 +1000 Subject: api: allow filtering patches and covers by msgid In the process of fixing the previous bug, I realised that: a) /api/patches/msgid is a perfectly reasonable thing to attempt b) We have no way of finding a patch by message id in the API We can't actualy make /api/patches/msgid work because it may not be unique, but we can add a filter. I'm shoehorning this into stable/2.2, even though it's technically an API change: it's minor, not incompatible and in hindsight a glaring hole. Cc: Michael Ellerman Tested-by: Jeremy Kerr Reviewed-by: Andrew Donnellan Reviewed-by: Stephen Finucane Signed-off-by: Daniel Axtens --- patchwork/api/filters.py | 14 ++++++++++---- patchwork/tests/api/test_cover.py | 12 ++++++++++++ patchwork/tests/api/test_patch.py | 12 ++++++++++++ 3 files changed, 34 insertions(+), 4 deletions(-) (limited to 'patchwork') diff --git a/patchwork/api/filters.py b/patchwork/api/filters.py index deb5ace..93e6281 100644 --- a/patchwork/api/filters.py +++ b/patchwork/api/filters.py @@ -184,6 +184,10 @@ class SeriesFilterSet(TimestampMixin, BaseFilterSet): fields = ('submitter', 'project') +def msgid_filter(queryset, name, value): + return queryset.filter(**{name: '<' + value + '>'}) + + class CoverLetterFilterSet(TimestampMixin, BaseFilterSet): project = ProjectFilter(queryset=Project.objects.all(), distinct=False) @@ -192,6 +196,7 @@ class CoverLetterFilterSet(TimestampMixin, BaseFilterSet): series = BaseFilter(queryset=Project.objects.all(), widget=MultipleHiddenInput, distinct=False) submitter = PersonFilter(queryset=Person.objects.all(), distinct=False) + msgid = CharFilter(method=msgid_filter) class Meta: model = CoverLetter @@ -210,17 +215,18 @@ class PatchFilterSet(TimestampMixin, BaseFilterSet): delegate = UserFilter(queryset=User.objects.all(), distinct=False) state = StateFilter(queryset=State.objects.all(), distinct=False) hash = CharFilter(lookup_expr='iexact') + msgid = CharFilter(method=msgid_filter) class Meta: model = Patch - # NOTE(dja): ideally we want to version the hash field, but I cannot - # find a way to do that which is reliable and not extremely ugly. + # NOTE(dja): ideally we want to version the hash/msgid field, but I + # can't find a way to do that which is reliable and not extremely ugly. # The best I can come up with is manually working with request.GET # which seems to rather defeat the point of using django-filters. fields = ('project', 'series', 'submitter', 'delegate', - 'state', 'archived', 'hash') + 'state', 'archived', 'hash', 'msgid') versioned_fields = { - '1.2': ('hash', ), + '1.2': ('hash', 'msgid'), } diff --git a/patchwork/tests/api/test_cover.py b/patchwork/tests/api/test_cover.py index 5eeb190..1b19ded 100644 --- a/patchwork/tests/api/test_cover.py +++ b/patchwork/tests/api/test_cover.py @@ -111,6 +111,18 @@ class TestCoverLetterAPI(utils.APITestCase): 'submitter': 'test@example.org'}) self.assertEqual(0, len(resp.data)) + def test_list_filter_msgid(self): + """Filter covers by msgid.""" + cover = create_cover() + + resp = self.client.get(self.api_url(), {'msgid': cover.url_msgid}) + self.assertEqual([cover.id], [x['id'] for x in resp.data]) + + # empty response if nothing matches + resp = self.client.get(self.api_url(), { + 'msgid': 'fishfish@fish.fish'}) + self.assertEqual(0, len(resp.data)) + @utils.store_samples('cover-list-1-0') def test_list_version_1_0(self): create_cover() diff --git a/patchwork/tests/api/test_patch.py b/patchwork/tests/api/test_patch.py index b24c5ab..da2dd6e 100644 --- a/patchwork/tests/api/test_patch.py +++ b/patchwork/tests/api/test_patch.py @@ -199,6 +199,18 @@ class TestPatchAPI(utils.APITestCase): {'hash': 'garbagevalue'}) self.assertEqual(1, len(resp.data)) + def test_list_filter_msgid(self): + """Filter patches by msgid.""" + patch = self._create_patch() + + resp = self.client.get(self.api_url(), {'msgid': patch.url_msgid}) + self.assertEqual([patch.id], [x['id'] for x in resp.data]) + + # empty response if nothing matches + resp = self.client.get(self.api_url(), { + 'msgid': 'fishfish@fish.fish'}) + self.assertEqual(0, len(resp.data)) + @utils.store_samples('patch-list-1-0') def test_list_version_1_0(self): """List patches using API v1.0.""" -- cgit v1.2.3