v4dev to v5; available on all confs now (#11331)
This commit is contained in:
Родитель
4303e11aae
Коммит
02fe0a4275
|
@ -178,14 +178,12 @@ If only a string is supplied, it will only be used to translate the field in
|
|||
the current language.
|
||||
|
||||
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
Alternate API (v4dev) behavior
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
^^^^^^^^^^^^^^^
|
||||
v5 API behavior
|
||||
^^^^^^^^^^^^^^^
|
||||
|
||||
On the addons-dev.allizom.org (dev) and addons.allizom.org servers (stage) servers
|
||||
an additional API version, `v4dev` is available. `v4dev` is not available on
|
||||
production AMO (addons.mozilla.org). In `4dev` the response if the ``lang``
|
||||
parameter is passed is an object only containing that translation is returned.
|
||||
In the experimental :ref:`v5 API <api-experimental-v5>` the response if the ``lang`` parameter is passed
|
||||
is an object only containing that translation is returned.
|
||||
|
||||
.. code-block:: json
|
||||
|
||||
|
@ -261,6 +259,17 @@ The downside of using the `v3` API is, of course, no new cool features!
|
|||
The documentation for `v3` can be accessed at: :ref:`v3-api-index`
|
||||
|
||||
|
||||
.. _api-experimental-v5:
|
||||
|
||||
----------------------------------------
|
||||
Extra-Experimental/Future-default v5 API
|
||||
----------------------------------------
|
||||
|
||||
The experimental `v5` API will eventually become the new default API when the
|
||||
current default, `v4`, is frozen and the stable `v3` deprecated. Any reference
|
||||
to v5 specific behavior/properties/endpoints will be explicit in these docs.
|
||||
|
||||
|
||||
----------------
|
||||
v4 API changelog
|
||||
----------------
|
||||
|
@ -293,7 +302,7 @@ v4 API changelog
|
|||
* 2018-11-22: added ``score`` parameter to the ratings API list endpoint.
|
||||
* 2019-01-10: added ``release_notes`` and ``license`` (except ``license.text``) to search API results ``current_version`` objects.
|
||||
* 2019-01-11: added new /reviewers/browse/ endpoint. https://github.com/mozilla/addons-server/issues/10322
|
||||
* 2019-01-16: removed /api/{v3,v4,v4dev}/github api entirely. They have been marked as experimental. https://github.com/mozilla/addons-server/issues/10411
|
||||
* 2019-01-16: removed /api/{v3,v4,v5}/github api entirely. They have been marked as experimental. https://github.com/mozilla/addons-server/issues/10411
|
||||
* 2019-04-11: removed ``id``, ``username`` and ``url`` from the ``user`` object in the activity review notes APIs. https://github.com/mozilla/addons-server/issues/11002
|
||||
* 2019-05-09: added ``is_recommended`` to addons API. https://github.com/mozilla/addons-server/issues/11278
|
||||
|
||||
* 2019-05-09: renamed the experimental `v4dev` api to `v5` (and updated references everywhere)
|
||||
|
|
|
@ -44,12 +44,12 @@ class TestStatus(TestCase):
|
|||
self.file = self.version.all_files[0]
|
||||
assert self.addon.status == amo.STATUS_APPROVED
|
||||
self.url = reverse_ns(
|
||||
'addon-detail', api_version='v4dev', kwargs={'pk': self.addon.pk})
|
||||
'addon-detail', api_version='v5', kwargs={'pk': self.addon.pk})
|
||||
|
||||
self.persona = Addon.objects.get(id=15663)
|
||||
assert self.persona.status == amo.STATUS_APPROVED
|
||||
self.persona_url = reverse_ns(
|
||||
'addon-detail', api_version='v4dev',
|
||||
'addon-detail', api_version='v5',
|
||||
kwargs={'pk': self.persona.pk})
|
||||
|
||||
def test_incomplete(self):
|
||||
|
@ -405,7 +405,7 @@ class TestAddonViewSetDetail(AddonAndVersionViewSetDetailMixin, TestCase):
|
|||
|
||||
def _set_tested_url(self, param):
|
||||
self.url = reverse_ns(
|
||||
'addon-detail', api_version='v4dev', kwargs={'pk': param})
|
||||
'addon-detail', api_version='v5', kwargs={'pk': param})
|
||||
|
||||
def test_detail_url_with_reviewers_in_the_url(self):
|
||||
self.addon.update(slug='something-reviewers')
|
||||
|
@ -480,7 +480,7 @@ class TestAddonViewSetDetail(AddonAndVersionViewSetDetailMixin, TestCase):
|
|||
assert result['name'] == {'en-US': u'My Addôn, mine'}
|
||||
|
||||
overridden_api_gates = {
|
||||
'v4dev': ('l10n_flat_input_output',)}
|
||||
'v5': ('l10n_flat_input_output',)}
|
||||
with override_settings(DRF_API_GATES=overridden_api_gates):
|
||||
response = self.client.get(self.url, {'lang': 'en-US'})
|
||||
assert response.status_code == 200
|
||||
|
@ -1826,7 +1826,7 @@ class TestAddonAutoCompleteSearchView(ESTestCase):
|
|||
|
||||
def setUp(self):
|
||||
super(TestAddonAutoCompleteSearchView, self).setUp()
|
||||
self.url = reverse_ns('addon-autocomplete', api_version='v4dev')
|
||||
self.url = reverse_ns('addon-autocomplete', api_version='v5')
|
||||
|
||||
def tearDown(self):
|
||||
super(TestAddonAutoCompleteSearchView, self).tearDown()
|
||||
|
@ -1895,7 +1895,7 @@ class TestAddonAutoCompleteSearchView(ESTestCase):
|
|||
|
||||
# And repeat with v3-style flat output when lang is specified:
|
||||
overridden_api_gates = {
|
||||
'v4dev': ('l10n_flat_input_output',)}
|
||||
'v5': ('l10n_flat_input_output',)}
|
||||
with override_settings(DRF_API_GATES=overridden_api_gates):
|
||||
data = self.perform_search(self.url, {'q': 'foobar', 'lang': 'fr'})
|
||||
assert data['results'][0]['name'] == 'foobar'
|
||||
|
|
|
@ -100,6 +100,13 @@ class TestRealAPIRouting(TestCase):
|
|||
assert response.status_code == 200
|
||||
assert response
|
||||
|
||||
def test_v5(self):
|
||||
url = reverse_ns('addon-detail', api_version='v5', args=('foo',))
|
||||
assert '/api/v5/' in url
|
||||
response = self.client.get(url, HTTP_ORIGIN='testserver')
|
||||
assert response.status_code == 200
|
||||
assert response
|
||||
|
||||
def test_default(self):
|
||||
url = reverse_ns('addon-detail', args=('foo',))
|
||||
assert '/api/%s/' % api_settings.DEFAULT_VERSION in url
|
||||
|
@ -107,7 +114,7 @@ class TestRealAPIRouting(TestCase):
|
|||
assert response.status_code == 200
|
||||
assert response
|
||||
|
||||
def test_v5(self):
|
||||
# There isn't a v5 API, so this should fail
|
||||
def test_v6(self):
|
||||
# There isn't a v6 API, so this should fail
|
||||
with self.assertRaises(NoReverseMatch):
|
||||
reverse_ns('addon-search', 'v5')
|
||||
reverse_ns('addon-search', 'v6')
|
||||
|
|
|
@ -28,5 +28,5 @@ v4_api_urls = [
|
|||
urlpatterns = [
|
||||
url(r'^v3/', include((v3_api_urls, 'v3'))),
|
||||
url(r'^v4/', include((v4_api_urls, 'v4'))),
|
||||
url(r'^v4dev/', include((v4_api_urls, 'v4dev'))),
|
||||
url(r'^v5/', include((v4_api_urls, 'v5'))),
|
||||
]
|
||||
|
|
|
@ -126,7 +126,7 @@ class TestCollectionViewSetDetail(TestCase):
|
|||
|
||||
def _get_url(self, user, collection):
|
||||
return reverse_ns(
|
||||
'collection-detail', api_version='v4dev', kwargs={
|
||||
'collection-detail', api_version='v5', kwargs={
|
||||
'user_pk': user.pk, 'slug': collection.slug})
|
||||
|
||||
def test_basic(self):
|
||||
|
@ -274,7 +274,7 @@ class TestCollectionViewSetDetail(TestCase):
|
|||
'en-US': get_outgoing_url(six.text_type(addon.support_url))}
|
||||
|
||||
overridden_api_gates = {
|
||||
'v4dev': ('l10n_flat_input_output',)}
|
||||
'v5': ('l10n_flat_input_output',)}
|
||||
with override_settings(DRF_API_GATES=overridden_api_gates):
|
||||
response = self.client.get(
|
||||
self.url + '?with_addons&lang=en-US&wrap_outgoing_links')
|
||||
|
@ -352,7 +352,7 @@ class CollectionViewSetDataMixin(object):
|
|||
'name': ['Name cannot be empty.']}
|
||||
|
||||
@override_settings(DRF_API_GATES={
|
||||
'v4dev': ('l10n_flat_input_output',)})
|
||||
'v5': ('l10n_flat_input_output',)})
|
||||
def test_update_name_invalid_flat_input(self):
|
||||
self.client.login_api(self.user)
|
||||
data = dict(self.data)
|
||||
|
@ -387,7 +387,7 @@ class CollectionViewSetDataMixin(object):
|
|||
'description': ['No links are allowed.']}
|
||||
|
||||
@override_settings(DRF_API_GATES={
|
||||
'v4dev': ('l10n_flat_input_output',)})
|
||||
'v5': ('l10n_flat_input_output',)})
|
||||
def test_biography_no_links_flat_input(self):
|
||||
self.client.login_api(self.user)
|
||||
data = dict(self.data)
|
||||
|
@ -485,7 +485,7 @@ class TestCollectionViewSetCreate(CollectionViewSetDataMixin, TestCase):
|
|||
|
||||
def get_url(self, user):
|
||||
return reverse_ns(
|
||||
'collection-list', api_version='v4dev',
|
||||
'collection-list', api_version='v5',
|
||||
kwargs={'user_pk': user.pk})
|
||||
|
||||
def test_basic_create(self):
|
||||
|
@ -520,7 +520,7 @@ class TestCollectionViewSetCreate(CollectionViewSetDataMixin, TestCase):
|
|||
'name': ['You must provide an object of {lang-code:value}.']}
|
||||
|
||||
@override_settings(DRF_API_GATES={
|
||||
'v4dev': ('l10n_flat_input_output',)})
|
||||
'v5': ('l10n_flat_input_output',)})
|
||||
def test_create_minimal_flat_input(self):
|
||||
self.client.login_api(self.user)
|
||||
data = {
|
||||
|
@ -592,7 +592,7 @@ class TestCollectionViewSetPatch(CollectionViewSetDataMixin, TestCase):
|
|||
|
||||
def get_url(self, user):
|
||||
return reverse_ns(
|
||||
'collection-detail', api_version='v4dev', kwargs={
|
||||
'collection-detail', api_version='v5', kwargs={
|
||||
'user_pk': user.pk, 'slug': self.collection.slug})
|
||||
|
||||
def test_basic_patch(self):
|
||||
|
@ -992,7 +992,7 @@ class TestCollectionAddonViewSetCreate(CollectionAddonViewSetMixin, TestCase):
|
|||
self.user = user_factory()
|
||||
self.collection = collection_factory(author=self.user)
|
||||
self.url = reverse_ns(
|
||||
'collection-addon-list', api_version='v4dev', kwargs={
|
||||
'collection-addon-list', api_version='v5', kwargs={
|
||||
'user_pk': self.user.pk,
|
||||
'collection_slug': self.collection.slug})
|
||||
self.addon = addon_factory()
|
||||
|
@ -1035,7 +1035,7 @@ class TestCollectionAddonViewSetCreate(CollectionAddonViewSetMixin, TestCase):
|
|||
'notes': ['You must provide an object of {lang-code:value}.']}
|
||||
|
||||
@override_settings(DRF_API_GATES={
|
||||
'v4dev': ('l10n_flat_input_output',)})
|
||||
'v5': ('l10n_flat_input_output',)})
|
||||
def test_add_with_comments_flat_input(self):
|
||||
self.client.login_api(self.user)
|
||||
response = self.send(self.url,
|
||||
|
@ -1098,7 +1098,7 @@ class TestCollectionAddonViewSetPatch(CollectionAddonViewSetMixin, TestCase):
|
|||
self.addon = addon_factory()
|
||||
self.collection.add_addon(self.addon)
|
||||
self.url = reverse_ns(
|
||||
'collection-addon-detail', api_version='v4dev', kwargs={
|
||||
'collection-addon-detail', api_version='v5', kwargs={
|
||||
'user_pk': self.user.pk,
|
||||
'collection_slug': self.collection.slug,
|
||||
'addon': self.addon.id})
|
||||
|
@ -1132,7 +1132,7 @@ class TestCollectionAddonViewSetPatch(CollectionAddonViewSetMixin, TestCase):
|
|||
'notes': ['You must provide an object of {lang-code:value}.']}
|
||||
# But with the correct api gate, we can use the old behavior
|
||||
overridden_api_gates = {
|
||||
'v4dev': ('l10n_flat_input_output',)}
|
||||
'v5': ('l10n_flat_input_output',)}
|
||||
with override_settings(DRF_API_GATES=overridden_api_gates):
|
||||
response = self.send(self.url, data)
|
||||
self.check_response(response)
|
||||
|
|
|
@ -134,6 +134,3 @@ TAAR_LITE_RECOMMENDATION_ENGINE_URL = env(
|
|||
FXA_SQS_AWS_QUEUE_URL = (
|
||||
'https://sqs.us-west-2.amazonaws.com/361527076523/'
|
||||
'amo-account-change-prod')
|
||||
|
||||
DRF_API_VERSIONS = ['v3', 'v4']
|
||||
DRF_API_REGEX = r'^/?api/(?:v3|v4)/'
|
||||
|
|
|
@ -87,7 +87,7 @@ class DiscoveryTestMixin(object):
|
|||
class TestDiscoveryViewList(DiscoveryTestMixin, TestCase):
|
||||
def setUp(self):
|
||||
super(TestDiscoveryViewList, self).setUp()
|
||||
self.url = reverse_ns('discovery-list', api_version='v4dev')
|
||||
self.url = reverse_ns('discovery-list', api_version='v5')
|
||||
self.addons = []
|
||||
|
||||
# This one should not appear anywhere, position isn't set.
|
||||
|
@ -145,7 +145,7 @@ class TestDiscoveryViewList(DiscoveryTestMixin, TestCase):
|
|||
self._check_disco_addon(result, discopane_items[i])
|
||||
|
||||
@override_settings(DRF_API_GATES={
|
||||
'v4dev': ('l10n_flat_input_output',)})
|
||||
'v5': ('l10n_flat_input_output',)})
|
||||
def test_list_flat_output(self):
|
||||
response = self.client.get(self.url, {'lang': 'en-US'})
|
||||
assert response.data
|
||||
|
@ -285,7 +285,7 @@ class TestDiscoveryRecommendations(DiscoveryTestMixin, TestCase):
|
|||
# If no recommendations then results should be as before - tests from
|
||||
# the parent class check this.
|
||||
self.get_disco_recommendations_mock.return_value = []
|
||||
self.url = reverse_ns('discovery-list', api_version='v4dev')
|
||||
self.url = reverse_ns('discovery-list', api_version='v5')
|
||||
|
||||
def test_recommendations(self):
|
||||
author = user_factory()
|
||||
|
|
|
@ -92,9 +92,8 @@ FLIGTAR = 'amo-admins+fligtar-rip@mozilla.org'
|
|||
THEMES_EMAIL = 'theme-reviews@mozilla.org'
|
||||
ABUSE_EMAIL = 'amo-admins+ivebeenabused@mozilla.org'
|
||||
|
||||
# prod conf overrides these settings to only have 'v3' and 'v4'.
|
||||
DRF_API_VERSIONS = ['v3', 'v4', 'v4dev']
|
||||
DRF_API_REGEX = r'^/?api/(?:v3|v4|v4dev)/'
|
||||
DRF_API_VERSIONS = ['v3', 'v4', 'v5']
|
||||
DRF_API_REGEX = r'^/?api/(?:v3|v4|v5)/'
|
||||
|
||||
# Add Access-Control-Allow-Origin: * header for the new API with
|
||||
# django-cors-headers.
|
||||
|
@ -1670,7 +1669,7 @@ DRF_API_GATES = {
|
|||
'ratings-can_reply',
|
||||
'ratings-score-filter',
|
||||
),
|
||||
'v4dev': (
|
||||
'v5': (
|
||||
'addons-search-_score-field',
|
||||
'ratings-can_reply',
|
||||
'ratings-score-filter',
|
||||
|
|
|
@ -20,10 +20,10 @@ class TestRankingScenarios(ESTestCase):
|
|||
name = item['name'].get(item['default_locale'], '??????')
|
||||
return name
|
||||
|
||||
# Use v4dev version to ensure we get objects for translations all the
|
||||
# Use v5 version to ensure we get objects for translations all the
|
||||
# time. We don't necessarily specify the language in all tests, but we
|
||||
# want objects all the time for simplicity.
|
||||
url = reverse_ns('addon-search', api_version='v4dev')
|
||||
url = reverse_ns('addon-search', api_version='v5')
|
||||
params = {
|
||||
'lang': 'en-US'
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче