Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Django Rest Framework - Image/File upload test
import os
import io
from PIL import Image
from django.core.urlresolvers import reverse
from django.conf import settings
from rest_framework import status
from rest_framework.test import APITestCase
from rest_framework.authtoken.models import Token
from rest_framework.renderers import JSONRenderer
# Custom user model based on Django Auth AbstractUser
from account.models import User
class CrewUploadPhotoTests(APITestCase):
fixtures = []
maxDiff = None
def setUp(self):
# Normal user
self.normal_user = User.objects.create(
first_name="Bob",
last_name="Green",
username="bob@green.com",
email="bob@green.com",
is_active=True,
is_staff=False)
self.normal_user.set_password('demo1234')
self.normal_user.save()
self.normal_token, created = Token.objects.get_or_create(
user=self.normal_user)
def generate_photo_file(self):
file = io.BytesIO()
image = Image.new('RGBA', size=(100, 100), color=(155, 0, 0))
image.save(file, 'png')
file.name = 'test.png'
file.seek(0)
return file
def test_upload_photo(self):
"""
Test if we can upload a photo
"""
self.client.credentials(HTTP_AUTHORIZATION='Token ' + self.normal_token.key)
url = reverse('crew-api:upload-photo', args=[self.normal_user.crew.uuid])
photo_file = self.generate_photo_file()
data = {
'photo':photo_file
}
response = self.client.post(url, data, format='multipart')
self.assertEqual(response.status_code, status.HTTP_200_OK)
@kmazi
Copy link

kmazi commented Jul 5, 2018

Cool

@DevJulianSalas
Copy link

DevJulianSalas commented May 8, 2019

The status_code would not have to be 201? nice job by the way.

@akshay-testpress
Copy link

akshay-testpress commented May 20, 2019

def generate_photo_file(self):
       file_obj = StringIO()
       image = Image.new("RGBA", size=(50, 50), color=(256, 0, 0))
       image.save(file_obj, "png")
       file_obj.seek(0)
       file_obj.name = "testasdas.png"
       file_obj.size = 1000
       return file_obj
self.client.post(reverse("registration_register"), data={'photo': self.photo()})

In form I'm getting these values
self.cleaned_data.get('photo').size # I'm getting 144 rather than 1000 why?
But
self.cleaned_data.get('photo').name # I'm getting testasdas.png
I didn't get this? Can anyone tell me the reason for this? Also, how can I mock the size of the file?

@KrzysztofWelc
Copy link

KrzysztofWelc commented Sep 29, 2020

hello, is there any way to delete image after tests? I'm asking, because found out, that all those images are stored in media_cdn folder

@guillaumepiot
Copy link
Author

guillaumepiot commented Sep 30, 2020

hello, is there any way to delete image after tests? I'm asking, because found out, that all those images are stored in media_cdn folder

I would recommend to use the tearDown method to delete the image using the filesystem. Your file path could be save in memory against your test (e.g. self.file_path) or you could just delete the upload folder altogether.

Example:

    def tearDown(self):
        if Path(settings.FILE_UPLOAD_PATH).is_dir():
            shutil.rmtree(settings.FILE_UPLOAD_PATH)

@guillaumepiot
Copy link
Author

guillaumepiot commented Sep 30, 2020

The status_code would not have to be 201? nice job by the way.

Should be yeah 🙃

@guillaumepiot
Copy link
Author

guillaumepiot commented Sep 30, 2020

def generate_photo_file(self):
       file_obj = StringIO()
       image = Image.new("RGBA", size=(50, 50), color=(256, 0, 0))
       image.save(file_obj, "png")
       file_obj.seek(0)
       file_obj.name = "testasdas.png"
       file_obj.size = 1000
       return file_obj
self.client.post(reverse("registration_register"), data={'photo': self.photo()})

In form I'm getting these values
self.cleaned_data.get('photo').size # I'm getting 144 rather than 1000 why?
But
self.cleaned_data.get('photo').name # I'm getting testasdas.png
I didn't get this? Can anyone tell me the reason for this? Also, how can I mock the size of the file?

.size would give you the file size in bytes, what you are looking for here is the image dimension. For that you need an image library such as Python Pillow to load the file and extract those values for you.
https://pillow.readthedocs.io/en/stable/reference/Image.html

Hope that helps and sorry for responding a year too late 🤦‍♂️

@lane-eb
Copy link

lane-eb commented Nov 3, 2020

Cool.
The key is generate_photo_file and I should also make the
avatar = factory.Sequence(lambda n: f"{settings.MEDIA_ROOT}/user_avatar/fake_{n}.jpg") correctly.

@wombstrat
Copy link

wombstrat commented Jun 11, 2021

Great example, thx

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment