- Use DRF ImageField, not FileField
- Ensure that permissions get updated correctly in 'test' mode
- Allow file upload in the APITester class
This commit is contained in:
Oliver 2021-06-23 10:28:21 +10:00
parent a866001ffe
commit 5ba7aeaa27
8 changed files with 88 additions and 12 deletions

3
.gitignore vendored
View File

@ -35,6 +35,9 @@ local_settings.py
*.backup *.backup
*.old *.old
# Files used for testing
dummy_image.*
# Sphinx files # Sphinx files
docs/_build docs/_build

View File

@ -109,12 +109,12 @@ class InvenTreeAPITestCase(APITestCase):
return response return response
def patch(self, url, data, expected_code=None): def patch(self, url, data, files=None, expected_code=None):
""" """
Issue a PATCH request Issue a PATCH request
""" """
response = self.client.patch(url, data=data, format='json') response = self.client.patch(url, data=data, files=files, format='json')
if expected_code is not None: if expected_code is not None:
self.assertEqual(response.status_code, expected_code) self.assertEqual(response.status_code, expected_code)

View File

@ -12,7 +12,7 @@ def isInTestMode():
return False return False
def canAppAccessDatabase(): def canAppAccessDatabase(allow_test=False):
""" """
Returns True if the apps.py file can access database records. Returns True if the apps.py file can access database records.
@ -39,6 +39,10 @@ def canAppAccessDatabase():
'compilemessages', 'compilemessages',
] ]
if not allow_test:
# Override for testing mode?
excluded_commands.append('test')
for cmd in excluded_commands: for cmd in excluded_commands:
if cmd in sys.argv: if cmd in sys.argv:
return False return False

View File

@ -103,7 +103,7 @@ class InvenTreeAttachmentSerializerField(serializers.FileField):
return os.path.join(str(settings.MEDIA_URL), str(value)) return os.path.join(str(settings.MEDIA_URL), str(value))
class InvenTreeImageSerializerField(serializers.FileField): class InvenTreeImageSerializerField(serializers.ImageField):
""" """
Custom image serializer. Custom image serializer.
On upload, validate that the file is a valid image file On upload, validate that the file is a valid image file

View File

@ -31,8 +31,6 @@ v3 -> 2021-05-22:
""" """
def inventreeInstanceName(): def inventreeInstanceName():
""" Returns the InstanceName settings for the current database """ """ Returns the InstanceName settings for the current database """
return common.models.InvenTreeSetting.get_setting("INVENTREE_INSTANCE", "") return common.models.InvenTreeSetting.get_setting("INVENTREE_INSTANCE", "")

View File

@ -1,16 +1,19 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
from rest_framework import status import PIL
from django.urls import reverse from django.urls import reverse
from rest_framework import status
from rest_framework.test import APIClient
from InvenTree.api_tester import InvenTreeAPITestCase
from InvenTree.status_codes import StockStatus
from part.models import Part, PartCategory from part.models import Part, PartCategory
from stock.models import StockItem from stock.models import StockItem
from company.models import Company from company.models import Company
from InvenTree.api_tester import InvenTreeAPITestCase
from InvenTree.status_codes import StockStatus
class PartAPITest(InvenTreeAPITestCase): class PartAPITest(InvenTreeAPITestCase):
""" """
@ -473,6 +476,74 @@ class PartDetailTests(InvenTreeAPITestCase):
self.assertEqual(response.status_code, 200) self.assertEqual(response.status_code, 200)
def test_image_upload(self):
"""
Test that we can upload an image to the part API
"""
self.assignRole('part.add')
# Create a new part
response = self.client.post(
reverse('api-part-list'),
{
'name': 'imagine',
'description': 'All the people',
'category': 1,
},
expected_code=201
)
pk = response.data['pk']
url = reverse('api-part-detail', kwargs={'pk': pk})
p = Part.objects.get(pk=pk)
# Part should not have an image!
with self.assertRaises(ValueError):
print(p.image.file)
# Create a custom APIClient for file uploads
# Ref: https://stackoverflow.com/questions/40453947/how-to-generate-a-file-upload-test-request-with-django-rest-frameworks-apireq
upload_client = APIClient()
upload_client.force_authenticate(user=self.user)
# Try to upload a non-image file
with open('dummy_image.txt', 'w') as dummy_image:
dummy_image.write('hello world')
with open('dummy_image.txt', 'rb') as dummy_image:
response = upload_client.patch(
url,
{
'image': dummy_image,
},
format='multipart',
)
self.assertEqual(response.status_code, 400)
# Now try to upload a valid image file
img = PIL.Image.new('RGB', (128, 128), color='red')
img.save('dummy_image.jpg')
with open('dummy_image.jpg', 'rb') as dummy_image:
response = upload_client.patch(
url,
{
'image': dummy_image,
},
format='multipart',
)
self.assertEqual(response.status_code, 200)
# And now check that the image has been set
p = Part.objects.get(pk=pk)
print("Image:", p.image.file)
class PartAPIAggregationTest(InvenTreeAPITestCase): class PartAPIAggregationTest(InvenTreeAPITestCase):
""" """

View File

@ -13,7 +13,7 @@ class UsersConfig(AppConfig):
def ready(self): def ready(self):
if canAppAccessDatabase(): if canAppAccessDatabase(allow_test=True):
try: try:
self.assign_permissions() self.assign_permissions()

View File

@ -276,7 +276,7 @@ def update_group_roles(group, debug=False):
""" """
if not canAppAccessDatabase(): if not canAppAccessDatabase(allow_test=True):
return return
# List of permissions already associated with this group # List of permissions already associated with this group