umap-project 3.4.0b3__py3-none-any.whl → 3.4.2__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.
Files changed (185) hide show
  1. umap/__init__.py +1 -1
  2. umap/locale/da/LC_MESSAGES/django.mo +0 -0
  3. umap/locale/da/LC_MESSAGES/django.po +18 -14
  4. umap/locale/en/LC_MESSAGES/django.po +5 -1
  5. umap/locale/es/LC_MESSAGES/django.mo +0 -0
  6. umap/locale/es/LC_MESSAGES/django.po +20 -16
  7. umap/locale/fr/LC_MESSAGES/django.mo +0 -0
  8. umap/locale/fr/LC_MESSAGES/django.po +18 -14
  9. umap/locale/pl/LC_MESSAGES/django.mo +0 -0
  10. umap/locale/pl/LC_MESSAGES/django.po +72 -71
  11. umap/static/umap/content.css +0 -3
  12. umap/static/umap/css/bar.css +9 -6
  13. umap/static/umap/css/form.css +25 -9
  14. umap/static/umap/css/popup.css +1 -0
  15. umap/static/umap/js/components/copiable.js +47 -0
  16. umap/static/umap/js/modules/autocomplete.js +31 -58
  17. umap/static/umap/js/modules/browser.js +4 -4
  18. umap/static/umap/js/modules/data/features.js +32 -35
  19. umap/static/umap/js/modules/data/fields.js +189 -23
  20. umap/static/umap/js/modules/data/layer.js +72 -87
  21. umap/static/umap/js/modules/domutils.js +21 -1
  22. umap/static/umap/js/modules/filters.js +13 -40
  23. umap/static/umap/js/modules/form/fields.js +4 -4
  24. umap/static/umap/js/modules/formatter.js +9 -1
  25. umap/static/umap/js/modules/help.js +12 -13
  26. umap/static/umap/js/modules/importer.js +17 -26
  27. umap/static/umap/js/modules/importers/banfr.js +0 -1
  28. umap/static/umap/js/modules/importers/cadastrefr.js +19 -19
  29. umap/static/umap/js/modules/importers/communesfr.js +7 -8
  30. umap/static/umap/js/modules/importers/datasets.js +14 -14
  31. umap/static/umap/js/modules/importers/geodatamine.js +20 -22
  32. umap/static/umap/js/modules/importers/opendata.js +10 -0
  33. umap/static/umap/js/modules/importers/overpass.js +19 -18
  34. umap/static/umap/js/modules/managers.js +1 -1
  35. umap/static/umap/js/modules/permissions.js +5 -3
  36. umap/static/umap/js/modules/rendering/controls.js +2 -2
  37. umap/static/umap/js/modules/rendering/icon.js +5 -9
  38. umap/static/umap/js/modules/rendering/layers/base.js +1 -1
  39. umap/static/umap/js/modules/rendering/layers/classified.js +15 -10
  40. umap/static/umap/js/modules/rendering/layers/heat.js +1 -0
  41. umap/static/umap/js/modules/rendering/map.js +22 -22
  42. umap/static/umap/js/modules/rendering/popup.js +6 -3
  43. umap/static/umap/js/modules/rendering/template.js +28 -34
  44. umap/static/umap/js/modules/rendering/ui.js +1 -2
  45. umap/static/umap/js/modules/rules.js +34 -41
  46. umap/static/umap/js/modules/schema.js +0 -7
  47. umap/static/umap/js/modules/share.js +36 -69
  48. umap/static/umap/js/modules/slideshow.js +3 -3
  49. umap/static/umap/js/modules/tableeditor.js +0 -1
  50. umap/static/umap/js/modules/ui/bar.js +51 -32
  51. umap/static/umap/js/modules/ui/panel.js +26 -21
  52. umap/static/umap/js/modules/ui/tooltip.js +1 -1
  53. umap/static/umap/js/modules/umap.js +75 -80
  54. umap/static/umap/js/modules/utils.js +12 -3
  55. umap/static/umap/js/umap.controls.js +33 -14
  56. umap/static/umap/locale/am_ET.js +6 -4
  57. umap/static/umap/locale/am_ET.json +6 -4
  58. umap/static/umap/locale/ar.js +6 -4
  59. umap/static/umap/locale/ar.json +6 -4
  60. umap/static/umap/locale/ast.js +6 -4
  61. umap/static/umap/locale/ast.json +6 -4
  62. umap/static/umap/locale/bg.js +6 -4
  63. umap/static/umap/locale/bg.json +6 -4
  64. umap/static/umap/locale/br.js +19 -8
  65. umap/static/umap/locale/br.json +19 -8
  66. umap/static/umap/locale/ca.js +6 -4
  67. umap/static/umap/locale/ca.json +6 -4
  68. umap/static/umap/locale/cs_CZ.js +7 -5
  69. umap/static/umap/locale/cs_CZ.json +7 -5
  70. umap/static/umap/locale/da.js +8 -6
  71. umap/static/umap/locale/da.json +8 -6
  72. umap/static/umap/locale/de.js +38 -36
  73. umap/static/umap/locale/de.json +38 -36
  74. umap/static/umap/locale/el.js +7 -5
  75. umap/static/umap/locale/el.json +7 -5
  76. umap/static/umap/locale/en.js +7 -5
  77. umap/static/umap/locale/en.json +7 -5
  78. umap/static/umap/locale/en_US.json +6 -4
  79. umap/static/umap/locale/es.js +19 -17
  80. umap/static/umap/locale/es.json +19 -17
  81. umap/static/umap/locale/et.js +7 -5
  82. umap/static/umap/locale/et.json +7 -5
  83. umap/static/umap/locale/eu.js +23 -21
  84. umap/static/umap/locale/eu.json +23 -21
  85. umap/static/umap/locale/fa_IR.js +7 -5
  86. umap/static/umap/locale/fa_IR.json +7 -5
  87. umap/static/umap/locale/fi.js +6 -4
  88. umap/static/umap/locale/fi.json +6 -4
  89. umap/static/umap/locale/fr.js +8 -6
  90. umap/static/umap/locale/fr.json +8 -6
  91. umap/static/umap/locale/gl.js +147 -145
  92. umap/static/umap/locale/gl.json +147 -145
  93. umap/static/umap/locale/he.js +6 -4
  94. umap/static/umap/locale/he.json +6 -4
  95. umap/static/umap/locale/hr.js +6 -4
  96. umap/static/umap/locale/hr.json +6 -4
  97. umap/static/umap/locale/hu.js +7 -5
  98. umap/static/umap/locale/hu.json +7 -5
  99. umap/static/umap/locale/id.js +6 -4
  100. umap/static/umap/locale/id.json +6 -4
  101. umap/static/umap/locale/is.js +7 -5
  102. umap/static/umap/locale/is.json +7 -5
  103. umap/static/umap/locale/it.js +7 -5
  104. umap/static/umap/locale/it.json +7 -5
  105. umap/static/umap/locale/ja.js +6 -4
  106. umap/static/umap/locale/ja.json +6 -4
  107. umap/static/umap/locale/ko.js +6 -4
  108. umap/static/umap/locale/ko.json +6 -4
  109. umap/static/umap/locale/lt.js +6 -4
  110. umap/static/umap/locale/lt.json +6 -4
  111. umap/static/umap/locale/ms.js +7 -5
  112. umap/static/umap/locale/ms.json +7 -5
  113. umap/static/umap/locale/nl.js +7 -5
  114. umap/static/umap/locale/nl.json +7 -5
  115. umap/static/umap/locale/no.js +6 -4
  116. umap/static/umap/locale/no.json +6 -4
  117. umap/static/umap/locale/pl.js +53 -51
  118. umap/static/umap/locale/pl.json +53 -51
  119. umap/static/umap/locale/pl_PL.json +6 -4
  120. umap/static/umap/locale/pt.js +7 -5
  121. umap/static/umap/locale/pt.json +7 -5
  122. umap/static/umap/locale/pt_BR.js +6 -4
  123. umap/static/umap/locale/pt_BR.json +6 -4
  124. umap/static/umap/locale/pt_PT.js +6 -4
  125. umap/static/umap/locale/pt_PT.json +6 -4
  126. umap/static/umap/locale/ro.js +6 -4
  127. umap/static/umap/locale/ro.json +6 -4
  128. umap/static/umap/locale/ru.js +6 -4
  129. umap/static/umap/locale/ru.json +6 -4
  130. umap/static/umap/locale/sk_SK.js +6 -4
  131. umap/static/umap/locale/sk_SK.json +6 -4
  132. umap/static/umap/locale/sl.js +6 -4
  133. umap/static/umap/locale/sl.json +6 -4
  134. umap/static/umap/locale/sr.js +6 -4
  135. umap/static/umap/locale/sr.json +6 -4
  136. umap/static/umap/locale/sv.js +6 -4
  137. umap/static/umap/locale/sv.json +6 -4
  138. umap/static/umap/locale/th_TH.js +6 -4
  139. umap/static/umap/locale/th_TH.json +6 -4
  140. umap/static/umap/locale/tr.js +6 -4
  141. umap/static/umap/locale/tr.json +6 -4
  142. umap/static/umap/locale/uk_UA.js +6 -4
  143. umap/static/umap/locale/uk_UA.json +6 -4
  144. umap/static/umap/locale/vi.js +6 -4
  145. umap/static/umap/locale/vi.json +6 -4
  146. umap/static/umap/locale/vi_VN.json +6 -4
  147. umap/static/umap/locale/zh.js +6 -4
  148. umap/static/umap/locale/zh.json +6 -4
  149. umap/static/umap/locale/zh_CN.json +6 -4
  150. umap/static/umap/locale/zh_TW.Big5.json +6 -4
  151. umap/static/umap/locale/zh_TW.js +20 -18
  152. umap/static/umap/locale/zh_TW.json +20 -18
  153. umap/static/umap/map.css +5 -4
  154. umap/static/umap/unittests/utils.js +7 -7
  155. umap/templates/umap/content_footer.html +1 -0
  156. umap/templates/umap/css.html +0 -2
  157. umap/templates/umap/js.html +1 -3
  158. umap/tests/integration/conftest.py +3 -2
  159. umap/tests/integration/test_anonymous_owned_map.py +1 -1
  160. umap/tests/integration/test_conditional_rules.py +106 -51
  161. umap/tests/integration/test_draw_polygon.py +4 -0
  162. umap/tests/integration/test_draw_polyline.py +11 -0
  163. umap/tests/integration/test_edit_datalayer.py +1 -1
  164. umap/tests/integration/test_fields.py +19 -0
  165. umap/tests/integration/test_iframe.py +1 -1
  166. umap/tests/integration/test_import.py +23 -0
  167. umap/tests/integration/test_map.py +2 -2
  168. umap/tests/integration/test_owned_map.py +2 -2
  169. umap/tests/integration/test_popup.py +31 -0
  170. umap/tests/integration/test_remote_data.py +4 -4
  171. umap/tests/integration/test_search.py +41 -0
  172. umap/tests/integration/test_share.py +2 -2
  173. umap/tests/integration/test_team.py +1 -1
  174. umap/tests/integration/test_websocket_sync.py +6 -1
  175. umap/tests/test_utils.py +4 -1
  176. umap/utils.py +1 -0
  177. {umap_project-3.4.0b3.dist-info → umap_project-3.4.2.dist-info}/METADATA +15 -15
  178. {umap_project-3.4.0b3.dist-info → umap_project-3.4.2.dist-info}/RECORD +181 -183
  179. umap/static/umap/js/umap.core.js +0 -93
  180. umap/static/umap/vendors/editinosm/Leaflet.EditInOSM.css +0 -46
  181. umap/static/umap/vendors/editinosm/Leaflet.EditInOSM.js +0 -240
  182. umap/static/umap/vendors/editinosm/edit-in-osm.png +0 -0
  183. {umap_project-3.4.0b3.dist-info → umap_project-3.4.2.dist-info}/WHEEL +0 -0
  184. {umap_project-3.4.0b3.dist-info → umap_project-3.4.2.dist-info}/entry_points.txt +0 -0
  185. {umap_project-3.4.0b3.dist-info → umap_project-3.4.2.dist-info}/licenses/LICENSE +0 -0
@@ -75,6 +75,7 @@ def test_umap_import_from_textarea(live_server, tilelayer, page, settings):
75
75
  page.goto(f"{live_server.url}/map/new/")
76
76
  page.get_by_role("button", name="Open browser").click()
77
77
  page.get_by_title("Import data").click()
78
+ page.wait_for_timeout(300) # Time for the panel animation to finish
78
79
  textarea = page.locator(".umap-import textarea")
79
80
  path = Path(__file__).parent.parent / "fixtures/test_upload_data.umap"
80
81
  textarea.fill(path.read_text())
@@ -108,6 +109,7 @@ def test_import_geojson_from_textarea(tilelayer, live_server, page):
108
109
  expect(paths).to_have_count(0)
109
110
  expect(layers).to_have_count(0)
110
111
  page.get_by_title("Import data").click()
112
+ page.wait_for_timeout(300) # Time for the panel animation to finish
111
113
  textarea = page.locator(".umap-import textarea")
112
114
  path = Path(__file__).parent.parent / "fixtures/test_upload_data.json"
113
115
  textarea.fill(path.read_text())
@@ -131,6 +133,7 @@ def test_import_invalid_data(tilelayer, live_server, page):
131
133
  expect(paths).to_have_count(0)
132
134
  expect(layers).to_have_count(0)
133
135
  page.get_by_title("Import data").click()
136
+ page.wait_for_timeout(300) # Time for the panel animation to finish
134
137
  textarea = page.locator(".umap-import textarea")
135
138
  textarea.fill("invalid data")
136
139
  for format in ["geojson", "csv", "gpx", "kml", "georss", "osm", "umap"]:
@@ -149,6 +152,7 @@ def test_import_kml_from_textarea(tilelayer, live_server, page):
149
152
  expect(paths).to_have_count(0)
150
153
  expect(layers).to_have_count(0)
151
154
  page.get_by_title("Import data").click()
155
+ page.wait_for_timeout(300) # Time for the panel animation to finish
152
156
  textarea = page.locator(".umap-import textarea")
153
157
  path = Path(__file__).parent.parent / "fixtures/test_upload_data.kml"
154
158
  textarea.fill(path.read_text())
@@ -171,6 +175,7 @@ def test_import_gpx_from_textarea(tilelayer, live_server, page, settings):
171
175
  expect(paths).to_have_count(0)
172
176
  expect(layers).to_have_count(0)
173
177
  page.get_by_title("Import data").click()
178
+ page.wait_for_timeout(300) # Time for the panel animation to finish
174
179
  textarea = page.locator(".umap-import textarea")
175
180
  path = Path(__file__).parent.parent / "fixtures/test_upload_data.gpx"
176
181
  textarea.fill(path.read_text())
@@ -226,6 +231,7 @@ def test_import_osm_from_textarea(tilelayer, live_server, page):
226
231
  expect(markers).to_have_count(0)
227
232
  expect(layers).to_have_count(0)
228
233
  page.get_by_title("Import data").click()
234
+ page.wait_for_timeout(300) # Time for the panel animation to finish
229
235
  textarea = page.locator(".umap-import textarea")
230
236
  path = Path(__file__).parent.parent / "fixtures/test_upload_data_osm.json"
231
237
  textarea.fill(path.read_text())
@@ -244,6 +250,7 @@ def test_import_csv_from_textarea(tilelayer, live_server, page):
244
250
  expect(markers).to_have_count(0)
245
251
  expect(layers).to_have_count(0)
246
252
  page.get_by_title("Import data").click()
253
+ page.wait_for_timeout(300) # Time for the panel animation to finish
247
254
  textarea = page.locator(".umap-import textarea")
248
255
  path = Path(__file__).parent.parent / "fixtures/test_upload_data.csv"
249
256
  textarea.fill(path.read_text())
@@ -263,6 +270,7 @@ def test_can_import_in_existing_datalayer(live_server, datalayer, page, openmap)
263
270
  expect(layers).to_have_count(1)
264
271
  page.get_by_role("button", name="Edit").click()
265
272
  page.get_by_title("Import data").click()
273
+ page.wait_for_timeout(300) # Time for the panel animation to finish
266
274
  textarea = page.locator(".umap-import textarea")
267
275
  path = Path(__file__).parent.parent / "fixtures/test_upload_data.csv"
268
276
  textarea.fill(path.read_text())
@@ -284,6 +292,7 @@ def test_can_replace_datalayer_data(live_server, datalayer, page, openmap):
284
292
  expect(layers).to_have_count(1)
285
293
  page.get_by_role("button", name="Edit").click()
286
294
  page.get_by_title("Import data").click()
295
+ page.wait_for_timeout(300) # Time for the panel animation to finish
287
296
  textarea = page.locator(".umap-import textarea")
288
297
  path = Path(__file__).parent.parent / "fixtures/test_upload_data.csv"
289
298
  textarea.fill(path.read_text())
@@ -305,6 +314,7 @@ def test_can_import_in_new_datalayer(live_server, datalayer, page, openmap):
305
314
  expect(layers).to_have_count(1)
306
315
  page.get_by_role("button", name="Edit").click()
307
316
  page.get_by_title("Import data").click()
317
+ page.wait_for_timeout(300) # Time for the panel animation to finish
308
318
  textarea = page.locator(".umap-import textarea")
309
319
  path = Path(__file__).parent.parent / "fixtures/test_upload_data.csv"
310
320
  textarea.fill(path.read_text())
@@ -351,6 +361,7 @@ def test_should_remove_dot_in_property_names(live_server, page, settings, tilela
351
361
  }
352
362
  page.goto(f"{live_server.url}/map/new/")
353
363
  page.get_by_title("Import data").click()
364
+ page.wait_for_timeout(300) # Time for the panel animation to finish
354
365
  textarea = page.locator(".umap-import textarea")
355
366
  textarea.fill(json.dumps(data))
356
367
  page.locator('select[name="format"]').select_option("geojson")
@@ -410,6 +421,7 @@ def test_import_geometry_collection(live_server, page, tilelayer):
410
421
  expect(paths).to_have_count(0)
411
422
  expect(layers).to_have_count(0)
412
423
  page.get_by_title("Import data").click()
424
+ page.wait_for_timeout(300) # Time for the panel animation to finish
413
425
  textarea = page.locator(".umap-import textarea")
414
426
  textarea.fill(json.dumps(data))
415
427
  page.locator('select[name="format"]').select_option("geojson")
@@ -463,6 +475,7 @@ def test_import_geometry_collection_in_feature(live_server, page, tilelayer):
463
475
  expect(paths).to_have_count(0)
464
476
  expect(layers).to_have_count(0)
465
477
  page.get_by_title("Import data").click()
478
+ page.wait_for_timeout(300) # Time for the panel animation to finish
466
479
  textarea = page.locator(".umap-import textarea")
467
480
  textarea.fill(json.dumps(data))
468
481
  page.locator('select[name="format"]').select_option("geojson")
@@ -497,6 +510,7 @@ def test_import_multipolygon(live_server, page, tilelayer):
497
510
  expect(paths).to_have_count(0)
498
511
  expect(layers).to_have_count(0)
499
512
  page.get_by_title("Import data").click()
513
+ page.wait_for_timeout(300) # Time for the panel animation to finish
500
514
  textarea = page.locator(".umap-import textarea")
501
515
  textarea.fill(json.dumps(data))
502
516
  page.locator('select[name="format"]').select_option("geojson")
@@ -527,6 +541,7 @@ def test_import_multipolyline(live_server, page, tilelayer):
527
541
  expect(paths).to_have_count(0)
528
542
  expect(layers).to_have_count(0)
529
543
  page.get_by_title("Import data").click()
544
+ page.wait_for_timeout(300) # Time for the panel animation to finish
530
545
  textarea = page.locator(".umap-import textarea")
531
546
  textarea.fill(json.dumps(data))
532
547
  page.locator('select[name="format"]').select_option("geojson")
@@ -557,6 +572,7 @@ def test_import_false_multipoint(live_server, page, tilelayer):
557
572
  expect(markers).to_have_count(0)
558
573
  expect(layers).to_have_count(0)
559
574
  page.get_by_title("Import data").click()
575
+ page.wait_for_timeout(300) # Time for the panel animation to finish
560
576
  textarea = page.locator(".umap-import textarea")
561
577
  textarea.fill(json.dumps(data))
562
578
  page.locator('select[name="format"]').select_option("geojson")
@@ -621,6 +637,7 @@ def test_should_not_import_empty_coordinates(live_server, page, tilelayer):
621
637
  page.goto(f"{live_server.url}/map/new/")
622
638
  page.get_by_title("Open browser").click()
623
639
  page.get_by_title("Import data").click()
640
+ page.wait_for_timeout(300) # Time for the panel animation to finish
624
641
  textarea = page.locator(".umap-import textarea")
625
642
  textarea.fill(json.dumps(data))
626
643
  page.locator('select[name="format"]').select_option("geojson")
@@ -636,6 +653,7 @@ def test_import_csv_without_valid_latlon_headers(tilelayer, live_server, page):
636
653
  layers = page.locator(".umap-browser .datalayer")
637
654
  markers = page.locator(".leaflet-marker-icon")
638
655
  page.get_by_title("Import data").click()
656
+ page.wait_for_timeout(300) # Time for the panel animation to finish
639
657
  textarea = page.locator(".umap-import textarea")
640
658
  textarea.fill("a,b,c\n12.23,48.34,mypoint\n12.23,48.34,mypoint2")
641
659
  page.locator('select[name="format"]').select_option("csv")
@@ -653,6 +671,7 @@ def test_import_csv_with_commas_in_latlon(tilelayer, live_server, page, settings
653
671
  layers = page.locator(".umap-browser .datalayer")
654
672
  markers = page.locator(".leaflet-marker-icon")
655
673
  page.get_by_title("Import data").click()
674
+ page.wait_for_timeout(300) # Time for the panel animation to finish
656
675
  textarea = page.locator(".umap-import textarea")
657
676
  textarea.fill("lat;lon;foobar\n12,24;48,34;mypoint\n12,23;48,35;mypoint2")
658
677
  page.locator('select[name="format"]').select_option("csv")
@@ -687,6 +706,7 @@ def test_import_csv_with_wkt_geom(tilelayer, live_server, page, settings):
687
706
  markers = page.locator(".leaflet-marker-icon")
688
707
  paths = page.locator("path")
689
708
  page.get_by_title("Import data").click()
709
+ page.wait_for_timeout(300) # Time for the panel animation to finish
690
710
  textarea = page.locator(".umap-import textarea")
691
711
  textarea.fill(
692
712
  "Geom;foobar\nPOLYGON ((-64.8 32.3, -65.5 18.3, -80.3 25.2, -64.8 32.3));mypoly\nPOINT(48.35 12.23);mypoint"
@@ -740,6 +760,7 @@ def test_import_csv_with_geojson_geom(tilelayer, live_server, page, settings):
740
760
  markers = page.locator(".leaflet-marker-icon")
741
761
  paths = page.locator("path")
742
762
  page.get_by_title("Import data").click()
763
+ page.wait_for_timeout(300) # Time for the panel animation to finish
743
764
  textarea = page.locator(".umap-import textarea")
744
765
  textarea.fill(
745
766
  "geojson;foobar\n"
@@ -1034,6 +1055,7 @@ def test_import_osm_relation(tilelayer, live_server, page):
1034
1055
  expect(paths).to_have_count(0)
1035
1056
  expect(layers).to_have_count(0)
1036
1057
  page.get_by_title("Import data").click()
1058
+ page.wait_for_timeout(300) # Time for the panel animation to finish
1037
1059
  textarea = page.locator(".umap-import textarea")
1038
1060
  file_path = Path(__file__).parent.parent / "fixtures/test_import_osm_relation.json"
1039
1061
  textarea.fill(file_path.read_text())
@@ -1052,6 +1074,7 @@ def test_import_georss_from_textarea(tilelayer, live_server, page):
1052
1074
  expect(markers).to_have_count(0)
1053
1075
  expect(layers).to_have_count(0)
1054
1076
  page.get_by_title("Import data").click()
1077
+ page.wait_for_timeout(300) # Time for the panel animation to finish
1055
1078
  textarea = page.locator(".umap-import textarea")
1056
1079
  path = Path(__file__).parent.parent / "fixtures/test_upload_georss.xml"
1057
1080
  textarea.fill(path.read_text())
@@ -147,14 +147,14 @@ def test_default_view_latest_with_polygon(map, live_server, page):
147
147
  expect(layers).to_have_count(1)
148
148
 
149
149
 
150
- def test_default_view_locate(browser, live_server, map):
150
+ def test_default_view_locate(browser, live_server, map, new_page):
151
151
  context = browser.new_context(
152
152
  geolocation={"longitude": 8.52967, "latitude": 39.16267},
153
153
  permissions=["geolocation"],
154
154
  )
155
155
  map.settings["properties"]["defaultView"] = "locate"
156
156
  map.save()
157
- page = context.new_page()
157
+ page = new_page(custom_context=context)
158
158
  page.goto(f"{live_server.url}{map.get_absolute_url()}")
159
159
  expect(page).to_have_url(re.compile(r".*#18/39\.16267/8\.52967"))
160
160
 
@@ -183,7 +183,7 @@ def test_can_change_perms_after_create(tilelayer, live_server, login, user):
183
183
  page.goto(f"{live_server.url}/en/map/new")
184
184
  # Create a layer
185
185
  page.get_by_title("Manage layers").click()
186
- page.get_by_title("Add a layer").click()
186
+ page.get_by_role("button", name="Add a layer").click()
187
187
  page.locator("input[name=name]").fill("Layer 1")
188
188
  expect(
189
189
  page.get_by_role("button", name="Visibility: Draft (private)")
@@ -217,7 +217,7 @@ def test_can_change_owner(map, live_server, login, user):
217
217
  page.goto(f"{live_server.url}{map.get_absolute_url()}?edit")
218
218
  edit_permissions = page.get_by_title("Update permissions and editors")
219
219
  edit_permissions.click()
220
- close = page.locator(".umap-field-owner .close")
220
+ close = page.locator(".umap-field-owner .icon-close")
221
221
  close.click()
222
222
  input = page.locator("input.edit-owner")
223
223
  with page.expect_response(re.compile(r".*/agnocomplete/.*")):
@@ -42,3 +42,34 @@ def test_openstreetmap_popup(live_server, map, page):
42
42
  "src",
43
43
  "https://api.panoramax.xyz/api/pictures/d811b398-d930-4cf8-95a2-0c29c34d9fca/sd.jpg",
44
44
  )
45
+
46
+
47
+ def test_table_popup(live_server, map, page):
48
+ data = {
49
+ "type": "FeatureCollection",
50
+ "features": [
51
+ {
52
+ "type": "Feature",
53
+ "geometry": {"type": "Point", "coordinates": [2.49, 48.79]},
54
+ "properties": {
55
+ "url": "https://restaurant.org",
56
+ "formatted": "with **bold**",
57
+ },
58
+ "id": "AzMjk",
59
+ },
60
+ ],
61
+ "_umap_options": {
62
+ "popupTemplate": "Table",
63
+ "fields": [
64
+ {"key": "url", "type": "String"},
65
+ {"key": "formatted", "type": "Text"},
66
+ ],
67
+ },
68
+ }
69
+ DataLayerFactory(map=map, data=data)
70
+ page.goto(f"{live_server.url}{map.get_absolute_url()}#18/48.79/2.49")
71
+ page.locator(".leaflet-marker-icon").click()
72
+ expect(page.get_by_role("link", name="https://restaurant.org")).to_be_visible()
73
+ expect(page.get_by_role("cell", name="with bold").locator("strong")).to_have_text(
74
+ "bold"
75
+ )
@@ -16,7 +16,7 @@ def intercept_remote_data(page):
16
16
  "features": [
17
17
  {
18
18
  "type": "Feature",
19
- "properties": {"name": "Point 2"},
19
+ "properties": {"name": "Point 2", "foobar": "bla"},
20
20
  "geometry": {
21
21
  "type": "Point",
22
22
  "coordinates": [4.3375, 11.2707],
@@ -29,7 +29,7 @@ def intercept_remote_data(page):
29
29
  "features": [
30
30
  {
31
31
  "type": "Feature",
32
- "properties": {"name": "Point 1"},
32
+ "properties": {"name": "Point 1", "foobar": "baz"},
33
33
  "geometry": {
34
34
  "type": "Point",
35
35
  "coordinates": [4.3375, 12.2707],
@@ -117,8 +117,8 @@ def test_create_remote_data_layer(page, live_server, tilelayer, settings):
117
117
  "type": "String",
118
118
  },
119
119
  {
120
- "key": "description",
121
- "type": "Text",
120
+ "key": "foobar",
121
+ "type": "String",
122
122
  },
123
123
  ],
124
124
  "id": str(datalayer.pk),
@@ -0,0 +1,41 @@
1
+ from playwright.sync_api import expect
2
+
3
+
4
+ def test_reverse_search(live_server, page, tilelayer):
5
+ photon_response = {
6
+ "type": "FeatureCollection",
7
+ "features": [
8
+ {
9
+ "type": "Feature",
10
+ "properties": {
11
+ "osm_type": "N",
12
+ "osm_id": 5055853416,
13
+ "osm_key": "place",
14
+ "osm_value": "locality",
15
+ "type": "locality",
16
+ "postcode": "10200",
17
+ "countrycode": "FR",
18
+ "name": "Le Haut Sentier",
19
+ "country": "France",
20
+ "city": "Thors",
21
+ "state": "Grand Est",
22
+ "county": "Aube",
23
+ },
24
+ "geometry": {"type": "Point", "coordinates": [4.7995256, 48.2985251]},
25
+ }
26
+ ],
27
+ }
28
+ page.goto(f"{live_server.url}/en/map/new")
29
+
30
+ def handle_search(route):
31
+ route.fulfill(json=photon_response)
32
+
33
+ # Intercept the route
34
+ page.route(
35
+ "https://photon.komoot.io/reverse/?limit=1&lat=48.3&lon=4.8",
36
+ handle_search,
37
+ )
38
+ page.get_by_role("button", name="Search location").click()
39
+ page.get_by_role("searchbox", name="Type a place name or").fill("48.3 4.8")
40
+ expect(page.get_by_text("48.3 4.8")).to_be_visible()
41
+ expect(page.get_by_text("Le Haut Sentier")).to_be_visible()
@@ -8,7 +8,7 @@ pytestmark = pytest.mark.django_db
8
8
 
9
9
  def test_iframe_code_can_contain_datalayers(map, live_server, datalayer, page):
10
10
  page.goto(f"{live_server.url}{map.get_absolute_url()}?share")
11
- textarea = page.locator(".umap-share-iframe")
11
+ textarea = page.get_by_label("Iframe")
12
12
  expect(textarea).to_be_visible()
13
13
  expect(textarea).to_have_text(re.compile('src="'))
14
14
  expect(textarea).to_have_text(re.compile('href="'))
@@ -28,7 +28,7 @@ def test_iframe_code_can_contain_datalayers(map, live_server, datalayer, page):
28
28
  def test_iframe_code_can_contain_feature(map, live_server, datalayer, page):
29
29
  page.goto(f"{live_server.url}{map.get_absolute_url()}?share")
30
30
  page.locator(".icon-container").click()
31
- textarea = page.locator(".umap-share-iframe")
31
+ textarea = page.get_by_label("Iframe")
32
32
  expect(textarea).to_be_visible()
33
33
  expect(textarea).not_to_have_text(re.compile("feature=Here"))
34
34
  # Open options
@@ -39,7 +39,7 @@ def test_can_remove_user_from_team(live_server, map, user, user2, team, login):
39
39
  page.get_by_role("link", name="My teams").click()
40
40
  with page.expect_navigation():
41
41
  page.get_by_role("link", name="Edit").click()
42
- page.locator("li").filter(has_text="Averell").locator(".close").click()
42
+ page.locator("li").filter(has_text="Averell").locator(".icon-close").click()
43
43
  page.get_by_role("button", name="Save").click()
44
44
  assert Team.objects.count() == 1
45
45
  modified = Team.objects.first()
@@ -53,6 +53,7 @@ def test_websocket_connection_can_sync_markers(
53
53
 
54
54
  a_map_el = peerA.locator("#map")
55
55
  a_map_el.click(position={"x": 220, "y": 220})
56
+ peerA.wait_for_timeout(300) # Time for the panel animation to finish
56
57
  expect(a_marker_pane).to_have_count(1)
57
58
  expect(b_marker_pane).to_have_count(1)
58
59
  # Peer B should not be in state dirty
@@ -330,6 +331,7 @@ def test_websocket_connection_can_sync_late_joining_peer(
330
331
 
331
332
  a_map_el = peerA.locator("#map")
332
333
  a_map_el.click(position={"x": 220, "y": 220})
334
+ peerA.wait_for_timeout(300) # Time for the panel animation to finish
333
335
  peerA.locator("body").type("First marker")
334
336
  peerA.locator("body").press("Escape")
335
337
  peerA.wait_for_timeout(300)
@@ -555,8 +557,10 @@ def test_create_and_sync_map(
555
557
 
556
558
  # Add a marker from peer A
557
559
  peerA.get_by_role("button", name="Edit").click()
560
+ peerA.wait_for_timeout(300) # Time for the animation to finish
558
561
  peerA.get_by_title("Draw a marker").click()
559
562
  peerA.locator("#map").click(position={"x": 220, "y": 220})
563
+ peerA.wait_for_timeout(300) # Time for the panel animation to finish
560
564
  expect(markersA).to_have_count(1)
561
565
  expect(markersB).to_have_count(1)
562
566
 
@@ -582,6 +586,7 @@ def test_create_and_sync_map(
582
586
  # Add a marker from peer B
583
587
  peerB.get_by_title("Draw a marker").click()
584
588
  peerB.locator("#map").click(position={"x": 200, "y": 200})
589
+ peerA.wait_for_timeout(300) # Time for the panel animation to finish
585
590
  expect(markersB).to_have_count(2)
586
591
  expect(markersA).to_have_count(1)
587
592
  with peerB.expect_response(re.compile("./datalayer/update/.*")):
@@ -607,7 +612,7 @@ def test_saved_datalayer_are_not_duplicated(
607
612
  wait_for_loaded(peerA)
608
613
  # Create a new datalayer
609
614
  peerA.get_by_title("Manage layers").click()
610
- peerA.get_by_title("Add a layer").click()
615
+ peerA.get_by_role("button", name="Add a layer").click()
611
616
  peerA.locator("#map").click(position={"x": 220, "y": 220})
612
617
  # Save layer to the server, so now the datalayer exist on the server AND
613
618
  # is still in the live operations of peer A
umap/tests/test_utils.py CHANGED
@@ -1,3 +1,4 @@
1
+ import stat
1
2
  from pathlib import Path
2
3
 
3
4
  import pytest
@@ -5,7 +6,8 @@ import pytest
5
6
  from umap.utils import gzip_file, normalize_string
6
7
 
7
8
 
8
- def test_gzip_file():
9
+ def test_gzip_file(settings):
10
+ settings.FILE_UPLOAD_PERMISSIONS = 0o666
9
11
  # Let's use any old file so we can check that the date of the gzip file is set.
10
12
  src = Path(__file__).parent / "settings.py"
11
13
  dest = Path("/tmp/test_settings.py.gz")
@@ -14,6 +16,7 @@ def test_gzip_file():
14
16
  dest_stat = dest.stat()
15
17
  dest.unlink()
16
18
  assert src_stat.st_mtime == dest_stat.st_mtime
19
+ assert stat.filemode(dest_stat.st_mode) == "-rw-rw-rw-"
17
20
 
18
21
 
19
22
  @pytest.mark.parametrize(
umap/utils.py CHANGED
@@ -150,6 +150,7 @@ def gzip_file(from_path, to_path):
150
150
  with gzip.open(to_path, "wb") as f_out:
151
151
  f_out.writelines(f_in)
152
152
  os.utime(to_path, ns=(stat.st_mtime_ns, stat.st_mtime_ns))
153
+ os.chmod(to_path, settings.FILE_UPLOAD_PERMISSIONS)
153
154
 
154
155
 
155
156
  def is_ajax(request):
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: umap-project
3
- Version: 3.4.0b3
3
+ Version: 3.4.2
4
4
  Summary: Create maps with OpenStreetMap layers in a minute and embed them in your site.
5
5
  Author-email: Yohan Boniface <yb@enix.org>
6
6
  Maintainer-email: David Larlet <david@larlet.fr>
@@ -19,31 +19,31 @@ Requires-Python: >=3.10
19
19
  Requires-Dist: django-agnocomplete==2.2.0
20
20
  Requires-Dist: django-environ==0.12.0
21
21
  Requires-Dist: django-probes==1.7.0
22
- Requires-Dist: django==5.2.7
23
- Requires-Dist: pillow==11.3.0
24
- Requires-Dist: psycopg==3.2.11
25
- Requires-Dist: rcssmin==1.2.1
22
+ Requires-Dist: django==5.2.8
23
+ Requires-Dist: pillow==12.0.0
24
+ Requires-Dist: psycopg==3.2.13
25
+ Requires-Dist: rcssmin==1.2.2
26
26
  Requires-Dist: requests==2.32.5
27
- Requires-Dist: rjsmin==1.2.4
28
- Requires-Dist: social-auth-app-django==5.4.3
29
- Requires-Dist: social-auth-core==4.5.6
27
+ Requires-Dist: rjsmin==1.2.5
28
+ Requires-Dist: social-auth-app-django==5.6.0
29
+ Requires-Dist: social-auth-core==4.8.1
30
30
  Provides-Extra: dev
31
31
  Requires-Dist: djlint==1.36.4; extra == 'dev'
32
- Requires-Dist: hatch==1.14.2; extra == 'dev'
33
- Requires-Dist: isort==6.0.1; extra == 'dev'
34
- Requires-Dist: mkdocs-material==9.6.21; extra == 'dev'
32
+ Requires-Dist: hatch==1.15.1; extra == 'dev'
33
+ Requires-Dist: isort==7.0.0; extra == 'dev'
34
+ Requires-Dist: mkdocs-material==9.7.0; extra == 'dev'
35
35
  Requires-Dist: mkdocs-static-i18n==1.3.0; extra == 'dev'
36
36
  Requires-Dist: mkdocs==1.6.1; extra == 'dev'
37
37
  Requires-Dist: pymdown-extensions==10.16.1; extra == 'dev'
38
- Requires-Dist: ruff==0.14.0; extra == 'dev'
39
- Requires-Dist: vermin==1.6.0; extra == 'dev'
38
+ Requires-Dist: ruff==0.14.5; extra == 'dev'
39
+ Requires-Dist: vermin==1.7.0; extra == 'dev'
40
40
  Provides-Extra: docker
41
- Requires-Dist: uvicorn==0.37.0; extra == 'docker'
41
+ Requires-Dist: uvicorn==0.38.0; extra == 'docker'
42
42
  Provides-Extra: s3
43
43
  Requires-Dist: django-storages[s3]==1.14.6; extra == 's3'
44
44
  Provides-Extra: sync
45
45
  Requires-Dist: pydantic==2.12.3; extra == 'sync'
46
- Requires-Dist: redis==6.4.0; extra == 'sync'
46
+ Requires-Dist: redis==7.1.0; extra == 'sync'
47
47
  Requires-Dist: websockets==15.0.1; extra == 'sync'
48
48
  Provides-Extra: test
49
49
  Requires-Dist: daphne==4.2.1; extra == 'test'