match both v3 and v4 when we're testing for api in middleware, etc (#8291)
This commit is contained in:
Родитель
1e9f1d5cc9
Коммит
561f57138c
|
@ -91,6 +91,10 @@ AES_KEYS = {
|
|||
ROOT, 'src', 'olympia', 'api', 'tests', 'assets', 'test-api-key.txt'),
|
||||
}
|
||||
|
||||
CORS_ENDPOINT_OVERRIDES = cors_endpoint_overrides(
|
||||
['localhost:3000', 'olympia.test']
|
||||
)
|
||||
|
||||
# FxA config for local development only.
|
||||
FXA_CONFIG = {
|
||||
'default': {
|
||||
|
|
|
@ -29,7 +29,7 @@ from . import urlresolvers
|
|||
from .templatetags.jinja_helpers import urlparams
|
||||
|
||||
|
||||
auth_path = re.compile(r'^/api/v3/accounts/authenticate/?$')
|
||||
auth_path = re.compile('%saccounts/authenticate/?$' % settings.DRF_API_REGEX)
|
||||
|
||||
|
||||
class LocaleAndAppURLMiddleware(object):
|
||||
|
@ -54,8 +54,9 @@ class LocaleAndAppURLMiddleware(object):
|
|||
request.path.rstrip('/').endswith('/' + amo.MOBILE.short)):
|
||||
return redirect_type(request.path.replace('/mobile', '/android'))
|
||||
|
||||
if ('lang' in request.GET and not prefixer.shortened_path.startswith(
|
||||
settings.SUPPORTED_NONAPPS_NONLOCALES_PREFIX)):
|
||||
if ('lang' in request.GET and not re.match(
|
||||
settings.SUPPORTED_NONAPPS_NONLOCALES_REGEX,
|
||||
prefixer.shortened_path)):
|
||||
# Blank out the locale so that we can set a new one. Remove lang
|
||||
# from query params so we don't have an infinite loop.
|
||||
prefixer.locale = ''
|
||||
|
@ -117,7 +118,7 @@ class NoVarySessionMiddleware(SessionMiddleware):
|
|||
We always touch request.user to see if the user is authenticated, so every
|
||||
request would be sending vary, so we'd get no caching.
|
||||
|
||||
We skip the cache in Zeus if someone has an AMOv3 cookie, so varying on
|
||||
We skip the cache in Zeus if someone has an AMOv3+ cookie, so varying on
|
||||
Cookie at this level only hurts us.
|
||||
"""
|
||||
def process_response(self, request, response):
|
||||
|
|
|
@ -14,7 +14,7 @@ class ESPaginator(Paginator):
|
|||
|
||||
:param use_elasticsearch_dsl:
|
||||
Used to activate support for our elasticsearch-dsl based pagination
|
||||
implementation. elasticsearch-dsl is being used in the v3 API while
|
||||
implementation. elasticsearch-dsl is being used in the v3+ API while
|
||||
we have our own wrapper implementation in :mod:`olympia.amo.search`.
|
||||
"""
|
||||
|
||||
|
|
|
@ -169,7 +169,7 @@ def test_drf_url():
|
|||
rendered = render(fragment, context={'request': request})
|
||||
# As no /vX/ in the request, RESTFRAMEWORK['DEFAULT_VERSION'] is used.
|
||||
assert rendered == jinja_helpers.absolutify(
|
||||
reverse('v3:addon-detail', args=['a3615'], add_prefix=False))
|
||||
reverse('v4:addon-detail', args=['a3615'], add_prefix=False))
|
||||
|
||||
with pytest.raises(NoReverseMatch):
|
||||
# Without a request it can't resolve the name correctly.
|
||||
|
|
|
@ -50,7 +50,11 @@ class TestMiddleware(TestCase):
|
|||
def test_authentication_is_used_with_accounts_auth(self, process_request):
|
||||
req = RequestFactory().get('/api/v3/accounts/authenticate/')
|
||||
AuthenticationMiddlewareWithoutAPI().process_request(req)
|
||||
assert process_request.called
|
||||
assert process_request.call_count == 1
|
||||
|
||||
req = RequestFactory().get('/api/v4/accounts/authenticate/')
|
||||
AuthenticationMiddlewareWithoutAPI().process_request(req)
|
||||
assert process_request.call_count == 2
|
||||
|
||||
|
||||
def test_redirect_with_unicode_get():
|
||||
|
|
|
@ -64,14 +64,13 @@ class MiddlewareTest(BaseTestCase):
|
|||
response = self.process('/services')
|
||||
assert response is None
|
||||
|
||||
# Things in settings.SUPPORTED_NONAPPS_NONLOCALES_PREFIX don't get
|
||||
# Things matching settings.SUPPORTED_NONAPPS_NONLOCALES_REGEX don't get
|
||||
# a redirect either, even if they have a lang GET parameter.
|
||||
with self.settings(SUPPORTED_NONAPPS_NONLOCALES_PREFIX=('lol',)):
|
||||
with self.settings(SUPPORTED_NONAPPS_NONLOCALES_REGEX=r'^lol'):
|
||||
response = self.process('/lol?lang=fr')
|
||||
assert self.request.LANG == 'fr'
|
||||
assert response is None
|
||||
|
||||
with self.settings(SUPPORTED_NONAPPS_NONLOCALES_PREFIX=('lol',)):
|
||||
response = self.process('/lol')
|
||||
assert self.request.LANG == 'en-US'
|
||||
assert response is None
|
||||
|
@ -79,6 +78,8 @@ class MiddlewareTest(BaseTestCase):
|
|||
def test_api_no_redirect(self):
|
||||
response = self.process('/api/v3/some/endpoint/')
|
||||
assert response is None
|
||||
response = self.process('/api/v4/some/endpoint/')
|
||||
assert response is None
|
||||
|
||||
def test_vary(self):
|
||||
response = self.process('/')
|
||||
|
|
|
@ -68,12 +68,18 @@ class Test404(TestCase):
|
|||
links = pq(res.content)('[role=main] ul a[href^="/en-US/thunderbird"]')
|
||||
assert links.length == 4
|
||||
|
||||
def test_404_api(self):
|
||||
def test_404_api_v3(self):
|
||||
response = self.client.get('/api/v3/lol')
|
||||
assert response.status_code == 404
|
||||
data = json.loads(response.content)
|
||||
assert data['detail'] == u'Not found.'
|
||||
|
||||
def test_404_api_v4(self):
|
||||
response = self.client.get('/api/v4/lol')
|
||||
assert response.status_code == 404
|
||||
data = json.loads(response.content)
|
||||
assert data['detail'] == u'Not found.'
|
||||
|
||||
def test_404_with_mobile_detected(self):
|
||||
res = self.client.get('/en-US/firefox/xxxxxxx', X_IS_MOBILE_AGENTS='1')
|
||||
assert res.status_code == 404
|
||||
|
@ -399,6 +405,14 @@ class TestCORS(TestCase):
|
|||
assert not response.has_header('Access-Control-Allow-Credentials')
|
||||
assert response['Access-Control-Allow-Origin'] == '*'
|
||||
|
||||
def test_cors_api_v4(self):
|
||||
url = reverse('v4:addon-detail', args=(3615,))
|
||||
assert '/api/v4/' in url
|
||||
response = self.get(url)
|
||||
assert response.status_code == 200
|
||||
assert not response.has_header('Access-Control-Allow-Credentials')
|
||||
assert response['Access-Control-Allow-Origin'] == '*'
|
||||
|
||||
|
||||
class TestContribute(TestCase):
|
||||
|
||||
|
|
|
@ -157,7 +157,7 @@ class Prefixer(object):
|
|||
path = path.lstrip('/')
|
||||
url_parts = [self.request.META['SCRIPT_NAME']]
|
||||
|
||||
if not path.startswith(settings.SUPPORTED_NONAPPS_NONLOCALES_PREFIX):
|
||||
if not re.match(settings.SUPPORTED_NONAPPS_NONLOCALES_REGEX, path):
|
||||
if path.partition('/')[0] not in settings.SUPPORTED_NONLOCALES:
|
||||
url_parts.append(self.locale or self.get_language())
|
||||
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
import json
|
||||
import os
|
||||
import re
|
||||
|
||||
from django import http
|
||||
from django.conf import settings
|
||||
|
@ -71,7 +72,7 @@ def handler403(request):
|
|||
|
||||
@non_atomic_requests
|
||||
def handler404(request):
|
||||
if request.path_info.startswith('/api/v3/'):
|
||||
if re.match(settings.DRF_API_REGEX, request.path_info):
|
||||
return JsonResponse(
|
||||
{'detail': unicode(NotFound.default_detail)}, status=404)
|
||||
elif request.path_info.startswith('/api/'):
|
||||
|
|
|
@ -186,14 +186,7 @@ DEFAULT_FXA_CONFIG_NAME = 'default'
|
|||
ALLOWED_FXA_CONFIGS = ['default', 'amo', 'local']
|
||||
|
||||
CORS_ENDPOINT_OVERRIDES = cors_endpoint_overrides(
|
||||
public=[
|
||||
'amo.addons-dev.allizom.org',
|
||||
'localhost:3000',
|
||||
],
|
||||
internal=[
|
||||
'addons-admin.dev.mozaws.net',
|
||||
'localhost:3000',
|
||||
],
|
||||
['amo.addons-dev.allizom.org', 'localhost:3000']
|
||||
)
|
||||
|
||||
RAVEN_DSN = (
|
||||
|
|
|
@ -153,11 +153,6 @@ FXA_CONFIG = {
|
|||
DEFAULT_FXA_CONFIG_NAME = 'default'
|
||||
ALLOWED_FXA_CONFIGS = ['default', 'amo']
|
||||
|
||||
CORS_ENDPOINT_OVERRIDES = cors_endpoint_overrides(
|
||||
public=['amo.addons.mozilla.org'],
|
||||
internal=['addons-admin.prod.mozaws.net'],
|
||||
)
|
||||
|
||||
VALIDATOR_TIMEOUT = 360
|
||||
|
||||
ES_DEFAULT_NUM_SHARDS = 10
|
||||
|
|
|
@ -179,11 +179,6 @@ FXA_CONFIG = {
|
|||
DEFAULT_FXA_CONFIG_NAME = 'default'
|
||||
ALLOWED_FXA_CONFIGS = ['default', 'amo', 'local']
|
||||
|
||||
CORS_ENDPOINT_OVERRIDES = cors_endpoint_overrides(
|
||||
public=['amo.addons.allizom.org'],
|
||||
internal=['addons-admin.stage.mozaws.net'],
|
||||
)
|
||||
|
||||
RAVEN_DSN = (
|
||||
'https://e35602be5252460d97587478bcc642df@sentry.prod.mozaws.net/77')
|
||||
RAVEN_ALLOW_LIST = ['addons.allizom.org', 'addons-cdn.allizom.org']
|
||||
|
|
|
@ -477,7 +477,7 @@ class TestVersion(TestCase):
|
|||
review_history_td = doc('#%s-review-history' % v1.id)[0]
|
||||
assert review_history_td.attrib['data-token'] == 'magicbeans'
|
||||
api_url = absolutify(drf_reverse(
|
||||
'v3:version-reviewnotes-list',
|
||||
'v4:version-reviewnotes-list',
|
||||
args=[self.addon.id, self.version.id]))
|
||||
assert review_history_td.attrib['data-api-url'] == api_url
|
||||
assert doc('.review-history-hide').length == 2
|
||||
|
|
|
@ -87,38 +87,28 @@ THEMES_EMAIL = 'theme-reviews@mozilla.org'
|
|||
ABUSE_EMAIL = 'amo-admins+ivebeenabused@mozilla.org'
|
||||
NOBODY_EMAIL = 'nobody@mozilla.org'
|
||||
|
||||
DRF_API_VERSIONS = ['v3', 'v4']
|
||||
DRF_API_REGEX = r'^/?api/(?:v3|v4)/'
|
||||
|
||||
# Add Access-Control-Allow-Origin: * header for the new API with
|
||||
# django-cors-headers.
|
||||
CORS_ORIGIN_ALLOW_ALL = True
|
||||
CORS_URLS_REGEX = r'^/api/v3/.*$'
|
||||
CORS_URLS_REGEX = DRF_API_REGEX
|
||||
|
||||
|
||||
# Sadly the term WHITELIST is used by the library
|
||||
# https://pypi.python.org/pypi/django-cors-headers-multi/1.2.0
|
||||
# TODO(andym): see if I can get them to accept a patch for that.
|
||||
def cors_endpoint_overrides(internal, public):
|
||||
def cors_endpoint_overrides(whitelist_endpoints):
|
||||
return [
|
||||
(r'^/api/v3/internal/accounts/login/?$', {
|
||||
('%saccounts/login/?$' % DRF_API_REGEX, {
|
||||
'CORS_ORIGIN_ALLOW_ALL': False,
|
||||
'CORS_ORIGIN_WHITELIST': internal,
|
||||
'CORS_ORIGIN_WHITELIST': whitelist_endpoints,
|
||||
'CORS_ALLOW_CREDENTIALS': True,
|
||||
}),
|
||||
(r'^/api/v3/accounts/login/?$', {
|
||||
'CORS_ORIGIN_ALLOW_ALL': False,
|
||||
'CORS_ORIGIN_WHITELIST': public,
|
||||
'CORS_ALLOW_CREDENTIALS': True,
|
||||
}),
|
||||
(r'^/api/v3/internal/.*$', {
|
||||
'CORS_ORIGIN_ALLOW_ALL': False,
|
||||
'CORS_ORIGIN_WHITELIST': internal,
|
||||
}),
|
||||
]
|
||||
|
||||
|
||||
CORS_ENDPOINT_OVERRIDES = cors_endpoint_overrides(
|
||||
public=['localhost:3000', 'olympia.test'],
|
||||
internal=['localhost:3000'],
|
||||
)
|
||||
CORS_ENDPOINT_OVERRIDES = []
|
||||
|
||||
DATABASES = {
|
||||
'default': env.db(default='mysql://root:@localhost/olympia')
|
||||
|
@ -318,9 +308,7 @@ DUMPED_APPS_DAYS_DELETE = 3600 * 24 * 30
|
|||
DUMPED_USERS_DAYS_DELETE = 3600 * 24 * 30
|
||||
|
||||
# path that isn't just one /, and doesn't require any locale or app.
|
||||
SUPPORTED_NONAPPS_NONLOCALES_PREFIX = (
|
||||
'api/v3',
|
||||
)
|
||||
SUPPORTED_NONAPPS_NONLOCALES_REGEX = DRF_API_REGEX
|
||||
|
||||
# paths that don't require an app prefix
|
||||
# This needs to be kept in sync with addons-frontend's
|
||||
|
@ -1699,8 +1687,8 @@ REST_FRAMEWORK = {
|
|||
'olympia.api.parsers.MultiPartParser',
|
||||
),
|
||||
|
||||
'ALLOWED_VERSIONS': ['v3', 'v4'],
|
||||
'DEFAULT_VERSION': 'v3',
|
||||
'ALLOWED_VERSIONS': DRF_API_VERSIONS,
|
||||
'DEFAULT_VERSION': 'v4',
|
||||
'DEFAULT_VERSIONING_CLASS': (
|
||||
'rest_framework.versioning.NamespaceVersioning'),
|
||||
|
||||
|
|
|
@ -81,7 +81,7 @@ urlpatterns = [
|
|||
# SAMO (Legacy API)
|
||||
url('^api/', include('olympia.legacy_api.urls')),
|
||||
|
||||
# API v3.
|
||||
# API v3+.
|
||||
url('^api/', include('olympia.api.urls')),
|
||||
|
||||
url('^compatibility/', include('olympia.compat.urls')),
|
||||
|
|
Загрузка…
Ссылка в новой задаче