mirror of
https://github.com/encode/django-rest-framework.git
synced 2025-02-23 23:12:59 +03:00
Fix NamespaceVersioning ignoring DEFAULT_VERSION on non-None namespaces (#7278)
* Fix the case where if the namespace is not None and there's no match, NamespaceVersioning always raises NotFound even if DEFAULT_VERSION is set or None is in ALLOWED_VERSIONS * Add test cases
This commit is contained in:
parent
aed7761a8d
commit
71f87a5864
|
@ -119,15 +119,16 @@ class NamespaceVersioning(BaseVersioning):
|
||||||
|
|
||||||
def determine_version(self, request, *args, **kwargs):
|
def determine_version(self, request, *args, **kwargs):
|
||||||
resolver_match = getattr(request, 'resolver_match', None)
|
resolver_match = getattr(request, 'resolver_match', None)
|
||||||
if resolver_match is None or not resolver_match.namespace:
|
if resolver_match is not None and resolver_match.namespace:
|
||||||
return self.default_version
|
|
||||||
|
|
||||||
# Allow for possibly nested namespaces.
|
# Allow for possibly nested namespaces.
|
||||||
possible_versions = resolver_match.namespace.split(':')
|
possible_versions = resolver_match.namespace.split(':')
|
||||||
for version in possible_versions:
|
for version in possible_versions:
|
||||||
if self.is_allowed_version(version):
|
if self.is_allowed_version(version):
|
||||||
return version
|
return version
|
||||||
|
|
||||||
|
if not self.is_allowed_version(self.default_version):
|
||||||
raise exceptions.NotFound(self.invalid_version_message)
|
raise exceptions.NotFound(self.invalid_version_message)
|
||||||
|
return self.default_version
|
||||||
|
|
||||||
def reverse(self, viewname, args=None, kwargs=None, request=None, format=None, **extra):
|
def reverse(self, viewname, args=None, kwargs=None, request=None, format=None, **extra):
|
||||||
if request.version is not None:
|
if request.version is not None:
|
||||||
|
|
|
@ -272,7 +272,7 @@ class TestInvalidVersion:
|
||||||
assert response.status_code == status.HTTP_404_NOT_FOUND
|
assert response.status_code == status.HTTP_404_NOT_FOUND
|
||||||
|
|
||||||
|
|
||||||
class TestAllowedAndDefaultVersion:
|
class TestAcceptHeaderAllowedAndDefaultVersion:
|
||||||
def test_missing_without_default(self):
|
def test_missing_without_default(self):
|
||||||
scheme = versioning.AcceptHeaderVersioning
|
scheme = versioning.AcceptHeaderVersioning
|
||||||
view = AllowedVersionsView.as_view(versioning_class=scheme)
|
view = AllowedVersionsView.as_view(versioning_class=scheme)
|
||||||
|
@ -318,6 +318,97 @@ class TestAllowedAndDefaultVersion:
|
||||||
assert response.data == {'version': 'v2'}
|
assert response.data == {'version': 'v2'}
|
||||||
|
|
||||||
|
|
||||||
|
class TestNamespaceAllowedAndDefaultVersion:
|
||||||
|
def test_no_namespace_without_default(self):
|
||||||
|
class FakeResolverMatch:
|
||||||
|
namespace = None
|
||||||
|
|
||||||
|
scheme = versioning.NamespaceVersioning
|
||||||
|
view = AllowedVersionsView.as_view(versioning_class=scheme)
|
||||||
|
|
||||||
|
request = factory.get('/endpoint/')
|
||||||
|
request.resolver_match = FakeResolverMatch
|
||||||
|
response = view(request)
|
||||||
|
assert response.status_code == status.HTTP_404_NOT_FOUND
|
||||||
|
|
||||||
|
def test_no_namespace_with_default(self):
|
||||||
|
class FakeResolverMatch:
|
||||||
|
namespace = None
|
||||||
|
|
||||||
|
scheme = versioning.NamespaceVersioning
|
||||||
|
view = AllowedAndDefaultVersionsView.as_view(versioning_class=scheme)
|
||||||
|
|
||||||
|
request = factory.get('/endpoint/')
|
||||||
|
request.resolver_match = FakeResolverMatch
|
||||||
|
response = view(request)
|
||||||
|
assert response.status_code == status.HTTP_200_OK
|
||||||
|
assert response.data == {'version': 'v2'}
|
||||||
|
|
||||||
|
def test_no_match_without_default(self):
|
||||||
|
class FakeResolverMatch:
|
||||||
|
namespace = 'no_match'
|
||||||
|
|
||||||
|
scheme = versioning.NamespaceVersioning
|
||||||
|
view = AllowedVersionsView.as_view(versioning_class=scheme)
|
||||||
|
|
||||||
|
request = factory.get('/endpoint/')
|
||||||
|
request.resolver_match = FakeResolverMatch
|
||||||
|
response = view(request)
|
||||||
|
assert response.status_code == status.HTTP_404_NOT_FOUND
|
||||||
|
|
||||||
|
def test_no_match_with_default(self):
|
||||||
|
class FakeResolverMatch:
|
||||||
|
namespace = 'no_match'
|
||||||
|
|
||||||
|
scheme = versioning.NamespaceVersioning
|
||||||
|
view = AllowedAndDefaultVersionsView.as_view(versioning_class=scheme)
|
||||||
|
|
||||||
|
request = factory.get('/endpoint/')
|
||||||
|
request.resolver_match = FakeResolverMatch
|
||||||
|
response = view(request)
|
||||||
|
assert response.status_code == status.HTTP_200_OK
|
||||||
|
assert response.data == {'version': 'v2'}
|
||||||
|
|
||||||
|
def test_with_default(self):
|
||||||
|
class FakeResolverMatch:
|
||||||
|
namespace = 'v1'
|
||||||
|
|
||||||
|
scheme = versioning.NamespaceVersioning
|
||||||
|
view = AllowedAndDefaultVersionsView.as_view(versioning_class=scheme)
|
||||||
|
|
||||||
|
request = factory.get('/endpoint/')
|
||||||
|
request.resolver_match = FakeResolverMatch
|
||||||
|
response = view(request)
|
||||||
|
assert response.status_code == status.HTTP_200_OK
|
||||||
|
assert response.data == {'version': 'v1'}
|
||||||
|
|
||||||
|
def test_no_match_without_default_but_none_allowed(self):
|
||||||
|
class FakeResolverMatch:
|
||||||
|
namespace = 'no_match'
|
||||||
|
|
||||||
|
scheme = versioning.NamespaceVersioning
|
||||||
|
view = AllowedWithNoneVersionsView.as_view(versioning_class=scheme)
|
||||||
|
|
||||||
|
request = factory.get('/endpoint/')
|
||||||
|
request.resolver_match = FakeResolverMatch
|
||||||
|
response = view(request)
|
||||||
|
assert response.status_code == status.HTTP_200_OK
|
||||||
|
assert response.data == {'version': None}
|
||||||
|
|
||||||
|
def test_no_match_with_default_and_none_allowed(self):
|
||||||
|
class FakeResolverMatch:
|
||||||
|
namespace = 'no_match'
|
||||||
|
|
||||||
|
scheme = versioning.NamespaceVersioning
|
||||||
|
view = AllowedWithNoneAndDefaultVersionsView.as_view(versioning_class=scheme)
|
||||||
|
|
||||||
|
request = factory.get('/endpoint/')
|
||||||
|
request.resolver_match = FakeResolverMatch
|
||||||
|
response = view(request)
|
||||||
|
assert response.status_code == status.HTTP_200_OK
|
||||||
|
assert response.data == {'version': 'v2'}
|
||||||
|
|
||||||
|
|
||||||
class TestHyperlinkedRelatedField(URLPatternsTestCase, APITestCase):
|
class TestHyperlinkedRelatedField(URLPatternsTestCase, APITestCase):
|
||||||
included = [
|
included = [
|
||||||
path('namespaced/<int:pk>/', dummy_pk_view, name='namespaced'),
|
path('namespaced/<int:pk>/', dummy_pk_view, name='namespaced'),
|
||||||
|
|
Loading…
Reference in New Issue
Block a user