61 lines
2.8 KiB
Python
61 lines
2.8 KiB
Python
import io
|
|
|
|
from django.core.files.uploadedfile import SimpleUploadedFile
|
|
from django.test import SimpleTestCase
|
|
from PIL import Image
|
|
|
|
from crochet.cover_image import InvalidCoverImage, LARGE_MAX_SIZE, THUMBNAIL_MAX_SIZE, build_cover_image_variants
|
|
|
|
|
|
def make_image_file(size=(2000, 1000), mode='RGB', color='red', name='cover.png', format='PNG'):
|
|
buffer = io.BytesIO()
|
|
Image.new(mode, size, color=color).save(buffer, format=format)
|
|
return SimpleUploadedFile(name, buffer.getvalue(), content_type=f'image/{format.lower()}')
|
|
|
|
|
|
class BuildCoverImageVariantsTests(SimpleTestCase):
|
|
def test_thumbnail_and_large_fit_within_max_size(self):
|
|
original, thumbnail, large = build_cover_image_variants(make_image_file(size=(2000, 1000)))
|
|
|
|
thumbnail_image = Image.open(io.BytesIO(thumbnail.read()))
|
|
large_image = Image.open(io.BytesIO(large.read()))
|
|
|
|
self.assertLessEqual(thumbnail_image.width, THUMBNAIL_MAX_SIZE[0])
|
|
self.assertLessEqual(thumbnail_image.height, THUMBNAIL_MAX_SIZE[1])
|
|
self.assertLessEqual(large_image.width, LARGE_MAX_SIZE[0])
|
|
self.assertLessEqual(large_image.height, LARGE_MAX_SIZE[1])
|
|
|
|
def test_preserves_aspect_ratio(self):
|
|
_, thumbnail, _ = build_cover_image_variants(make_image_file(size=(2000, 1000)))
|
|
thumbnail_image = Image.open(io.BytesIO(thumbnail.read()))
|
|
|
|
self.assertAlmostEqual(thumbnail_image.width / thumbnail_image.height, 2.0, places=1)
|
|
|
|
def test_small_image_is_not_upscaled(self):
|
|
_, thumbnail, _ = build_cover_image_variants(make_image_file(size=(50, 50)))
|
|
thumbnail_image = Image.open(io.BytesIO(thumbnail.read()))
|
|
|
|
self.assertEqual(thumbnail_image.size, (50, 50))
|
|
|
|
def test_original_is_kept_unprocessed(self):
|
|
original, _, _ = build_cover_image_variants(make_image_file(size=(50, 50), name='mine.png'))
|
|
|
|
self.assertEqual(original.name, 'mine.png')
|
|
original_image = Image.open(io.BytesIO(original.read()))
|
|
self.assertEqual(original_image.size, (50, 50))
|
|
|
|
def test_transparent_png_is_flattened_for_jpeg_variants(self):
|
|
# Si el aplanado a RGB no funcionase, Pillow lanzaría un error al
|
|
# intentar guardar un canal alfa como JPEG (ver build_cover_image_variants).
|
|
uploaded = make_image_file(size=(50, 50), mode='RGBA', color=(255, 0, 0, 0))
|
|
_, thumbnail, large = build_cover_image_variants(uploaded)
|
|
|
|
self.assertEqual(Image.open(io.BytesIO(thumbnail.read())).mode, 'RGB')
|
|
self.assertEqual(Image.open(io.BytesIO(large.read())).mode, 'RGB')
|
|
|
|
def test_invalid_file_raises(self):
|
|
invalid_file = SimpleUploadedFile('not-an-image.png', b'this is not an image', content_type='image/png')
|
|
|
|
with self.assertRaises(InvalidCoverImage):
|
|
build_cover_image_variants(invalid_file)
|