umap-project 2.5.0__py3-none-any.whl → 2.6.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of umap-project might be problematic. Click here for more details.

Files changed (276) hide show
  1. umap/__init__.py +1 -1
  2. umap/admin.py +6 -1
  3. umap/context_processors.py +2 -1
  4. umap/decorators.py +13 -2
  5. umap/forms.py +26 -2
  6. umap/locale/br/LC_MESSAGES/django.mo +0 -0
  7. umap/locale/br/LC_MESSAGES/django.po +252 -146
  8. umap/locale/ca/LC_MESSAGES/django.mo +0 -0
  9. umap/locale/ca/LC_MESSAGES/django.po +274 -162
  10. umap/locale/cs_CZ/LC_MESSAGES/django.mo +0 -0
  11. umap/locale/cs_CZ/LC_MESSAGES/django.po +261 -150
  12. umap/locale/de/LC_MESSAGES/django.mo +0 -0
  13. umap/locale/de/LC_MESSAGES/django.po +299 -187
  14. umap/locale/el/LC_MESSAGES/django.mo +0 -0
  15. umap/locale/el/LC_MESSAGES/django.po +215 -159
  16. umap/locale/en/LC_MESSAGES/django.po +211 -155
  17. umap/locale/es/LC_MESSAGES/django.mo +0 -0
  18. umap/locale/es/LC_MESSAGES/django.po +255 -144
  19. umap/locale/eu/LC_MESSAGES/django.mo +0 -0
  20. umap/locale/eu/LC_MESSAGES/django.po +254 -198
  21. umap/locale/fa_IR/LC_MESSAGES/django.mo +0 -0
  22. umap/locale/fa_IR/LC_MESSAGES/django.po +347 -235
  23. umap/locale/fr/LC_MESSAGES/django.mo +0 -0
  24. umap/locale/fr/LC_MESSAGES/django.po +216 -160
  25. umap/locale/hu/LC_MESSAGES/django.mo +0 -0
  26. umap/locale/hu/LC_MESSAGES/django.po +215 -159
  27. umap/locale/it/LC_MESSAGES/django.mo +0 -0
  28. umap/locale/it/LC_MESSAGES/django.po +252 -146
  29. umap/locale/ms/LC_MESSAGES/django.mo +0 -0
  30. umap/locale/ms/LC_MESSAGES/django.po +252 -146
  31. umap/locale/pl/LC_MESSAGES/django.mo +0 -0
  32. umap/locale/pl/LC_MESSAGES/django.po +254 -148
  33. umap/locale/pt/LC_MESSAGES/django.mo +0 -0
  34. umap/locale/pt/LC_MESSAGES/django.po +215 -159
  35. umap/locale/sv/LC_MESSAGES/django.mo +0 -0
  36. umap/locale/sv/LC_MESSAGES/django.po +254 -143
  37. umap/locale/th_TH/LC_MESSAGES/django.mo +0 -0
  38. umap/locale/th_TH/LC_MESSAGES/django.po +125 -70
  39. umap/locale/zh_TW/LC_MESSAGES/django.mo +0 -0
  40. umap/locale/zh_TW/LC_MESSAGES/django.po +256 -145
  41. umap/migrations/0022_add_team.py +94 -0
  42. umap/models.py +45 -10
  43. umap/settings/__init__.py +2 -0
  44. umap/settings/base.py +9 -2
  45. umap/static/umap/base.css +32 -41
  46. umap/static/umap/content.css +19 -25
  47. umap/static/umap/css/icon.css +63 -37
  48. umap/static/umap/css/importers.css +1 -1
  49. umap/static/umap/css/slideshow.css +7 -5
  50. umap/static/umap/css/tableeditor.css +4 -3
  51. umap/static/umap/img/16-white.svg +1 -4
  52. umap/static/umap/img/16.svg +2 -6
  53. umap/static/umap/img/24-white.svg +4 -4
  54. umap/static/umap/img/24.svg +6 -6
  55. umap/static/umap/img/source/16-white.svg +2 -5
  56. umap/static/umap/img/source/16.svg +3 -7
  57. umap/static/umap/img/source/24-white.svg +7 -14
  58. umap/static/umap/img/source/24.svg +10 -17
  59. umap/static/umap/js/components/alerts/alert.css +20 -8
  60. umap/static/umap/js/modules/autocomplete.js +8 -12
  61. umap/static/umap/js/modules/browser.js +4 -3
  62. umap/static/umap/js/modules/caption.js +9 -11
  63. umap/static/umap/js/modules/data/features.js +993 -0
  64. umap/static/umap/js/modules/data/layer.js +1210 -0
  65. umap/static/umap/js/modules/formatter.js +12 -3
  66. umap/static/umap/js/modules/global.js +21 -5
  67. umap/static/umap/js/modules/importers/overpass.js +22 -8
  68. umap/static/umap/js/modules/permissions.js +280 -0
  69. umap/static/umap/js/{umap.icon.js → modules/rendering/icon.js} +77 -56
  70. umap/static/umap/js/modules/rendering/layers/base.js +105 -0
  71. umap/static/umap/js/modules/rendering/layers/classified.js +484 -0
  72. umap/static/umap/js/modules/rendering/layers/cluster.js +103 -0
  73. umap/static/umap/js/modules/rendering/layers/heat.js +182 -0
  74. umap/static/umap/js/modules/rendering/popup.js +99 -0
  75. umap/static/umap/js/modules/rendering/template.js +217 -0
  76. umap/static/umap/js/modules/rendering/ui.js +610 -0
  77. umap/static/umap/js/modules/rules.js +16 -3
  78. umap/static/umap/js/modules/schema.js +25 -1
  79. umap/static/umap/js/modules/share.js +66 -45
  80. umap/static/umap/js/modules/sync/updaters.js +9 -10
  81. umap/static/umap/js/modules/tableeditor.js +7 -7
  82. umap/static/umap/js/modules/ui/dialog.js +8 -4
  83. umap/static/umap/js/modules/utils.js +22 -13
  84. umap/static/umap/js/umap.controls.js +80 -146
  85. umap/static/umap/js/umap.core.js +9 -9
  86. umap/static/umap/js/umap.forms.js +41 -17
  87. umap/static/umap/js/umap.js +72 -65
  88. umap/static/umap/locale/am_ET.js +8 -2
  89. umap/static/umap/locale/am_ET.json +8 -2
  90. umap/static/umap/locale/ar.js +8 -2
  91. umap/static/umap/locale/ar.json +8 -2
  92. umap/static/umap/locale/ast.js +8 -2
  93. umap/static/umap/locale/ast.json +8 -2
  94. umap/static/umap/locale/bg.js +8 -2
  95. umap/static/umap/locale/bg.json +8 -2
  96. umap/static/umap/locale/br.js +42 -36
  97. umap/static/umap/locale/br.json +42 -36
  98. umap/static/umap/locale/ca.js +67 -61
  99. umap/static/umap/locale/ca.json +67 -61
  100. umap/static/umap/locale/cs_CZ.js +8 -2
  101. umap/static/umap/locale/cs_CZ.json +8 -2
  102. umap/static/umap/locale/da.js +8 -2
  103. umap/static/umap/locale/da.json +8 -2
  104. umap/static/umap/locale/de.js +143 -137
  105. umap/static/umap/locale/de.json +143 -137
  106. umap/static/umap/locale/el.js +54 -48
  107. umap/static/umap/locale/el.json +54 -48
  108. umap/static/umap/locale/en.js +10 -2
  109. umap/static/umap/locale/en.json +10 -2
  110. umap/static/umap/locale/en_US.json +8 -2
  111. umap/static/umap/locale/es.js +8 -2
  112. umap/static/umap/locale/es.json +8 -2
  113. umap/static/umap/locale/et.js +8 -2
  114. umap/static/umap/locale/et.json +8 -2
  115. umap/static/umap/locale/eu.js +346 -338
  116. umap/static/umap/locale/eu.json +346 -338
  117. umap/static/umap/locale/fa_IR.js +415 -407
  118. umap/static/umap/locale/fa_IR.json +415 -407
  119. umap/static/umap/locale/fi.js +8 -2
  120. umap/static/umap/locale/fi.json +8 -2
  121. umap/static/umap/locale/fr.js +11 -3
  122. umap/static/umap/locale/fr.json +11 -3
  123. umap/static/umap/locale/gl.js +8 -2
  124. umap/static/umap/locale/gl.json +8 -2
  125. umap/static/umap/locale/he.js +8 -2
  126. umap/static/umap/locale/he.json +8 -2
  127. umap/static/umap/locale/hr.js +8 -2
  128. umap/static/umap/locale/hr.json +8 -2
  129. umap/static/umap/locale/hu.js +31 -23
  130. umap/static/umap/locale/hu.json +31 -23
  131. umap/static/umap/locale/id.js +8 -2
  132. umap/static/umap/locale/id.json +8 -2
  133. umap/static/umap/locale/is.js +8 -2
  134. umap/static/umap/locale/is.json +8 -2
  135. umap/static/umap/locale/it.js +8 -2
  136. umap/static/umap/locale/it.json +8 -2
  137. umap/static/umap/locale/ja.js +8 -2
  138. umap/static/umap/locale/ja.json +8 -2
  139. umap/static/umap/locale/ko.js +8 -2
  140. umap/static/umap/locale/ko.json +8 -2
  141. umap/static/umap/locale/lt.js +8 -2
  142. umap/static/umap/locale/lt.json +8 -2
  143. umap/static/umap/locale/ms.js +8 -2
  144. umap/static/umap/locale/ms.json +8 -2
  145. umap/static/umap/locale/nl.js +8 -2
  146. umap/static/umap/locale/nl.json +8 -2
  147. umap/static/umap/locale/no.js +8 -2
  148. umap/static/umap/locale/no.json +8 -2
  149. umap/static/umap/locale/pl.js +54 -48
  150. umap/static/umap/locale/pl.json +54 -48
  151. umap/static/umap/locale/pl_PL.json +8 -2
  152. umap/static/umap/locale/pt.js +24 -18
  153. umap/static/umap/locale/pt.json +24 -18
  154. umap/static/umap/locale/pt_BR.js +8 -2
  155. umap/static/umap/locale/pt_BR.json +8 -2
  156. umap/static/umap/locale/pt_PT.js +214 -208
  157. umap/static/umap/locale/pt_PT.json +214 -208
  158. umap/static/umap/locale/ro.js +8 -2
  159. umap/static/umap/locale/ro.json +8 -2
  160. umap/static/umap/locale/ru.js +8 -2
  161. umap/static/umap/locale/ru.json +8 -2
  162. umap/static/umap/locale/sk_SK.js +8 -2
  163. umap/static/umap/locale/sk_SK.json +8 -2
  164. umap/static/umap/locale/sl.js +8 -2
  165. umap/static/umap/locale/sl.json +8 -2
  166. umap/static/umap/locale/sr.js +8 -2
  167. umap/static/umap/locale/sr.json +8 -2
  168. umap/static/umap/locale/sv.js +8 -2
  169. umap/static/umap/locale/sv.json +8 -2
  170. umap/static/umap/locale/th_TH.js +33 -27
  171. umap/static/umap/locale/th_TH.json +33 -27
  172. umap/static/umap/locale/tr.js +8 -2
  173. umap/static/umap/locale/tr.json +8 -2
  174. umap/static/umap/locale/uk_UA.js +8 -2
  175. umap/static/umap/locale/uk_UA.json +8 -2
  176. umap/static/umap/locale/vi.js +8 -2
  177. umap/static/umap/locale/vi.json +8 -2
  178. umap/static/umap/locale/vi_VN.json +8 -2
  179. umap/static/umap/locale/zh.js +8 -2
  180. umap/static/umap/locale/zh.json +8 -2
  181. umap/static/umap/locale/zh_CN.json +8 -2
  182. umap/static/umap/locale/zh_TW.Big5.json +8 -2
  183. umap/static/umap/locale/zh_TW.js +102 -96
  184. umap/static/umap/locale/zh_TW.json +102 -96
  185. umap/static/umap/map.css +111 -108
  186. umap/static/umap/nav.css +19 -10
  187. umap/static/umap/unittests/utils.js +230 -107
  188. umap/static/umap/vars.css +1 -0
  189. umap/static/umap/vendors/csv2geojson/csv2geojson.js +62 -40
  190. umap/static/umap/vendors/editable/Leaflet.Editable.js +2079 -1937
  191. umap/storage.py +4 -3
  192. umap/templates/404.html +5 -1
  193. umap/templates/500.html +3 -1
  194. umap/templates/auth/user_detail.html +8 -2
  195. umap/templates/auth/user_form.html +19 -10
  196. umap/templates/auth/user_stars.html +8 -2
  197. umap/templates/base.html +1 -0
  198. umap/templates/registration/login.html +18 -3
  199. umap/templates/umap/about.html +1 -0
  200. umap/templates/umap/about_summary.html +22 -7
  201. umap/templates/umap/components/alerts/alert.html +42 -21
  202. umap/templates/umap/content.html +2 -0
  203. umap/templates/umap/content_footer.html +7 -3
  204. umap/templates/umap/css.html +1 -0
  205. umap/templates/umap/dashboard_menu.html +15 -0
  206. umap/templates/umap/home.html +14 -4
  207. umap/templates/umap/js.html +4 -9
  208. umap/templates/umap/login_popup_end.html +10 -4
  209. umap/templates/umap/map_detail.html +8 -2
  210. umap/templates/umap/map_fragment.html +3 -1
  211. umap/templates/umap/map_init.html +2 -1
  212. umap/templates/umap/map_list.html +6 -3
  213. umap/templates/umap/map_table.html +36 -12
  214. umap/templates/umap/messages.html +0 -1
  215. umap/templates/umap/navigation.html +2 -1
  216. umap/templates/umap/password_change.html +5 -1
  217. umap/templates/umap/password_change_done.html +8 -2
  218. umap/templates/umap/search.html +8 -2
  219. umap/templates/umap/search_bar.html +1 -0
  220. umap/templates/umap/team_confirm_delete.html +19 -0
  221. umap/templates/umap/team_detail.html +27 -0
  222. umap/templates/umap/team_form.html +60 -0
  223. umap/templates/umap/user_dashboard.html +7 -9
  224. umap/templates/umap/user_teams.html +51 -0
  225. umap/tests/base.py +8 -1
  226. umap/tests/conftest.py +6 -0
  227. umap/tests/fixtures/test_circles_layer.geojson +219 -0
  228. umap/tests/fixtures/test_upload_georss.xml +20 -0
  229. umap/tests/integration/conftest.py +18 -4
  230. umap/tests/integration/helpers.py +12 -0
  231. umap/tests/integration/test_anonymous_owned_map.py +23 -0
  232. umap/tests/integration/test_basics.py +29 -0
  233. umap/tests/integration/test_browser.py +20 -0
  234. umap/tests/integration/test_caption.py +20 -0
  235. umap/tests/integration/test_circles_layer.py +69 -0
  236. umap/tests/integration/test_conditional_rules.py +102 -17
  237. umap/tests/integration/test_draw_polygon.py +138 -13
  238. umap/tests/integration/test_draw_polyline.py +8 -18
  239. umap/tests/integration/test_edit_datalayer.py +3 -3
  240. umap/tests/integration/test_import.py +124 -5
  241. umap/tests/integration/test_owned_map.py +21 -13
  242. umap/tests/integration/test_querystring.py +7 -0
  243. umap/tests/integration/test_team.py +47 -0
  244. umap/tests/integration/test_tilelayer.py +19 -2
  245. umap/tests/integration/test_view_marker.py +28 -1
  246. umap/tests/integration/test_websocket_sync.py +5 -5
  247. umap/tests/test_datalayer.py +32 -7
  248. umap/tests/test_datalayer_views.py +1 -1
  249. umap/tests/test_map.py +30 -4
  250. umap/tests/test_map_views.py +2 -2
  251. umap/tests/test_statics.py +40 -0
  252. umap/tests/test_team_views.py +131 -0
  253. umap/tests/test_views.py +15 -1
  254. umap/urls.py +23 -13
  255. umap/views.py +116 -10
  256. {umap_project-2.5.0.dist-info → umap_project-2.6.0.dist-info}/METADATA +14 -14
  257. {umap_project-2.5.0.dist-info → umap_project-2.6.0.dist-info}/RECORD +260 -253
  258. umap/static/umap/js/umap.datalayer.permissions.js +0 -70
  259. umap/static/umap/js/umap.features.js +0 -1290
  260. umap/static/umap/js/umap.layer.js +0 -1837
  261. umap/static/umap/js/umap.permissions.js +0 -208
  262. umap/static/umap/js/umap.popup.js +0 -341
  263. umap/static/umap/test/TableEditor.js +0 -104
  264. umap/static/umap/vendors/leaflet/leaflet-src.js +0 -14512
  265. umap/static/umap/vendors/leaflet/leaflet-src.js.map +0 -1
  266. umap/static/umap/vendors/leaflet/leaflet.js +0 -6
  267. umap/static/umap/vendors/leaflet/leaflet.js.map +0 -1
  268. umap/static/umap/vendors/markercluster/WhereAreTheJavascriptFiles.txt +0 -5
  269. umap/static/umap/vendors/markercluster/leaflet.markercluster-src.js +0 -2718
  270. umap/static/umap/vendors/markercluster/leaflet.markercluster-src.js.map +0 -1
  271. umap/static/umap/vendors/toolbar/leaflet.toolbar-src.css +0 -117
  272. umap/static/umap/vendors/toolbar/leaflet.toolbar-src.js +0 -365
  273. umap/tests/integration/test_statics.py +0 -47
  274. {umap_project-2.5.0.dist-info → umap_project-2.6.0.dist-info}/WHEEL +0 -0
  275. {umap_project-2.5.0.dist-info → umap_project-2.6.0.dist-info}/entry_points.txt +0 -0
  276. {umap_project-2.5.0.dist-info → umap_project-2.6.0.dist-info}/licenses/LICENSE +0 -0
@@ -0,0 +1,12 @@
1
+ import json
2
+ import re
3
+ from pathlib import Path
4
+
5
+ from umap.models import DataLayer
6
+
7
+
8
+ def save_and_get_json(page):
9
+ with page.expect_response(re.compile(r".*/datalayer/create/.*")):
10
+ page.get_by_role("button", name="Save").click()
11
+ datalayer = DataLayer.objects.last()
12
+ return json.loads(Path(datalayer.geojson.path).read_text())
@@ -219,3 +219,26 @@ def test_alert_message_after_create_show_link_even_without_mail(
219
219
  ).to_be_visible()
220
220
  expect(alert.get_by_role("button", name="Copy")).to_be_visible()
221
221
  expect(alert.get_by_role("button", name="Send me the link")).to_be_hidden()
222
+
223
+
224
+ def test_anonymous_owner_can_delete_the_map(anonymap, live_server, owner_session):
225
+ assert Map.objects.count() == 1
226
+ owner_session.goto(f"{live_server.url}{anonymap.get_absolute_url()}")
227
+ owner_session.get_by_role("button", name="Edit").click()
228
+ owner_session.get_by_role("link", name="Map advanced properties").click()
229
+ owner_session.get_by_text("Advanced actions").click()
230
+ expect(owner_session.get_by_role("button", name="Delete")).to_be_visible()
231
+ owner_session.get_by_role("button", name="Delete").click()
232
+ with owner_session.expect_response(re.compile(r".*/update/delete/.*")):
233
+ owner_session.get_by_role("button", name="OK").click()
234
+ assert not Map.objects.count()
235
+
236
+
237
+ def test_non_owner_cannot_see_delete_button(anonymap, live_server, page):
238
+ anonymap.edit_status = Map.ANONYMOUS
239
+ anonymap.save()
240
+ page.goto(f"{live_server.url}{anonymap.get_absolute_url()}")
241
+ page.get_by_role("button", name="Edit").click()
242
+ page.get_by_role("link", name="Map advanced properties").click()
243
+ page.get_by_text("Advanced actions").click()
244
+ expect(page.get_by_role("button", name="Delete")).to_be_hidden()
@@ -1,6 +1,10 @@
1
+ import re
2
+
1
3
  import pytest
2
4
  from playwright.sync_api import expect
3
5
 
6
+ from umap.models import Map
7
+
4
8
 
5
9
  def test_page_title(page, live_server):
6
10
  page.goto(live_server.url)
@@ -66,3 +70,28 @@ def test_cannot_put_script_tag_in_datalayer_name_or_description(
66
70
  expect(page.get_by_text('<script>alert("attack")</script>')).to_be_visible()
67
71
  # Description should contain escaped HTML
68
72
  expect(page.get_by_text("before after")).to_be_visible()
73
+
74
+
75
+ def test_login_from_map_page(live_server, page, tilelayer, settings, user, context):
76
+ settings.ENABLE_ACCOUNT_LOGIN = True
77
+ assert Map.objects.count() == 0
78
+ page.goto(f"{live_server.url}/en/map/new/")
79
+ with (
80
+ page.expect_response(re.compile(r".*/map/create/")),
81
+ context.expect_page() as login_page_info,
82
+ ):
83
+ page.get_by_role("button", name="Save").click()
84
+ assert Map.objects.count() == 0
85
+ login_page = login_page_info.value
86
+ expect(login_page).to_have_title("Login")
87
+ login_page.get_by_placeholder("Username").fill(user.username)
88
+ login_page.get_by_placeholder("Password").fill("123123")
89
+ with page.expect_response(re.compile(r".*/map/create/")):
90
+ login_page.locator('#login_form input[type="submit"]').click()
91
+ # Login page should be closed
92
+ page.wait_for_timeout(500) # Seems needed from time to time…
93
+ assert len(context.pages) == 1
94
+ # Save should have proceed
95
+ assert Map.objects.count() == 1
96
+ # Use name should now appear on the header toolbar
97
+ expect(page.get_by_text("My Dashboard (Joe)")).to_be_visible()
@@ -176,6 +176,26 @@ def test_filter_works_with_variable_in_labelKey(live_server, page, map):
176
176
  expect(paths).to_have_count(1) # Only polygon
177
177
 
178
178
 
179
+ def test_filter_works_with_missing_name(live_server, page, map):
180
+ map.settings["properties"]["onLoadPanel"] = "databrowser"
181
+ map.save()
182
+ data = deepcopy(DATALAYER_DATA)
183
+ del data["features"][0]["properties"]["name"]
184
+ DataLayerFactory(map=map, data=data, name="foobar")
185
+ page.goto(f"{live_server.url}{map.get_absolute_url()}")
186
+ expect(page.get_by_title("Features in this layer: 3")).to_be_visible()
187
+ markers = page.locator(".leaflet-marker-icon")
188
+ paths = page.locator(".leaflet-overlay-pane path")
189
+ expect(markers).to_have_count(1)
190
+ expect(paths).to_have_count(2)
191
+ page.locator(".filters summary").click()
192
+ filter_ = page.locator("input[name='filter']")
193
+ expect(filter_).to_be_visible()
194
+ filter_.type("foob")
195
+ expect(markers).to_have_count(1)
196
+ expect(paths).to_have_count(0)
197
+
198
+
179
199
  def test_data_browser_can_show_only_visible_features(live_server, page, bootstrap, map):
180
200
  # Zoom on France
181
201
  page.goto(f"{live_server.url}{map.get_absolute_url()}#6/51.000/2.000")
@@ -25,3 +25,23 @@ def test_caption(live_server, page, map):
25
25
  panel.locator(".datalayer-legend .off").get_by_text(non_loaded.name)
26
26
  ).to_be_visible()
27
27
  expect(panel.locator(".datalayer-legend").get_by_text(hidden.name)).to_be_hidden()
28
+
29
+
30
+ def test_caption_should_display_owner_as_author(live_server, page, map):
31
+ map.settings["properties"]["onLoadPanel"] = "caption"
32
+ map.save()
33
+ page.goto(f"{live_server.url}{map.get_absolute_url()}")
34
+ panel = page.locator(".panel.left.on")
35
+ expect(panel).to_be_visible()
36
+ expect(panel.get_by_text("By Gabriel")).to_be_visible()
37
+
38
+
39
+ def test_caption_should_display_team_as_author(live_server, page, map, team):
40
+ map.settings["properties"]["onLoadPanel"] = "caption"
41
+ map.team = team
42
+ map.save()
43
+ page.goto(f"{live_server.url}{map.get_absolute_url()}")
44
+ panel = page.locator(".panel.left.on")
45
+ expect(panel).to_be_visible()
46
+ expect(panel.get_by_text("By Gabriel")).to_be_hidden()
47
+ expect(panel.get_by_text("By Awesome Team")).to_be_visible()
@@ -0,0 +1,69 @@
1
+ import json
2
+ from pathlib import Path
3
+
4
+ import pytest
5
+ from playwright.sync_api import expect
6
+
7
+ from ..base import DataLayerFactory
8
+
9
+ pytestmark = pytest.mark.django_db
10
+
11
+
12
+ def test_basic_circles_layer(map, live_server, page):
13
+ path = Path(__file__).parent.parent / "fixtures/test_circles_layer.geojson"
14
+ data = json.loads(path.read_text())
15
+ DataLayerFactory(data=data, map=map)
16
+ page.goto(f"{live_server.url}{map.get_absolute_url()}#12/47.2210/-1.5621")
17
+ paths = page.locator("path")
18
+ expect(paths).to_have_count(10)
19
+ # Last arc curve command
20
+ assert (
21
+ page.locator("[data-feature=c1160]")
22
+ .get_attribute("d")
23
+ .endswith("a40,40 0 1,0 -80,0 ")
24
+ )
25
+ assert (
26
+ page.locator("[data-feature=ca676]")
27
+ .get_attribute("d")
28
+ .endswith("a31,31 0 1,0 -62,0 ")
29
+ )
30
+ assert (
31
+ page.locator("[data-feature=cap64]")
32
+ .get_attribute("d")
33
+ .endswith("a10,10 0 1,0 -20,0 ")
34
+ )
35
+ assert (
36
+ page.locator("[data-feature=cap27]")
37
+ .get_attribute("d")
38
+ .endswith("a6,6 0 1,0 -12,0 ")
39
+ )
40
+ assert (
41
+ page.locator("[data-feature=capa8]")
42
+ .get_attribute("d")
43
+ .endswith("a4,4 0 1,0 -8,0 ")
44
+ )
45
+ assert (
46
+ page.locator("[data-feature=capa6]")
47
+ .get_attribute("d")
48
+ .endswith("a3,3 0 1,0 -6,0 ")
49
+ )
50
+ assert (
51
+ page.locator("[data-feature=capa4]")
52
+ .get_attribute("d")
53
+ .endswith("a3,3 0 1,0 -6,0 ")
54
+ )
55
+ assert (
56
+ page.locator("[data-feature=capa3]")
57
+ .get_attribute("d")
58
+ .endswith("a2,2 0 1,0 -4,0 ")
59
+ )
60
+ assert (
61
+ page.locator("[data-feature=capa2]")
62
+ .get_attribute("d")
63
+ .endswith("a2,2 0 1,0 -4,0 ")
64
+ )
65
+ assert (
66
+ page.locator("[data-feature=capa0]")
67
+ .get_attribute("d")
68
+ .endswith("a2,2 0 1,0 -4,0 ")
69
+ )
@@ -24,6 +24,7 @@ DATALAYER_DATA1 = {
24
24
  "mynumber": 10,
25
25
  "myboolean": True,
26
26
  "mydate": "2024/04/14 12:19:17",
27
+ "maybeempty": "not empty",
27
28
  },
28
29
  "geometry": {"type": "Point", "coordinates": [0.065918, 48.385442]},
29
30
  },
@@ -35,6 +36,7 @@ DATALAYER_DATA1 = {
35
36
  "mynumber": 12,
36
37
  "myboolean": False,
37
38
  "mydate": "2024/03/13 12:20:20",
39
+ "maybeempty": "",
38
40
  },
39
41
  "geometry": {"type": "Point", "coordinates": [3.55957, 49.767074]},
40
42
  },
@@ -56,6 +58,7 @@ DATALAYER_DATA2 = {
56
58
  "mynumber": 10,
57
59
  "myboolean": "true",
58
60
  "mydate": "2024/08/18 13:14:15",
61
+ "maybeempty": None,
59
62
  },
60
63
  "geometry": {"type": "Point", "coordinates": [0.856934, 45.290347]},
61
64
  },
@@ -69,6 +72,18 @@ DATALAYER_DATA2 = {
69
72
  },
70
73
  "geometry": {"type": "Point", "coordinates": [4.372559, 47.945786]},
71
74
  },
75
+ {
76
+ "type": "Feature",
77
+ "properties": {
78
+ "mytype": "odd",
79
+ "name": "Point 5",
80
+ "mynumber": 10,
81
+ "mydate": "2024-04-14T10:19:17.000Z",
82
+ "myboolean": "notaboolean",
83
+ "maybeempty": "foo",
84
+ },
85
+ "geometry": {"type": "Point", "coordinates": [4.1, 47.3]},
86
+ },
72
87
  ],
73
88
  "_umap_options": {
74
89
  "name": "Calque 2",
@@ -85,9 +100,9 @@ def test_simple_equal_rule_at_load(live_server, page, map):
85
100
  DataLayerFactory(map=map, data=DATALAYER_DATA2)
86
101
  page.goto(f"{live_server.url}{map.get_absolute_url()}#6/48.948/1.670")
87
102
  markers = page.locator(".leaflet-marker-icon .icon_container")
88
- expect(markers).to_have_count(4)
103
+ expect(markers).to_have_count(5)
89
104
  colors = getColors(markers)
90
- assert colors.count("rgb(240, 248, 255)") == 2
105
+ assert colors.count("rgb(240, 248, 255)") == 3
91
106
 
92
107
 
93
108
  def test_simple_not_equal_rule_at_load(live_server, page, map):
@@ -99,9 +114,9 @@ def test_simple_not_equal_rule_at_load(live_server, page, map):
99
114
  DataLayerFactory(map=map, data=DATALAYER_DATA2)
100
115
  page.goto(f"{live_server.url}{map.get_absolute_url()}#6/48.948/1.670")
101
116
  markers = page.locator(".leaflet-marker-icon .icon_container")
102
- expect(markers).to_have_count(4)
117
+ expect(markers).to_have_count(5)
103
118
  colors = getColors(markers)
104
- assert colors.count("rgb(240, 248, 255)") == 2
119
+ assert colors.count("rgb(240, 248, 255)") == 3
105
120
 
106
121
 
107
122
  def test_gt_rule_with_number_at_load(live_server, page, map):
@@ -113,7 +128,7 @@ def test_gt_rule_with_number_at_load(live_server, page, map):
113
128
  DataLayerFactory(map=map, data=DATALAYER_DATA2)
114
129
  page.goto(f"{live_server.url}{map.get_absolute_url()}#6/48.948/1.670")
115
130
  markers = page.locator(".leaflet-marker-icon .icon_container")
116
- expect(markers).to_have_count(4)
131
+ expect(markers).to_have_count(5)
117
132
  colors = getColors(markers)
118
133
  assert colors.count("rgb(240, 248, 255)") == 2
119
134
 
@@ -127,9 +142,9 @@ def test_lt_rule_with_number_at_load(live_server, page, map):
127
142
  DataLayerFactory(map=map, data=DATALAYER_DATA2)
128
143
  page.goto(f"{live_server.url}{map.get_absolute_url()}#6/48.948/1.670")
129
144
  markers = page.locator(".leaflet-marker-icon .icon_container")
130
- expect(markers).to_have_count(4)
145
+ expect(markers).to_have_count(5)
131
146
  colors = getColors(markers)
132
- assert colors.count("rgb(240, 248, 255)") == 3
147
+ assert colors.count("rgb(240, 248, 255)") == 4
133
148
 
134
149
 
135
150
  def test_lt_rule_with_float_at_load(live_server, page, map):
@@ -141,9 +156,9 @@ def test_lt_rule_with_float_at_load(live_server, page, map):
141
156
  DataLayerFactory(map=map, data=DATALAYER_DATA2)
142
157
  page.goto(f"{live_server.url}{map.get_absolute_url()}#6/48.948/1.670")
143
158
  markers = page.locator(".leaflet-marker-icon .icon_container")
144
- expect(markers).to_have_count(4)
159
+ expect(markers).to_have_count(5)
145
160
  colors = getColors(markers)
146
- assert colors.count("rgb(240, 248, 255)") == 3
161
+ assert colors.count("rgb(240, 248, 255)") == 4
147
162
 
148
163
 
149
164
  def test_equal_rule_with_boolean_at_load(live_server, page, map):
@@ -155,7 +170,77 @@ def test_equal_rule_with_boolean_at_load(live_server, page, map):
155
170
  DataLayerFactory(map=map, data=DATALAYER_DATA2)
156
171
  page.goto(f"{live_server.url}{map.get_absolute_url()}#6/48.948/1.670")
157
172
  markers = page.locator(".leaflet-marker-icon .icon_container")
158
- expect(markers).to_have_count(4)
173
+ expect(markers).to_have_count(5)
174
+ colors = getColors(markers)
175
+ assert colors.count("rgb(240, 248, 255)") == 2
176
+
177
+
178
+ def test_equal_rule_with_boolean_not_true_at_load(live_server, page, map):
179
+ map.settings["properties"]["rules"] = [
180
+ {"condition": "myboolean!=true", "options": {"color": "aliceblue"}}
181
+ ]
182
+ map.save()
183
+ DataLayerFactory(map=map, data=DATALAYER_DATA1)
184
+ DataLayerFactory(map=map, data=DATALAYER_DATA2)
185
+ page.goto(f"{live_server.url}{map.get_absolute_url()}#6/48.948/1.670")
186
+ markers = page.locator(".leaflet-marker-icon .icon_container")
187
+ expect(markers).to_have_count(5)
188
+ colors = getColors(markers)
189
+ assert colors.count("rgb(240, 248, 255)") == 3
190
+
191
+
192
+ def test_equal_rule_with_boolean_false_at_load(live_server, page, map):
193
+ map.settings["properties"]["rules"] = [
194
+ {"condition": "myboolean=false", "options": {"color": "aliceblue"}}
195
+ ]
196
+ map.save()
197
+ DataLayerFactory(map=map, data=DATALAYER_DATA1)
198
+ DataLayerFactory(map=map, data=DATALAYER_DATA2)
199
+ page.goto(f"{live_server.url}{map.get_absolute_url()}#6/48.948/1.670")
200
+ markers = page.locator(".leaflet-marker-icon .icon_container")
201
+ expect(markers).to_have_count(5)
202
+ colors = getColors(markers)
203
+ assert colors.count("rgb(240, 248, 255)") == 1
204
+
205
+
206
+ def test_equal_rule_with_boolean_not_false_at_load(live_server, page, map):
207
+ map.settings["properties"]["rules"] = [
208
+ {"condition": "myboolean!=false", "options": {"color": "aliceblue"}}
209
+ ]
210
+ map.save()
211
+ DataLayerFactory(map=map, data=DATALAYER_DATA1)
212
+ DataLayerFactory(map=map, data=DATALAYER_DATA2)
213
+ page.goto(f"{live_server.url}{map.get_absolute_url()}#6/48.948/1.670")
214
+ markers = page.locator(".leaflet-marker-icon .icon_container")
215
+ expect(markers).to_have_count(5)
216
+ colors = getColors(markers)
217
+ assert colors.count("rgb(240, 248, 255)") == 4
218
+
219
+
220
+ def test_empty_rule_at_load(live_server, page, map):
221
+ map.settings["properties"]["rules"] = [
222
+ {"condition": "maybeempty=", "options": {"color": "aliceblue"}}
223
+ ]
224
+ map.save()
225
+ DataLayerFactory(map=map, data=DATALAYER_DATA1)
226
+ DataLayerFactory(map=map, data=DATALAYER_DATA2)
227
+ page.goto(f"{live_server.url}{map.get_absolute_url()}#6/48.948/1.670")
228
+ markers = page.locator(".leaflet-marker-icon .icon_container")
229
+ expect(markers).to_have_count(5)
230
+ colors = getColors(markers)
231
+ assert colors.count("rgb(240, 248, 255)") == 3
232
+
233
+
234
+ def test_not_empty_rule_at_load(live_server, page, map):
235
+ map.settings["properties"]["rules"] = [
236
+ {"condition": "maybeempty!=", "options": {"color": "aliceblue"}}
237
+ ]
238
+ map.save()
239
+ DataLayerFactory(map=map, data=DATALAYER_DATA1)
240
+ DataLayerFactory(map=map, data=DATALAYER_DATA2)
241
+ page.goto(f"{live_server.url}{map.get_absolute_url()}#6/48.948/1.670")
242
+ markers = page.locator(".leaflet-marker-icon .icon_container")
243
+ expect(markers).to_have_count(5)
159
244
  colors = getColors(markers)
160
245
  assert colors.count("rgb(240, 248, 255)") == 2
161
246
 
@@ -165,7 +250,7 @@ def test_can_create_new_rule(live_server, page, openmap):
165
250
  DataLayerFactory(map=openmap, data=DATALAYER_DATA2)
166
251
  page.goto(f"{live_server.url}{openmap.get_absolute_url()}#6/48.948/1.670")
167
252
  markers = page.locator(".leaflet-marker-icon .icon_container")
168
- expect(markers).to_have_count(4)
253
+ expect(markers).to_have_count(5)
169
254
  page.get_by_role("button", name="Edit").click()
170
255
  page.get_by_role("link", name="Map advanced properties").click()
171
256
  page.get_by_text("Conditional style rules").click()
@@ -175,7 +260,7 @@ def test_can_create_new_rule(live_server, page, openmap):
175
260
  page.locator(".umap-field-color .define").first.click()
176
261
  page.get_by_title("AliceBlue").first.click()
177
262
  colors = getColors(markers)
178
- assert colors.count("rgb(240, 248, 255)") == 2
263
+ assert colors.count("rgb(240, 248, 255)") == 3
179
264
 
180
265
 
181
266
  def test_can_deactive_rule_from_list(live_server, page, openmap):
@@ -187,9 +272,9 @@ def test_can_deactive_rule_from_list(live_server, page, openmap):
187
272
  DataLayerFactory(map=openmap, data=DATALAYER_DATA2)
188
273
  page.goto(f"{live_server.url}{openmap.get_absolute_url()}#6/48.948/1.670")
189
274
  markers = page.locator(".leaflet-marker-icon .icon_container")
190
- expect(markers).to_have_count(4)
275
+ expect(markers).to_have_count(5)
191
276
  colors = getColors(markers)
192
- assert colors.count("rgb(240, 248, 255)") == 2
277
+ assert colors.count("rgb(240, 248, 255)") == 3
193
278
  page.get_by_role("button", name="Edit").click()
194
279
  page.get_by_role("link", name="Map advanced properties").click()
195
280
  page.get_by_text("Conditional style rules").click()
@@ -198,7 +283,7 @@ def test_can_deactive_rule_from_list(live_server, page, openmap):
198
283
  assert colors.count("rgb(240, 248, 255)") == 0
199
284
  page.get_by_role("button", name="Show/hide layer").click()
200
285
  colors = getColors(markers)
201
- assert colors.count("rgb(240, 248, 255)") == 2
286
+ assert colors.count("rgb(240, 248, 255)") == 3
202
287
 
203
288
 
204
289
  def test_autocomplete_datalist(live_server, page, openmap):
@@ -209,9 +294,9 @@ def test_autocomplete_datalist(live_server, page, openmap):
209
294
  page.get_by_role("button", name="Add rule").click()
210
295
  panel = page.locator(".panel.right.on")
211
296
  datalist = panel.locator(".umap-field-condition datalist option")
212
- expect(datalist).to_have_count(5)
297
+ expect(datalist).to_have_count(6)
213
298
  values = {option.inner_text() for option in datalist.all()}
214
- assert values == {"myboolean", "mytype", "mynumber", "mydate", "name"}
299
+ assert values == {"myboolean", "mytype", "mynumber", "mydate", "name", "maybeempty"}
215
300
  page.get_by_placeholder("key=value or key!=value").fill("mytype")
216
301
  expect(datalist).to_have_count(4)
217
302
  values = {option.inner_text() for option in datalist.all()}
@@ -1,22 +1,11 @@
1
- import json
2
- import re
3
- from pathlib import Path
4
-
5
1
  import pytest
6
2
  from playwright.sync_api import expect
7
3
 
8
- from umap.models import DataLayer
4
+ from .helpers import save_and_get_json
9
5
 
10
6
  pytestmark = pytest.mark.django_db
11
7
 
12
8
 
13
- def save_and_get_json(page):
14
- with page.expect_response(re.compile(r".*/datalayer/create/.*")):
15
- page.get_by_role("button", name="Save").click()
16
- datalayer = DataLayer.objects.last()
17
- return json.loads(Path(datalayer.geojson.path).read_text())
18
-
19
-
20
9
  def test_draw_polygon(page, live_server, tilelayer):
21
10
  page.goto(f"{live_server.url}/en/map/new/")
22
11
 
@@ -243,7 +232,8 @@ def test_can_transfer_shape_from_simple_polygon(live_server, page, tilelayer):
243
232
  expect(polygons).to_have_count(1)
244
233
 
245
234
 
246
- def test_can_extract_shape(live_server, page, tilelayer):
235
+ def test_can_extract_shape(live_server, page, tilelayer, settings):
236
+ settings.UMAP_ALLOW_ANONYMOUS = True
247
237
  page.goto(f"{live_server.url}/en/map/new/")
248
238
  polygons = page.locator(".leaflet-overlay-pane path")
249
239
  expect(polygons).to_have_count(0)
@@ -269,6 +259,58 @@ def test_can_extract_shape(live_server, page, tilelayer):
269
259
  polygons.first.click(position={"x": 20, "y": 20}, button="right")
270
260
  extract_button.click()
271
261
  expect(polygons).to_have_count(2)
262
+ data = save_and_get_json(page)
263
+ assert len(data["features"]) == 2
264
+ assert data["features"][0]["geometry"]["type"] == "Polygon"
265
+ assert data["features"][1]["geometry"]["type"] == "Polygon"
266
+ assert data["features"][0]["geometry"]["coordinates"] == [
267
+ [
268
+ [
269
+ -6.569824,
270
+ 53.159947,
271
+ ],
272
+ [
273
+ -6.569824,
274
+ 52.49616,
275
+ ],
276
+ [
277
+ -7.668457,
278
+ 52.49616,
279
+ ],
280
+ [
281
+ -7.668457,
282
+ 53.159947,
283
+ ],
284
+ [
285
+ -6.569824,
286
+ 53.159947,
287
+ ],
288
+ ],
289
+ ]
290
+ assert data["features"][1]["geometry"]["coordinates"] == [
291
+ [
292
+ [
293
+ -8.76709,
294
+ 54.457267,
295
+ ],
296
+ [
297
+ -8.76709,
298
+ 53.813626,
299
+ ],
300
+ [
301
+ -9.865723,
302
+ 53.813626,
303
+ ],
304
+ [
305
+ -9.865723,
306
+ 54.457267,
307
+ ],
308
+ [
309
+ -8.76709,
310
+ 54.457267,
311
+ ],
312
+ ],
313
+ ]
272
314
 
273
315
 
274
316
  def test_cannot_transfer_shape_to_line(live_server, page, tilelayer):
@@ -367,3 +409,86 @@ def test_can_transform_polygon_to_line(live_server, page, tilelayer, settings):
367
409
  data = save_and_get_json(page)
368
410
  assert len(data["features"]) == 1
369
411
  assert data["features"][0]["geometry"]["type"] == "LineString"
412
+
413
+
414
+ def test_can_draw_a_polygon_and_invert_it(live_server, page, tilelayer, settings):
415
+ settings.UMAP_ALLOW_ANONYMOUS = True
416
+ page.goto(f"{live_server.url}/en/map/new/")
417
+ paths = page.locator(".leaflet-overlay-pane path")
418
+ expect(paths).to_have_count(0)
419
+ page.get_by_title("Draw a polygon").click()
420
+ map = page.locator("#map")
421
+ map.click(position={"x": 200, "y": 100})
422
+ map.click(position={"x": 200, "y": 200})
423
+ map.click(position={"x": 100, "y": 200})
424
+ map.click(position={"x": 100, "y": 100})
425
+ # Click again to finish
426
+ map.click(position={"x": 100, "y": 100})
427
+ expect(paths).to_have_count(1)
428
+ page.get_by_text("Advanced properties").click()
429
+ page.get_by_text("Display the polygon inverted").click()
430
+ data = save_and_get_json(page)
431
+ assert len(data["features"]) == 1
432
+ assert data["features"][0]["geometry"]["type"] == "Polygon"
433
+ assert data["features"][0]["geometry"]["coordinates"] == [
434
+ [
435
+ [
436
+ -7.668457,
437
+ 54.457267,
438
+ ],
439
+ [
440
+ -7.668457,
441
+ 53.159947,
442
+ ],
443
+ [
444
+ -9.865723,
445
+ 53.159947,
446
+ ],
447
+ [
448
+ -9.865723,
449
+ 54.457267,
450
+ ],
451
+ [
452
+ -7.668457,
453
+ 54.457267,
454
+ ],
455
+ ],
456
+ ]
457
+
458
+ page.get_by_role("button", name="View").click()
459
+ popup = page.locator(".leaflet-popup")
460
+ expect(popup).to_be_hidden()
461
+ # Now click on the middle of the polygon, it should not show the popup
462
+ map.click(position={"x": 150, "y": 150})
463
+ expect(popup).to_be_hidden()
464
+ # Click elsewhere on the map, it should now show the popup
465
+ map.click(position={"x": 250, "y": 250})
466
+ expect(popup).to_be_visible()
467
+
468
+
469
+ def test_vertexmarker_not_shown_if_too_many(live_server, map, page, settings):
470
+ geojson = '{"type":"Feature","geometry":{"type":"Polygon","coordinates":[[[3.350602,48.438077],[3.349287,48.438082],[3.34921,48.438124],[3.348519,48.438108],[3.34546,48.437416],[3.343752,48.436955],[3.339092,48.435705],[3.333756,48.434278],[3.330224,48.433336],[3.326293,48.43229],[3.323154,48.430374],[3.32129,48.429238],[3.321234,48.429191],[3.321164,48.429221],[3.320893,48.429117],[3.320766,48.42912],[3.320575,48.429213],[3.320289,48.429303],[3.320042,48.429427],[3.319659,48.429542],[3.319215,48.429622],[3.318547,48.429691],[3.317845,48.429671],[3.317751,48.429698],[3.316503,48.430404],[3.316247,48.430481],[3.316101,48.431152],[3.316181,48.431164],[3.315466,48.432852],[3.315229,48.432981],[3.314785,48.433076],[3.314588,48.432699],[3.314474,48.432376],[3.314197,48.431965],[3.313812,48.431626],[3.313264,48.431253],[3.312393,48.430865],[3.311687,48.43069],[3.311471,48.430693],[3.311199,48.430622],[3.310632,48.430628],[3.30879,48.430373],[3.307032,48.430298],[3.306597,48.430211],[3.306301,48.430213],[3.306137,48.430161],[3.305651,48.430165],[3.304839,48.430046],[3.303726,48.429803],[3.302861,48.42972],[3.302237,48.429635],[3.300559,48.429488],[3.300396,48.429435],[3.299502,48.429335],[3.298528,48.429198],[3.298176,48.429201],[3.296263,48.429039],[3.296267,48.429307],[3.296237,48.429425],[3.295882,48.429848],[3.295665,48.429789],[3.295397,48.430056],[3.295377,48.430132],[3.295186,48.430421],[3.295198,48.430531],[3.295344,48.430735],[3.296077,48.431333],[3.295938,48.431617],[3.29576,48.43168],[3.294082,48.431442],[3.292288,48.431198],[3.292303,48.431101],[3.29082,48.431007],[3.29043,48.430975],[3.290451,48.431129],[3.290115,48.431105],[3.289097,48.430993],[3.289185,48.430805],[3.288545,48.430699],[3.288311,48.430684],[3.287686,48.430687],[3.287456,48.431129],[3.287465,48.43122],[3.288277,48.431574],[3.28896,48.431915],[3.288937,48.431969],[3.289431,48.432499],[3.289672,48.43292],[3.289871,48.433156],[3.29036,48.433602],[3.290557,48.433724],[3.290781,48.433809],[3.291035,48.433857],[3.291537,48.434024],[3.291819,48.434151],[3.292118,48.434341],[3.292479,48.434677],[3.292929,48.435388],[3.293207,48.435792],[3.293881,48.43672],[3.293762,48.436772],[3.294056,48.437209],[3.294117,48.437385],[3.294618,48.437579],[3.294465,48.437764],[3.294424,48.438087],[3.294357,48.438293],[3.293776,48.438817],[3.293308,48.439323],[3.292929,48.439844],[3.292671,48.440235],[3.29233,48.440924],[3.291807,48.441432],[3.29161,48.441661],[3.291402,48.44196],[3.291265,48.442663],[3.291255,48.442806],[3.291328,48.443126],[3.291407,48.443202],[3.291574,48.443473],[3.292253,48.444495],[3.292329,48.444596],[3.293056,48.445276],[3.293138,48.445309],[3.293368,48.445628],[3.293661,48.445985],[3.29374,48.446117],[3.29396,48.446372],[3.294304,48.446627],[3.294761,48.446912],[3.295881,48.447668],[3.295849,48.447688],[3.296837,48.448338],[3.297547,48.44891],[3.297465,48.44892],[3.297188,48.449195],[3.297597,48.449543],[3.297753,48.449701],[3.297845,48.449851],[3.298264,48.450055],[3.298478,48.450121],[3.298946,48.450221],[3.299309,48.450317],[3.299359,48.450237],[3.300493,48.450461],[3.301087,48.450674],[3.301703,48.45101],[3.301995,48.451197],[3.3024,48.451534],[3.302702,48.45174],[3.303329,48.452007],[3.304029,48.452197],[3.304569,48.452446],[3.304803,48.452502],[3.305096,48.452877],[3.30567,48.453409],[3.305998,48.453617],[3.306329,48.453567],[3.306999,48.453359],[3.307147,48.453453],[3.307452,48.453162],[3.307621,48.452853],[3.307637,48.452428],[3.307707,48.452345],[3.307741,48.452152],[3.307605,48.451823],[3.307551,48.45153],[3.307474,48.451395],[3.307218,48.451316],[3.307069,48.45119],[3.307261,48.450528],[3.307483,48.449868],[3.307603,48.449365],[3.30774,48.448909],[3.307598,48.448808],[3.307761,48.448604],[3.307863,48.447956],[3.307886,48.447645],[3.307972,48.447245],[3.308239,48.446362],[3.308306,48.446042],[3.308487,48.445329],[3.308442,48.444844],[3.308479,48.444713],[3.308967,48.443542],[3.309235,48.442927],[3.309464,48.442289],[3.309372,48.442046],[3.309621,48.441616],[3.310152,48.441065],[3.310213,48.440729],[3.310237,48.440329],[3.310167,48.439906],[3.31076,48.439111],[3.31118,48.438009],[3.311161,48.437961],[3.311906,48.437902],[3.312261,48.437839],[3.312486,48.437744],[3.31306,48.437674],[3.312613,48.438361],[3.312487,48.43883],[3.312493,48.439136],[3.312443,48.439388],[3.312598,48.440393],[3.312739,48.440752],[3.312879,48.440985],[3.313263,48.441305],[3.313916,48.441515],[3.314457,48.441565],[3.315105,48.44156],[3.31581,48.441607],[3.317056,48.441849],[3.318361,48.442198],[3.319041,48.442408],[3.319287,48.442604],[3.319343,48.442711],[3.320216,48.443117],[3.320709,48.443437],[3.32126,48.444007],[3.321788,48.444776],[3.322181,48.445618],[3.322479,48.445616],[3.32283,48.445577],[3.323344,48.445663],[3.324048,48.445693],[3.324695,48.445562],[3.324992,48.445559],[3.325558,48.445482],[3.325963,48.445479],[3.327479,48.445592],[3.327939,48.445678],[3.328502,48.445481],[3.328942,48.445392],[3.329169,48.44538],[3.330112,48.445466],[3.330715,48.445575],[3.330881,48.44557],[3.332155,48.445373],[3.33243,48.445375],[3.332727,48.445438],[3.3332,48.445588],[3.333358,48.445683],[3.333737,48.446027],[3.333998,48.446169],[3.334135,48.446334],[3.334611,48.447294],[3.33488,48.447909],[3.334992,48.447959],[3.335297,48.448013],[3.336516,48.448161],[3.336874,48.44825],[3.337258,48.448531],[3.337442,48.448737],[3.337525,48.448936],[3.337649,48.448967],[3.338263,48.448902],[3.33836,48.44894],[3.338765,48.44921],[3.339281,48.449513],[3.339464,48.449515],[3.339877,48.448856],[3.339867,48.448673],[3.340611,48.447311],[3.341744,48.447535],[3.343846,48.447943],[3.345266,48.448152],[3.345478,48.447345],[3.345816,48.446774],[3.345976,48.446809],[3.346142,48.44657],[3.346,48.446493],[3.346043,48.446099],[3.346047,48.445835],[3.346203,48.44558],[3.34717,48.444977],[3.347471,48.444638],[3.347571,48.444466],[3.347583,48.444183],[3.347678,48.443989],[3.348162,48.443428],[3.348326,48.443259],[3.348351,48.443136],[3.34831,48.442736],[3.348141,48.442484],[3.348246,48.442411],[3.348271,48.442293],[3.348097,48.442202],[3.347875,48.442142],[3.347773,48.441997],[3.34751,48.441531],[3.347394,48.441212],[3.349317,48.441364],[3.349478,48.441055],[3.349528,48.44103],[3.350119,48.441039],[3.350252,48.440793],[3.35052,48.440779],[3.350618,48.440612],[3.35069,48.440129],[3.350806,48.43921],[3.350792,48.439037],[3.350698,48.438594],[3.350566,48.438327],[3.350602,48.438077]]]},"properties":{"nom":"Grisy-sur-Seine","code":"77218","codeDepartement":"77","siren":"217702182","codeEpci":"200040251","codeRegion":"11","codesPostaux":["77480"],"population":107},"id":"g0OTg"}'
471
+ settings.UMAP_ALLOW_ANONYMOUS = True
472
+ page.goto(f"{live_server.url}/en/map/new/#15/48.4395/3.3189")
473
+ page.get_by_title("Import data").click()
474
+ page.locator(".umap-upload textarea").fill(geojson)
475
+ page.locator('select[name="format"]').select_option("geojson")
476
+ page.get_by_role("button", name="Import data", exact=True).click()
477
+ page.locator("path").click()
478
+ page.get_by_role("link", name="Toggle edit mode (⇧+Click)").click()
479
+ expect(page.locator("#umap-tooltip-container")).to_contain_text(
480
+ "Please zoom in to edit the geometry"
481
+ )
482
+ expect(page.locator(".leaflet-vertex-icon")).to_be_hidden()
483
+ page.get_by_label("Zoom in").click()
484
+ expect(page.locator("#umap-tooltip-container")).to_contain_text(
485
+ "Please zoom in to edit the geometry"
486
+ )
487
+ page.get_by_label("Zoom in").click()
488
+ page.wait_for_timeout(500)
489
+ page.get_by_label("Zoom out").click()
490
+ page.wait_for_timeout(500)
491
+ expect(page.locator(".leaflet-vertex-icon")).to_be_hidden()
492
+ expect(page.locator("#umap-tooltip-container")).to_contain_text(
493
+ "Please zoom in to edit the geometry"
494
+ )