map: add zoom level configuration validation (#64640) #216

Merged
yweber merged 1 commits from wip/64640-map-cell-edit-zoom-validation into main 2024-01-16 18:02:09 +01:00
3 changed files with 72 additions and 2 deletions

View File

@ -15,13 +15,14 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
from django import forms
from django.core.exceptions import ValidationError
from django.utils.encoding import force_str
from django.utils.text import slugify
from django.utils.translation import gettext_lazy as _
from combo.data.fields import TemplatableURLField
from .models import MapLayer, MapLayerOptions
from .models import Map, MapLayer, MapLayerOptions
class IconRadioSelect(forms.RadioSelect):
@ -122,3 +123,24 @@ class MapLayerOptionsForm(forms.ModelForm):
self.fields['opacity'].required = True
self.fields['opacity'].initial = 1
del self.fields['properties']
class MapCellEditForm(forms.ModelForm):
class Meta:
model = Map
fields = ('initial_zoom', 'min_zoom', 'max_zoom')
def clean(self):
cleaned_data = super().clean()
initial_zoom = cleaned_data.get('initial_zoom')
max_zoom = cleaned_data.get('max_zoom')
min_zoom = cleaned_data.get('min_zoom')
if min_zoom > max_zoom:
raise ValidationError(
_('Invalid zoom configuration: minimal zoom must be lower than maximal zoom')
vdeniaud marked this conversation as resolved Outdated

Il n'y a pas d'espace avant le : en anglais (à retirer également plus bas)

Il n'y a pas d'espace avant le : en anglais (à retirer également plus bas)
)
if not (max_zoom >= initial_zoom >= min_zoom):
raise ValidationError(
_('Invalid zoom configuration: initial zoom is not between minimal & maximal zoom'),
)
return cleaned_data

View File

@ -469,13 +469,15 @@ class Map(CellBase):
return forms.models.modelform_factory(self.__class__, fields=fields)
def get_manager_tabs(self):
from .forms import MapCellEditForm
tabs = super().get_manager_tabs()
tabs.insert(
1,
{
'slug': 'zoom',
'name': _('Zoom'),
'fields': ['initial_zoom', 'min_zoom', 'max_zoom'],
'form': MapCellEditForm,
},
)
return tabs

View File

@ -321,3 +321,49 @@ def test_manager_maps_cell_tabs(app, admin_user):
assert not resp.pyquery('[data-tab-slug="general"] input[name$="title"]')
assert resp.pyquery('[data-tab-slug="appearance"] input[name$="title"]')
def test_manager_map_edit_zoom_check(app, layer, admin_user):
app = login(app)
page = Page(title='xxx', slug='test', template_name='standard')
page.save()
cell = Map(page=page, placeholder='content', order=0, public=True)
cell.title = 'TestMap'
cell.save()
resp = app.get(f'/manage/pages/{page.pk}/')
# Valid zooms
vdeniaud marked this conversation as resolved Outdated

Pour ce point là c'est plutôt un bug, j'ai ouvert https://dev.entrouvert.org/issues/85720. En attendant un contournement plus simple c'est d'hériter de la fixture layer, comme ça la cellule ne sera pas désactivée et l'onglet Général apparaîtra

Pour ce point là c'est plutôt un bug, j'ai ouvert https://dev.entrouvert.org/issues/85720. En attendant un contournement plus simple c'est d'hériter de la fixture layer, comme ça la cellule ne sera pas désactivée et l'onglet Général apparaîtra
resp.form[f'cmaps_map-{cell.pk}-initial_zoom'] = 0
resp.form[f'cmaps_map-{cell.pk}-min_zoom'] = 0
resp.form[f'cmaps_map-{cell.pk}-max_zoom'] = 0
vdeniaud marked this conversation as resolved Outdated

Notre pratique quand il s'agit d'écrire des tests c'est de toujours privilégier la simplicité du code, en n'hésitant jamais à faire long et répétitif. Ici je te conseillerais de reprendre l'écriture de ce test, avec la contrainte de n'utiliser ni définition de fonction ni boucle for :)

Notre pratique quand il s'agit d'écrire des tests c'est de toujours privilégier la simplicité du code, en n'hésitant jamais à faire long et répétitif. Ici je te conseillerais de reprendre l'écriture de ce test, avec la contrainte de n'utiliser ni définition de fonction ni boucle for :)
manager_submit_cell(resp.form)
assert resp.status_int == 200
resp.form[f'cmaps_map-{cell.pk}-initial_zoom'] = 6
resp.form[f'cmaps_map-{cell.pk}-min_zoom'] = 0
resp.form[f'cmaps_map-{cell.pk}-max_zoom'] = 6
manager_submit_cell(resp.form)
assert resp.status_int == 200
# Invalid zooms
resp.form[f'cmaps_map-{cell.pk}-initial_zoom'] = 0
resp.form[f'cmaps_map-{cell.pk}-min_zoom'] = 6
resp.form[f'cmaps_map-{cell.pk}-max_zoom'] = 6
manager_submit_cell(resp.form, expect_errors=True)
assert resp.status_int == 200
assert 'Invalid zoom configuration: initial zoom is not between minimal &amp; maximal zoom' in resp.text
resp.form[f'cmaps_map-{cell.pk}-initial_zoom'] = 6
resp.form[f'cmaps_map-{cell.pk}-min_zoom'] = 0
resp.form[f'cmaps_map-{cell.pk}-max_zoom'] = 0
manager_submit_cell(resp.form, expect_errors=True)
vdeniaud marked this conversation as resolved Outdated

Il faudrait vérifier explicitement quelle erreur est affichée, pour ça il n'y a effectivement pas beaucoup d'exemples mais je dirais de faire comme https://git.entrouvert.org/entrouvert/combo/src/branch/main/tests/test_manager.py#L1928 (mais cette façon là est également correcte https://git.entrouvert.org/entrouvert/combo/src/branch/main/tests/test_dataviz.py#L2088)

Il faudrait vérifier explicitement quelle erreur est affichée, pour ça il n'y a effectivement pas beaucoup d'exemples mais je dirais de faire comme https://git.entrouvert.org/entrouvert/combo/src/branch/main/tests/test_manager.py#L1928 (mais cette façon là est également correcte https://git.entrouvert.org/entrouvert/combo/src/branch/main/tests/test_dataviz.py#L2088)
assert resp.status_int == 200
assert 'Invalid zoom configuration: initial zoom is not between minimal &amp; maximal zoom' in resp.text
resp.form[f'cmaps_map-{cell.pk}-initial_zoom'] = 6
resp.form[f'cmaps_map-{cell.pk}-min_zoom'] = 6
resp.form[f'cmaps_map-{cell.pk}-max_zoom'] = 0
manager_submit_cell(resp.form, expect_errors=True)
assert resp.status_int == 200
assert 'Invalid zoom configuration: minimal zoom must be lower than maximal zoom' in resp.text