diff --git a/care/utils/models/validators.py b/care/utils/models/validators.py index 58624d1143..73fdffc9df 100644 --- a/care/utils/models/validators.py +++ b/care/utils/models/validators.py @@ -250,13 +250,20 @@ def __eq__(self, other: object) -> bool: ] ) - def _humanize_bytes(self, size: int) -> str: + @staticmethod + def _format_size(size: float) -> str: + # Trim the trailing zeros of the fixed-point form first, then the bare + # decimal point. Stripping "." and "0" in one pass also eats the + # significant zeros of a round number, turning 10.00 into "1". + return f"{size:.2f}".rstrip("0").rstrip(".") + + def _humanize_bytes(self, size: float) -> str: byte_size = 1024.0 for unit in ["B", "KB"]: if size < byte_size: - return f"{f'{size:.2f}'.rstrip('.0')} {unit}" + return f"{self._format_size(size)} {unit}" size /= byte_size - return f"{f'{size:.2f}'.rstrip('.0')} MB" + return f"{self._format_size(size)} MB" cover_image_validator = ImageSizeValidator( diff --git a/care/utils/tests/test_image_validator.py b/care/utils/tests/test_image_validator.py index dccdfb5165..5a09d0b6a7 100644 --- a/care/utils/tests/test_image_validator.py +++ b/care/utils/tests/test_image_validator.py @@ -60,3 +60,37 @@ def test_invalid_image_too_large(self): "Image size is greater than the maximum allowed size of 2 MB.", ], ) + + def _image_file(self, reported_size: int) -> UploadedFile: + image = Image.new("RGB", (10, 10)) + file = io.BytesIO() + image.save(file, format="JPEG") + return UploadedFile(file, "test.jpg", "image/jpeg", reported_size) + + def test_min_size_limit_is_reported_verbatim(self): + for min_size, expected in [ + (500, "500 B"), + (1536, "1.5 KB"), + (10 * 1024, "10 KB"), + (10 * 1024 * 1024, "10 MB"), + ]: + with self.subTest(min_size=min_size): + validator = ImageSizeValidator(min_size=min_size) + with self.assertRaises(ValidationError) as cm: + validator(self._image_file(1)) + self.assertEqual( + cm.exception.messages, + [ + "Image size is less than the minimum allowed size of " + f"{expected}.", + ], + ) + + def test_max_size_limit_is_reported_verbatim(self): + validator = ImageSizeValidator(max_size=10 * 1024 * 1024) + with self.assertRaises(ValidationError) as cm: + validator(self._image_file(20 * 1024 * 1024)) + self.assertEqual( + cm.exception.messages, + ["Image size is greater than the maximum allowed size of 10 MB."], + )