[FIX] tools: x_studio image field size

__Current behavior before PR:__
The size of an image field is guessed using the field name. For instance, an image field with `field_name = "XXXX_123"` is resized to 123 pixels when fetched.
This is can be an issue if a user creates an image field using studio in a form view.
If the user sets the label of the field as "Image 1", the technical name will become `x_studio_image_1`. Therefore, the image field will be resized to 1 pixel width.

__Description of the fix:__
Refactor the `image_guess_size_from_field_name` method to return `(0, 0)` when the field name starts with `x_studio_`.

__Steps to reproduce the issue:__
1. Open a form view (of any model)
2. Open studio
3. Add an image field with label "Image 1" (notice the technical name becomes in `x_studio_image_1` in debug mode)
4. Close studio
5. Upload an image on the created field
6. Save... The image is resized to 1 pixel width

opw-3242084
opw-3249632
opw-3253133

closes odoo/odoo#118960

X-original-commit: 3318f0e67da40983f52595aba933d8c8fd0f5cc5
Signed-off-by: Sébastien Theys (seb) <seb@odoo.com>
This commit is contained in:
Julien (jula)
2023-04-24 16:57:44 +02:00
parent d9972ddec4
commit 0a267b3336
2 changed files with 37 additions and 3 deletions
+25
View File
@@ -276,6 +276,31 @@ class TestImage(TransactionCase):
"""Test that image_data_uri is working as expected."""
self.assertEqual(tools.image_data_uri(base64.b64encode(self.img_1x1_png)), 'data:image/png;base64,' + base64.b64encode(self.img_1x1_png).decode('ascii'))
def test_21_image_guess_size_from_field_name(self):
f = tools.image_guess_size_from_field_name
# Test case: empty field_name input
self.assertEqual(f(''), (0, 0))
# Test case: custom field_name input
self.assertEqual(f('custom_field'), (0, 0))
# Test case: field_name input that starts with 'x_'
self.assertEqual(f('x_field'), (0, 0))
# Test case: field_name input that starts with 'x_' and ends with a number less than 16
self.assertEqual(f('x_studio_image_1'), (0, 0))
# Test case: field_name input that starts with 'x_' and ends with a number greater than 16
self.assertEqual(f('x_studio_image_32'), (0, 0))
# Test case: field_name input that has a suffix less than 16
self.assertEqual(f('image_15'), (0, 0))
# Test case: field_name input that has a suffix equal to 16
self.assertEqual(f('image_16'), (16, 16))
# Test case: field_name input that has a suffix greater than 16
self.assertEqual(f('image_32'), (32, 32))
# Test case: field_name input that has a suffix with 2 numbers
self.assertEqual(f('image_1920_1080'), (1080, 1080))
# Test case: field_name input that has a float as suffix
self.assertEqual(f('image_32.5'), (0, 0))
# Test case: field_name input that has a suffix greater than 16 but no underscore
self.assertEqual(f('image32'), (0, 0))
def _assertAlmostEqualSequence(self, rgb1, rgb2, delta=10):
self.assertEqual(len(rgb1), len(rgb2))
for index, t in enumerate(zip(rgb1, rgb2)):
+12 -3
View File
@@ -449,18 +449,27 @@ def is_image_size_above(base64_source_1, base64_source_2):
def image_guess_size_from_field_name(field_name):
"""Attempt to guess the image size based on `field_name`.
If it can't be guessed, return (0, 0) instead.
If it can't be guessed or if it is a custom field: return (0, 0) instead.
:param str field_name: the name of a field
:return: the guessed size
:rtype: tuple (width, height)
"""
suffix = '1024' if field_name == 'image' else field_name.split('_')[-1]
if field_name == 'image':
return (1024, 1024)
if field_name.startswith('x_'):
return (0, 0)
try:
return (int(suffix), int(suffix))
suffix = int(field_name.split('_')[-1])
except ValueError:
return (0, 0)
if suffix < 16:
# If the suffix is less than 16, it's probably not the size
return (0, 0)
return (suffix, suffix)
def image_data_uri(base64_source):
"""This returns data URL scheme according RFC 2397