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

This comment has been minimized.

Copy link

@kmazi kmazi commented Jul 5, 2018

Cool

@DevJulianSalas

This comment has been minimized.

Copy link

@DevJulianSalas DevJulianSalas commented May 8, 2019

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

@akshay-testpress

This comment has been minimized.

Copy link

@akshay-testpress 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

This comment has been minimized.

Copy link

@KrzysztofWelc 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

This comment has been minimized.

Copy link
Owner Author

@guillaumepiot 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

This comment has been minimized.

Copy link
Owner Author

@guillaumepiot guillaumepiot commented Sep 30, 2020

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

Should be yeah 🙃

@guillaumepiot

This comment has been minimized.

Copy link
Owner Author

@guillaumepiot 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

This comment has been minimized.

Copy link

@lane-eb 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

This comment has been minimized.

Copy link

@wombstrat 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