Files
AdventureLog/backend/server/adventures/tests/test_share_image.py

205 lines
7.9 KiB
Python

from datetime import date, timedelta
from django.contrib.auth import get_user_model
from django.test import TestCase
from PIL import Image as PILImage
import io
from adventures.models import Collection, Location
from adventures.services.share_image import (
ASPECTS,
build_collection_share_image,
build_location_share_image,
valid_aspect,
)
User = get_user_model()
class ShareImageServiceTests(TestCase):
def setUp(self):
self.user = User.objects.create_user(username='shareuser', password='testpass123')
self.other = User.objects.create_user(username='otheruser', password='testpass123')
def _png_size(self, png_bytes: bytes) -> tuple[int, int]:
img = PILImage.open(io.BytesIO(png_bytes))
return img.size
def test_valid_aspect(self):
self.assertTrue(valid_aspect('square'))
self.assertTrue(valid_aspect('story'))
self.assertTrue(valid_aspect('landscape'))
self.assertFalse(valid_aspect('wide'))
def test_build_collection_share_image_all_aspects(self):
start = date.today() + timedelta(days=10)
end = start + timedelta(days=3)
collection = Collection.objects.create(
user=self.user,
name='Coastal Road Trip',
start_date=start,
end_date=end,
is_public=True,
)
location = Location.objects.create(
user=self.user,
name='Beach Stop',
location='Pacific Coast',
is_public=True,
)
collection.locations.add(location)
for aspect, (width, height) in ASPECTS.items():
png = build_collection_share_image(
collection, aspect, f'http://example.com/collections/{collection.id}'
)
self.assertTrue(png.startswith(b'\x89PNG'))
self.assertEqual(self._png_size(png), (width, height))
def test_build_location_share_image_all_aspects(self):
location = Location.objects.create(
user=self.user,
name='Summit View',
location='Rocky Mountains',
rating=4.5,
tags=['hiking', 'scenic'],
is_public=True,
)
for aspect, (width, height) in ASPECTS.items():
png = build_location_share_image(
location, aspect, f'http://example.com/locations/{location.id}'
)
self.assertTrue(png.startswith(b'\x89PNG'))
self.assertEqual(self._png_size(png), (width, height))
def test_collection_share_image_without_hero_image(self):
collection = Collection.objects.create(
user=self.user,
name='No Photo Trip',
is_public=True,
)
png = build_collection_share_image(
collection, 'square', f'http://example.com/collections/{collection.id}'
)
self.assertTrue(png.startswith(b'\x89PNG'))
self.assertEqual(self._png_size(png), ASPECTS['square'])
class ShareImageApiTests(TestCase):
def setUp(self):
self.user = User.objects.create_user(username='apiuser', password='testpass123')
self.other = User.objects.create_user(username='apiother', password='testpass123')
self.client.login(username='apiuser', password='testpass123')
self.public_collection = Collection.objects.create(
user=self.user,
name='Public Trip',
is_public=True,
)
self.private_collection = Collection.objects.create(
user=self.user,
name='Private Trip',
is_public=False,
)
self.public_location = Location.objects.create(
user=self.user,
name='Public Place',
is_public=True,
)
self.private_location = Location.objects.create(
user=self.user,
name='Private Place',
is_public=False,
)
def test_owner_can_fetch_private_collection_share_image(self):
url = f'/api/collections/{self.private_collection.id}/share-image/square/'
res = self.client.get(url)
self.assertEqual(res.status_code, 200)
self.assertEqual(res['Content-Type'], 'image/png')
self.assertTrue(res.content.startswith(b'\x89PNG'))
def test_anonymous_can_fetch_public_collection_share_image(self):
self.client.logout()
url = f'/api/collections/{self.public_collection.id}/share-image/landscape/'
res = self.client.get(url)
self.assertEqual(res.status_code, 200)
self.assertEqual(res['Content-Type'], 'image/png')
def test_anonymous_cannot_fetch_private_collection_share_image(self):
self.client.logout()
url = f'/api/collections/{self.private_collection.id}/share-image/square/'
res = self.client.get(url)
self.assertIn(res.status_code, (403, 404))
def test_owner_can_fetch_private_location_share_image(self):
url = f'/api/locations/{self.private_location.id}/share-image/story/'
res = self.client.get(url)
self.assertEqual(res.status_code, 200)
self.assertEqual(res['Content-Type'], 'image/png')
def test_anonymous_can_fetch_public_location_share_image(self):
self.client.logout()
url = f'/api/locations/{self.public_location.id}/share-image/square/'
res = self.client.get(url)
self.assertEqual(res.status_code, 200)
self.assertEqual(res['Content-Type'], 'image/png')
def test_anonymous_cannot_fetch_private_location_share_image(self):
self.client.logout()
url = f'/api/locations/{self.private_location.id}/share-image/square/'
res = self.client.get(url)
self.assertIn(res.status_code, (403, 404))
def test_invalid_aspect_returns_400(self):
url = f'/api/collections/{self.public_collection.id}/share-image/wide/'
res = self.client.get(url)
self.assertEqual(res.status_code, 404)
def test_download_disposition(self):
url = (
f'/api/collections/{self.public_collection.id}/share-image/square/?download=1'
)
res = self.client.get(url)
self.assertEqual(res.status_code, 200)
self.assertIn('attachment', res['Content-Disposition'])
def test_shared_user_can_fetch_private_collection_share_image(self):
self.private_collection.shared_with.add(self.other)
self.client.logout()
self.client.login(username='apiother', password='testpass123')
url = f'/api/collections/{self.private_collection.id}/share-image/square/'
res = self.client.get(url)
self.assertEqual(res.status_code, 200)
self.assertEqual(res['Content-Type'], 'image/png')
def test_anonymous_can_export_public_collection_pdf(self):
self.client.logout()
url = f'/api/collections/{self.public_collection.id}/export-pdf/'
res = self.client.get(url)
self.assertEqual(res.status_code, 200)
self.assertEqual(res['Content-Type'], 'application/pdf')
self.assertTrue(res.content.startswith(b'%PDF'))
def test_owner_can_export_private_collection_pdf(self):
url = f'/api/collections/{self.private_collection.id}/export-pdf/'
res = self.client.get(url)
self.assertEqual(res.status_code, 200)
self.assertEqual(res['Content-Type'], 'application/pdf')
def test_anonymous_cannot_export_private_collection_pdf(self):
self.client.logout()
url = f'/api/collections/{self.private_collection.id}/export-pdf/'
res = self.client.get(url)
self.assertIn(res.status_code, (403, 404))
def test_shared_user_can_export_private_collection_pdf(self):
self.private_collection.shared_with.add(self.other)
self.client.logout()
self.client.login(username='apiother', password='testpass123')
url = f'/api/collections/{self.private_collection.id}/export-pdf/'
res = self.client.get(url)
self.assertEqual(res.status_code, 200)
self.assertEqual(res['Content-Type'], 'application/pdf')