Commit 2b6ae748 by J. Cliff Dyer

fixup: dedupe test code.

parent d5a96ee0
...@@ -210,7 +210,10 @@ def _update_exif_orientation(exif, orientation): ...@@ -210,7 +210,10 @@ def _update_exif_orientation(exif, orientation):
def _get_exif_orientation(exif): def _get_exif_orientation(exif):
"""Return the orientation value for the given Image object""" """
Return the orientation value for the given Image object, or None if the
value is not set.
"""
exif_dict = piexif.load(exif) exif_dict = piexif.load(exif)
return exif_dict['0th'].get(piexif.ImageIFD.Orientation) return exif_dict['0th'].get(piexif.ImageIFD.Orientation)
......
...@@ -6,8 +6,8 @@ import os ...@@ -6,8 +6,8 @@ import os
from tempfile import NamedTemporaryFile from tempfile import NamedTemporaryFile
from django.core.files.uploadedfile import UploadedFile from django.core.files.uploadedfile import UploadedFile
from PIL import Image
import piexif import piexif
from PIL import Image
@contextmanager @contextmanager
......
...@@ -13,6 +13,7 @@ from django.test import TestCase ...@@ -13,6 +13,7 @@ from django.test import TestCase
from django.test.utils import override_settings from django.test.utils import override_settings
import ddt import ddt
import mock import mock
import piexif
from PIL import Image from PIL import Image
from ..exceptions import ImageValidationError from ..exceptions import ImageValidationError
...@@ -127,6 +128,18 @@ class TestGenerateProfileImages(TestCase): ...@@ -127,6 +128,18 @@ class TestGenerateProfileImages(TestCase):
""" """
Test create_profile_images Test create_profile_images
""" """
def check_exif_orientation(self, image, expected_orientation):
"""
Check that the created object is a JPEG and that it has the expected
"""
self.assertEqual(image.format, 'JPEG')
if expected_orientation is not None:
self.assertIn('exif', image.info)
self.assertEqual(_get_exif_orientation(image.info['exif']), expected_orientation)
else:
self.assertIsNone(_get_exif_orientation(image.info.get('exif', piexif.dump({}))))
@ddt.data( @ddt.data(
*product( *product(
["gif", "jpg", "png"], ["gif", "jpg", "png"],
...@@ -148,44 +161,36 @@ class TestGenerateProfileImages(TestCase): ...@@ -148,44 +161,36 @@ class TestGenerateProfileImages(TestCase):
1000: "thousand.jpg", 1000: "thousand.jpg",
} }
with make_uploaded_file(dimensions=dimensions, extension=extension, content_type=content_type) as uploaded_file: with make_uploaded_file(dimensions=dimensions, extension=extension, content_type=content_type) as uploaded_file:
names_and_files = self._create_mocked_profile_images(uploaded_file, requested_sizes) names_and_images = self._create_mocked_profile_images(uploaded_file, requested_sizes)
actual_sizes = {} actual_sizes = {}
self.assertEqual(len(names_and_files), 3) for name, image_obj in names_and_images:
for name, file_ in names_and_files:
# get the size of the image file and ensure it's square jpeg # get the size of the image file and ensure it's square jpeg
with closing(Image.open(file_)) as image_obj: width, height = image_obj.size
width, height = image_obj.size self.assertEqual(width, height)
self.assertEqual(width, height) actual_sizes[width] = name
self.assertEqual(image_obj.format, 'JPEG')
actual_sizes[width] = name
self.assertEqual(requested_sizes, actual_sizes) self.assertEqual(requested_sizes, actual_sizes)
def test_jpeg_with_exif_orientation(self): def test_jpeg_with_exif_orientation(self):
requested_images = {10: "ten.jpg"} requested_images = {10: "ten.jpg", 100: "hunnert.jpg"}
rotate_90_clockwise = 8 # Value used in EXIF Orientation field. rotate_90_clockwise = 8 # Value used in EXIF Orientation field.
with make_image_file(orientation=rotate_90_clockwise, extension='.jpg') as imfile: with make_image_file(orientation=rotate_90_clockwise, extension='.jpg') as imfile:
names_and_files = self._create_mocked_profile_images(imfile, requested_images) for _, image in self._create_mocked_profile_images(imfile, requested_images):
self.assertEqual(len(names_and_files), 1) self.check_exif_orientation(image, rotate_90_clockwise)
for file_ in [nf[1] for nf in names_and_files]:
with closing(Image.open(file_)) as image_obj:
self.assertEqual(image_obj.format, 'JPEG')
self.assertIn('exif', image_obj.info)
self.assertEqual(_get_exif_orientation(image_obj.info['exif']), rotate_90_clockwise)
def test_jpeg_without_exif_orientation(self): def test_jpeg_without_exif_orientation(self):
requested_images = {10: "ten.jpg"} requested_images = {10: "ten.jpg", 100: "hunnert.jpg"}
with make_image_file(extension='.jpg') as imfile: with make_image_file(extension='.jpg') as imfile:
names_and_files = self._create_mocked_profile_images(imfile, requested_images) for _, image in self._create_mocked_profile_images(imfile, requested_images):
self.assertEqual(len(names_and_files), 1) self.check_exif_orientation(image, None)
for file_ in [nf[1] for nf in names_and_files]:
with closing(Image.open(file_)) as image_obj:
self.assertEqual(image_obj.format, 'JPEG')
self.assertNotIn('exif', image_obj.info)
def _create_mocked_profile_images(self, image_file, requested_images): def _create_mocked_profile_images(self, image_file, requested_images):
""" """
Create image files with mocked-out storage. Return a list of tuples Create image files with mocked-out storage.
consisting of the name and content of the file.
Verifies that an image was created for each element in
requested_images, and returns an iterator of 2-tuples representing
those imageswhere each tuple consists of a filename and a PIL.Image
object.
""" """
mock_storage = mock.Mock() mock_storage = mock.Mock()
with mock.patch( with mock.patch(
...@@ -194,7 +199,10 @@ class TestGenerateProfileImages(TestCase): ...@@ -194,7 +199,10 @@ class TestGenerateProfileImages(TestCase):
): ):
create_profile_images(image_file, requested_images) create_profile_images(image_file, requested_images)
names_and_files = [v[0] for v in mock_storage.save.call_args_list] names_and_files = [v[0] for v in mock_storage.save.call_args_list]
return names_and_files self.assertEqual(len(names_and_files), len(requested_images))
for name, file_ in names_and_files:
with closing(Image.open(file_)) as image:
yield name, image
@unittest.skipUnless(settings.ROOT_URLCONF == 'lms.urls', 'Profile Image API is only supported in LMS') @unittest.skipUnless(settings.ROOT_URLCONF == 'lms.urls', 'Profile Image API is only supported in LMS')
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment