Multi-platform: support multiple files per version #201
BIN
extensions/tests/files/addon-with-split-platforms-windows.zip
Normal file
BIN
extensions/tests/files/addon-with-split-platforms-windows.zip
Normal file
Binary file not shown.
@ -239,7 +239,8 @@ class VersionUploadAPITest(APITestCase):
|
||||
self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN)
|
||||
self.assertEqual(
|
||||
response.data['message'],
|
||||
f'Extension "{other_extension.extension_id}" not maintained by user "{self.user.username}"',
|
||||
f'Extension "{other_extension.extension_id}" not maintained by user '
|
||||
f'"{self.user.username}"',
|
||||
)
|
||||
|
||||
def test_version_upload_extension_does_not_exist(self):
|
||||
@ -289,3 +290,59 @@ class VersionUploadAPITest(APITestCase):
|
||||
self.assertEqual(response.status_code, status.HTTP_201_CREATED)
|
||||
self.token.refresh_from_db()
|
||||
self.assertIsNotNone(self.token.date_last_access)
|
||||
|
||||
def test_multiplatform_upload(self):
|
||||
extension = create_version(
|
||||
metadata__id="some_addon",
|
||||
metadata__version="0.0.1",
|
||||
user=self.user,
|
||||
).extension
|
||||
file_linux = TEST_FILES_DIR / 'addon-with-split-platforms-linux.zip'
|
||||
file_windows = TEST_FILES_DIR / 'addon-with-split-platforms-windows.zip'
|
||||
|
||||
with open(file_linux, 'rb') as version_file:
|
||||
response = self.client.post(
|
||||
self._get_upload_url('some_addon'),
|
||||
{
|
||||
'version_file': version_file,
|
||||
'release_notes': 'only linux',
|
||||
},
|
||||
format='multipart',
|
||||
HTTP_AUTHORIZATION=f'Bearer {self.token_key}',
|
||||
)
|
||||
self.assertEqual(response.status_code, status.HTTP_201_CREATED, response.json())
|
||||
extension.refresh_from_db()
|
||||
self.assertEqual(extension.latest_version.files.count(), 1)
|
||||
self.assertEqual(extension.latest_version.platforms.count(), 1)
|
||||
|
||||
with open(file_windows, 'rb') as version_file:
|
||||
response = self.client.post(
|
||||
self._get_upload_url('some_addon'),
|
||||
{
|
||||
'version_file': version_file,
|
||||
'release_notes': 'linux and windows',
|
||||
},
|
||||
format='multipart',
|
||||
HTTP_AUTHORIZATION=f'Bearer {self.token_key}',
|
||||
)
|
||||
self.assertEqual(response.status_code, status.HTTP_201_CREATED, response.json())
|
||||
extension.refresh_from_db()
|
||||
self.assertEqual(extension.latest_version.release_notes, 'linux and windows')
|
||||
self.assertEqual(extension.latest_version.files.count(), 2)
|
||||
self.assertEqual(extension.latest_version.platforms.count(), 2)
|
||||
|
||||
with open(file_windows, 'rb') as version_file:
|
||||
response = self.client.post(
|
||||
self._get_upload_url('some_addon'),
|
||||
{
|
||||
'version_file': version_file,
|
||||
'release_notes': 'linux and windows',
|
||||
},
|
||||
format='multipart',
|
||||
HTTP_AUTHORIZATION=f'Bearer {self.token_key}',
|
||||
)
|
||||
self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST, response.json())
|
||||
self.assertEqual(
|
||||
response.data['message']['version_file'],
|
||||
[f'{extension.latest_version} already has files for windows-x64'],
|
||||
)
|
||||
|
@ -80,7 +80,7 @@ EXPECTED_EXTENSION_DATA = {
|
||||
'version_str': '0.1.0',
|
||||
'slug': 'some-addon',
|
||||
},
|
||||
'addon-with-split-platforms.zip': {
|
||||
'addon-with-split-platforms-linux.zip': {
|
||||
'metadata': {
|
||||
'tagline': 'Some add-on tag line',
|
||||
'name': 'Some Add-on',
|
||||
|
@ -210,6 +210,8 @@ class UploadExtensionVersionView(APIView):
|
||||
form.fields['source'].initial = version_file
|
||||
|
||||
if not form.is_valid():
|
||||
if 'source' in form.errors:
|
||||
form.errors['version_file'] = form.errors.pop('source')
|
||||
return Response({'message': form.errors}, status=status.HTTP_400_BAD_REQUEST)
|
||||
|
||||
with transaction.atomic():
|
||||
@ -218,7 +220,12 @@ class UploadExtensionVersionView(APIView):
|
||||
file_instance.user = user
|
||||
file_instance.save()
|
||||
|
||||
# FIXME check if version already exists, then append file and update release_notes
|
||||
manifest_version = file_instance.metadata['version']
|
||||
if version := extension.versions.filter(version=manifest_version).first():
|
||||
version.add_file(file_instance)
|
||||
version.release_notes = release_notes
|
||||
version.save(update_fields={'release_notes'})
|
||||
else:
|
||||
version = extension.create_version_from_file(
|
||||
file=file_instance,
|
||||
release_notes=release_notes,
|
||||
|
@ -178,7 +178,10 @@ class File(CreatedModifiedMixin, TrackChangesMixin, models.Model):
|
||||
}
|
||||
|
||||
def platforms(self):
|
||||
data = self.metadata
|
||||
return self.parse_platforms_from_manifest(self.metadata)
|
||||
|
||||
@classmethod
|
||||
def parse_platforms_from_manifest(self, data):
|
||||
build_generated_platforms = None
|
||||
if 'build' in data and 'generated' in data['build']:
|
||||
build_generated_platforms = data['build']['generated'].get('platforms')
|
||||
|
@ -16,6 +16,7 @@ from extensions.models import (
|
||||
)
|
||||
from constants.base import EXTENSION_TYPE_SLUGS_SINGULAR, EXTENSION_TYPE_CHOICES
|
||||
from files.utils import guess_mimetype_from_ext, guess_mimetype_from_content
|
||||
import files.models
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
@ -197,7 +198,7 @@ class ExtensionVersionManifestValidator:
|
||||
# check for platforms
|
||||
# TODO test coverage
|
||||
available_platforms = version.get_available_platforms()
|
||||
if platforms := manifest.get('platforms', None):
|
||||
if platforms := files.models.File.parse_platforms_from_manifest(manifest):
|
||||
if diff := set(platforms) - available_platforms:
|
||||
raise ValidationError(
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user