umap-project 2.1.2__py3-none-any.whl → 2.2.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 (211) hide show
  1. umap/__init__.py +1 -1
  2. umap/context_processors.py +1 -0
  3. umap/locale/br/LC_MESSAGES/django.mo +0 -0
  4. umap/locale/en/LC_MESSAGES/django.po +32 -32
  5. umap/locale/hu/LC_MESSAGES/django.mo +0 -0
  6. umap/locale/it/LC_MESSAGES/django.mo +0 -0
  7. umap/locale/ms/LC_MESSAGES/django.mo +0 -0
  8. umap/migrations/0020_alter_tilelayer_url_template.py +19 -0
  9. umap/migrations/0021_remove_map_description.py +16 -0
  10. umap/models.py +10 -6
  11. umap/settings/base.py +1 -0
  12. umap/static/umap/base.css +43 -156
  13. umap/static/umap/content.css +7 -25
  14. umap/static/umap/css/icon.css +112 -0
  15. umap/static/umap/css/panel.css +140 -0
  16. umap/static/umap/img/16-white.svg +5 -1
  17. umap/static/umap/img/16.svg +7 -4
  18. umap/static/umap/img/24-white.svg +3 -1
  19. umap/static/umap/img/24.svg +3 -4
  20. umap/static/umap/img/source/16-white.svg +176 -940
  21. umap/static/umap/img/source/16.svg +8 -5
  22. umap/static/umap/img/source/24-white.svg +5 -3
  23. umap/static/umap/img/source/24.svg +6 -7
  24. umap/static/umap/js/modules/browser.js +97 -73
  25. umap/static/umap/js/modules/dompurify.js +12 -0
  26. umap/static/umap/js/modules/facets.js +149 -0
  27. umap/static/umap/js/modules/global.js +9 -1
  28. umap/static/umap/js/modules/i18n.js +7 -0
  29. umap/static/umap/js/modules/orderable.js +84 -0
  30. umap/static/umap/js/modules/panel.js +76 -0
  31. umap/static/umap/js/modules/request.js +0 -1
  32. umap/static/umap/js/modules/schema.js +324 -223
  33. umap/static/umap/js/modules/urls.js +1 -16
  34. umap/static/umap/js/modules/utils.js +340 -0
  35. umap/static/umap/js/umap.autocomplete.js +40 -25
  36. umap/static/umap/js/umap.controls.js +248 -361
  37. umap/static/umap/js/umap.core.js +77 -366
  38. umap/static/umap/js/umap.datalayer.permissions.js +1 -1
  39. umap/static/umap/js/umap.features.js +65 -43
  40. umap/static/umap/js/umap.forms.js +128 -36
  41. umap/static/umap/js/umap.icon.js +11 -4
  42. umap/static/umap/js/umap.importer.js +78 -58
  43. umap/static/umap/js/umap.js +206 -192
  44. umap/static/umap/js/umap.layer.js +86 -46
  45. umap/static/umap/js/umap.permissions.js +13 -9
  46. umap/static/umap/js/umap.popup.js +26 -30
  47. umap/static/umap/js/umap.share.js +12 -9
  48. umap/static/umap/js/umap.tableeditor.js +4 -6
  49. umap/static/umap/js/umap.ui.js +10 -60
  50. umap/static/umap/locale/am_ET.js +243 -227
  51. umap/static/umap/locale/am_ET.json +21 -9
  52. umap/static/umap/locale/ar.js +243 -227
  53. umap/static/umap/locale/ar.json +21 -9
  54. umap/static/umap/locale/ast.js +243 -227
  55. umap/static/umap/locale/ast.json +21 -9
  56. umap/static/umap/locale/bg.js +243 -227
  57. umap/static/umap/locale/bg.json +21 -9
  58. umap/static/umap/locale/br.js +253 -237
  59. umap/static/umap/locale/br.json +25 -13
  60. umap/static/umap/locale/ca.js +243 -227
  61. umap/static/umap/locale/ca.json +21 -9
  62. umap/static/umap/locale/cs_CZ.js +243 -227
  63. umap/static/umap/locale/cs_CZ.json +21 -9
  64. umap/static/umap/locale/da.js +243 -227
  65. umap/static/umap/locale/da.json +21 -9
  66. umap/static/umap/locale/de.js +243 -227
  67. umap/static/umap/locale/de.json +21 -9
  68. umap/static/umap/locale/el.js +243 -227
  69. umap/static/umap/locale/el.json +21 -9
  70. umap/static/umap/locale/en.js +243 -234
  71. umap/static/umap/locale/en.json +22 -10
  72. umap/static/umap/locale/en_US.json +21 -9
  73. umap/static/umap/locale/es.js +243 -227
  74. umap/static/umap/locale/es.json +21 -9
  75. umap/static/umap/locale/et.js +243 -227
  76. umap/static/umap/locale/et.json +21 -9
  77. umap/static/umap/locale/eu.js +227 -199
  78. umap/static/umap/locale/eu.json +1 -1
  79. umap/static/umap/locale/fa_IR.js +243 -227
  80. umap/static/umap/locale/fa_IR.json +21 -9
  81. umap/static/umap/locale/fi.js +243 -227
  82. umap/static/umap/locale/fi.json +21 -9
  83. umap/static/umap/locale/fr.js +243 -234
  84. umap/static/umap/locale/fr.json +21 -9
  85. umap/static/umap/locale/gl.js +243 -227
  86. umap/static/umap/locale/gl.json +21 -9
  87. umap/static/umap/locale/he.js +243 -227
  88. umap/static/umap/locale/he.json +21 -9
  89. umap/static/umap/locale/hr.js +243 -227
  90. umap/static/umap/locale/hr.json +21 -9
  91. umap/static/umap/locale/hu.js +243 -234
  92. umap/static/umap/locale/hu.json +21 -9
  93. umap/static/umap/locale/id.js +243 -227
  94. umap/static/umap/locale/id.json +21 -9
  95. umap/static/umap/locale/is.js +243 -227
  96. umap/static/umap/locale/is.json +21 -9
  97. umap/static/umap/locale/it.js +243 -234
  98. umap/static/umap/locale/it.json +21 -9
  99. umap/static/umap/locale/ja.js +243 -227
  100. umap/static/umap/locale/ja.json +21 -9
  101. umap/static/umap/locale/ko.js +243 -227
  102. umap/static/umap/locale/ko.json +21 -9
  103. umap/static/umap/locale/lt.js +243 -227
  104. umap/static/umap/locale/lt.json +21 -9
  105. umap/static/umap/locale/ms.js +243 -234
  106. umap/static/umap/locale/ms.json +22 -10
  107. umap/static/umap/locale/nl.js +246 -230
  108. umap/static/umap/locale/nl.json +21 -9
  109. umap/static/umap/locale/no.js +243 -227
  110. umap/static/umap/locale/no.json +21 -9
  111. umap/static/umap/locale/pl.js +243 -227
  112. umap/static/umap/locale/pl.json +21 -9
  113. umap/static/umap/locale/pl_PL.json +21 -9
  114. umap/static/umap/locale/pt.js +243 -227
  115. umap/static/umap/locale/pt.json +21 -9
  116. umap/static/umap/locale/pt_BR.js +243 -227
  117. umap/static/umap/locale/pt_BR.json +21 -9
  118. umap/static/umap/locale/pt_PT.js +243 -227
  119. umap/static/umap/locale/pt_PT.json +21 -9
  120. umap/static/umap/locale/ro.js +243 -227
  121. umap/static/umap/locale/ro.json +21 -9
  122. umap/static/umap/locale/ru.js +243 -227
  123. umap/static/umap/locale/ru.json +21 -9
  124. umap/static/umap/locale/si.js +1 -1
  125. umap/static/umap/locale/si.json +1 -1
  126. umap/static/umap/locale/sk_SK.js +243 -227
  127. umap/static/umap/locale/sk_SK.json +21 -9
  128. umap/static/umap/locale/sl.js +243 -227
  129. umap/static/umap/locale/sl.json +21 -9
  130. umap/static/umap/locale/sr.js +243 -227
  131. umap/static/umap/locale/sr.json +21 -9
  132. umap/static/umap/locale/sv.js +243 -227
  133. umap/static/umap/locale/sv.json +21 -9
  134. umap/static/umap/locale/th_TH.js +243 -227
  135. umap/static/umap/locale/th_TH.json +21 -9
  136. umap/static/umap/locale/tr.js +243 -227
  137. umap/static/umap/locale/tr.json +21 -9
  138. umap/static/umap/locale/uk_UA.js +243 -227
  139. umap/static/umap/locale/uk_UA.json +21 -9
  140. umap/static/umap/locale/vi.js +243 -227
  141. umap/static/umap/locale/vi.json +21 -9
  142. umap/static/umap/locale/vi_VN.json +21 -9
  143. umap/static/umap/locale/zh.js +243 -227
  144. umap/static/umap/locale/zh.json +21 -9
  145. umap/static/umap/locale/zh_CN.json +21 -9
  146. umap/static/umap/locale/zh_TW.Big5.json +21 -9
  147. umap/static/umap/locale/zh_TW.js +243 -234
  148. umap/static/umap/locale/zh_TW.json +21 -9
  149. umap/static/umap/map.css +124 -264
  150. umap/static/umap/test/DataLayer.js +1 -1
  151. umap/static/umap/test/Feature.js +0 -226
  152. umap/static/umap/test/Map.js +0 -304
  153. umap/static/umap/test/Polygon.js +0 -256
  154. umap/static/umap/test/Polyline.js +0 -116
  155. umap/static/umap/test/TableEditor.js +10 -10
  156. umap/static/umap/test/Util.js +0 -521
  157. umap/static/umap/test/index.html +1 -5
  158. umap/static/umap/unittests/URLs.js +1 -1
  159. umap/static/umap/unittests/utils.js +610 -0
  160. umap/static/umap/vars.css +9 -0
  161. umap/static/umap/vendors/dompurify/purify.es.mjs +1525 -0
  162. umap/static/umap/vendors/formbuilder/Leaflet.FormBuilder.js +1 -0
  163. umap/static/umap/vendors/iconlayers/iconLayers.js +1 -1
  164. umap/templates/umap/css.html +2 -0
  165. umap/templates/umap/js.html +0 -1
  166. umap/templates/umap/map_detail.html +4 -0
  167. umap/templates/umap/map_table.html +12 -10
  168. umap/templatetags/umap_tags.py +5 -0
  169. umap/tests/conftest.py +9 -0
  170. umap/tests/fixtures/test_upload_data.csv +2 -1
  171. umap/tests/fixtures/test_upload_data.umap +171 -0
  172. umap/tests/fixtures/test_upload_data_osm.json +33 -0
  173. umap/tests/integration/conftest.py +16 -0
  174. umap/tests/integration/test_anonymous_owned_map.py +30 -5
  175. umap/tests/integration/test_basics.py +21 -0
  176. umap/tests/integration/test_browser.py +16 -36
  177. umap/tests/integration/test_choropleth.py +89 -0
  178. umap/tests/integration/test_collaborative_editing.py +30 -1
  179. umap/tests/integration/test_dashboard.py +10 -0
  180. umap/tests/integration/test_datalayer.py +132 -0
  181. umap/tests/integration/test_draw_polygon.py +363 -0
  182. umap/tests/integration/test_draw_polyline.py +325 -0
  183. umap/tests/integration/test_edit_datalayer.py +145 -6
  184. umap/tests/integration/test_edit_map.py +202 -0
  185. umap/tests/integration/test_edit_marker.py +120 -0
  186. umap/tests/integration/test_edit_polygon.py +122 -0
  187. umap/tests/integration/test_facets_browser.py +132 -11
  188. umap/tests/integration/test_import.py +407 -10
  189. umap/tests/integration/test_map.py +36 -54
  190. umap/tests/integration/test_map_list.py +28 -0
  191. umap/tests/integration/test_owned_map.py +24 -6
  192. umap/tests/integration/test_picto.py +25 -38
  193. umap/tests/integration/test_querystring.py +9 -15
  194. umap/tests/integration/test_slideshow.py +0 -5
  195. umap/tests/integration/test_statics.py +3 -2
  196. umap/tests/integration/test_tableeditor.py +23 -0
  197. umap/tests/integration/test_tilelayer.py +10 -0
  198. umap/tests/integration/test_view_marker.py +64 -0
  199. umap/tests/integration/test_view_polygon.py +59 -0
  200. umap/tests/integration/test_view_polyline.py +51 -0
  201. umap/tests/test_map_views.py +13 -0
  202. {umap_project-2.1.2.dist-info → umap_project-2.2.0.dist-info}/METADATA +12 -12
  203. {umap_project-2.1.2.dist-info → umap_project-2.2.0.dist-info}/RECORD +206 -187
  204. {umap_project-2.1.2.dist-info → umap_project-2.2.0.dist-info}/WHEEL +1 -1
  205. umap/static/umap/test/Choropleth.js +0 -245
  206. umap/static/umap/test/Permissions.js +0 -74
  207. umap/static/umap/vendors/dompurify/purify.min.js +0 -3
  208. umap/static/umap/vendors/dompurify/purify.min.js.map +0 -1
  209. umap/tests/integration/test_drawing.py +0 -243
  210. {umap_project-2.1.2.dist-info → umap_project-2.2.0.dist-info}/entry_points.txt +0 -0
  211. {umap_project-2.1.2.dist-info → umap_project-2.2.0.dist-info}/licenses/LICENSE +0 -0
@@ -22,7 +22,7 @@ def test_map_update_with_owner(map, live_server, login):
22
22
  expect(save).to_be_visible()
23
23
  add_marker = page.get_by_title("Draw a marker")
24
24
  expect(add_marker).to_be_visible()
25
- edit_settings = page.get_by_title("Edit map properties")
25
+ edit_settings = page.get_by_title("Map advanced properties")
26
26
  expect(edit_settings).to_be_visible()
27
27
  edit_permissions = page.get_by_title("Update permissions and editors")
28
28
  expect(edit_permissions).to_be_visible()
@@ -49,7 +49,7 @@ def test_map_update_with_anonymous_but_editable_datalayer(
49
49
  enable.click()
50
50
  add_marker = page.get_by_title("Draw a marker")
51
51
  expect(add_marker).to_be_visible()
52
- edit_settings = page.get_by_title("Edit map properties")
52
+ edit_settings = page.get_by_title("Map advanced properties")
53
53
  expect(edit_settings).to_be_hidden()
54
54
  edit_permissions = page.get_by_title("Update permissions and editors")
55
55
  expect(edit_permissions).to_be_hidden()
@@ -97,7 +97,7 @@ def test_map_update_with_editor(map, live_server, login, user):
97
97
  expect(save).to_be_visible()
98
98
  add_marker = page.get_by_title("Draw a marker")
99
99
  expect(add_marker).to_be_visible()
100
- edit_settings = page.get_by_title("Edit map properties")
100
+ edit_settings = page.get_by_title("Map advanced properties")
101
101
  expect(edit_settings).to_be_visible()
102
102
  edit_permissions = page.get_by_title("Update permissions and editors")
103
103
  expect(edit_permissions).to_be_visible()
@@ -126,7 +126,7 @@ def test_permissions_form_with_editor(map, datalayer, live_server, login, user):
126
126
  def test_owner_has_delete_map_button(map, live_server, login):
127
127
  page = login(map.owner)
128
128
  page.goto(f"{live_server.url}{map.get_absolute_url()}?edit")
129
- settings = page.get_by_title("Edit map properties")
129
+ settings = page.get_by_title("Map advanced properties")
130
130
  expect(settings).to_be_visible()
131
131
  settings.click()
132
132
  advanced = page.get_by_text("Advanced actions")
@@ -154,7 +154,7 @@ def test_editor_do_not_have_delete_map_button(map, live_server, login, user):
154
154
  map.save()
155
155
  page = login(user)
156
156
  page.goto(f"{live_server.url}{map.get_absolute_url()}?edit")
157
- settings = page.get_by_title("Edit map properties")
157
+ settings = page.get_by_title("Map advanced properties")
158
158
  expect(settings).to_be_visible()
159
159
  settings.click()
160
160
  advanced = page.get_by_text("Advanced actions")
@@ -187,7 +187,7 @@ def test_can_change_perms_after_create(tilelayer, live_server, login, user):
187
187
  page.goto(f"{live_server.url}/en/map/new")
188
188
  # Create a layer
189
189
  page.get_by_title("Manage layers").click()
190
- page.get_by_role("button", name="Add a layer").click()
190
+ page.get_by_title("Add a layer").click()
191
191
  page.locator("input[name=name]").fill("Layer 1")
192
192
  save = page.get_by_role("button", name="Save")
193
193
  expect(save).to_be_visible()
@@ -231,3 +231,21 @@ def test_can_change_owner(map, live_server, login, user):
231
231
  save.click()
232
232
  modified = Map.objects.get(pk=map.pk)
233
233
  assert modified.owner == user
234
+
235
+
236
+ def test_can_delete_datalayer(live_server, map, login, datalayer):
237
+ page = login(map.owner)
238
+ page.goto(f"{live_server.url}{map.get_absolute_url()}?edit")
239
+ page.get_by_title("See layers").click()
240
+ layers = page.locator(".umap-browser .datalayer")
241
+ markers = page.locator(".leaflet-marker-icon")
242
+ expect(layers).to_have_count(1)
243
+ expect(markers).to_have_count(1)
244
+ page.get_by_role("link", name="Manage layers").click()
245
+ page.once("dialog", lambda dialog: dialog.accept())
246
+ page.locator(".panel.right").get_by_title("Delete layer").click()
247
+ with page.expect_response(re.compile(r".*/datalayer/delete/.*")):
248
+ page.get_by_role("button", name="Save").click()
249
+ expect(markers).to_have_count(0)
250
+ # FIXME does not work, resolve to 1 element, even if this command is empty:
251
+ expect(layers).to_have_count(0)
@@ -5,7 +5,7 @@ import pytest
5
5
  from django.core.files.base import ContentFile
6
6
  from playwright.sync_api import expect
7
7
 
8
- from umap.models import Map, Pictogram
8
+ from umap.models import Pictogram
9
9
 
10
10
  from ..base import DataLayerFactory
11
11
 
@@ -37,17 +37,14 @@ def pictos():
37
37
  Pictogram(name="circle", pictogram=ContentFile(path.read_text(), path.name)).save()
38
38
 
39
39
 
40
- def test_can_change_picto_at_map_level(map, live_server, page, pictos):
41
- # Faster than doing a login
42
- map.edit_status = Map.ANONYMOUS
43
- map.save()
44
- DataLayerFactory(map=map, data=DATALAYER_DATA)
45
- page.goto(f"{live_server.url}{map.get_absolute_url()}?edit")
40
+ def test_can_change_picto_at_map_level(openmap, live_server, page, pictos):
41
+ DataLayerFactory(map=openmap, data=DATALAYER_DATA)
42
+ page.goto(f"{live_server.url}{openmap.get_absolute_url()}?edit")
46
43
  marker = page.locator(".umap-div-icon img")
47
44
  expect(marker).to_have_count(1)
48
45
  # Should have default img
49
46
  expect(marker).to_have_attribute("src", "/static/umap/img/marker.svg")
50
- edit_settings = page.get_by_title("Edit map properties")
47
+ edit_settings = page.get_by_title("Map advanced properties")
51
48
  expect(edit_settings).to_be_visible()
52
49
  edit_settings.click()
53
50
  shape_settings = page.get_by_text("Default shape properties")
@@ -71,13 +68,11 @@ def test_can_change_picto_at_map_level(map, live_server, page, pictos):
71
68
  expect(marker).to_have_attribute("src", "/static/umap/img/marker.svg")
72
69
 
73
70
 
74
- def test_can_change_picto_at_datalayer_level(map, live_server, page, pictos):
75
- # Faster than doing a login
76
- map.edit_status = Map.ANONYMOUS
77
- map.settings["properties"]["iconUrl"] = "/uploads/pictogram/star.svg"
78
- map.save()
79
- DataLayerFactory(map=map, data=DATALAYER_DATA)
80
- page.goto(f"{live_server.url}{map.get_absolute_url()}?edit")
71
+ def test_can_change_picto_at_datalayer_level(openmap, live_server, page, pictos):
72
+ openmap.settings["properties"]["iconUrl"] = "/uploads/pictogram/star.svg"
73
+ openmap.save()
74
+ DataLayerFactory(map=openmap, data=DATALAYER_DATA)
75
+ page.goto(f"{live_server.url}{openmap.get_absolute_url()}?edit")
81
76
  marker = page.locator(".umap-div-icon img")
82
77
  expect(marker).to_have_count(1)
83
78
  # Should have default img
@@ -112,13 +107,11 @@ def test_can_change_picto_at_datalayer_level(map, live_server, page, pictos):
112
107
  expect(marker).to_have_attribute("src", "/uploads/pictogram/star.svg")
113
108
 
114
109
 
115
- def test_can_change_picto_at_marker_level(map, live_server, page, pictos):
116
- # Faster than doing a login
117
- map.edit_status = Map.ANONYMOUS
118
- map.settings["properties"]["iconUrl"] = "/uploads/pictogram/star.svg"
119
- map.save()
120
- DataLayerFactory(map=map, data=DATALAYER_DATA)
121
- page.goto(f"{live_server.url}{map.get_absolute_url()}?edit")
110
+ def test_can_change_picto_at_marker_level(openmap, live_server, page, pictos):
111
+ openmap.settings["properties"]["iconUrl"] = "/uploads/pictogram/star.svg"
112
+ openmap.save()
113
+ DataLayerFactory(map=openmap, data=DATALAYER_DATA)
114
+ page.goto(f"{live_server.url}{openmap.get_absolute_url()}?edit")
122
115
  marker = page.locator(".umap-div-icon img")
123
116
  expect(marker).to_have_count(1)
124
117
  # Should have default img
@@ -152,17 +145,14 @@ def test_can_change_picto_at_marker_level(map, live_server, page, pictos):
152
145
  expect(marker).to_have_attribute("src", "/uploads/pictogram/star.svg")
153
146
 
154
147
 
155
- def test_can_use_remote_url_as_picto(map, live_server, page, pictos):
156
- # Faster than doing a login
157
- map.edit_status = Map.ANONYMOUS
158
- map.save()
159
- DataLayerFactory(map=map, data=DATALAYER_DATA)
160
- page.goto(f"{live_server.url}{map.get_absolute_url()}?edit")
148
+ def test_can_use_remote_url_as_picto(openmap, live_server, page, pictos):
149
+ DataLayerFactory(map=openmap, data=DATALAYER_DATA)
150
+ page.goto(f"{live_server.url}{openmap.get_absolute_url()}?edit")
161
151
  marker = page.locator(".umap-div-icon img")
162
152
  expect(marker).to_have_count(1)
163
153
  # Should have default img
164
154
  expect(marker).to_have_attribute("src", "/static/umap/img/marker.svg")
165
- edit_settings = page.get_by_title("Edit map properties")
155
+ edit_settings = page.get_by_title("Map advanced properties")
166
156
  expect(edit_settings).to_be_visible()
167
157
  edit_settings.click()
168
158
  shape_settings = page.get_by_text("Default shape properties")
@@ -181,7 +171,7 @@ def test_can_use_remote_url_as_picto(map, live_server, page, pictos):
181
171
  input_el.blur()
182
172
  expect(marker).to_have_attribute("src", "https://foo.bar/img.jpg")
183
173
  # Now close and reopen the form, it should still be the URL tab
184
- close = page.locator("#umap-ui-container .toolbox").get_by_title("Close")
174
+ close = page.locator(".panel.right.on .toolbox").get_by_title("Close")
185
175
  expect(close).to_be_visible()
186
176
  close.click()
187
177
  edit_settings.click()
@@ -195,16 +185,13 @@ def test_can_use_remote_url_as_picto(map, live_server, page, pictos):
195
185
  expect(symbols).to_have_count(1)
196
186
 
197
187
 
198
- def test_can_use_char_as_picto(map, live_server, page, pictos):
199
- # Faster than doing a login
200
- map.edit_status = Map.ANONYMOUS
201
- map.save()
202
- DataLayerFactory(map=map, data=DATALAYER_DATA)
203
- page.goto(f"{live_server.url}{map.get_absolute_url()}?edit")
188
+ def test_can_use_char_as_picto(openmap, live_server, page, pictos):
189
+ DataLayerFactory(map=openmap, data=DATALAYER_DATA)
190
+ page.goto(f"{live_server.url}{openmap.get_absolute_url()}?edit")
204
191
  marker = page.locator(".umap-div-icon span")
205
192
  # Should have default img, so not a span
206
193
  expect(marker).to_have_count(0)
207
- edit_settings = page.get_by_title("Edit map properties")
194
+ edit_settings = page.get_by_title("Map advanced properties")
208
195
  expect(edit_settings).to_be_visible()
209
196
  edit_settings.click()
210
197
  shape_settings = page.get_by_text("Default shape properties")
@@ -223,7 +210,7 @@ def test_can_use_char_as_picto(map, live_server, page, pictos):
223
210
  expect(marker).to_have_count(1)
224
211
  expect(marker).to_have_text("♩")
225
212
  # Now close and reopen the form, it should still be the URL tab
226
- close = page.locator("#umap-ui-container .toolbox").get_by_title("Close")
213
+ close = page.locator(".panel.right.on .toolbox").get_by_title("Close")
227
214
  expect(close).to_be_visible()
228
215
  close.click()
229
216
  edit_settings.click()
@@ -15,30 +15,24 @@ def test_scale_control(map, live_server, datalayer, page):
15
15
 
16
16
 
17
17
  def test_datalayers_control(map, live_server, datalayer, page):
18
- control = page.locator(".umap-browse-toggle")
19
- box = page.locator(".umap-browse-datalayers")
20
- more = page.get_by_title("More controls")
18
+ control = page.locator(".umap-control-browse")
19
+ browser = page.locator(".umap-browser")
21
20
  page.goto(f"{live_server.url}{map.get_absolute_url()}")
22
21
  expect(control).to_be_visible()
23
- expect(box).to_be_hidden()
22
+ expect(browser).to_be_hidden()
24
23
  page.goto(f"{live_server.url}{map.get_absolute_url()}?datalayersControl=true")
25
24
  expect(control).to_be_visible()
26
- expect(box).to_be_hidden()
25
+ expect(browser).to_be_hidden()
27
26
  page.goto(f"{live_server.url}{map.get_absolute_url()}?datalayersControl=null")
28
27
  expect(control).to_be_hidden()
29
- expect(more).to_be_visible()
30
- more.click()
31
- expect(control).to_be_visible()
32
- expect(box).to_be_hidden()
28
+ expect(browser).to_be_hidden()
33
29
  page.goto(f"{live_server.url}{map.get_absolute_url()}?datalayersControl=false")
34
30
  expect(control).to_be_hidden()
35
- expect(more).to_be_visible()
36
- more.click()
37
- expect(control).to_be_hidden()
38
- expect(box).to_be_hidden()
31
+ expect(browser).to_be_hidden()
32
+ # Retrocompat
39
33
  page.goto(f"{live_server.url}{map.get_absolute_url()}?datalayersControl=expanded")
40
- expect(control).to_be_hidden()
41
- expect(box).to_be_visible()
34
+ expect(control).to_be_visible()
35
+ expect(browser).to_be_visible()
42
36
 
43
37
 
44
38
  def test_can_deactivate_wheel_from_query_string(map, live_server, page):
@@ -1,11 +1,6 @@
1
- from pathlib import Path
2
-
3
1
  import pytest
4
- from django.core.files.base import ContentFile
5
2
  from playwright.sync_api import expect
6
3
 
7
- from umap.models import Map, Pictogram
8
-
9
4
  from ..base import DataLayerFactory
10
5
 
11
6
  pytestmark = pytest.mark.django_db
@@ -40,7 +40,8 @@ def test_javascript_have_been_loaded(
40
40
  expect(page).to_have_url(re.compile(r".*#7/48\..+/13\..+"))
41
41
  expect(page).to_have_url(re.compile(r".*/fr/"))
42
42
  # Should be in French, so hashed locale file has been loaded correctly
43
- button = page.get_by_text("Voir les calques")
43
+ button = page.get_by_role("button", name="Voir les calques")
44
44
  expect(button).to_be_visible()
45
- layers = page.locator(".umap-browse-datalayers li")
45
+ button.click()
46
+ layers = page.locator(".umap-browser .datalayer")
46
47
  expect(layers).to_have_count(1)
@@ -0,0 +1,23 @@
1
+ import json
2
+ import re
3
+ from pathlib import Path
4
+
5
+ from umap.models import DataLayer
6
+
7
+
8
+ def test_table_editor(live_server, openmap, datalayer, page):
9
+ page.goto(f"{live_server.url}{openmap.get_absolute_url()}?edit")
10
+ page.get_by_role("link", name="Manage layers").click()
11
+ page.locator(".panel").get_by_title("Edit properties in a table").click()
12
+ page.once("dialog", lambda dialog: dialog.accept(prompt_text="newprop"))
13
+ page.get_by_text("Add a new property").click()
14
+ page.locator('input[name="newprop"]').fill("newvalue")
15
+ page.once("dialog", lambda dialog: dialog.accept())
16
+ page.hover(".umap-table-editor .tcell")
17
+ page.get_by_title("Delete this property on all").first.click()
18
+ with page.expect_response(re.compile(r".*/datalayer/update/.*")):
19
+ page.get_by_role("button", name="Save").click()
20
+ saved = DataLayer.objects.last()
21
+ data = json.loads(Path(saved.geojson.path).read_text())
22
+ assert data["features"][0]["properties"]["newprop"] == "newvalue"
23
+ assert "name" not in data["features"][0]["properties"]
@@ -112,3 +112,13 @@ def test_map_should_display_custom_tilelayer(map, live_server, tilelayers, page)
112
112
  iconTiles = page.locator(".leaflet-iconLayers .leaflet-iconLayers-layer")
113
113
  # The second of the list should be the current
114
114
  expect(iconTiles.nth(1)).to_have_css("background-image", url_pattern)
115
+
116
+
117
+ def test_can_have_smart_text_in_attribution(tilelayer, map, live_server, page):
118
+ map.settings["properties"]["tilelayer"]["attribution"] = (
119
+ "© [[http://www.openstreetmap.org/copyright|OpenStreetMap]] contributors"
120
+ )
121
+ map.save()
122
+ page.goto(f"{live_server.url}{map.get_absolute_url()}")
123
+ expect(page.get_by_text("© OpenStreetMap contributors")).to_be_visible()
124
+ expect(page.get_by_role("link", name="OpenStreetMap")).to_be_visible()
@@ -0,0 +1,64 @@
1
+ from copy import deepcopy
2
+
3
+ import pytest
4
+ from playwright.sync_api import expect
5
+
6
+ from ..base import DataLayerFactory
7
+
8
+ pytestmark = pytest.mark.django_db
9
+
10
+ DATALAYER_DATA = {
11
+ "type": "FeatureCollection",
12
+ "features": [
13
+ {
14
+ "type": "Feature",
15
+ "properties": {
16
+ "name": "test marker",
17
+ "description": "Some description",
18
+ },
19
+ "geometry": {
20
+ "type": "Point",
21
+ "coordinates": [14.6889, 48.5529],
22
+ },
23
+ },
24
+ ],
25
+ }
26
+
27
+
28
+ @pytest.fixture
29
+ def bootstrap(map, live_server):
30
+ DataLayerFactory(map=map, data=DATALAYER_DATA)
31
+
32
+
33
+ def test_should_open_popup_on_click(live_server, map, page, bootstrap):
34
+ page.goto(f"{live_server.url}{map.get_absolute_url()}")
35
+ expect(page.locator(".umap-icon-active")).to_be_hidden()
36
+ page.locator(".leaflet-marker-icon").click()
37
+ expect(page.locator(".umap-icon-active")).to_be_visible()
38
+ expect(page.locator(".leaflet-popup-content-wrapper")).to_be_visible()
39
+ expect(page.get_by_role("heading", name="test marker")).to_be_visible()
40
+ expect(page.get_by_text("Some description")).to_be_visible()
41
+ # Close popup
42
+ page.locator("#map").click()
43
+ expect(page.locator(".umap-icon-active")).to_be_hidden()
44
+
45
+
46
+ def test_should_handle_locale_var_in_description(live_server, map, page):
47
+ data = deepcopy(DATALAYER_DATA)
48
+ data["features"][0]["properties"]["description"] = (
49
+ "this is a link to [[https://domain.org/?locale={locale}|Wikipedia]]"
50
+ )
51
+ DataLayerFactory(map=map, data=data)
52
+ page.goto(f"{live_server.url}{map.get_absolute_url()}")
53
+ page.locator(".leaflet-marker-icon").click()
54
+ link = page.get_by_role("link", name="Wikipedia")
55
+ expect(link).to_be_visible()
56
+ expect(link).to_have_attribute("href", "https://domain.org/?locale=en")
57
+
58
+
59
+ def test_should_display_tooltip_with_variable(live_server, map, page, bootstrap):
60
+ map.settings["properties"]["showLabel"] = True
61
+ map.settings["properties"]["labelKey"] = "Foo {name}"
62
+ map.save()
63
+ page.goto(f"{live_server.url}{map.get_absolute_url()}")
64
+ expect(page.get_by_text("Foo test marker")).to_be_visible()
@@ -0,0 +1,59 @@
1
+ import re
2
+
3
+ import pytest
4
+ from playwright.sync_api import expect
5
+
6
+ from ..base import DataLayerFactory
7
+
8
+ pytestmark = pytest.mark.django_db
9
+
10
+ DATALAYER_DATA = {
11
+ "type": "FeatureCollection",
12
+ "features": [
13
+ {
14
+ "type": "Feature",
15
+ "properties": {"name": "name poly", "description": "poly description"},
16
+ "id": "gyNzM",
17
+ "geometry": {
18
+ "type": "Polygon",
19
+ "coordinates": [
20
+ [
21
+ [11.25, 53.585984],
22
+ [10.151367, 52.975108],
23
+ [12.689209, 52.167194],
24
+ [14.084473, 53.199452],
25
+ [12.634277, 53.618579],
26
+ [11.25, 53.585984],
27
+ [11.25, 53.585984],
28
+ ],
29
+ ],
30
+ },
31
+ },
32
+ ],
33
+ }
34
+
35
+
36
+ @pytest.fixture
37
+ def bootstrap(map, live_server):
38
+ map.settings["properties"]["zoom"] = 6
39
+ map.settings["geometry"] = {
40
+ "type": "Point",
41
+ "coordinates": [8.429, 53.239],
42
+ }
43
+ map.save()
44
+ DataLayerFactory(map=map, data=DATALAYER_DATA)
45
+
46
+
47
+ def test_should_open_popup_on_click(live_server, map, page, bootstrap):
48
+ page.goto(f"{live_server.url}{map.get_absolute_url()}")
49
+ polygon = page.locator("path").first
50
+ expect(polygon).to_have_attribute("fill-opacity", "0.3")
51
+ polygon.click()
52
+ expect(page.locator(".leaflet-popup-content-wrapper")).to_be_visible()
53
+ expect(page.get_by_role("heading", name="name poly")).to_be_visible()
54
+ expect(page.get_by_text("poly description")).to_be_visible()
55
+ # It's not a round value
56
+ expect(polygon).to_have_attribute("fill-opacity", re.compile(r"0.5\d+"))
57
+ # Close popup
58
+ page.locator("#map").click()
59
+ expect(polygon).to_have_attribute("fill-opacity", "0.3")
@@ -0,0 +1,51 @@
1
+ import pytest
2
+ from playwright.sync_api import expect
3
+
4
+ from ..base import DataLayerFactory
5
+
6
+ pytestmark = pytest.mark.django_db
7
+
8
+ DATALAYER_DATA = {
9
+ "type": "FeatureCollection",
10
+ "features": [
11
+ {
12
+ "type": "Feature",
13
+ "properties": {"name": "name line", "description": "line description"},
14
+ "geometry": {
15
+ "type": "LineString",
16
+ "coordinates": [
17
+ # Flat line so PW will click on it
18
+ # (it compute the center of the element)
19
+ [11.25, 53.585984],
20
+ [10.151367, 52.975108],
21
+ ],
22
+ },
23
+ },
24
+ ],
25
+ }
26
+
27
+
28
+ @pytest.fixture
29
+ def bootstrap(map, live_server):
30
+ map.settings["properties"]["zoom"] = 6
31
+ map.settings["geometry"] = {
32
+ "type": "Point",
33
+ "coordinates": [8.429, 53.239],
34
+ }
35
+ map.save()
36
+ DataLayerFactory(map=map, data=DATALAYER_DATA)
37
+
38
+
39
+ def test_should_open_popup_on_click(live_server, map, page, bootstrap):
40
+ page.goto(f"{live_server.url}{map.get_absolute_url()}")
41
+ line = page.locator("path").first
42
+ expect(line).to_have_attribute("stroke-opacity", "0.5")
43
+ line.click()
44
+ expect(page.locator(".leaflet-popup-content-wrapper")).to_be_visible()
45
+ expect(page.get_by_role("heading", name="name line")).to_be_visible()
46
+ expect(page.get_by_text("line description")).to_be_visible()
47
+ # It's not a round value
48
+ expect(line).to_have_attribute("stroke-opacity", "1")
49
+ # Close popup
50
+ page.locator("#map").click()
51
+ expect(line).to_have_attribute("stroke-opacity", "0.5")
@@ -847,3 +847,16 @@ def test_oembed_link(client, map, datalayer):
847
847
  f'?url=http%3A%2F%2Ftestserver%2Fen%2Fmap%2Ftest-map_{map.id}&format=json"'
848
848
  ) in response.content.decode()
849
849
  assert 'title="test map oEmbed URL" />' in response.content.decode()
850
+
851
+
852
+ def test_ogp_links(client, map, datalayer):
853
+ response = client.get(map.get_absolute_url())
854
+ assert response.status_code == 200
855
+ content = response.content.decode()
856
+ assert (
857
+ f'<meta property="og:url" content="http://umap.org{map.get_absolute_url()}" />'
858
+ in content
859
+ )
860
+ assert f'<meta property="og:title" content="{map.name}" />' in content
861
+ assert f'<meta property="og:description" content="{map.description}" />' in content
862
+ assert '<meta property="og:site_name" content="uMap" />' in content
@@ -1,6 +1,6 @@
1
- Metadata-Version: 2.1
1
+ Metadata-Version: 2.3
2
2
  Name: umap-project
3
- Version: 2.1.2
3
+ Version: 2.2.0
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,32 +19,32 @@ Requires-Python: >=3.10
19
19
  Requires-Dist: django-agnocomplete==2.2.0
20
20
  Requires-Dist: django-environ==0.11.2
21
21
  Requires-Dist: django-probes==1.7.0
22
- Requires-Dist: django==5.0.3
23
- Requires-Dist: pillow==10.2.0
22
+ Requires-Dist: django==5.0.4
23
+ Requires-Dist: pillow==10.3.0
24
24
  Requires-Dist: psycopg==3.1.18
25
25
  Requires-Dist: rcssmin==1.1.2
26
26
  Requires-Dist: requests==2.31.0
27
27
  Requires-Dist: rjsmin==1.2.2
28
- Requires-Dist: social-auth-app-django==5.4.0
29
- Requires-Dist: social-auth-core==4.5.3
28
+ Requires-Dist: social-auth-app-django==5.4.1
29
+ Requires-Dist: social-auth-core==4.5.4
30
30
  Provides-Extra: dev
31
31
  Requires-Dist: djlint==1.34.1; extra == 'dev'
32
- Requires-Dist: hatch==1.9.4; extra == 'dev'
32
+ Requires-Dist: hatch==1.9.7; extra == 'dev'
33
33
  Requires-Dist: isort==5.13.2; extra == 'dev'
34
- Requires-Dist: mkdocs-material==9.5.14; extra == 'dev'
34
+ Requires-Dist: mkdocs-material==9.5.18; extra == 'dev'
35
35
  Requires-Dist: mkdocs==1.5.3; extra == 'dev'
36
- Requires-Dist: pymdown-extensions==10.7.1; extra == 'dev'
37
- Requires-Dist: ruff==0.3.3; extra == 'dev'
36
+ Requires-Dist: pymdown-extensions==10.8.1; extra == 'dev'
37
+ Requires-Dist: ruff==0.4.2; extra == 'dev'
38
38
  Requires-Dist: vermin==1.6.0; extra == 'dev'
39
39
  Provides-Extra: docker
40
- Requires-Dist: uwsgi==2.0.24; extra == 'docker'
40
+ Requires-Dist: uwsgi==2.0.25.1; extra == 'docker'
41
41
  Provides-Extra: test
42
42
  Requires-Dist: factory-boy==3.2.1; extra == 'test'
43
43
  Requires-Dist: playwright>=1.39; extra == 'test'
44
44
  Requires-Dist: pytest-django==4.8.0; extra == 'test'
45
45
  Requires-Dist: pytest-playwright==0.4.4; extra == 'test'
46
46
  Requires-Dist: pytest-xdist<4,>=3.5.0; extra == 'test'
47
- Requires-Dist: pytest==8.0.2; extra == 'test'
47
+ Requires-Dist: pytest==8.2.0; extra == 'test'
48
48
  Description-Content-Type: text/markdown
49
49
 
50
50
  # uMap project