Multi-platform: support multiple files per version #201

Merged
Oleg-Komarov merged 43 commits from multi-os into main 2024-07-09 16:27:46 +02:00
3 changed files with 49 additions and 15 deletions
Showing only changes of commit e791dfb61d - Show all commits

View File

@ -677,10 +677,23 @@ class Version(CreatedModifiedMixin, TrackChangesMixin, models.Model):
@cached_property @cached_property
def file(self): def file(self):
files = list(self.files.all()) files = list(self.files.all())
if files: if len(files) == 1:
return files[0] return files[0]
else: elif len(files) == 0:
Oleg-Komarov marked this conversation as resolved Outdated

s/get_available_platforms/get_missing_platforms/?

`s/get_available_platforms/get_missing_platforms/`?
return None return None
else:
raise Exception('FIXME: multiple files accessed via .file property')
@property
def can_upload_more_files(self):
all_platforms = set(p.slug for p in Platform.objects.all())
for file in self.files.all():
platforms = file.platforms()
if not platforms:
# no platforms means any platform
return False
all_platforms -= set(platforms)
return len(all_platforms) > 0
@property @property
def is_listed(self): def is_listed(self):

View File

@ -5,7 +5,9 @@ from django.test import TestCase
from common.admin import get_admin_change_path from common.admin import get_admin_change_path
from common.log_entries import entries_for from common.log_entries import entries_for
from common.tests.factories.extensions import create_version from common.tests.factories.extensions import create_version
from common.tests.factories.files import FileFactory
from common.tests.factories.users import UserFactory from common.tests.factories.users import UserFactory
from extensions.models import Platform
class ExtensionTest(TestCase): class ExtensionTest(TestCase):
@ -70,19 +72,16 @@ class VersionTest(TestCase):
maxDiff = None maxDiff = None
fixtures = ['dev', 'licenses'] fixtures = ['dev', 'licenses']
def setUp(self): def test_admin_change_view(self):
super().setUp() version = create_version(
self.version = create_version(
metadata__blender_version_min='2.83.1', metadata__blender_version_min='2.83.1',
metadata__name='Extension name', metadata__name='Extension name',
metadata__support='https://example.com/', metadata__support='https://example.com/',
metadata__version='1.1.2', metadata__version='1.1.2',
metadata__website='https://example.com/', metadata__website='https://example.com/',
) )
self.assertEqual(entries_for(self.version).count(), 0) self.assertEqual(entries_for(version).count(), 0)
path = get_admin_change_path(obj=version)
def test_admin_change_view(self):
path = get_admin_change_path(obj=self.version)
self.assertEqual(path, '/admin/extensions/version/1/change/') self.assertEqual(path, '/admin/extensions/version/1/change/')
admin_user = UserFactory(is_staff=True, is_superuser=True) admin_user = UserFactory(is_staff=True, is_superuser=True)
@ -91,6 +90,26 @@ class VersionTest(TestCase):
self.assertEqual(response.status_code, 200, path) self.assertEqual(response.status_code, 200, path)
def test_can_upload_more_files(self):
version_platforms_none = create_version(metadata__platforms=None)
self.assertFalse(version_platforms_none.can_upload_more_files)
version_platforms_empty = create_version(metadata__platforms=[])
self.assertFalse(version_platforms_empty.can_upload_more_files)
version_platforms_some = create_version(metadata__platforms=['linux-x64', 'windows-x64'])
self.assertTrue(version_platforms_some.can_upload_more_files)
version_two_files = create_version(metadata__platforms=['linux-x64'])
file = FileFactory(metadata__platforms=['windows-x64'])
version_two_files.files.add(file)
self.assertTrue(version_two_files.can_upload_more_files)
version_platforms_all = create_version(
metadata__platforms=[p.slug for p in Platform.objects.all()]
)
self.assertFalse(version_platforms_all.can_upload_more_files)
class UpdateMetadataTest(TestCase): class UpdateMetadataTest(TestCase):
fixtures = ['dev', 'licenses'] fixtures = ['dev', 'licenses']

View File

@ -177,15 +177,17 @@ class File(CreatedModifiedMixin, TrackChangesMixin, models.Model):
'website': data.get('website'), 'website': data.get('website'),
} }
@property def platforms(self):
def parsed_version_fields(self) -> Dict[str, Any]:
"""Return Version-related data that was parsed from file's content."""
# Currently, the content of the manifest file is the only
# kind of file metadata that is supported.
data = self.metadata data = self.metadata
build_generated_platforms = None build_generated_platforms = None
if 'build' in data and 'generated' in data['build']: if 'build' in data and 'generated' in data['build']:
build_generated_platforms = data['build']['generated'].get('platforms') build_generated_platforms = data['build']['generated'].get('platforms')
return build_generated_platforms or data.get('platforms')
@property
def parsed_version_fields(self) -> Dict[str, Any]:
"""Return Version-related data that was parsed from file's content."""
data = self.metadata
return { return {
'version': data.get('version'), 'version': data.get('version'),
'tagline': data.get('tagline'), 'tagline': data.get('tagline'),
@ -193,7 +195,7 @@ class File(CreatedModifiedMixin, TrackChangesMixin, models.Model):
'schema_version': data.get('schema_version'), 'schema_version': data.get('schema_version'),
'licenses': data.get('license'), 'licenses': data.get('license'),
'permissions': data.get('permissions'), 'permissions': data.get('permissions'),
'platforms': build_generated_platforms or data.get('platforms'), 'platforms': self.platforms(),
'tags': data.get('tags'), 'tags': data.get('tags'),
} }
Oleg-Komarov marked this conversation as resolved Outdated

if keeping it a method is preferable, then get_platforms() might be cleaner,
otherwise making it a platforms property would make sense.

if keeping it a method is preferable, then `get_platforms()` might be cleaner, otherwise making it a `platforms` property would make sense.