map: add zoom level configuration validation (#64640) #216
|
@ -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
|
||||
)
|
||||
if not (max_zoom >= initial_zoom >= min_zoom):
|
||||
raise ValidationError(
|
||||
_('Invalid zoom configuration: initial zoom is not between minimal & maximal zoom'),
|
||||
)
|
||||
return cleaned_data
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
vdeniaud
commented
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
vdeniaud
commented
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 & 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
vdeniaud
commented
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 & 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
|
||||
|
|
Il n'y a pas d'espace avant le : en anglais (à retirer également plus bas)