Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Refactor ideal_size template tag to use explicit file existence checks
  • Loading branch information
iampujan committed Mar 16, 2026
commit 48baed155aff99b430ad282d0e2d132d003d9674
10 changes: 6 additions & 4 deletions apps/sponsors/templatetags/sponsors.py
Original file line number Diff line number Diff line change
Expand Up @@ -81,14 +81,16 @@ def benefit_name_for_display(benefit, package):
def ideal_size(image, ideal_dimension):
"""Scale an image width to fit within the given ideal dimension area."""
ideal_dimension = int(ideal_dimension)

# image could be an ImageFieldFile; if it's falsey, it means no file is associated with it.
if not image:
return ideal_dimension

try:
w, h = image.width, image.height
except (FileNotFoundError, ValueError) as e:
except FileNotFoundError:
# local dev doesn't have all images if DB is a copy from prod environment
# in that case, we return a fallback size to avoid 500 errors.
# we only catch the specific ValueError raised by Django when a file is missing.
if isinstance(e, ValueError) and "no file associated with it" not in str(e):
raise
return ideal_dimension

return int(w * math.sqrt((100 * ideal_dimension) / (w * h)))
41 changes: 17 additions & 24 deletions apps/sponsors/tests/test_templatetags.py
Original file line number Diff line number Diff line change
Expand Up @@ -91,43 +91,36 @@ def test_display_name_for_display_from_benefit(self, mocked_name_for_display):
mocked_name_for_display.assert_called_once_with(package=package)


class IdealSizeTemplateTagTests(TestCase):
def test_ideal_size_handles_missing_file_association(self):
class MockImageWithoutFile:
def __bool__(self):
return False
Comment thread
iampujan marked this conversation as resolved.

size = ideal_size(MockImageWithoutFile(), 250)
# Should return ideal_dimension directly as fallback
self.assertEqual(size, 250)

def test_ideal_size_scales_properly(self):
class MockImage:
width = 400
height = 200

def __bool__(self):
return True

size = ideal_size(MockImage(), 200)
# int(400 * sqrt(20000 / 80000)) = int(400 * 0.5) = 200
self.assertEqual(size, 200)

def test_ideal_size_handles_file_not_found(self):
class MockImageWithoutFile:
class MockImageWithMissingFileOnDisk:
@property
def width(self):
raise FileNotFoundError

size = ideal_size(MockImageWithoutFile(), 300)
# Should return ideal_dimension directly as fallback
self.assertEqual(size, 300)

def test_ideal_size_handles_value_error(self):
class MockImageWithoutFileValue:
@property
def width(self):
msg = "The 'web_logo' attribute has no file associated with it."
raise ValueError(msg)
def __bool__(self):
return True

size = ideal_size(MockImageWithoutFileValue(), 250)
size = ideal_size(MockImageWithMissingFileOnDisk(), 300)
# Should return ideal_dimension directly as fallback
self.assertEqual(size, 250)

def test_ideal_size_raises_other_value_errors(self):
class MockImageWithOtherValueError:
@property
def width(self):
msg = "Other error"
raise ValueError(msg)

with self.assertRaises(ValueError):
ideal_size(MockImageWithOtherValueError(), 250)
self.assertEqual(size, 300)
Loading