Remove support for filtering by `platform` in the search/autocomplete API (#16611)
* Remove support for filtering by `platform` in the search/autocomplete API Also add a migration to ensure all Files have platform=all set now that versions no longer have multiple files in our database. * Remove obsolete test
This commit is contained in:
Родитель
2a68f62012
Коммит
11f4549f2b
|
@ -32,7 +32,6 @@ This endpoint allows you to search through public add-ons.
|
|||
:query string lang: Activate translations in the specific language for that query. (See :ref:`translated fields <api-overview-translations>`)
|
||||
:query int page: 1-based page number. Defaults to 1.
|
||||
:query int page_size: Maximum number of results to return for the requested page. Defaults to 25.
|
||||
:query string platform: Filter by :ref:`add-on platform <addon-detail-platform>` availability.
|
||||
:query string promoted: Filter to add-ons in a specific :ref:`promoted category <addon-detail-promoted-category>`. Can be combined with `app`. Multiple promoted categories can be specified, separated by comma(s), in which case any add-ons in any of the promotions will be returned.
|
||||
:query string tag: Filter by exact tag name. Multiple tag names can be specified, separated by comma(s), in which case add-ons containing *all* specified tags are returned.
|
||||
:query string type: Filter by :ref:`add-on type <addon-detail-type>`. Multiple types can be specified, separated by comma(s), in which case add-ons that are any of the matching types are returned.
|
||||
|
@ -102,7 +101,6 @@ for autocomplete though, there are a couple key differences:
|
|||
:query string author: Filter by exact (listed) author username. Multiple author names can be specified, separated by comma(s), in which case add-ons with at least one matching author are returned.
|
||||
:query string category: Filter by :ref:`category slug <category-list>`. ``app`` and ``type`` parameters need to be set, otherwise this parameter is ignored.
|
||||
:query string lang: Activate translations in the specific language for that query. (See :ref:`translated fields <api-overview-translations>`)
|
||||
:query string platform: Filter by :ref:`add-on platform <addon-detail-platform>` availability.
|
||||
:query string tag: Filter by exact tag name. Multiple tag names can be specified, separated by comma(s).
|
||||
:query string type: Filter by :ref:`add-on type <addon-detail-type>`.
|
||||
:>json array results: An array of :ref:`add-ons <addon-detail-object>`. Only the ``id``, ``icon_url``, ``name``, ``promoted``, ``type`` and ``url`` fields are supported though.
|
||||
|
@ -389,7 +387,7 @@ This endpoint allows you to fetch a single version belonging to a specific add-o
|
|||
:>json boolean files[].is_webextension: Whether the file is a WebExtension or not.
|
||||
:>json array files[].optional_permissions[]: Array of the optional webextension permissions for this File, as strings. Empty for non-webextensions.
|
||||
:>json array files[].permissions[]: Array of the webextension permissions for this File, as strings. Empty for non-webextensions.
|
||||
:>json string files[].platform: The :ref:`platform <addon-detail-platform>` for a file.
|
||||
:>json string files[].platform: The :ref:`platform <addon-detail-platform>` for a file (obsolete, will be removed soon: all add-ons should have their ``platform`` set to ``all`` already).
|
||||
:>json int files[].size: The size for a file, in bytes.
|
||||
:>json int files[].status: The :ref:`status <addon-detail-status>` for a file.
|
||||
:>json string files[].url: The (absolute) URL to download a file.
|
||||
|
|
|
@ -390,6 +390,7 @@ v4 API changelog
|
|||
* 2020-11-05: added endpoint to receive Stripe events. https://github.com/mozilla/addons-server/issues/15879
|
||||
* 2021-01-14: as addons-frontend now uses /v5/, v5 becomes the stable default; v4 becomes frozen; v3 is deprecated
|
||||
* 2021-02-12: added ``versions_url`` to addon detail endpoint. https://github.com/mozilla/addons-server/issues/16534
|
||||
* 2021-02-25: ``platform`` filtering was remoed from add-on search and autocomplete endpoints. https://github.com/mozilla/addons-server/issues/16463
|
||||
|
||||
----------------
|
||||
v5 API changelog
|
||||
|
@ -414,6 +415,7 @@ These are `v5` specific changes - `v4` changes apply also.
|
|||
* 2021-02-11: added ``show_grouped_ratings`` to addon detail endpoint. https://github.com/mozilla/addons-server/issues/16459
|
||||
* 2021-02-18: made ``description``, ``headline``, and ``cta.text`` in shelves/hero endpoint translated fields in the response. (They were always localized, we just didn't return them as such). https://github.com/mozilla/addons-server/issues/16515
|
||||
* 2021-02-18: added ``versions_url`` to addon detail endpoint. https://github.com/mozilla/addons-server/issues/16534
|
||||
* 2021-02-25: ``platform`` filtering was remoed from add-on search and autocomplete endpoints. https://github.com/mozilla/addons-server/issues/16463
|
||||
|
||||
.. _`#11380`: https://github.com/mozilla/addons-server/issues/11380/
|
||||
.. _`#11379`: https://github.com/mozilla/addons-server/issues/11379/
|
||||
|
|
|
@ -32,7 +32,6 @@ This endpoint allows you to search through public add-ons.
|
|||
:query string lang: Activate translations in the specific language for that query. (See :ref:`translated fields <v4-api-overview-translations>`)
|
||||
:query int page: 1-based page number. Defaults to 1.
|
||||
:query int page_size: Maximum number of results to return for the requested page. Defaults to 25.
|
||||
:query string platform: Filter by :ref:`add-on platform <v4-addon-detail-platform>` availability.
|
||||
:query string promoted: Filter to add-ons in a specific :ref:`promoted category <v4-addon-detail-promoted-category>`. Can be combined with `app`. Multiple promoted categories can be specified, separated by comma(s), in which case any add-ons in any of the promotions will be returned.
|
||||
:query string tag: Filter by exact tag name. Multiple tag names can be specified, separated by comma(s), in which case add-ons containing *all* specified tags are returned.
|
||||
:query string type: Filter by :ref:`add-on type <v4-addon-detail-type>`. Multiple types can be specified, separated by comma(s), in which case add-ons that are any of the matching types are returned.
|
||||
|
@ -102,7 +101,6 @@ for autocomplete though, there are a couple key differences:
|
|||
:query string author: Filter by exact (listed) author username. Multiple author names can be specified, separated by comma(s), in which case add-ons with at least one matching author are returned.
|
||||
:query string category: Filter by :ref:`category slug <v4-category-list>`. ``app`` and ``type`` parameters need to be set, otherwise this parameter is ignored.
|
||||
:query string lang: Activate translations in the specific language for that query. (See :ref:`translated fields <v4-api-overview-translations>`)
|
||||
:query string platform: Filter by :ref:`add-on platform <v4-addon-detail-platform>` availability.
|
||||
:query string tag: Filter by exact tag name. Multiple tag names can be specified, separated by comma(s).
|
||||
:query string type: Filter by :ref:`add-on type <v4-addon-detail-type>`.
|
||||
:>json array results: An array of :ref:`add-ons <v4-addon-detail-object>`. Only the ``id``, ``icon_url``, ``name``, ``promoted``, ``type`` and ``url`` fields are supported though.
|
||||
|
|
|
@ -1502,34 +1502,6 @@ class TestAddonSearchView(ESTestCase):
|
|||
assert len(data['results']) == 1
|
||||
assert data['results'][0]['id'] == addon.pk
|
||||
|
||||
def test_filter_by_platform(self):
|
||||
# First add-on is available for all platforms.
|
||||
addon = addon_factory(slug='my-addon', name='My Addôn', popularity=33)
|
||||
addon_factory(
|
||||
slug='my-linux-addon',
|
||||
name='My linux-only Addön',
|
||||
file_kw={'platform': amo.PLATFORM_LINUX.id},
|
||||
popularity=22,
|
||||
)
|
||||
mac_addon = addon_factory(
|
||||
slug='my-mac-addon',
|
||||
name='My mac-only Addön',
|
||||
file_kw={'platform': amo.PLATFORM_MAC.id},
|
||||
popularity=11,
|
||||
)
|
||||
self.refresh()
|
||||
|
||||
data = self.perform_search(self.url)
|
||||
assert data['count'] == 3
|
||||
assert len(data['results']) == 3
|
||||
assert data['results'][0]['id'] == addon.pk
|
||||
|
||||
data = self.perform_search(self.url, {'platform': 'mac'})
|
||||
assert data['count'] == 2
|
||||
assert len(data['results']) == 2
|
||||
assert data['results'][0]['id'] == addon.pk
|
||||
assert data['results'][1]['id'] == mac_addon.pk
|
||||
|
||||
def test_filter_by_app(self):
|
||||
addon = addon_factory(
|
||||
slug='my-addon',
|
||||
|
|
|
@ -0,0 +1,25 @@
|
|||
# Generated by Django 2.2.18 on 2021-02-23 12:15
|
||||
|
||||
from django.db import migrations
|
||||
|
||||
from olympia.constants.platforms import PLATFORM_ALL
|
||||
|
||||
|
||||
def set_all_files_platform_to_all(apps, schema_editor):
|
||||
File = apps.get_model('files', 'File')
|
||||
# At this point we should no longer have more than one File per Version.
|
||||
# We already set platform=ALL on Files on Versions that did have duplicate
|
||||
# Files, and we've been setting it for new Files for a while now as well,
|
||||
# now we need to do it for all the rest of them.
|
||||
File.objects.exclude(platform=PLATFORM_ALL.id).update(platform=PLATFORM_ALL.id)
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('files', '0005_auto_20201120_0926'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.RunPython(set_all_files_platform_to_all)
|
||||
]
|
|
@ -228,27 +228,6 @@ class AddonGuidQueryParam(AddonQueryMultiParam):
|
|||
return isinstance(value, str)
|
||||
|
||||
|
||||
class AddonPlatformQueryParam(AddonQueryParam):
|
||||
query_param = 'platform'
|
||||
reverse_dict = amo.PLATFORM_DICT
|
||||
valid_values = amo.PLATFORMS
|
||||
es_field = 'platforms'
|
||||
operator = 'terms' # Because we'll be sending a list every time.
|
||||
|
||||
def get_value(self):
|
||||
value = super(AddonPlatformQueryParam, self).get_value()
|
||||
# No matter what platform the client wants to see, we always need to
|
||||
# include PLATFORM_ALL to match add-ons compatible with all platforms.
|
||||
if value != amo.PLATFORM_ALL.id:
|
||||
value = [value, amo.PLATFORM_ALL.id]
|
||||
else:
|
||||
value = [value]
|
||||
return value
|
||||
|
||||
def get_value_from_reverse_dict(self):
|
||||
return self.get_value_from_object_from_reverse_dict()
|
||||
|
||||
|
||||
class AddonTypeQueryParam(AddonQueryMultiParam):
|
||||
query_param = 'type'
|
||||
reverse_dict = amo.ADDON_SEARCH_SLUGS
|
||||
|
@ -854,7 +833,8 @@ class SearchParameterFilter(BaseFilterBackend):
|
|||
"""
|
||||
A django-rest-framework filter backend for ES queries that look for items
|
||||
matching a specific set of params in request.GET: app, appversion,
|
||||
author, category, exclude_addons, platform, tag and type.
|
||||
author, category, exclude_addons, featured, guid, promoted, tag, type,
|
||||
color...
|
||||
"""
|
||||
|
||||
available_clauses = [
|
||||
|
@ -865,7 +845,6 @@ class SearchParameterFilter(BaseFilterBackend):
|
|||
AddonExcludeAddonsQueryParam,
|
||||
AddonFeaturedQueryParam,
|
||||
AddonGuidQueryParam,
|
||||
AddonPlatformQueryParam,
|
||||
AddonPromotedQueryParam,
|
||||
AddonTagQueryParam,
|
||||
AddonTypeQueryParam,
|
||||
|
|
|
@ -704,80 +704,6 @@ class TestSearchParameterFilter(FilterTestsBase):
|
|||
'range': {'current_version.compatible_apps.1.max': {'gte': 46000000000100}}
|
||||
} in filter_
|
||||
|
||||
def test_search_by_platform_invalid(self):
|
||||
with self.assertRaises(serializers.ValidationError) as context:
|
||||
self._filter(data={'platform': str(amo.PLATFORM_WIN.id + 42)})
|
||||
|
||||
with self.assertRaises(serializers.ValidationError) as context:
|
||||
self._filter(data={'platform': 'nosuchplatform'})
|
||||
assert context.exception.detail == ['Invalid "platform" parameter.']
|
||||
|
||||
def test_search_by_platform_id(self):
|
||||
qs = self._filter(data={'platform': str(amo.PLATFORM_WIN.id)})
|
||||
assert 'must' not in qs['query']['bool']
|
||||
assert 'must_not' not in qs['query']['bool']
|
||||
filter_ = qs['query']['bool']['filter']
|
||||
assert {
|
||||
'terms': {'platforms': [amo.PLATFORM_WIN.id, amo.PLATFORM_ALL.id]}
|
||||
} in filter_
|
||||
|
||||
qs = self._filter(data={'platform': str(amo.PLATFORM_LINUX.id)})
|
||||
assert 'must' not in qs['query']['bool']
|
||||
assert 'must_not' not in qs['query']['bool']
|
||||
filter_ = qs['query']['bool']['filter']
|
||||
assert {
|
||||
'terms': {'platforms': [amo.PLATFORM_LINUX.id, amo.PLATFORM_ALL.id]}
|
||||
} in filter_
|
||||
|
||||
def test_search_by_platform_string(self):
|
||||
qs = self._filter(data={'platform': 'windows'})
|
||||
assert 'must' not in qs['query']['bool']
|
||||
assert 'must_not' not in qs['query']['bool']
|
||||
filter_ = qs['query']['bool']['filter']
|
||||
assert {
|
||||
'terms': {'platforms': [amo.PLATFORM_WIN.id, amo.PLATFORM_ALL.id]}
|
||||
} in filter_
|
||||
|
||||
qs = self._filter(data={'platform': 'win'})
|
||||
assert 'must' not in qs['query']['bool']
|
||||
assert 'must_not' not in qs['query']['bool']
|
||||
filter_ = qs['query']['bool']['filter']
|
||||
assert {
|
||||
'terms': {'platforms': [amo.PLATFORM_WIN.id, amo.PLATFORM_ALL.id]}
|
||||
} in filter_
|
||||
|
||||
qs = self._filter(data={'platform': 'darwin'})
|
||||
assert 'must' not in qs['query']['bool']
|
||||
assert 'must_not' not in qs['query']['bool']
|
||||
filter_ = qs['query']['bool']['filter']
|
||||
assert {
|
||||
'terms': {'platforms': [amo.PLATFORM_MAC.id, amo.PLATFORM_ALL.id]}
|
||||
} in filter_
|
||||
|
||||
qs = self._filter(data={'platform': 'mac'})
|
||||
assert 'must' not in qs['query']['bool']
|
||||
assert 'must_not' not in qs['query']['bool']
|
||||
filter_ = qs['query']['bool']['filter']
|
||||
assert {
|
||||
'terms': {'platforms': [amo.PLATFORM_MAC.id, amo.PLATFORM_ALL.id]}
|
||||
} in filter_
|
||||
|
||||
qs = self._filter(data={'platform': 'macosx'})
|
||||
assert 'must' not in qs['query']['bool']
|
||||
assert 'must_not' not in qs['query']['bool']
|
||||
filter_ = qs['query']['bool']['filter']
|
||||
assert {
|
||||
'terms': {'platforms': [amo.PLATFORM_MAC.id, amo.PLATFORM_ALL.id]}
|
||||
} in filter_
|
||||
|
||||
qs = self._filter(data={'platform': 'linux'})
|
||||
assert 'must' not in qs['query']['bool']
|
||||
assert 'must_not' not in qs['query']['bool']
|
||||
filter_ = qs['query']['bool']['filter']
|
||||
assert {
|
||||
'terms': {'platforms': [amo.PLATFORM_LINUX.id, amo.PLATFORM_ALL.id]}
|
||||
} in filter_
|
||||
|
||||
def test_search_by_category_slug_no_app_or_type(self):
|
||||
with self.assertRaises(serializers.ValidationError) as context:
|
||||
self._filter(data={'category': 'other'})
|
||||
|
|
Загрузка…
Ссылка в новой задаче