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
@@ -1,16 +1,41 @@
1
+ import json
2
+ import platform
3
+ import re
1
4
  from pathlib import Path
5
+ from time import sleep
2
6
 
3
7
  import pytest
4
8
  from playwright.sync_api import expect
5
9
 
10
+ from umap.models import DataLayer
11
+
6
12
  pytestmark = pytest.mark.django_db
7
13
 
8
14
 
9
- def test_umap_import_from_file(live_server, datalayer, page):
15
+ def test_layers_list_is_updated(live_server, tilelayer, page):
10
16
  page.goto(f"{live_server.url}/map/new/")
11
- button = page.get_by_title("Import data")
12
- expect(button).to_be_visible()
13
- button.click()
17
+ modifier = "Cmd" if platform.system() == "Darwin" else "Ctrl"
18
+ page.get_by_role("link", name=f"Import data ({modifier}+I)").click()
19
+ # Should work
20
+ page.get_by_label("Choose the layer to import").select_option(
21
+ label="Import in a new layer"
22
+ )
23
+ page.get_by_role("link", name="Manage layers").click()
24
+ page.get_by_role("button", name="Add a layer").click()
25
+ page.locator('input[name="name"]').click()
26
+ page.locator('input[name="name"]').fill("foobar")
27
+ page.get_by_role("link", name=f"Import data ({modifier}+I)").click()
28
+ # Should still work
29
+ page.get_by_label("Choose the layer to import").select_option(
30
+ label="Import in a new layer"
31
+ )
32
+ # Now layer should be visible in the options
33
+ page.get_by_label("Choose the layer to import").select_option(label="foobar")
34
+
35
+
36
+ def test_umap_import_from_file(live_server, tilelayer, page):
37
+ page.goto(f"{live_server.url}/map/new/")
38
+ page.get_by_title("Import data").click()
14
39
  file_input = page.locator("input[type='file']")
15
40
  with page.expect_file_chooser() as fc_info:
16
41
  file_input.click()
@@ -20,19 +45,55 @@ def test_umap_import_from_file(live_server, datalayer, page):
20
45
  button = page.get_by_role("button", name="Import", exact=True)
21
46
  expect(button).to_be_visible()
22
47
  button.click()
23
- layers = page.locator(".umap-browse-datalayers li")
24
- expect(layers).to_have_count(2)
25
- nonloaded = page.locator(".umap-browse-datalayers li.off")
26
- expect(nonloaded).to_have_count(1)
27
48
  assert file_input.input_value()
28
49
  # Close the import panel
29
50
  page.keyboard.press("Escape")
51
+ # Reopen
52
+ page.get_by_title("Import data").click()
53
+ sleep(1) # Wait for CSS transition to happen
30
54
  assert not file_input.input_value()
55
+ expect(page.locator(".umap-main-edit-toolbox .map-name")).to_have_text(
56
+ "Carte sans nom"
57
+ )
58
+ page.get_by_title("See layers").click()
59
+ layers = page.locator(".umap-browser .datalayer")
60
+ expect(layers).to_have_count(2)
61
+ nonloaded = page.locator(".umap-browser .datalayer.off")
62
+ expect(nonloaded).to_have_count(1)
63
+
64
+
65
+ def test_umap_import_from_textarea(live_server, tilelayer, page, settings):
66
+ settings.UMAP_ALLOW_ANONYMOUS = True
67
+ page.goto(f"{live_server.url}/map/new/")
68
+ page.get_by_role("button", name="See layers").click()
69
+ page.get_by_title("Import data").click()
70
+ textarea = page.locator(".umap-upload textarea")
71
+ path = Path(__file__).parent.parent / "fixtures/test_upload_data.umap"
72
+ textarea.fill(path.read_text())
73
+ page.locator('select[name="format"]').select_option("umap")
74
+ page.get_by_role("button", name="Import", exact=True).click()
75
+ layers = page.locator(".umap-browser .datalayer")
76
+ expect(layers).to_have_count(2)
77
+ expect(page.locator(".umap-main-edit-toolbox .map-name")).to_have_text(
78
+ "Imported map"
79
+ )
80
+ expect(page.get_by_text("Tunnels")).to_be_visible()
81
+ expect(page.get_by_text("Cities")).to_be_visible()
82
+ expect(page.locator(".leaflet-control-minimap")).to_be_visible()
83
+ expect(
84
+ page.locator('img[src="https://tile.openstreetmap.fr/hot/6/32/21.png"]')
85
+ ).to_be_visible()
86
+ # Should not have imported umap_id, while in the file options
87
+ assert not page.evaluate("U.MAP.options.umap_id")
88
+ with page.expect_response(re.compile(r".*/datalayer/create/.*")):
89
+ page.get_by_role("button", name="Save").click()
90
+ assert page.evaluate("U.MAP.options.umap_id")
31
91
 
32
92
 
33
- def test_umap_import_geojson_from_textarea(live_server, datalayer, page):
93
+ def test_import_geojson_from_textarea(tilelayer, live_server, page):
34
94
  page.goto(f"{live_server.url}/map/new/")
35
- layers = page.locator(".umap-browse-datalayers li")
95
+ page.get_by_title("See layers").click()
96
+ layers = page.locator(".umap-browser .datalayer")
36
97
  markers = page.locator(".leaflet-marker-icon")
37
98
  paths = page.locator("path")
38
99
  expect(markers).to_have_count(0)
@@ -52,3 +113,339 @@ def test_umap_import_geojson_from_textarea(live_server, datalayer, page):
52
113
  expect(layers).to_have_count(1)
53
114
  expect(markers).to_have_count(2)
54
115
  expect(paths).to_have_count(3)
116
+
117
+
118
+ def test_import_kml_from_textarea(tilelayer, live_server, page):
119
+ page.goto(f"{live_server.url}/map/new/")
120
+ page.get_by_title("See layers").click()
121
+ layers = page.locator(".umap-browser .datalayer")
122
+ markers = page.locator(".leaflet-marker-icon")
123
+ paths = page.locator("path")
124
+ expect(markers).to_have_count(0)
125
+ expect(paths).to_have_count(0)
126
+ expect(layers).to_have_count(0)
127
+ button = page.get_by_title("Import data")
128
+ expect(button).to_be_visible()
129
+ button.click()
130
+ textarea = page.locator(".umap-upload textarea")
131
+ path = Path(__file__).parent.parent / "fixtures/test_upload_data.kml"
132
+ textarea.fill(path.read_text())
133
+ page.locator('select[name="format"]').select_option("kml")
134
+ button = page.get_by_role("button", name="Import", exact=True)
135
+ expect(button).to_be_visible()
136
+ button.click()
137
+ # A layer has been created
138
+ expect(layers).to_have_count(1)
139
+ expect(markers).to_have_count(1)
140
+ expect(paths).to_have_count(2)
141
+
142
+
143
+ def test_import_gpx_from_textarea(tilelayer, live_server, page):
144
+ page.goto(f"{live_server.url}/map/new/")
145
+ page.get_by_title("See layers").click()
146
+ layers = page.locator(".umap-browser .datalayer")
147
+ markers = page.locator(".leaflet-marker-icon")
148
+ paths = page.locator("path")
149
+ expect(markers).to_have_count(0)
150
+ expect(paths).to_have_count(0)
151
+ expect(layers).to_have_count(0)
152
+ button = page.get_by_title("Import data")
153
+ expect(button).to_be_visible()
154
+ button.click()
155
+ textarea = page.locator(".umap-upload textarea")
156
+ path = Path(__file__).parent.parent / "fixtures/test_upload_data.gpx"
157
+ textarea.fill(path.read_text())
158
+ page.locator('select[name="format"]').select_option("gpx")
159
+ button = page.get_by_role("button", name="Import", exact=True)
160
+ expect(button).to_be_visible()
161
+ button.click()
162
+ # A layer has been created
163
+ expect(layers).to_have_count(1)
164
+ expect(markers).to_have_count(1)
165
+ expect(paths).to_have_count(1)
166
+
167
+
168
+ def test_import_osm_from_textarea(tilelayer, live_server, page):
169
+ page.goto(f"{live_server.url}/map/new/")
170
+ page.get_by_title("See layers").click()
171
+ layers = page.locator(".umap-browser .datalayer")
172
+ markers = page.locator(".leaflet-marker-icon")
173
+ expect(markers).to_have_count(0)
174
+ expect(layers).to_have_count(0)
175
+ button = page.get_by_title("Import data")
176
+ expect(button).to_be_visible()
177
+ button.click()
178
+ textarea = page.locator(".umap-upload textarea")
179
+ path = Path(__file__).parent.parent / "fixtures/test_upload_data_osm.json"
180
+ textarea.fill(path.read_text())
181
+ page.locator('select[name="format"]').select_option("osm")
182
+ page.get_by_role("button", name="Import", exact=True).click()
183
+ # A layer has been created
184
+ expect(layers).to_have_count(1)
185
+ expect(markers).to_have_count(2)
186
+
187
+
188
+ def test_import_csv_from_textarea(tilelayer, live_server, page):
189
+ page.goto(f"{live_server.url}/map/new/")
190
+ page.get_by_title("See layers").click()
191
+ layers = page.locator(".umap-browser .datalayer")
192
+ markers = page.locator(".leaflet-marker-icon")
193
+ expect(markers).to_have_count(0)
194
+ expect(layers).to_have_count(0)
195
+ button = page.get_by_title("Import data")
196
+ expect(button).to_be_visible()
197
+ button.click()
198
+ textarea = page.locator(".umap-upload textarea")
199
+ path = Path(__file__).parent.parent / "fixtures/test_upload_data.csv"
200
+ textarea.fill(path.read_text())
201
+ page.locator('select[name="format"]').select_option("csv")
202
+ page.get_by_role("button", name="Import", exact=True).click()
203
+ # A layer has been created
204
+ expect(layers).to_have_count(1)
205
+ expect(markers).to_have_count(2)
206
+
207
+
208
+ def test_can_import_in_existing_datalayer(live_server, datalayer, page, openmap):
209
+ page.goto(f"{live_server.url}{openmap.get_absolute_url()}")
210
+ page.get_by_title("See layers").click()
211
+ layers = page.locator(".umap-browser .datalayer")
212
+ markers = page.locator(".leaflet-marker-icon")
213
+ expect(markers).to_have_count(1)
214
+ expect(layers).to_have_count(1)
215
+ page.get_by_role("button", name="Edit").click()
216
+ page.get_by_title("Import data").click()
217
+ textarea = page.locator(".umap-upload textarea")
218
+ path = Path(__file__).parent.parent / "fixtures/test_upload_data.csv"
219
+ textarea.fill(path.read_text())
220
+ page.locator('select[name="format"]').select_option("csv")
221
+ page.get_by_role("button", name="Import", exact=True).click()
222
+ # No layer has been created
223
+ expect(layers).to_have_count(1)
224
+ expect(markers).to_have_count(3)
225
+
226
+
227
+ def test_can_replace_datalayer_data(live_server, datalayer, page, openmap):
228
+ page.goto(f"{live_server.url}{openmap.get_absolute_url()}")
229
+ page.get_by_title("See layers").click()
230
+ layers = page.locator(".umap-browser .datalayer")
231
+ markers = page.locator(".leaflet-marker-icon")
232
+ expect(markers).to_have_count(1)
233
+ expect(layers).to_have_count(1)
234
+ page.get_by_role("button", name="Edit").click()
235
+ page.get_by_title("Import data").click()
236
+ textarea = page.locator(".umap-upload textarea")
237
+ path = Path(__file__).parent.parent / "fixtures/test_upload_data.csv"
238
+ textarea.fill(path.read_text())
239
+ page.locator('select[name="format"]').select_option("csv")
240
+ page.get_by_label("Replace layer content").check()
241
+ page.get_by_role("button", name="Import", exact=True).click()
242
+ # No layer has been created
243
+ expect(layers).to_have_count(1)
244
+ expect(markers).to_have_count(2)
245
+
246
+
247
+ def test_can_import_in_new_datalayer(live_server, datalayer, page, openmap):
248
+ page.goto(f"{live_server.url}{openmap.get_absolute_url()}")
249
+ page.get_by_title("See layers").click()
250
+ layers = page.locator(".umap-browser .datalayer")
251
+ markers = page.locator(".leaflet-marker-icon")
252
+ expect(markers).to_have_count(1)
253
+ expect(layers).to_have_count(1)
254
+ page.get_by_role("button", name="Edit").click()
255
+ page.get_by_title("Import data").click()
256
+ textarea = page.locator(".umap-upload textarea")
257
+ path = Path(__file__).parent.parent / "fixtures/test_upload_data.csv"
258
+ textarea.fill(path.read_text())
259
+ page.locator('select[name="format"]').select_option("csv")
260
+ page.get_by_label("Choose the layer to import").select_option(
261
+ label="Import in a new layer"
262
+ )
263
+ page.get_by_role("button", name="Import", exact=True).click()
264
+ # A new layer has been created
265
+ expect(layers).to_have_count(2)
266
+ expect(markers).to_have_count(3)
267
+
268
+
269
+ def test_should_remove_dot_in_property_names(live_server, page, settings, tilelayer):
270
+ settings.UMAP_ALLOW_ANONYMOUS = True
271
+ data = {
272
+ "type": "FeatureCollection",
273
+ "features": [
274
+ {
275
+ "geometry": {
276
+ "type": "Point",
277
+ "coordinates": [6.922931671142578, 47.481161607175736],
278
+ },
279
+ "type": "Feature",
280
+ "properties": {
281
+ "color": "",
282
+ "name": "Chez Rémy",
283
+ "A . in the name": "",
284
+ },
285
+ },
286
+ {
287
+ "geometry": {
288
+ "type": "LineString",
289
+ "coordinates": [
290
+ [2.4609375, 48.88639177703194],
291
+ [2.48291015625, 48.76343113791796],
292
+ [2.164306640625, 48.719961222646276],
293
+ ],
294
+ },
295
+ "type": "Feature",
296
+ "properties": {"color": "", "name": "Périf", "with a dot.": ""},
297
+ },
298
+ ],
299
+ }
300
+ page.goto(f"{live_server.url}/map/new/")
301
+ page.get_by_title("Import data").click()
302
+ textarea = page.locator(".umap-upload textarea")
303
+ textarea.fill(json.dumps(data))
304
+ page.locator('select[name="format"]').select_option("geojson")
305
+ page.get_by_role("button", name="Import", exact=True).click()
306
+ with page.expect_response(re.compile(r".*/datalayer/create/.*")):
307
+ page.get_by_role("button", name="Save").click()
308
+ datalayer = DataLayer.objects.last()
309
+ saved_data = json.loads(Path(datalayer.geojson.path).read_text())
310
+ assert saved_data["features"][0]["properties"] == {
311
+ "color": "",
312
+ "name": "Chez Rémy",
313
+ "A _ in the name": "",
314
+ }
315
+ assert saved_data["features"][1]["properties"] == {
316
+ "color": "",
317
+ "name": "Périf",
318
+ "with a dot_": "",
319
+ }
320
+
321
+
322
+ def test_import_geometry_collection(live_server, page, tilelayer):
323
+ data = {
324
+ "type": "GeometryCollection",
325
+ "geometries": [
326
+ {"type": "Point", "coordinates": [-80.6608, 35.0493]},
327
+ {
328
+ "type": "Polygon",
329
+ "coordinates": [
330
+ [
331
+ [-80.6645, 35.0449],
332
+ [-80.6634, 35.0460],
333
+ [-80.6625, 35.0455],
334
+ [-80.6638, 35.0442],
335
+ [-80.6645, 35.0449],
336
+ ]
337
+ ],
338
+ },
339
+ {
340
+ "type": "LineString",
341
+ "coordinates": [
342
+ [-80.66237, 35.05950],
343
+ [-80.66269, 35.05926],
344
+ [-80.66284, 35.05893],
345
+ [-80.66308, 35.05833],
346
+ [-80.66385, 35.04387],
347
+ [-80.66303, 35.04371],
348
+ ],
349
+ },
350
+ ],
351
+ }
352
+ page.goto(f"{live_server.url}/map/new/")
353
+ page.get_by_title("See layers").click()
354
+ layers = page.locator(".umap-browser .datalayer")
355
+ markers = page.locator(".leaflet-marker-icon")
356
+ paths = page.locator("path")
357
+ expect(markers).to_have_count(0)
358
+ expect(paths).to_have_count(0)
359
+ expect(layers).to_have_count(0)
360
+ button = page.get_by_title("Import data")
361
+ expect(button).to_be_visible()
362
+ button.click()
363
+ textarea = page.locator(".umap-upload textarea")
364
+ textarea.fill(json.dumps(data))
365
+ page.locator('select[name="format"]').select_option("geojson")
366
+ page.get_by_role("button", name="Import", exact=True).click()
367
+ # A layer has been created
368
+ expect(layers).to_have_count(1)
369
+ expect(markers).to_have_count(1)
370
+ expect(paths).to_have_count(2)
371
+
372
+
373
+ def test_import_multipolygon(live_server, page, tilelayer):
374
+ data = {
375
+ "type": "Feature",
376
+ "properties": {"name": "Some states"},
377
+ "geometry": {
378
+ "type": "MultiPolygon",
379
+ "coordinates": [
380
+ [
381
+ [[-109, 36], [-109, 40], [-102, 37], [-109, 36]],
382
+ [[-108, 39], [-107, 37], [-104, 37], [-108, 39]],
383
+ ],
384
+ [[[-119, 42], [-120, 39], [-114, 41], [-119, 42]]],
385
+ ],
386
+ },
387
+ }
388
+ page.goto(f"{live_server.url}/map/new/")
389
+ page.get_by_title("See layers").click()
390
+ layers = page.locator(".umap-browser .datalayer")
391
+ paths = page.locator("path")
392
+ expect(paths).to_have_count(0)
393
+ expect(layers).to_have_count(0)
394
+ button = page.get_by_title("Import data")
395
+ expect(button).to_be_visible()
396
+ button.click()
397
+ textarea = page.locator(".umap-upload textarea")
398
+ textarea.fill(json.dumps(data))
399
+ page.locator('select[name="format"]').select_option("geojson")
400
+ page.get_by_role("button", name="Import", exact=True).click()
401
+ # A layer has been created
402
+ expect(layers).to_have_count(1)
403
+ expect(paths).to_have_count(1)
404
+
405
+
406
+ def test_import_multipolyline(live_server, page, tilelayer):
407
+ data = {
408
+ "type": "FeatureCollection",
409
+ "features": [
410
+ {
411
+ "type": "Feature",
412
+ "properties": {},
413
+ "geometry": {
414
+ "type": "MultiLineString",
415
+ "coordinates": [[[-108, 46], [-113, 43]], [[-112, 45], [-115, 44]]],
416
+ },
417
+ }
418
+ ],
419
+ }
420
+ page.goto(f"{live_server.url}/map/new/")
421
+ page.get_by_title("See layers").click()
422
+ layers = page.locator(".umap-browser .datalayer")
423
+ paths = page.locator("path")
424
+ expect(paths).to_have_count(0)
425
+ expect(layers).to_have_count(0)
426
+ button = page.get_by_title("Import data")
427
+ expect(button).to_be_visible()
428
+ button.click()
429
+ textarea = page.locator(".umap-upload textarea")
430
+ textarea.fill(json.dumps(data))
431
+ page.locator('select[name="format"]').select_option("geojson")
432
+ page.get_by_role("button", name="Import", exact=True).click()
433
+ # A layer has been created
434
+ expect(layers).to_have_count(1)
435
+ expect(paths).to_have_count(1)
436
+
437
+
438
+ def test_import_csv_without_valid_latlon_headers(tilelayer, live_server, page):
439
+ page.goto(f"{live_server.url}/map/new/")
440
+ page.get_by_title("See layers").click()
441
+ layers = page.locator(".umap-browser .datalayer")
442
+ markers = page.locator(".leaflet-marker-icon")
443
+ page.get_by_title("Import data").click()
444
+ textarea = page.locator(".umap-upload textarea")
445
+ textarea.fill("a,b,c\n12.23,48.34,mypoint\n12.23,48.34,mypoint2")
446
+ page.locator('select[name="format"]').select_option("csv")
447
+ page.get_by_role("button", name="Import", exact=True).click()
448
+ # FIXME do not create a layer
449
+ expect(layers).to_have_count(1)
450
+ expect(markers).to_have_count(0)
451
+ expect(page.locator(".umap-alert")).to_be_visible()
@@ -1,12 +1,8 @@
1
- import json
2
1
  import re
3
- from pathlib import Path
4
2
 
5
3
  import pytest
6
4
  from playwright.sync_api import expect
7
5
 
8
- from umap.models import Map
9
-
10
6
  from ..base import DataLayerFactory
11
7
 
12
8
  pytestmark = pytest.mark.django_db
@@ -46,10 +42,10 @@ def test_default_view_without_datalayer_should_use_default_center(
46
42
  ):
47
43
  datalayer.settings["displayOnLoad"] = False
48
44
  datalayer.save()
49
- page.goto(f"{live_server.url}{map.get_absolute_url()}")
45
+ page.goto(f"{live_server.url}{map.get_absolute_url()}?onLoadPanel=datalayers")
50
46
  # Hash is defined, so map is initialized
51
47
  expect(page).to_have_url(re.compile(r".*#7/48\..+/13\..+"))
52
- layers = page.locator(".umap-browse-datalayers li")
48
+ layers = page.locator(".umap-browser .datalayer h5")
53
49
  expect(layers).to_have_count(1)
54
50
 
55
51
 
@@ -60,10 +56,10 @@ def test_default_view_latest_without_datalayer_should_use_default_center(
60
56
  datalayer.save()
61
57
  map.settings["properties"]["defaultView"] = "latest"
62
58
  map.save()
63
- page.goto(f"{live_server.url}{map.get_absolute_url()}")
59
+ page.goto(f"{live_server.url}{map.get_absolute_url()}?onLoadPanel=datalayers")
64
60
  # Hash is defined, so map is initialized
65
61
  expect(page).to_have_url(re.compile(r".*#7/48\..+/13\..+"))
66
- layers = page.locator(".umap-browse-datalayers li")
62
+ layers = page.locator(".umap-browser .datalayer h5")
67
63
  expect(layers).to_have_count(1)
68
64
 
69
65
 
@@ -74,21 +70,22 @@ def test_default_view_data_without_datalayer_should_use_default_center(
74
70
  datalayer.save()
75
71
  map.settings["properties"]["defaultView"] = "data"
76
72
  map.save()
77
- page.goto(f"{live_server.url}{map.get_absolute_url()}")
73
+ page.goto(f"{live_server.url}{map.get_absolute_url()}?onLoadPanel=datalayers")
78
74
  # Hash is defined, so map is initialized
79
75
  expect(page).to_have_url(re.compile(r".*#7/48\..+/13\..+"))
80
- layers = page.locator(".umap-browse-datalayers li")
76
+ layers = page.locator(".umap-browser .datalayer h5")
81
77
  expect(layers).to_have_count(1)
82
78
 
83
79
 
84
80
  def test_default_view_latest_with_marker(map, live_server, datalayer, page):
85
81
  map.settings["properties"]["defaultView"] = "latest"
86
82
  map.save()
87
- page.goto(f"{live_server.url}{map.get_absolute_url()}")
83
+ page.goto(f"{live_server.url}{map.get_absolute_url()}?onLoadPanel=datalayers")
88
84
  # Hash is defined, so map is initialized
89
85
  expect(page).to_have_url(re.compile(r".*#7/48\..+/14\..+"))
90
- layers = page.locator(".umap-browse-datalayers li")
86
+ layers = page.locator(".umap-browser .datalayer h5")
91
87
  expect(layers).to_have_count(1)
88
+ expect(page.locator(".leaflet-popup")).to_be_visible()
92
89
 
93
90
 
94
91
  def test_default_view_latest_with_line(map, live_server, page):
@@ -113,9 +110,9 @@ def test_default_view_latest_with_line(map, live_server, page):
113
110
  DataLayerFactory(map=map, data=data)
114
111
  map.settings["properties"]["defaultView"] = "latest"
115
112
  map.save()
116
- page.goto(f"{live_server.url}{map.get_absolute_url()}")
113
+ page.goto(f"{live_server.url}{map.get_absolute_url()}?onLoadPanel=datalayers")
117
114
  expect(page).to_have_url(re.compile(r".*#8/48\..+/2\..+"))
118
- layers = page.locator(".umap-browse-datalayers li")
115
+ layers = page.locator(".umap-browser .datalayer h5")
119
116
  expect(layers).to_have_count(1)
120
117
 
121
118
 
@@ -144,29 +141,38 @@ def test_default_view_latest_with_polygon(map, live_server, page):
144
141
  DataLayerFactory(map=map, data=data)
145
142
  map.settings["properties"]["defaultView"] = "latest"
146
143
  map.save()
147
- page.goto(f"{live_server.url}{map.get_absolute_url()}")
144
+ page.goto(f"{live_server.url}{map.get_absolute_url()}?onLoadPanel=datalayers")
148
145
  expect(page).to_have_url(re.compile(r".*#8/48\..+/2\..+"))
149
- layers = page.locator(".umap-browse-datalayers li")
146
+ layers = page.locator(".umap-browser .datalayer h5")
150
147
  expect(layers).to_have_count(1)
151
148
 
152
149
 
150
+ def test_default_view_locate(browser, live_server, map):
151
+ context = browser.new_context(
152
+ geolocation={"longitude": 8.52967, "latitude": 39.16267},
153
+ permissions=["geolocation"],
154
+ )
155
+ map.settings["properties"]["defaultView"] = "locate"
156
+ map.save()
157
+ page = context.new_page()
158
+ page.goto(f"{live_server.url}{map.get_absolute_url()}")
159
+ expect(page).to_have_url(re.compile(r".*#18/39\.16267/8\.52967"))
160
+
161
+
153
162
  def test_remote_layer_should_not_be_used_as_datalayer_for_created_features(
154
- map, live_server, datalayer, page
163
+ openmap, live_server, datalayer, page
155
164
  ):
156
- # Faster than doing a login
157
- map.edit_status = Map.ANONYMOUS
158
- map.save()
159
165
  datalayer.settings["remoteData"] = {
160
166
  "url": "https://overpass-api.de/api/interpreter?data=[out:xml];node[harbour=yes]({south},{west},{north},{east});out body;",
161
167
  "format": "osm",
162
168
  "from": "10",
163
169
  }
164
170
  datalayer.save()
165
- page.goto(f"{live_server.url}{map.get_absolute_url()}?edit")
166
- toggle = page.get_by_role("button", name="See data layers")
171
+ page.goto(f"{live_server.url}{openmap.get_absolute_url()}?edit")
172
+ toggle = page.get_by_role("button", name="See layers")
167
173
  expect(toggle).to_be_visible()
168
174
  toggle.click()
169
- layers = page.locator(".umap-browse-datalayers li")
175
+ layers = page.locator(".umap-browser .datalayer h5")
170
176
  expect(layers).to_have_count(1)
171
177
  map_el = page.locator("#map")
172
178
  add_marker = page.get_by_title("Draw a marker")
@@ -174,53 +180,29 @@ def test_remote_layer_should_not_be_used_as_datalayer_for_created_features(
174
180
  marker = page.locator(".leaflet-marker-icon")
175
181
  expect(marker).to_have_count(0)
176
182
  add_marker.click()
177
- map_el.click(position={"x": 100, "y": 100})
183
+ map_el.click(position={"x": 500, "y": 100})
178
184
  expect(marker).to_have_count(1)
179
185
  # A new datalayer has been created to host this created feature
180
186
  # given the remote one cannot accept new features
187
+ page.get_by_title("See layers").click()
181
188
  expect(layers).to_have_count(2)
182
189
 
183
190
 
184
- def test_can_hide_datalayer_from_caption(map, live_server, datalayer, page):
185
- # Faster than doing a login
186
- map.edit_status = Map.ANONYMOUS
187
- map.save()
191
+ def test_can_hide_datalayer_from_caption(openmap, live_server, datalayer, page):
188
192
  # Add another DataLayer
189
- other = DataLayerFactory(map=map, name="Hidden", settings={"inCaption": False})
190
- page.goto(f"{live_server.url}{map.get_absolute_url()}")
193
+ other = DataLayerFactory(map=openmap, name="Hidden", settings={"inCaption": False})
194
+ page.goto(f"{live_server.url}{openmap.get_absolute_url()}")
191
195
  toggle = page.get_by_text("About").first
192
196
  expect(toggle).to_be_visible()
193
197
  toggle.click()
194
198
  layers = page.locator(".umap-caption .datalayer-legend")
195
199
  expect(layers).to_have_count(1)
196
- found = page.locator("#umap-ui-container").get_by_text(datalayer.name)
200
+ found = page.locator(".panel.left.on").get_by_text(datalayer.name)
197
201
  expect(found).to_be_visible()
198
- hidden = page.locator("#umap-ui-container").get_by_text(other.name)
202
+ hidden = page.locator(".panel.left.on").get_by_text(other.name)
199
203
  expect(hidden).to_be_hidden()
200
204
 
201
205
 
202
- def test_basic_choropleth_map(map, live_server, page):
203
- path = Path(__file__).parent.parent / "fixtures/choropleth_region_chomage.geojson"
204
- data = json.loads(path.read_text())
205
- DataLayerFactory(data=data, map=map)
206
- page.goto(f"{live_server.url}{map.get_absolute_url()}")
207
- # Hauts-de-France
208
- paths = page.locator("path[fill='#08519c']")
209
- expect(paths).to_have_count(1)
210
- # Occitanie
211
- paths = page.locator("path[fill='#3182bd']")
212
- expect(paths).to_have_count(1)
213
- # Grand-Est, PACA
214
- paths = page.locator("path[fill='#6baed6']")
215
- expect(paths).to_have_count(2)
216
- # Bourgogne-Franche-Comté, Centre-Val-de-Loire, IdF, Normandie, Corse, Nouvelle-Aquitaine
217
- paths = page.locator("path[fill='#bdd7e7']")
218
- expect(paths).to_have_count(6)
219
- # Bretagne, Pays de la Loire, AURA
220
- paths = page.locator("path[fill='#eff3ff']")
221
- expect(paths).to_have_count(3)
222
-
223
-
224
206
  def test_minimap_on_load(map, live_server, datalayer, page):
225
207
  page.goto(f"{live_server.url}{map.get_absolute_url()}")
226
208
  expect(page.locator(".leaflet-control-minimap")).to_be_hidden()
@@ -0,0 +1,28 @@
1
+ import pytest
2
+ from playwright.sync_api import expect
3
+
4
+ pytestmark = pytest.mark.django_db
5
+
6
+
7
+ def test_should_not_render_any_control(live_server, tilelayer, page, map):
8
+ map.settings["properties"]["onLoadPanel"] = "databrowser"
9
+ map.settings["properties"]["miniMap"] = True
10
+ map.settings["properties"]["captionBar"] = True
11
+ map.save()
12
+ # Make sure those controls are visible in normal view
13
+ page.goto(f"{live_server.url}{map.get_absolute_url()}")
14
+ expect(page.locator(".leaflet-control-minimap")).to_be_visible()
15
+ expect(page.locator(".umap-browser")).to_be_visible()
16
+ expect(page.locator(".umap-caption-bar")).to_be_visible()
17
+ expect(page.locator(".leaflet-control-zoom")).to_be_visible()
18
+ expect(page.locator(".leaflet-control-attribution")).to_be_visible()
19
+
20
+ # Now load home page to have the list view
21
+ page.goto(live_server.url)
22
+ map_el = page.locator(".map_fragment")
23
+ expect(map_el).to_be_visible()
24
+ expect(map_el.locator(".leaflet-control-minimap")).to_be_hidden()
25
+ expect(map_el.locator(".umap-browser")).to_be_hidden()
26
+ expect(map_el.locator(".umap-caption-bar")).to_be_hidden()
27
+ expect(map_el.locator(".leaflet-control-zoom")).to_be_hidden()
28
+ expect(map_el.locator(".leaflet-control-attribution")).to_be_hidden()