Add an appversions list endpoint (#20067)

This commit is contained in:
Andrew Williamson 2022-12-08 16:44:04 +00:00 коммит произвёл GitHub
Родитель c3651cea17
Коммит e6eda91e40
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
9 изменённых файлов: 125 добавлений и 36 удалений

Просмотреть файл

@ -241,8 +241,7 @@ This endpoint allows you to fetch a specific add-on by id, slug or guid.
============== ==========================================================
.. note::
For possible version values per application, see
`valid application versions`_.
See the :ref:`supported versions <applications-version-list>`.
.. _addon-detail-type:
@ -509,8 +508,8 @@ This endpoint allows you to fetch a single version belonging to a specific add-o
:>json string channel: The version channel, which determines its visibility on the site. Can be either ``unlisted`` or ``listed``.
:>json object compatibility:
Object detailing which :ref:`applications <addon-detail-application>` the version is compatible with.
The exact min/max version numbers in the object correspond to
`valid application versions`_. Example:
The exact min/max version numbers in the object correspond to the :ref:`supported versions<applications-version-list>`.
Example:
.. code-block:: json
@ -888,8 +887,6 @@ on AMO.
:>json string results[].type: The :ref:`add-on type <addon-detail-type>`.
:>json string results[].url: The (absolute) add-on detail URL.
.. _`valid application versions`: https://addons.mozilla.org/en-US/firefox/pages/appversions/
-------------------
Replacement Add-ons

Просмотреть файл

@ -1,19 +1,39 @@
============
Applications
============
---------------------
=====================
Applications Versions
---------------------
=====================
.. _applications-version:
.. note::
These APIs are not frozen and can change at any time without warning.
See :ref:`the API versions available<api-versions-list>` for alternatives
if you need stability.
----
List
----
.. _applications-version-list:
This endpoint allows you to list all versions that AMO currently supports for a given application.
.. http:get:: /api/v5/applications/(string:application)/
:param application: The :ref:`application <addon-detail-application>`,
:>json string guid: The GUID for the requested application.
:>json array versions: An array of all the supported version strings.
------
Create
------
.. _applications-version-create:
This internal endpoint allows you to create applications versions to be
referenced in add-ons manifests. It requires :ref:`authentication<api-auth>`
and a special permission.
The currently available applications versions are listed on a dedicated page:
https://addons.mozilla.org/en-US/firefox/pages/appversions/
The currently available applications versions are :ref:`available to list<applications-version-list>`.
When a valid request is made to this endpoint, AMO will create the requested
version if it didn't exist, and also attempt to create a corresponding minimum

Просмотреть файл

@ -445,6 +445,7 @@ These are `v5` specific changes - `v4` changes apply also.
* 2022-06-02: enabled setting ``default_locale`` via addon submission and edit endpoints. https://github.com/mozilla/addons-server/issues/18235
* 2022-06-16: added the ability to "PUT" an add-on upload to either create or update an add-on. https://github.com/mozilla/addons-server/issues/15353
* 2022-08-25: added ``approval_notes`` for version create or edit, and exposed via the version detail response for authorized developers of the add-on and reviewers. https://github.com/mozilla/addons-server/issues/19554
* 2023-01-05: added ``applications/<application>/`` API endpoint to list all valid appversions for a given application. https://github.com/mozilla/addons-server/issues/20066
.. _`#11380`: https://github.com/mozilla/addons-server/issues/11380/
.. _`#11379`: https://github.com/mozilla/addons-server/issues/11379/

Просмотреть файл

@ -242,8 +242,7 @@ This endpoint allows you to fetch a specific add-on by id, slug or guid.
============== ==========================================================
.. note::
For possible version values per application, see
`valid application versions`_.
See the :ref:`supported versions <applications-version-list>`.
.. _v3-addon-detail-platform:
@ -349,8 +348,8 @@ This endpoint allows you to fetch a single version belonging to a specific add-o
:>json string channel: The version channel, which determines its visibility on the site. Can be either ``unlisted`` or ``listed``.
:>json object compatibility:
Object detailing which :ref:`applications <v3-addon-detail-application>` the version is compatible with.
The exact min/max version numbers in the object correspond to
`valid application versions`_. Example:
The exact min/max version numbers in the object correspond to the :ref:`supported versions<applications-version-list>`.
Example:
.. code-block:: json
@ -450,8 +449,6 @@ on AMO.
:>json string results[].type: The :ref:`add-on type <v3-addon-detail-type>`.
:>json string results[].url: The (absolute) add-on detail URL.
.. _`valid application versions`: https://addons.mozilla.org/en-US/firefox/pages/appversions/
-------------------
Replacement Add-ons
@ -502,7 +499,7 @@ Compatibilty overrides are used within Firefox i(and other toolkit applications
:>json int results[].version_ranges[].applications[].id: Application id on AMO.
:>json string results[].version_ranges[].applications[].min_version: minimum version of the application to be disabled in.
:>json string results[].version_ranges[].applications[].max_version: maximum version of the application to be disabled in.
:>json string results[].version_ranges[].applications[].guid: Application `guid <https://addons.mozilla.org/en-US/firefox/pages/appversions/>`_.
:>json string results[].version_ranges[].applications[].guid: Application :ref:`guid<applications-version-list>`.
---------------

Просмотреть файл

@ -222,8 +222,7 @@ This endpoint allows you to fetch a specific add-on by id, slug or guid.
============== ==========================================================
.. note::
For possible version values per application, see
`valid application versions`_.
See the :ref:`supported versions <applications-version-list>`.
.. _v4-addon-detail-platform:
@ -350,8 +349,8 @@ This endpoint allows you to fetch a single version belonging to a specific add-o
:>json string channel: The version channel, which determines its visibility on the site. Can be either ``unlisted`` or ``listed``.
:>json object compatibility:
Object detailing which :ref:`applications <v4-addon-detail-application>` the version is compatible with.
The exact min/max version numbers in the object correspond to
`valid application versions`_. Example:
The exact min/max version numbers in the object correspond to the :ref:`supported versions<applications-version-list>`.
Example:
.. code-block:: json
@ -453,8 +452,6 @@ on AMO.
:>json string results[].type: The :ref:`v4-add-on type <addon-detail-type>`.
:>json string results[].url: The (absolute) add-on detail URL.
.. _`valid application versions`: https://addons.mozilla.org/en-US/firefox/pages/appversions/
-------------------
Replacement Add-ons

Просмотреть файл

@ -12,8 +12,7 @@ This internal endpoint allows you to create applications versions to be
referenced in add-ons manifests. It requires :ref:`v4-authentication<api-auth>`
and a special permission.
The currently available applications versions are listed on a dedicated page:
https://addons.mozilla.org/en-US/firefox/pages/appversions/
The currently available applications versions are :ref:`available to list<applications-version-list>`.
When a valid request is made to this endpoint, AMO will create the requested
version if it didn't exist, and also attempt to create a corresponding minimum

Просмотреть файл

@ -4,6 +4,7 @@ from .views import AppVersionView
urlpatterns = [
path('<str:application>/', AppVersionView.as_view(), name='appversions-list'),
path(
'<str:application>/<str:version>/', AppVersionView.as_view(), name='appversions'
),

Просмотреть файл

@ -5,7 +5,7 @@ from unittest import mock
from olympia import amo
from olympia.amo.templatetags.jinja_helpers import url
from olympia.amo.tests import reverse_ns, TestCase
from olympia.amo.tests import APITestClientSessionID, reverse_ns, TestCase
from olympia.api.tests.utils import APIKeyAuthTestMixin
from olympia.applications.models import AppVersion
@ -29,7 +29,55 @@ class TestViews(TestCase):
assert self.client.get(url('apps.appversions.rss')).status_code == 200
class TestAppVersionsAPI(APIKeyAuthTestMixin, TestCase):
class TestAppVersionsAPIGet(TestCase):
client_class = APITestClientSessionID
def setUp(self):
self.url = reverse_ns('appversions-list', kwargs={'application': 'firefox'})
def test_invalid_application_argument(self):
url = reverse_ns('appversions-list', kwargs={'application': 'unknown'})
response = self.client.get(url)
assert response.status_code == 400
def test_appversions_api_wrong_verb(self):
# We could need other verbs in the future, but those are not
# implemented for the moment.
response = self.client.post(self.url)
assert response.status_code == 405
response = self.client.put(self.url)
assert response.status_code == 401
response = self.client.head(self.url)
assert response.status_code == 405
response = self.client.delete(self.url)
assert response.status_code == 405
def test_response(self):
AppVersion.objects.create(application=amo.FIREFOX.id, version='123')
AppVersion.objects.create(application=amo.FIREFOX.id, version='123.0')
AppVersion.objects.create(application=amo.FIREFOX.id, version='123.*')
# Android appversions shouldn't be included in a /firefox/ request
AppVersion.objects.create(application=amo.ANDROID.id, version='123.1')
response = self.client.get(self.url)
assert response.data == {
'guid': amo.FIREFOX.guid,
'versions': [
# Ordered by the version, not by the creation date
'123',
'123.0',
'123.*',
],
}
assert response.status_code == 200
# cached for an hour
assert response['cache-control'] == 'max-age=3600'
class TestAppVersionsAPIPut(APIKeyAuthTestMixin, TestCase):
def setUp(self):
self.url = reverse_ns(
'appversions', kwargs={'application': 'firefox', 'version': '42.0'}
@ -56,7 +104,7 @@ class TestAppVersionsAPI(APIKeyAuthTestMixin, TestCase):
assert response.status_code == 405
response = self.get(self.url)
assert response.status_code == 405
assert response.status_code == 200
response = self.head(self.url)
assert response.status_code == 405

Просмотреть файл

@ -1,18 +1,20 @@
from django.core.cache import cache
from django.db.transaction import non_atomic_requests
from django.template.response import TemplateResponse
from django.utils.cache import patch_cache_control
from django.utils.translation import gettext
from rest_framework.exceptions import ParseError
from rest_framework.response import Response
from rest_framework.views import APIView
from rest_framework.permissions import AllowAny
from rest_framework.status import HTTP_201_CREATED, HTTP_202_ACCEPTED
from rest_framework.views import APIView
from olympia import amo
from olympia.api.authentication import JWTKeyAuthentication
from olympia.amo.feeds import BaseFeed
from olympia.amo.templatetags.jinja_helpers import absolutify, url
from olympia.api.permissions import GroupPermission
from olympia.api.permissions import ByHttpMethod, GroupPermission
from olympia.versions.compare import version_dict, version_re
from .models import AppVersion
@ -77,7 +79,34 @@ class AppversionsFeed(BaseFeed):
class AppVersionView(APIView):
authentication_classes = [JWTKeyAuthentication]
permission_classes = [GroupPermission(amo.permissions.APPVERSIONS_CREATE)]
permission_classes = []
permission_classes = [
ByHttpMethod(
{
'get': AllowAny,
'options': AllowAny, # Needed for CORS.
'put': GroupPermission(amo.permissions.APPVERSIONS_CREATE),
}
),
]
def get(self, request, *args, **kwargs):
application = amo.APPS.get(kwargs.get('application'))
if not application:
raise ParseError('Invalid application parameter')
versions = (
AppVersion.objects.filter(application=application.id)
.order_by('version_int')
.values_list('version', flat=True)
)
response = Response(
{
'guid': application.guid,
'versions': list(versions),
}
)
patch_cache_control(response, max_age=60 * 60)
return response
def put(self, request, *args, **kwargs):
# For each request, we'll try to create up to 3 versions for each app,