WIP: API: add icon_url
#122
@ -6,6 +6,7 @@ from mdgen import MarkdownPostProvider
|
|||||||
import factory
|
import factory
|
||||||
import factory.fuzzy
|
import factory.fuzzy
|
||||||
|
|
||||||
|
from constants.base import FILE_TYPE_CHOICES
|
||||||
from extensions.models import Extension, Version, Tag, Preview
|
from extensions.models import Extension, Version, Tag, Preview
|
||||||
from ratings.models import Rating
|
from ratings.models import Rating
|
||||||
|
|
||||||
@ -22,6 +23,15 @@ class ExtensionFactory(DjangoModelFactory):
|
|||||||
description = factory.LazyAttribute(
|
description = factory.LazyAttribute(
|
||||||
lambda _: fake_markdown.post(size=random.choice(('medium', 'large')))
|
lambda _: fake_markdown.post(size=random.choice(('medium', 'large')))
|
||||||
)
|
)
|
||||||
|
icon = factory.SubFactory(
|
||||||
|
'common.tests.factories.files.FileFactory',
|
||||||
|
original_name=factory.Faker('file_name', extension='png'),
|
||||||
|
source='images/de/deadbeef.png',
|
||||||
|
original_hash=factory.Faker('lexify', text='hash:??????????????'),
|
||||||
|
hash=factory.Faker('lexify', text='hash:??????????????'),
|
||||||
|
type=FILE_TYPE_CHOICES.IMAGE,
|
||||||
|
size_bytes=1234,
|
||||||
|
)
|
||||||
support = factory.Faker('url')
|
support = factory.Faker('url')
|
||||||
website = factory.Faker('url')
|
website = factory.Faker('url')
|
||||||
|
|
||||||
|
@ -273,6 +273,7 @@ class SubmitFinaliseTest(TestCase):
|
|||||||
extension__name=file_data['metadata']['name'],
|
extension__name=file_data['metadata']['name'],
|
||||||
extension__slug=file_data['metadata']['id'].replace("_", "-"),
|
extension__slug=file_data['metadata']['id'].replace("_", "-"),
|
||||||
extension__website=None,
|
extension__website=None,
|
||||||
|
extension__icon=None,
|
||||||
tagline=file_data['metadata']['tagline'],
|
tagline=file_data['metadata']['tagline'],
|
||||||
version=file_data['metadata']['version'],
|
version=file_data['metadata']['version'],
|
||||||
blender_version_min=file_data['metadata']['blender_version_min'],
|
blender_version_min=file_data['metadata']['blender_version_min'],
|
||||||
|
@ -97,6 +97,7 @@ class UpdateTest(TestCase):
|
|||||||
|
|
||||||
def test_post_upload_multiple_preview_images(self):
|
def test_post_upload_multiple_preview_images(self):
|
||||||
extension = create_approved_version().extension
|
extension = create_approved_version().extension
|
||||||
|
images_count_before = File.objects.filter(type=File.TYPES.IMAGE).count()
|
||||||
|
|
||||||
data = {
|
data = {
|
||||||
**POST_DATA,
|
**POST_DATA,
|
||||||
@ -122,7 +123,9 @@ class UpdateTest(TestCase):
|
|||||||
self.assertEqual(response.status_code, 302, _get_all_form_errors(response))
|
self.assertEqual(response.status_code, 302, _get_all_form_errors(response))
|
||||||
self.assertEqual(response['Location'], url)
|
self.assertEqual(response['Location'], url)
|
||||||
extension.refresh_from_db()
|
extension.refresh_from_db()
|
||||||
self.assertEqual(File.objects.filter(type=File.TYPES.IMAGE).count(), 2)
|
self.assertEqual(
|
||||||
|
File.objects.filter(type=File.TYPES.IMAGE).count(), images_count_before + 2
|
||||||
|
)
|
||||||
self.assertEqual(extension.previews.count(), 2)
|
self.assertEqual(extension.previews.count(), 2)
|
||||||
file1 = extension.previews.all()[0]
|
file1 = extension.previews.all()[0]
|
||||||
file2 = extension.previews.all()[1]
|
file2 = extension.previews.all()[1]
|
||||||
|
@ -70,6 +70,9 @@ class PublicViewsTest(_BaseTestCase):
|
|||||||
self.assertIn('license', v)
|
self.assertIn('license', v)
|
||||||
self.assertIn('website', v)
|
self.assertIn('website', v)
|
||||||
self.assertIn('schema_version', v)
|
self.assertIn('schema_version', v)
|
||||||
|
self.assertEqual(
|
||||||
|
v['icon_url'], 'https://extensions.local:8111/media/images/de/deadbeef.png'
|
||||||
|
)
|
||||||
return response
|
return response
|
||||||
|
|
||||||
def test_home_page_view_api(self):
|
def test_home_page_view_api(self):
|
||||||
|
@ -5,10 +5,12 @@ from rest_framework import serializers
|
|||||||
from rest_framework.views import APIView
|
from rest_framework.views import APIView
|
||||||
from drf_spectacular.utils import OpenApiParameter, extend_schema
|
from drf_spectacular.utils import OpenApiParameter, extend_schema
|
||||||
from django.core.exceptions import ValidationError
|
from django.core.exceptions import ValidationError
|
||||||
|
from django.templatetags.static import static
|
||||||
|
|
||||||
from common.compare import is_in_version_range, version
|
from common.compare import is_in_version_range, version
|
||||||
from extensions.models import Extension
|
from extensions.models import Extension
|
||||||
from extensions.utils import clean_json_dictionary_from_optional_fields
|
from extensions.utils import clean_json_dictionary_from_optional_fields
|
||||||
|
from utils import absolutify
|
||||||
|
|
||||||
|
|
||||||
from constants.base import (
|
from constants.base import (
|
||||||
@ -68,6 +70,10 @@ class ListedExtensionsSerializer(serializers.ModelSerializer):
|
|||||||
if not matching_version:
|
if not matching_version:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
# Use the same stub image as on the website
|
||||||
|
icon_path = static('common/images/no-icon.png')
|
||||||
|
if instance.icon:
|
||||||
|
icon_path = instance.icon.source.url
|
||||||
data = {
|
data = {
|
||||||
'id': instance.extension_id,
|
'id': instance.extension_id,
|
||||||
'schema_version': matching_version.schema_version,
|
'schema_version': matching_version.schema_version,
|
||||||
@ -87,6 +93,7 @@ class ListedExtensionsSerializer(serializers.ModelSerializer):
|
|||||||
'permissions': [permission.slug for permission in matching_version.permissions.all()],
|
'permissions': [permission.slug for permission in matching_version.permissions.all()],
|
||||||
# TODO: handle copyright
|
# TODO: handle copyright
|
||||||
'tags': [str(tag) for tag in matching_version.tags.all()],
|
'tags': [str(tag) for tag in matching_version.tags.all()],
|
||||||
|
'icon_url': absolutify(icon_path),
|
||||||
}
|
}
|
||||||
|
|
||||||
return clean_json_dictionary_from_optional_fields(data)
|
return clean_json_dictionary_from_optional_fields(data)
|
||||||
@ -106,14 +113,20 @@ class ExtensionsAPIView(APIView):
|
|||||||
)
|
)
|
||||||
def get(self, request):
|
def get(self, request):
|
||||||
blender_version = request.GET.get('blender_version')
|
blender_version = request.GET.get('blender_version')
|
||||||
qs = Extension.objects.listed.prefetch_related(
|
qs = (
|
||||||
|
Extension.objects.listed.select_related(
|
||||||
|
'icon',
|
||||||
|
)
|
||||||
|
.prefetch_related(
|
||||||
'authors',
|
'authors',
|
||||||
'versions',
|
'versions',
|
||||||
'versions__file',
|
'versions__file',
|
||||||
'versions__licenses',
|
'versions__licenses',
|
||||||
'versions__permissions',
|
'versions__permissions',
|
||||||
'versions__tags',
|
'versions__tags',
|
||||||
).all()
|
)
|
||||||
|
.all()
|
||||||
|
)
|
||||||
serializer = self.serializer_class(
|
serializer = self.serializer_class(
|
||||||
qs, blender_version=blender_version, request=request, many=True
|
qs, blender_version=blender_version, request=request, many=True
|
||||||
)
|
)
|
||||||
|
Loading…
Reference in New Issue
Block a user