umap-project 2.3.1__py3-none-any.whl → 2.4.0b0__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 (210) hide show
  1. umap/.DS_Store +0 -0
  2. umap/__init__.py +1 -1
  3. umap/locale/en/LC_MESSAGES/django.po +81 -31
  4. umap/locale/fr/LC_MESSAGES/django.mo +0 -0
  5. umap/locale/fr/LC_MESSAGES/django.po +109 -59
  6. umap/management/commands/run_websocket_server.py +23 -0
  7. umap/models.py +6 -1
  8. umap/settings/base.py +11 -3
  9. umap/static/.DS_Store +0 -0
  10. umap/static/umap/.DS_Store +0 -0
  11. umap/static/umap/base.css +53 -162
  12. umap/static/umap/content.css +3 -2
  13. umap/static/umap/css/dialog.css +18 -0
  14. umap/static/umap/css/icon.css +8 -0
  15. umap/static/umap/css/importers.css +44 -0
  16. umap/static/umap/css/panel.css +19 -57
  17. umap/static/umap/css/tooltip.css +59 -0
  18. umap/static/umap/css/window.css +35 -0
  19. umap/static/umap/favicons/.DS_Store +0 -0
  20. umap/static/umap/fonts/.DS_Store +0 -0
  21. umap/static/umap/img/.DS_Store +0 -0
  22. umap/static/umap/img/alert-icon-error.svg +8 -0
  23. umap/static/umap/img/alert-icon-info.svg +4 -0
  24. umap/static/umap/img/alert-icon-success.svg +3 -0
  25. umap/static/umap/img/icon-external-link.svg +3 -0
  26. umap/static/umap/img/importers/communesfr.svg +5 -0
  27. umap/static/umap/img/importers/datasets.svg +13 -0
  28. umap/static/umap/img/importers/geodatamine.svg +10 -0
  29. umap/static/umap/img/importers/overpass.svg +7 -0
  30. umap/static/umap/img/importers/random.svg +18 -0
  31. umap/static/umap/img/importers/random1.svg +4 -0
  32. umap/static/umap/img/importers/random2.svg +4 -0
  33. umap/static/umap/img/source/.DS_Store +0 -0
  34. umap/static/umap/js/components/alerts/alert.css +160 -0
  35. umap/static/umap/js/components/alerts/alert.js +169 -0
  36. umap/static/umap/js/components/base.js +54 -0
  37. umap/static/umap/js/modules/autocomplete.js +347 -0
  38. umap/static/umap/js/modules/browser.js +1 -1
  39. umap/static/umap/js/modules/caption.js +4 -3
  40. umap/static/umap/js/modules/global.js +36 -12
  41. umap/static/umap/js/modules/help.js +255 -0
  42. umap/static/umap/js/modules/importer.js +280 -0
  43. umap/static/umap/js/modules/importers/communesfr.js +44 -0
  44. umap/static/umap/js/modules/importers/datasets.js +41 -0
  45. umap/static/umap/js/modules/importers/geodatamine.js +95 -0
  46. umap/static/umap/js/modules/importers/overpass.js +84 -0
  47. umap/static/umap/js/modules/request.js +12 -14
  48. umap/static/umap/js/modules/rules.js +241 -0
  49. umap/static/umap/js/modules/schema.js +63 -14
  50. umap/static/umap/js/modules/sync/engine.js +93 -0
  51. umap/static/umap/js/modules/sync/updaters.js +109 -0
  52. umap/static/umap/js/modules/sync/websocket.js +25 -0
  53. umap/static/umap/js/modules/ui/dialog.js +52 -0
  54. umap/static/umap/js/modules/{panel.js → ui/panel.js} +25 -14
  55. umap/static/umap/js/modules/ui/tooltip.js +116 -0
  56. umap/static/umap/js/modules/utils.js +25 -18
  57. umap/static/umap/js/umap.controls.js +13 -14
  58. umap/static/umap/js/umap.core.js +1 -324
  59. umap/static/umap/js/umap.features.js +67 -27
  60. umap/static/umap/js/umap.forms.js +9 -13
  61. umap/static/umap/js/umap.js +220 -180
  62. umap/static/umap/js/umap.layer.js +142 -74
  63. umap/static/umap/js/umap.permissions.js +5 -9
  64. umap/static/umap/js/umap.tableeditor.js +8 -8
  65. umap/static/umap/locale/am_ET.js +51 -16
  66. umap/static/umap/locale/am_ET.json +51 -16
  67. umap/static/umap/locale/ar.js +51 -16
  68. umap/static/umap/locale/ar.json +51 -16
  69. umap/static/umap/locale/ast.js +51 -16
  70. umap/static/umap/locale/ast.json +51 -16
  71. umap/static/umap/locale/bg.js +51 -16
  72. umap/static/umap/locale/bg.json +51 -16
  73. umap/static/umap/locale/br.js +55 -20
  74. umap/static/umap/locale/br.json +55 -20
  75. umap/static/umap/locale/ca.js +51 -16
  76. umap/static/umap/locale/ca.json +51 -16
  77. umap/static/umap/locale/cs_CZ.js +93 -58
  78. umap/static/umap/locale/cs_CZ.json +93 -58
  79. umap/static/umap/locale/da.js +51 -16
  80. umap/static/umap/locale/da.json +51 -16
  81. umap/static/umap/locale/de.js +56 -21
  82. umap/static/umap/locale/de.json +56 -21
  83. umap/static/umap/locale/el.js +51 -16
  84. umap/static/umap/locale/el.json +51 -16
  85. umap/static/umap/locale/en.js +51 -16
  86. umap/static/umap/locale/en.json +51 -16
  87. umap/static/umap/locale/en_US.json +51 -16
  88. umap/static/umap/locale/es.js +51 -16
  89. umap/static/umap/locale/es.json +51 -16
  90. umap/static/umap/locale/et.js +51 -16
  91. umap/static/umap/locale/et.json +51 -16
  92. umap/static/umap/locale/eu.js +51 -16
  93. umap/static/umap/locale/eu.json +51 -16
  94. umap/static/umap/locale/fa_IR.js +51 -16
  95. umap/static/umap/locale/fa_IR.json +51 -16
  96. umap/static/umap/locale/fi.js +51 -16
  97. umap/static/umap/locale/fi.json +51 -16
  98. umap/static/umap/locale/fr.js +52 -17
  99. umap/static/umap/locale/fr.json +52 -17
  100. umap/static/umap/locale/gl.js +51 -16
  101. umap/static/umap/locale/gl.json +51 -16
  102. umap/static/umap/locale/he.js +51 -16
  103. umap/static/umap/locale/he.json +51 -16
  104. umap/static/umap/locale/hr.js +51 -16
  105. umap/static/umap/locale/hr.json +51 -16
  106. umap/static/umap/locale/hu.js +51 -16
  107. umap/static/umap/locale/hu.json +51 -16
  108. umap/static/umap/locale/id.js +51 -16
  109. umap/static/umap/locale/id.json +51 -16
  110. umap/static/umap/locale/is.js +51 -16
  111. umap/static/umap/locale/is.json +51 -16
  112. umap/static/umap/locale/it.js +51 -16
  113. umap/static/umap/locale/it.json +51 -16
  114. umap/static/umap/locale/ja.js +51 -16
  115. umap/static/umap/locale/ja.json +51 -16
  116. umap/static/umap/locale/ko.js +51 -16
  117. umap/static/umap/locale/ko.json +51 -16
  118. umap/static/umap/locale/lt.js +51 -16
  119. umap/static/umap/locale/lt.json +51 -16
  120. umap/static/umap/locale/ms.js +51 -16
  121. umap/static/umap/locale/ms.json +51 -16
  122. umap/static/umap/locale/nl.js +51 -16
  123. umap/static/umap/locale/nl.json +51 -16
  124. umap/static/umap/locale/no.js +51 -16
  125. umap/static/umap/locale/no.json +51 -16
  126. umap/static/umap/locale/pl.js +93 -58
  127. umap/static/umap/locale/pl.json +93 -58
  128. umap/static/umap/locale/pl_PL.json +51 -16
  129. umap/static/umap/locale/pt.js +215 -180
  130. umap/static/umap/locale/pt.json +215 -180
  131. umap/static/umap/locale/pt_BR.js +51 -16
  132. umap/static/umap/locale/pt_BR.json +51 -16
  133. umap/static/umap/locale/pt_PT.js +51 -16
  134. umap/static/umap/locale/pt_PT.json +51 -16
  135. umap/static/umap/locale/ro.js +51 -16
  136. umap/static/umap/locale/ro.json +51 -16
  137. umap/static/umap/locale/ru.js +51 -16
  138. umap/static/umap/locale/ru.json +51 -16
  139. umap/static/umap/locale/si.js +51 -16
  140. umap/static/umap/locale/si.json +51 -16
  141. umap/static/umap/locale/sk_SK.js +51 -16
  142. umap/static/umap/locale/sk_SK.json +51 -16
  143. umap/static/umap/locale/sl.js +51 -16
  144. umap/static/umap/locale/sl.json +51 -16
  145. umap/static/umap/locale/sr.js +51 -16
  146. umap/static/umap/locale/sr.json +51 -16
  147. umap/static/umap/locale/sv.js +51 -16
  148. umap/static/umap/locale/sv.json +51 -16
  149. umap/static/umap/locale/th_TH.js +51 -16
  150. umap/static/umap/locale/th_TH.json +51 -16
  151. umap/static/umap/locale/tr.js +51 -16
  152. umap/static/umap/locale/tr.json +51 -16
  153. umap/static/umap/locale/uk_UA.js +51 -16
  154. umap/static/umap/locale/uk_UA.json +51 -16
  155. umap/static/umap/locale/vi.js +51 -16
  156. umap/static/umap/locale/vi.json +51 -16
  157. umap/static/umap/locale/vi_VN.json +51 -16
  158. umap/static/umap/locale/zh.js +51 -16
  159. umap/static/umap/locale/zh.json +51 -16
  160. umap/static/umap/locale/zh_CN.json +51 -16
  161. umap/static/umap/locale/zh_TW.Big5.json +51 -16
  162. umap/static/umap/locale/zh_TW.js +51 -16
  163. umap/static/umap/locale/zh_TW.json +51 -16
  164. umap/static/umap/map.css +27 -41
  165. umap/static/umap/unittests/sync.js +105 -0
  166. umap/static/umap/unittests/utils.js +76 -34
  167. umap/static/umap/vars.css +18 -1
  168. umap/static/umap/vendors/dompurify/purify.es.js +5 -59
  169. umap/static/umap/vendors/dompurify/purify.es.mjs.map +1 -1
  170. umap/templates/umap/components/alerts/alert.html +89 -0
  171. umap/templates/umap/content.html +4 -3
  172. umap/templates/umap/css.html +4 -0
  173. umap/templates/umap/home.html +3 -0
  174. umap/templates/umap/js.html +0 -3
  175. umap/templates/umap/map_init.html +2 -8
  176. umap/templates/umap/messages.html +9 -11
  177. umap/templates/umap/search.html +3 -0
  178. umap/tests/.DS_Store +0 -0
  179. umap/tests/base.py +2 -0
  180. umap/tests/integration/.DS_Store +0 -0
  181. umap/tests/integration/conftest.py +30 -0
  182. umap/tests/integration/test_anonymous_owned_map.py +8 -13
  183. umap/tests/integration/test_browser.py +1 -1
  184. umap/tests/integration/test_conditional_rules.py +201 -0
  185. umap/tests/integration/test_dashboard.py +1 -1
  186. umap/tests/integration/test_datalayer.py +2 -3
  187. umap/tests/integration/test_edit_datalayer.py +4 -4
  188. umap/tests/integration/test_edit_map.py +1 -1
  189. umap/tests/integration/test_facets_browser.py +3 -3
  190. umap/tests/integration/test_import.py +138 -49
  191. umap/tests/integration/test_map.py +2 -2
  192. umap/tests/integration/{test_collaborative_editing.py → test_optimistic_merge.py} +7 -7
  193. umap/tests/integration/test_owned_map.py +1 -1
  194. umap/tests/integration/test_picto.py +2 -2
  195. umap/tests/integration/test_statics.py +1 -1
  196. umap/tests/integration/test_websocket_sync.py +283 -0
  197. umap/tests/settings.py +5 -0
  198. umap/tests/test_datalayer_views.py +0 -1
  199. umap/tests/test_views.py +53 -0
  200. umap/urls.py +5 -0
  201. umap/views.py +40 -11
  202. umap/websocket_server.py +92 -0
  203. {umap_project-2.3.1.dist-info → umap_project-2.4.0b0.dist-info}/METADATA +11 -9
  204. {umap_project-2.3.1.dist-info → umap_project-2.4.0b0.dist-info}/RECORD +207 -164
  205. {umap_project-2.3.1.dist-info → umap_project-2.4.0b0.dist-info}/WHEEL +1 -1
  206. umap/static/umap/js/umap.autocomplete.js +0 -341
  207. umap/static/umap/js/umap.importer.js +0 -187
  208. umap/static/umap/js/umap.ui.js +0 -190
  209. {umap_project-2.3.1.dist-info → umap_project-2.4.0b0.dist-info}/entry_points.txt +0 -0
  210. {umap_project-2.3.1.dist-info → umap_project-2.4.0b0.dist-info}/licenses/LICENSE +0 -0
@@ -17,20 +17,22 @@ def test_layers_list_is_updated(live_server, tilelayer, page):
17
17
  modifier = "Cmd" if platform.system() == "Darwin" else "Ctrl"
18
18
  page.get_by_role("link", name=f"Import data ({modifier}+I)").click()
19
19
  # Should work
20
- page.get_by_label("Choose the layer to import").select_option(
21
- label="Import in a new layer"
22
- )
20
+ page.locator("[name=layer-id]").select_option(label="Import in a new layer")
23
21
  page.get_by_role("link", name="Manage layers").click()
24
22
  page.get_by_role("button", name="Add a layer").click()
25
23
  page.locator('input[name="name"]').click()
26
24
  page.locator('input[name="name"]').fill("foobar")
27
25
  page.get_by_role("link", name=f"Import data ({modifier}+I)").click()
28
26
  # Should still work
29
- page.get_by_label("Choose the layer to import").select_option(
30
- label="Import in a new layer"
31
- )
27
+ page.locator("[name=layer-id]").select_option(label="Import in a new layer")
32
28
  # Now layer should be visible in the options
33
- page.get_by_label("Choose the layer to import").select_option(label="foobar")
29
+ page.locator("[name=layer-id]").select_option(label="foobar")
30
+ expect(
31
+ page.get_by_role("button", name="Import full map data", exact=True)
32
+ ).to_be_hidden()
33
+ expect(
34
+ page.get_by_role("button", name="Link to the layer as remote data", exact=True)
35
+ ).to_be_hidden()
34
36
 
35
37
 
36
38
  def test_umap_import_from_file(live_server, tilelayer, page):
@@ -42,9 +44,13 @@ def test_umap_import_from_file(live_server, tilelayer, page):
42
44
  file_chooser = fc_info.value
43
45
  path = Path(__file__).parent.parent / "fixtures/display_on_load.umap"
44
46
  file_chooser.set_files(path)
45
- button = page.get_by_role("button", name="Import", exact=True)
46
- expect(button).to_be_visible()
47
- button.click()
47
+ expect(
48
+ page.get_by_role("button", name="Copy into the layer", exact=True)
49
+ ).to_be_hidden()
50
+ expect(
51
+ page.get_by_role("button", name="Link to the layer as remote data", exact=True)
52
+ ).to_be_hidden()
53
+ page.get_by_role("button", name="Import data", exact=True).click()
48
54
  assert file_input.input_value()
49
55
  # Close the import panel
50
56
  page.keyboard.press("Escape")
@@ -55,7 +61,7 @@ def test_umap_import_from_file(live_server, tilelayer, page):
55
61
  expect(page.locator(".umap-main-edit-toolbox .map-name")).to_have_text(
56
62
  "Carte sans nom"
57
63
  )
58
- page.get_by_title("See layers").click()
64
+ page.get_by_title("Open browser").click()
59
65
  layers = page.locator(".umap-browser .datalayer")
60
66
  expect(layers).to_have_count(2)
61
67
  nonloaded = page.locator(".umap-browser .datalayer.off")
@@ -65,13 +71,13 @@ def test_umap_import_from_file(live_server, tilelayer, page):
65
71
  def test_umap_import_from_textarea(live_server, tilelayer, page, settings):
66
72
  settings.UMAP_ALLOW_ANONYMOUS = True
67
73
  page.goto(f"{live_server.url}/map/new/")
68
- page.get_by_role("button", name="See layers").click()
74
+ page.get_by_role("button", name="Open browser").click()
69
75
  page.get_by_title("Import data").click()
70
76
  textarea = page.locator(".umap-upload textarea")
71
77
  path = Path(__file__).parent.parent / "fixtures/test_upload_data.umap"
72
78
  textarea.fill(path.read_text())
73
79
  page.locator('select[name="format"]').select_option("umap")
74
- page.get_by_role("button", name="Import", exact=True).click()
80
+ page.get_by_role("button", name="Import data", exact=True).click()
75
81
  layers = page.locator(".umap-browser .datalayer")
76
82
  expect(layers).to_have_count(2)
77
83
  expect(page.locator(".umap-main-edit-toolbox .map-name")).to_have_text(
@@ -92,7 +98,7 @@ def test_umap_import_from_textarea(live_server, tilelayer, page, settings):
92
98
 
93
99
  def test_import_geojson_from_textarea(tilelayer, live_server, page):
94
100
  page.goto(f"{live_server.url}/map/new/")
95
- page.get_by_title("See layers").click()
101
+ page.get_by_title("Open browser").click()
96
102
  layers = page.locator(".umap-browser .datalayer")
97
103
  markers = page.locator(".leaflet-marker-icon")
98
104
  paths = page.locator("path")
@@ -106,9 +112,7 @@ def test_import_geojson_from_textarea(tilelayer, live_server, page):
106
112
  path = Path(__file__).parent.parent / "fixtures/test_upload_data.json"
107
113
  textarea.fill(path.read_text())
108
114
  page.locator('select[name="format"]').select_option("geojson")
109
- button = page.get_by_role("button", name="Import", exact=True)
110
- expect(button).to_be_visible()
111
- button.click()
115
+ page.get_by_role("button", name="Import data", exact=True).click()
112
116
  # A layer has been created
113
117
  expect(layers).to_have_count(1)
114
118
  expect(markers).to_have_count(2)
@@ -117,7 +121,7 @@ def test_import_geojson_from_textarea(tilelayer, live_server, page):
117
121
 
118
122
  def test_import_kml_from_textarea(tilelayer, live_server, page):
119
123
  page.goto(f"{live_server.url}/map/new/")
120
- page.get_by_title("See layers").click()
124
+ page.get_by_title("Open browser").click()
121
125
  layers = page.locator(".umap-browser .datalayer")
122
126
  markers = page.locator(".leaflet-marker-icon")
123
127
  paths = page.locator("path")
@@ -131,9 +135,7 @@ def test_import_kml_from_textarea(tilelayer, live_server, page):
131
135
  path = Path(__file__).parent.parent / "fixtures/test_upload_data.kml"
132
136
  textarea.fill(path.read_text())
133
137
  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()
138
+ page.get_by_role("button", name="Import data", exact=True).click()
137
139
  # A layer has been created
138
140
  expect(layers).to_have_count(1)
139
141
  expect(markers).to_have_count(1)
@@ -142,7 +144,7 @@ def test_import_kml_from_textarea(tilelayer, live_server, page):
142
144
 
143
145
  def test_import_gpx_from_textarea(tilelayer, live_server, page):
144
146
  page.goto(f"{live_server.url}/map/new/")
145
- page.get_by_title("See layers").click()
147
+ page.get_by_title("Open browser").click()
146
148
  layers = page.locator(".umap-browser .datalayer")
147
149
  markers = page.locator(".leaflet-marker-icon")
148
150
  paths = page.locator("path")
@@ -156,9 +158,7 @@ def test_import_gpx_from_textarea(tilelayer, live_server, page):
156
158
  path = Path(__file__).parent.parent / "fixtures/test_upload_data.gpx"
157
159
  textarea.fill(path.read_text())
158
160
  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()
161
+ page.get_by_role("button", name="Import data", exact=True).click()
162
162
  # A layer has been created
163
163
  expect(layers).to_have_count(1)
164
164
  expect(markers).to_have_count(1)
@@ -167,7 +167,7 @@ def test_import_gpx_from_textarea(tilelayer, live_server, page):
167
167
 
168
168
  def test_import_osm_from_textarea(tilelayer, live_server, page):
169
169
  page.goto(f"{live_server.url}/map/new/")
170
- page.get_by_title("See layers").click()
170
+ page.get_by_title("Open browser").click()
171
171
  layers = page.locator(".umap-browser .datalayer")
172
172
  markers = page.locator(".leaflet-marker-icon")
173
173
  expect(markers).to_have_count(0)
@@ -179,7 +179,7 @@ def test_import_osm_from_textarea(tilelayer, live_server, page):
179
179
  path = Path(__file__).parent.parent / "fixtures/test_upload_data_osm.json"
180
180
  textarea.fill(path.read_text())
181
181
  page.locator('select[name="format"]').select_option("osm")
182
- page.get_by_role("button", name="Import", exact=True).click()
182
+ page.get_by_role("button", name="Import data", exact=True).click()
183
183
  # A layer has been created
184
184
  expect(layers).to_have_count(1)
185
185
  expect(markers).to_have_count(2)
@@ -187,7 +187,7 @@ def test_import_osm_from_textarea(tilelayer, live_server, page):
187
187
 
188
188
  def test_import_csv_from_textarea(tilelayer, live_server, page):
189
189
  page.goto(f"{live_server.url}/map/new/")
190
- page.get_by_title("See layers").click()
190
+ page.get_by_title("Open browser").click()
191
191
  layers = page.locator(".umap-browser .datalayer")
192
192
  markers = page.locator(".leaflet-marker-icon")
193
193
  expect(markers).to_have_count(0)
@@ -199,7 +199,7 @@ def test_import_csv_from_textarea(tilelayer, live_server, page):
199
199
  path = Path(__file__).parent.parent / "fixtures/test_upload_data.csv"
200
200
  textarea.fill(path.read_text())
201
201
  page.locator('select[name="format"]').select_option("csv")
202
- page.get_by_role("button", name="Import", exact=True).click()
202
+ page.get_by_role("button", name="Import data", exact=True).click()
203
203
  # A layer has been created
204
204
  expect(layers).to_have_count(1)
205
205
  expect(markers).to_have_count(2)
@@ -207,7 +207,7 @@ def test_import_csv_from_textarea(tilelayer, live_server, page):
207
207
 
208
208
  def test_can_import_in_existing_datalayer(live_server, datalayer, page, openmap):
209
209
  page.goto(f"{live_server.url}{openmap.get_absolute_url()}")
210
- page.get_by_title("See layers").click()
210
+ page.get_by_title("Open browser").click()
211
211
  layers = page.locator(".umap-browser .datalayer")
212
212
  markers = page.locator(".leaflet-marker-icon")
213
213
  expect(markers).to_have_count(1)
@@ -218,7 +218,9 @@ def test_can_import_in_existing_datalayer(live_server, datalayer, page, openmap)
218
218
  path = Path(__file__).parent.parent / "fixtures/test_upload_data.csv"
219
219
  textarea.fill(path.read_text())
220
220
  page.locator('select[name="format"]').select_option("csv")
221
- page.get_by_role("button", name="Import", exact=True).click()
221
+ page.locator('select[name="layer-id"]').select_option(datalayer.name)
222
+ expect(page.locator("input[name=layer-name]")).to_be_hidden()
223
+ page.get_by_role("button", name="Import data", exact=True).click()
222
224
  # No layer has been created
223
225
  expect(layers).to_have_count(1)
224
226
  expect(markers).to_have_count(3)
@@ -226,7 +228,7 @@ def test_can_import_in_existing_datalayer(live_server, datalayer, page, openmap)
226
228
 
227
229
  def test_can_replace_datalayer_data(live_server, datalayer, page, openmap):
228
230
  page.goto(f"{live_server.url}{openmap.get_absolute_url()}")
229
- page.get_by_title("See layers").click()
231
+ page.get_by_title("Open browser").click()
230
232
  layers = page.locator(".umap-browser .datalayer")
231
233
  markers = page.locator(".leaflet-marker-icon")
232
234
  expect(markers).to_have_count(1)
@@ -237,8 +239,9 @@ def test_can_replace_datalayer_data(live_server, datalayer, page, openmap):
237
239
  path = Path(__file__).parent.parent / "fixtures/test_upload_data.csv"
238
240
  textarea.fill(path.read_text())
239
241
  page.locator('select[name="format"]').select_option("csv")
242
+ page.locator('select[name="layer-id"]').select_option(datalayer.name)
240
243
  page.get_by_label("Replace layer content").check()
241
- page.get_by_role("button", name="Import", exact=True).click()
244
+ page.get_by_role("button", name="Import data", exact=True).click()
242
245
  # No layer has been created
243
246
  expect(layers).to_have_count(1)
244
247
  expect(markers).to_have_count(2)
@@ -246,7 +249,7 @@ def test_can_replace_datalayer_data(live_server, datalayer, page, openmap):
246
249
 
247
250
  def test_can_import_in_new_datalayer(live_server, datalayer, page, openmap):
248
251
  page.goto(f"{live_server.url}{openmap.get_absolute_url()}")
249
- page.get_by_title("See layers").click()
252
+ page.get_by_title("Open browser").click()
250
253
  layers = page.locator(".umap-browser .datalayer")
251
254
  markers = page.locator(".leaflet-marker-icon")
252
255
  expect(markers).to_have_count(1)
@@ -256,14 +259,14 @@ def test_can_import_in_new_datalayer(live_server, datalayer, page, openmap):
256
259
  textarea = page.locator(".umap-upload textarea")
257
260
  path = Path(__file__).parent.parent / "fixtures/test_upload_data.csv"
258
261
  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()
262
+ page.locator("select[name=format]").select_option("csv")
263
+ page.locator("[name=layer-id]").select_option(label="Import in a new layer")
264
+ page.locator("[name=layer-name]").fill("My new layer name")
265
+ page.get_by_role("button", name="Import data", exact=True).click()
264
266
  # A new layer has been created
265
267
  expect(layers).to_have_count(2)
266
268
  expect(markers).to_have_count(3)
269
+ expect(page.get_by_text("My new layer name")).to_be_visible()
267
270
 
268
271
 
269
272
  def test_should_remove_dot_in_property_names(live_server, page, settings, tilelayer):
@@ -302,7 +305,7 @@ def test_should_remove_dot_in_property_names(live_server, page, settings, tilela
302
305
  textarea = page.locator(".umap-upload textarea")
303
306
  textarea.fill(json.dumps(data))
304
307
  page.locator('select[name="format"]').select_option("geojson")
305
- page.get_by_role("button", name="Import", exact=True).click()
308
+ page.get_by_role("button", name="Import data", exact=True).click()
306
309
  with page.expect_response(re.compile(r".*/datalayer/create/.*")):
307
310
  page.get_by_role("button", name="Save").click()
308
311
  datalayer = DataLayer.objects.last()
@@ -350,7 +353,7 @@ def test_import_geometry_collection(live_server, page, tilelayer):
350
353
  ],
351
354
  }
352
355
  page.goto(f"{live_server.url}/map/new/")
353
- page.get_by_title("See layers").click()
356
+ page.get_by_title("Open browser").click()
354
357
  layers = page.locator(".umap-browser .datalayer")
355
358
  markers = page.locator(".leaflet-marker-icon")
356
359
  paths = page.locator("path")
@@ -363,7 +366,7 @@ def test_import_geometry_collection(live_server, page, tilelayer):
363
366
  textarea = page.locator(".umap-upload textarea")
364
367
  textarea.fill(json.dumps(data))
365
368
  page.locator('select[name="format"]').select_option("geojson")
366
- page.get_by_role("button", name="Import", exact=True).click()
369
+ page.get_by_role("button", name="Import data", exact=True).click()
367
370
  # A layer has been created
368
371
  expect(layers).to_have_count(1)
369
372
  expect(markers).to_have_count(1)
@@ -386,7 +389,7 @@ def test_import_multipolygon(live_server, page, tilelayer):
386
389
  },
387
390
  }
388
391
  page.goto(f"{live_server.url}/map/new/")
389
- page.get_by_title("See layers").click()
392
+ page.get_by_title("Open browser").click()
390
393
  layers = page.locator(".umap-browser .datalayer")
391
394
  paths = page.locator("path")
392
395
  expect(paths).to_have_count(0)
@@ -397,7 +400,7 @@ def test_import_multipolygon(live_server, page, tilelayer):
397
400
  textarea = page.locator(".umap-upload textarea")
398
401
  textarea.fill(json.dumps(data))
399
402
  page.locator('select[name="format"]').select_option("geojson")
400
- page.get_by_role("button", name="Import", exact=True).click()
403
+ page.get_by_role("button", name="Import data", exact=True).click()
401
404
  # A layer has been created
402
405
  expect(layers).to_have_count(1)
403
406
  expect(paths).to_have_count(1)
@@ -418,7 +421,7 @@ def test_import_multipolyline(live_server, page, tilelayer):
418
421
  ],
419
422
  }
420
423
  page.goto(f"{live_server.url}/map/new/")
421
- page.get_by_title("See layers").click()
424
+ page.get_by_title("Open browser").click()
422
425
  layers = page.locator(".umap-browser .datalayer")
423
426
  paths = page.locator("path")
424
427
  expect(paths).to_have_count(0)
@@ -429,7 +432,7 @@ def test_import_multipolyline(live_server, page, tilelayer):
429
432
  textarea = page.locator(".umap-upload textarea")
430
433
  textarea.fill(json.dumps(data))
431
434
  page.locator('select[name="format"]').select_option("geojson")
432
- page.get_by_role("button", name="Import", exact=True).click()
435
+ page.get_by_role("button", name="Import data", exact=True).click()
433
436
  # A layer has been created
434
437
  expect(layers).to_have_count(1)
435
438
  expect(paths).to_have_count(1)
@@ -437,15 +440,101 @@ def test_import_multipolyline(live_server, page, tilelayer):
437
440
 
438
441
  def test_import_csv_without_valid_latlon_headers(tilelayer, live_server, page):
439
442
  page.goto(f"{live_server.url}/map/new/")
440
- page.get_by_title("See layers").click()
443
+ page.get_by_title("Open browser").click()
441
444
  layers = page.locator(".umap-browser .datalayer")
442
445
  markers = page.locator(".leaflet-marker-icon")
443
446
  page.get_by_title("Import data").click()
444
447
  textarea = page.locator(".umap-upload textarea")
445
448
  textarea.fill("a,b,c\n12.23,48.34,mypoint\n12.23,48.34,mypoint2")
446
449
  page.locator('select[name="format"]').select_option("csv")
447
- page.get_by_role("button", name="Import", exact=True).click()
450
+ page.get_by_role("button", name="Import data", exact=True).click()
448
451
  # FIXME do not create a layer
449
452
  expect(layers).to_have_count(1)
450
453
  expect(markers).to_have_count(0)
451
- expect(page.locator(".umap-alert")).to_be_visible()
454
+ expect(page.locator('umap-alert div[data-level="error"]')).to_be_visible()
455
+
456
+
457
+ def test_create_remote_data(page, live_server, tilelayer):
458
+ def handle(route):
459
+ route.fulfill(
460
+ json={
461
+ "type": "FeatureCollection",
462
+ "features": [
463
+ {
464
+ "type": "Feature",
465
+ "properties": {},
466
+ "geometry": {
467
+ "type": "Point",
468
+ "coordinates": [4.3375, 51.2707],
469
+ },
470
+ }
471
+ ],
472
+ }
473
+ )
474
+
475
+ # Intercept the route to the proxy
476
+ page.route("*/**/ajax-proxy/**", handle)
477
+ page.goto(f"{live_server.url}/map/new/")
478
+ expect(page.locator(".leaflet-marker-icon")).to_be_hidden()
479
+ page.get_by_role("link", name="Import data (Ctrl+I)").click()
480
+ page.get_by_placeholder("Provide an URL here").click()
481
+ page.get_by_placeholder("Provide an URL here").fill("https://remote.org/data.json")
482
+ page.locator("[name=format]").select_option("geojson")
483
+ page.get_by_role("radio", name="Link to the layer as remote data").click()
484
+ page.get_by_role("button", name="Import data", exact=True).click()
485
+ expect(page.locator(".leaflet-marker-icon")).to_be_visible()
486
+ page.get_by_role("link", name="Manage layers").click()
487
+ page.get_by_role("button", name="Edit", exact=True).click()
488
+ page.locator("summary").filter(has_text="Remote data").click()
489
+ expect(page.locator('.panel input[name="url"]')).to_have_value(
490
+ "https://remote.org/data.json"
491
+ )
492
+
493
+
494
+ def test_import_geojson_from_url(page, live_server, tilelayer):
495
+ def handle(route):
496
+ route.fulfill(
497
+ json={
498
+ "type": "FeatureCollection",
499
+ "features": [
500
+ {
501
+ "type": "Feature",
502
+ "properties": {},
503
+ "geometry": {
504
+ "type": "Point",
505
+ "coordinates": [4.3375, 51.2707],
506
+ },
507
+ }
508
+ ],
509
+ }
510
+ )
511
+
512
+ # Intercept the route
513
+ page.route("https://remote.org/data.json", handle)
514
+ page.goto(f"{live_server.url}/map/new/")
515
+ expect(page.locator(".leaflet-marker-icon")).to_be_hidden()
516
+ page.get_by_role("link", name="Import data (Ctrl+I)").click()
517
+ page.get_by_placeholder("Provide an URL here").click()
518
+ page.get_by_placeholder("Provide an URL here").fill("https://remote.org/data.json")
519
+ page.locator("[name=format]").select_option("geojson")
520
+ page.get_by_role("radio", name="Copy into the layer").click()
521
+ page.get_by_role("button", name="Import data", exact=True).click()
522
+ expect(page.locator(".leaflet-marker-icon")).to_be_visible()
523
+ page.get_by_role("link", name="Manage layers").click()
524
+ page.get_by_role("button", name="Edit", exact=True).click()
525
+ page.locator("summary").filter(has_text="Remote data").click()
526
+ expect(page.locator('.panel input[name="url"]')).to_have_value("")
527
+
528
+
529
+ def test_overpass_import_with_bbox(page, live_server, tilelayer, settings):
530
+ settings.UMAP_IMPORTERS = {
531
+ "overpass": {"url": "https://my.overpass.io/interpreter"}
532
+ }
533
+ page.goto(f"{live_server.url}/map/new/")
534
+ page.get_by_role("link", name="Import data (Ctrl+I)").click()
535
+ page.get_by_role("button", name="Overpass").click()
536
+ page.get_by_placeholder("amenity=drinking_water").fill("building")
537
+ page.get_by_role("button", name="Choose this data").click()
538
+ expect(page.get_by_placeholder("Provide an URL here")).to_have_value(
539
+ "https://my.overpass.io/interpreter?data=[out:json];nwr[building]({south},{west},{north},{east});out geom;"
540
+ )
@@ -169,7 +169,7 @@ def test_remote_layer_should_not_be_used_as_datalayer_for_created_features(
169
169
  }
170
170
  datalayer.save()
171
171
  page.goto(f"{live_server.url}{openmap.get_absolute_url()}?edit")
172
- toggle = page.get_by_role("button", name="See layers")
172
+ toggle = page.get_by_role("button", name="Open browser")
173
173
  expect(toggle).to_be_visible()
174
174
  toggle.click()
175
175
  layers = page.locator(".umap-browser .datalayer h5")
@@ -184,7 +184,7 @@ def test_remote_layer_should_not_be_used_as_datalayer_for_created_features(
184
184
  expect(marker).to_have_count(1)
185
185
  # A new datalayer has been created to host this created feature
186
186
  # given the remote one cannot accept new features
187
- page.get_by_title("See layers").click()
187
+ page.get_by_title("Open browser").click()
188
188
  expect(layers).to_have_count(2)
189
189
 
190
190
 
@@ -5,16 +5,16 @@ from time import sleep
5
5
 
6
6
  from playwright.sync_api import expect
7
7
 
8
- from umap.models import DataLayer, Map
8
+ from umap.models import DataLayer
9
9
 
10
10
  from ..base import DataLayerFactory, MapFactory
11
11
 
12
12
  DATALAYER_UPDATE = re.compile(r".*/datalayer/update/.*")
13
13
 
14
14
 
15
- def test_collaborative_editing_create_markers(context, live_server, tilelayer):
15
+ def test_created_markers_are_merged(context, live_server, tilelayer):
16
16
  # Let's create a new map with an empty datalayer
17
- map = MapFactory(name="collaborative editing")
17
+ map = MapFactory(name="server-side merge")
18
18
  datalayer = DataLayerFactory(map=map, edit_status=DataLayer.ANONYMOUS, data={})
19
19
 
20
20
  # Now navigate to this map and create marker
@@ -146,7 +146,7 @@ def test_collaborative_editing_create_markers(context, live_server, tilelayer):
146
146
 
147
147
  def test_empty_datalayers_can_be_merged(context, live_server, tilelayer):
148
148
  # Let's create a new map with an empty datalayer
149
- map = MapFactory(name="collaborative editing")
149
+ map = MapFactory(name="server-side merge")
150
150
  DataLayerFactory(map=map, edit_status=DataLayer.ANONYMOUS, data={})
151
151
 
152
152
  # Open two tabs at the same time, on the same empty map
@@ -202,7 +202,7 @@ def test_empty_datalayers_can_be_merged(context, live_server, tilelayer):
202
202
 
203
203
  def test_same_second_edit_doesnt_conflict(context, live_server, tilelayer):
204
204
  # Let's create a new map with an empty datalayer
205
- map = MapFactory(name="collaborative editing")
205
+ map = MapFactory(name="server-side merge")
206
206
  datalayer = DataLayerFactory(map=map, edit_status=DataLayer.ANONYMOUS, data={})
207
207
 
208
208
  # Open the created map on two pages.
@@ -288,9 +288,9 @@ def test_should_display_alert_on_conflict(context, live_server, datalayer, openm
288
288
  saved = DataLayer.objects.last()
289
289
  data = json.loads(Path(saved.geojson.path).read_text())
290
290
  assert data["features"][0]["properties"]["name"] == "new name"
291
- expect(page_two.get_by_text("Woops! Someone else seems to")).to_be_visible()
291
+ expect(page_two.get_by_text("Whoops! Other contributor(s) changed")).to_be_visible()
292
292
  with page_two.expect_response(re.compile(r".*/datalayer/update/.*")):
293
- page_two.get_by_role("button", name="Save anyway").click()
293
+ page_two.get_by_text("Keep your changes and loose theirs").click()
294
294
  saved = DataLayer.objects.last()
295
295
  data = json.loads(Path(saved.geojson.path).read_text())
296
296
  assert data["features"][0]["properties"]["name"] == "custom name"
@@ -236,7 +236,7 @@ def test_can_change_owner(map, live_server, login, user):
236
236
  def test_can_delete_datalayer(live_server, map, login, datalayer):
237
237
  page = login(map.owner)
238
238
  page.goto(f"{live_server.url}{map.get_absolute_url()}?edit")
239
- page.get_by_title("See layers").click()
239
+ page.get_by_title("Open browser").click()
240
240
  layers = page.locator(".umap-browser .datalayer")
241
241
  markers = page.locator(".leaflet-marker-icon")
242
242
  expect(layers).to_have_count(1)
@@ -171,7 +171,7 @@ def test_can_use_remote_url_as_picto(openmap, live_server, page, pictos):
171
171
  input_el.blur()
172
172
  expect(marker).to_have_attribute("src", "https://foo.bar/img.jpg")
173
173
  # Now close and reopen the form, it should still be the URL tab
174
- close = page.locator(".panel.right.on .toolbox").get_by_title("Close")
174
+ close = page.locator(".panel.right.on .buttons").get_by_title("Close")
175
175
  expect(close).to_be_visible()
176
176
  close.click()
177
177
  edit_settings.click()
@@ -210,7 +210,7 @@ def test_can_use_char_as_picto(openmap, live_server, page, pictos):
210
210
  expect(marker).to_have_count(1)
211
211
  expect(marker).to_have_text("♩")
212
212
  # Now close and reopen the form, it should still be the URL tab
213
- close = page.locator(".panel.right.on .toolbox").get_by_title("Close")
213
+ close = page.locator(".panel.right.on .buttons").get_by_title("Close")
214
214
  expect(close).to_be_visible()
215
215
  close.click()
216
216
  edit_settings.click()
@@ -40,7 +40,7 @@ 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_role("button", name="Voir les calques")
43
+ button = page.get_by_role("button", name="Explorateur")
44
44
  expect(button).to_be_visible()
45
45
  button.click()
46
46
  layers = page.locator(".umap-browser .datalayer")