extensions-website/common/tests/utils.py
Dalai Felinto 1de4f84144 API: Upload new version of an extension (#138)
URL: /api/v1/extensions/<extension_id>/versions/new/
Method: POST
Parameters:
 * version_file
 * release_notes

Ref: !138
Reviewed-by: Oleg-Komarov
2024-05-27 16:18:03 +02:00

124 lines
4.0 KiB
Python

import itertools
from typing import Tuple
import django.urls as urls
from django.utils.functional import cached_property
from django.utils.regex_helper import normalize
from apitokens.models import UserToken
try: # Django 2.0
url_resolver_types = (urls.URLResolver,)
DJANGO_2 = True
except AttributeError: # Django 1.11
url_resolver_types = (urls.RegexURLResolver,)
DJANGO_2 = False
class URLEntry:
def __init__(self, url_bits):
self.bits = url_bits[:]
self.name = url_bits[-1].name
def normalize(self):
return normalize(self.merged_pattern)
@cached_property
def namespace(self):
return getattr(self.bits[0], 'namespace', None)
@cached_property
def qualified_name(self):
if self.name and self.namespace:
return '{namespace}:{name}'.format(namespace=self.namespace, name=self.name)
return self.name
@cached_property
def regexes(self):
if DJANGO_2:
return [bit.pattern.regex for bit in self.bits]
else:
return [bit.regex for bit in self.bits]
@cached_property
def merged_pattern(self):
return ''.join(re.pattern.lstrip('^').rstrip('$') for re in self.regexes)
@cached_property
def named_groups(self):
keys = (re.groupindex.keys() for re in self.regexes)
return set(itertools.chain(*keys))
@cached_property
def group_count(self):
return sum(re.groups for re in self.regexes)
def _extract_urls(urlpatterns, parents):
for pattern in urlpatterns:
path = parents[:] + [pattern]
if isinstance(pattern, url_resolver_types):
yield from _extract_urls(pattern.url_patterns, path)
else:
yield URLEntry(path)
def extract_urls(urlpatterns=None):
"""Extract URLEntry objects from the given iterable of Django URL pattern objects.
If no iterable is given, the patterns exposed by the root resolver are used, i.e.
all of the URLs routed in the project.
:param urlpatterns: Iterable of URLPattern objects
:return: Generator of `URLEntry` objects.
:rtype: list[URLEntry]
"""
if urlpatterns is None:
urlpatterns = urls.get_resolver(None).url_patterns
yield from _extract_urls(urlpatterns, [])
def _get_all_form_errors(response):
return (
{
key: [
response.context[key].errors,
getattr(response.context[key], 'non_form_errors', lambda: None)(),
]
for key in response.context.keys()
if key.endswith('_formset') or key == 'form' or key.endswith('_form')
}
if response.context
else None
)
class CheckFilePropertiesMixin:
def _test_file_properties(self, file, **kwargs):
if 'content_type' in kwargs:
self.assertEqual(file.content_type, kwargs.get('content_type'))
if 'get_status_display' in kwargs:
self.assertEqual(file.get_status_display(), kwargs.get('get_status_display'))
if 'get_type_display' in kwargs:
self.assertEqual(file.get_type_display(), kwargs.get('get_type_display'))
if 'hash' in kwargs:
self.assertTrue(file.hash.startswith(kwargs.get('hash')), file.hash)
if 'name' in kwargs:
self.assertTrue(file.source.name.startswith(kwargs.get('name')), file.source.name)
if 'original_hash' in kwargs:
self.assertTrue(
file.original_hash.startswith(kwargs.get('original_hash')), file.original_hash
)
if 'original_name' in kwargs:
self.assertEqual(file.original_name, kwargs.get('original_name'))
if 'size_bytes' in kwargs:
self.assertEqual(file.size_bytes, kwargs.get('size_bytes'))
def create_user_token(*args, **kwargs) -> Tuple['UserToken', str]:
token_key = UserToken.generate_token_key()
kwargs['token_hash'] = UserToken.generate_hash(token_key)
kwargs['token_prefix'] = UserToken.generate_token_prefix(token_key)
token = UserToken.objects.create(*args, **kwargs)
return token, token_key