umap-project 2.1.2__py3-none-any.whl → 2.1.3__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 (41) hide show
  1. umap/__init__.py +1 -1
  2. umap/models.py +2 -0
  3. umap/static/umap/js/umap.controls.js +29 -0
  4. umap/static/umap/js/umap.features.js +3 -1
  5. umap/static/umap/js/umap.importer.js +4 -5
  6. umap/static/umap/js/umap.js +27 -36
  7. umap/static/umap/js/umap.layer.js +7 -6
  8. umap/static/umap/test/Map.js +0 -304
  9. umap/static/umap/test/Polygon.js +0 -256
  10. umap/static/umap/test/Polyline.js +0 -116
  11. umap/static/umap/test/index.html +1 -4
  12. umap/tests/conftest.py +9 -0
  13. umap/tests/fixtures/test_upload_data.csv +2 -1
  14. umap/tests/fixtures/test_upload_data.umap +171 -0
  15. umap/tests/fixtures/test_upload_data_osm.json +33 -0
  16. umap/tests/integration/conftest.py +5 -0
  17. umap/tests/integration/test_anonymous_owned_map.py +3 -0
  18. umap/tests/integration/test_browser.py +4 -11
  19. umap/tests/integration/test_choropleth.py +89 -0
  20. umap/tests/integration/test_collaborative_editing.py +30 -1
  21. umap/tests/integration/test_datalayer.py +130 -0
  22. umap/tests/integration/test_edit_datalayer.py +134 -0
  23. umap/tests/integration/test_edit_map.py +15 -0
  24. umap/tests/integration/test_facets_browser.py +31 -0
  25. umap/tests/integration/test_import.py +347 -2
  26. umap/tests/integration/test_map.py +17 -37
  27. umap/tests/integration/test_owned_map.py +18 -0
  28. umap/tests/integration/test_picto.py +20 -33
  29. umap/tests/integration/test_polygon.py +363 -0
  30. umap/tests/integration/test_polyline.py +325 -0
  31. umap/tests/integration/test_tableeditor.py +27 -0
  32. {umap_project-2.1.2.dist-info → umap_project-2.1.3.dist-info}/METADATA +4 -4
  33. {umap_project-2.1.2.dist-info → umap_project-2.1.3.dist-info}/RECORD +36 -33
  34. umap/static/umap/test/Choropleth.js +0 -245
  35. umap/static/umap/test/DataLayer.js +0 -463
  36. umap/static/umap/test/Permissions.js +0 -74
  37. umap/static/umap/test/TableEditor.js +0 -104
  38. umap/tests/integration/test_drawing.py +0 -243
  39. {umap_project-2.1.2.dist-info → umap_project-2.1.3.dist-info}/WHEEL +0 -0
  40. {umap_project-2.1.2.dist-info → umap_project-2.1.3.dist-info}/entry_points.txt +0 -0
  41. {umap_project-2.1.2.dist-info → umap_project-2.1.3.dist-info}/licenses/LICENSE +0 -0
@@ -0,0 +1,363 @@
1
+ import json
2
+ import re
3
+ from pathlib import Path
4
+
5
+ import pytest
6
+ from playwright.sync_api import expect
7
+
8
+ from umap.models import DataLayer
9
+
10
+ pytestmark = pytest.mark.django_db
11
+
12
+
13
+ def save_and_get_json(page):
14
+ with page.expect_response(re.compile(r".*/datalayer/create/.*")):
15
+ page.get_by_role("button", name="Save").click()
16
+ datalayer = DataLayer.objects.last()
17
+ return json.loads(Path(datalayer.geojson.path).read_text())
18
+
19
+
20
+ def test_draw_polygon(page, live_server, tilelayer):
21
+ page.goto(f"{live_server.url}/en/map/new/")
22
+
23
+ # Click on the Draw a polygon button on a new map.
24
+ create_line = page.locator(".leaflet-control-toolbar ").get_by_title(
25
+ "Draw a polygon"
26
+ )
27
+ create_line.click()
28
+
29
+ # Check no polygon is present by default.
30
+ # We target with the color, because there is also the drawing line guide (dash-array)
31
+ # around
32
+ lines = page.locator(".leaflet-overlay-pane path[stroke='DarkBlue']")
33
+ guide = page.locator(".leaflet-overlay-pane > svg > g > path")
34
+ expect(lines).to_have_count(0)
35
+ expect(guide).to_have_count(0)
36
+
37
+ # Click on the map, it will create a polygon.
38
+ map = page.locator("#map")
39
+ map.click(position={"x": 200, "y": 200})
40
+ expect(lines).to_have_count(1)
41
+ expect(guide).to_have_count(1)
42
+ map.click(position={"x": 100, "y": 200})
43
+ expect(lines).to_have_count(1)
44
+ expect(guide).to_have_count(2)
45
+ map.click(position={"x": 100, "y": 100})
46
+ expect(lines).to_have_count(1)
47
+ expect(guide).to_have_count(2)
48
+ # Click again to finish
49
+ map.click(position={"x": 100, "y": 100})
50
+ expect(lines).to_have_count(1)
51
+ expect(guide).to_have_count(0)
52
+
53
+
54
+ def test_clicking_esc_should_finish_polygon(page, live_server, tilelayer):
55
+ page.goto(f"{live_server.url}/en/map/new/")
56
+
57
+ # Click on the Draw a polygon button on a new map.
58
+ create_line = page.locator(".leaflet-control-toolbar ").get_by_title(
59
+ "Draw a polygon"
60
+ )
61
+ create_line.click()
62
+
63
+ # Check no polygon is present by default.
64
+ # We target with the color, because there is also the drawing line guide (dash-array)
65
+ # around
66
+ lines = page.locator(".leaflet-overlay-pane path[stroke='DarkBlue']")
67
+ guide = page.locator(".leaflet-overlay-pane > svg > g > path")
68
+ expect(lines).to_have_count(0)
69
+ expect(guide).to_have_count(0)
70
+
71
+ # Click on the map, it will create a polygon.
72
+ map = page.locator("#map")
73
+ map.click(position={"x": 200, "y": 200})
74
+ expect(lines).to_have_count(1)
75
+ expect(guide).to_have_count(1)
76
+ map.click(position={"x": 100, "y": 200})
77
+ expect(lines).to_have_count(1)
78
+ expect(guide).to_have_count(2)
79
+ map.click(position={"x": 100, "y": 100})
80
+ expect(lines).to_have_count(1)
81
+ expect(guide).to_have_count(2)
82
+ # Click ESC to finish
83
+ page.keyboard.press("Escape")
84
+ expect(lines).to_have_count(1)
85
+ expect(guide).to_have_count(0)
86
+
87
+
88
+ def test_clicking_esc_should_delete_polygon_if_empty(page, live_server, tilelayer):
89
+ page.goto(f"{live_server.url}/en/map/new/")
90
+
91
+ # Click on the Draw a polygon button on a new map.
92
+ create_line = page.locator(".leaflet-control-toolbar ").get_by_title(
93
+ "Draw a polygon"
94
+ )
95
+ create_line.click()
96
+
97
+ # Check no polygon is present by default.
98
+ # We target with the color, because there is also the drawing line guide (dash-array)
99
+ # around
100
+ lines = page.locator(".leaflet-overlay-pane path[stroke='DarkBlue']")
101
+ guide = page.locator(".leaflet-overlay-pane > svg > g > path")
102
+ expect(lines).to_have_count(0)
103
+ expect(guide).to_have_count(0)
104
+
105
+ # Click ESC to finish, no polygon should have been created
106
+ page.keyboard.press("Escape")
107
+ expect(lines).to_have_count(0)
108
+ expect(guide).to_have_count(0)
109
+
110
+
111
+ def test_clicking_esc_should_delete_polygon_if_invalid(page, live_server, tilelayer):
112
+ page.goto(f"{live_server.url}/en/map/new/")
113
+
114
+ # Click on the Draw a polygon button on a new map.
115
+ create_line = page.locator(".leaflet-control-toolbar ").get_by_title(
116
+ "Draw a polygon"
117
+ )
118
+ create_line.click()
119
+
120
+ # Check no polygon is present by default.
121
+ # We target with the color, because there is also the drawing line guide (dash-array)
122
+ # around
123
+ lines = page.locator(".leaflet-overlay-pane path[stroke='DarkBlue']")
124
+ guide = page.locator(".leaflet-overlay-pane > svg > g > path")
125
+ expect(lines).to_have_count(0)
126
+ expect(guide).to_have_count(0)
127
+
128
+ # Click on the map twice, it will start a polygon.
129
+ map = page.locator("#map")
130
+ map.click(position={"x": 200, "y": 200})
131
+ expect(lines).to_have_count(1)
132
+ expect(guide).to_have_count(1)
133
+ map.click(position={"x": 100, "y": 200})
134
+ expect(lines).to_have_count(1)
135
+ expect(guide).to_have_count(2)
136
+ # Click ESC to finish, the polygon is invalid, it should not be persisted
137
+ page.keyboard.press("Escape")
138
+ expect(lines).to_have_count(0)
139
+ expect(guide).to_have_count(0)
140
+
141
+
142
+ def test_can_draw_multi(live_server, page, tilelayer):
143
+ page.goto(f"{live_server.url}/en/map/new/")
144
+ polygons = page.locator(".leaflet-overlay-pane path")
145
+ expect(polygons).to_have_count(0)
146
+ multi_button = page.get_by_title("Add a polygon to the current multi")
147
+ expect(multi_button).to_be_hidden()
148
+ page.get_by_title("Draw a polygon").click()
149
+ map = page.locator("#map")
150
+ map.click(position={"x": 150, "y": 100})
151
+ map.click(position={"x": 150, "y": 150})
152
+ map.click(position={"x": 100, "y": 150})
153
+ map.click(position={"x": 100, "y": 100})
154
+ # Click again to finish
155
+ map.click(position={"x": 100, "y": 100})
156
+ expect(multi_button).to_be_visible()
157
+ expect(polygons).to_have_count(1)
158
+ multi_button.click()
159
+ map.click(position={"x": 250, "y": 200})
160
+ map.click(position={"x": 250, "y": 250})
161
+ map.click(position={"x": 200, "y": 250})
162
+ map.click(position={"x": 200, "y": 200})
163
+ # Click again to finish
164
+ map.click(position={"x": 200, "y": 200})
165
+ expect(polygons).to_have_count(1)
166
+ page.keyboard.press("Escape")
167
+ expect(multi_button).to_be_hidden()
168
+ polygons.first.click(button="right", position={"x": 10, "y": 10})
169
+ expect(page.get_by_role("link", name="Transform to lines")).to_be_hidden()
170
+ expect(page.get_by_role("link", name="Remove shape from the multi")).to_be_visible()
171
+
172
+
173
+ def test_can_draw_hole(page, live_server, tilelayer):
174
+ page.goto(f"{live_server.url}/en/map/new/")
175
+
176
+ page.get_by_title("Draw a polygon").click()
177
+
178
+ polygons = page.locator(".leaflet-overlay-pane path")
179
+ vertices = page.locator(".leaflet-vertex-icon")
180
+
181
+ # Click on the map, it will create a polygon.
182
+ map = page.locator("#map")
183
+ map.click(position={"x": 200, "y": 100})
184
+ map.click(position={"x": 200, "y": 200})
185
+ map.click(position={"x": 100, "y": 200})
186
+ map.click(position={"x": 100, "y": 100})
187
+ # Click again to finish
188
+ map.click(position={"x": 100, "y": 100})
189
+ expect(polygons).to_have_count(1)
190
+ expect(vertices).to_have_count(4)
191
+
192
+ # First vertex of the hole will be created here
193
+ map.click(position={"x": 180, "y": 120})
194
+ page.get_by_role("link", name="Start a hole here").click()
195
+ map.click(position={"x": 180, "y": 180})
196
+ map.click(position={"x": 120, "y": 180})
197
+ map.click(position={"x": 120, "y": 120})
198
+ # Click again to finish
199
+ map.click(position={"x": 120, "y": 120})
200
+ expect(polygons).to_have_count(1)
201
+ expect(vertices).to_have_count(8)
202
+ # Click on the polygon but not in the hole
203
+ polygons.first.click(button="right", position={"x": 10, "y": 10})
204
+ expect(page.get_by_role("link", name="Transform to lines")).to_be_hidden()
205
+
206
+
207
+ def test_can_transfer_shape_from_simple_polygon(live_server, page, tilelayer):
208
+ page.goto(f"{live_server.url}/en/map/new/")
209
+ polygons = page.locator(".leaflet-overlay-pane path")
210
+ expect(polygons).to_have_count(0)
211
+ page.get_by_title("Draw a polygon").click()
212
+ map = page.locator("#map")
213
+
214
+ # Draw a first polygon
215
+ map.click(position={"x": 150, "y": 100})
216
+ map.click(position={"x": 150, "y": 150})
217
+ map.click(position={"x": 100, "y": 150})
218
+ map.click(position={"x": 100, "y": 100})
219
+ # Click again to finish
220
+ map.click(position={"x": 100, "y": 100})
221
+ expect(polygons).to_have_count(1)
222
+
223
+ # Draw another polygon
224
+ page.get_by_title("Draw a polygon").click()
225
+ map.click(position={"x": 250, "y": 200})
226
+ map.click(position={"x": 250, "y": 250})
227
+ map.click(position={"x": 200, "y": 250})
228
+ map.click(position={"x": 200, "y": 200})
229
+ # Click again to finish
230
+ map.click(position={"x": 200, "y": 200})
231
+ expect(polygons).to_have_count(2)
232
+
233
+ # Now that polygon 2 is selected, right click on first one
234
+ # and transfer shape
235
+ polygons.first.click(position={"x": 20, "y": 20}, button="right")
236
+ page.get_by_role("link", name="Transfer shape to edited feature").click()
237
+ expect(polygons).to_have_count(1)
238
+
239
+
240
+ def test_can_extract_shape(live_server, page, tilelayer):
241
+ page.goto(f"{live_server.url}/en/map/new/")
242
+ polygons = page.locator(".leaflet-overlay-pane path")
243
+ expect(polygons).to_have_count(0)
244
+ page.get_by_title("Draw a polygon").click()
245
+ map = page.locator("#map")
246
+ map.click(position={"x": 150, "y": 100})
247
+ map.click(position={"x": 150, "y": 150})
248
+ map.click(position={"x": 100, "y": 150})
249
+ map.click(position={"x": 100, "y": 100})
250
+ # Click again to finish
251
+ map.click(position={"x": 100, "y": 100})
252
+ expect(polygons).to_have_count(1)
253
+ extract_button = page.get_by_role("link", name="Extract shape to separate feature")
254
+ expect(extract_button).to_be_hidden()
255
+ page.get_by_title("Add a polygon to the current multi").click()
256
+ map.click(position={"x": 250, "y": 200})
257
+ map.click(position={"x": 250, "y": 250})
258
+ map.click(position={"x": 200, "y": 250})
259
+ map.click(position={"x": 200, "y": 200})
260
+ # Click again to finish
261
+ map.click(position={"x": 200, "y": 200})
262
+ expect(polygons).to_have_count(1)
263
+ polygons.first.click(position={"x": 20, "y": 20}, button="right")
264
+ extract_button.click()
265
+ expect(polygons).to_have_count(2)
266
+
267
+
268
+ def test_cannot_transfer_shape_to_line(live_server, page, tilelayer):
269
+ page.goto(f"{live_server.url}/en/map/new/")
270
+ polygons = page.locator(".leaflet-overlay-pane path")
271
+ expect(polygons).to_have_count(0)
272
+ page.get_by_title("Draw a polygon").click()
273
+ map = page.locator("#map")
274
+ map.click(position={"x": 150, "y": 100})
275
+ map.click(position={"x": 150, "y": 150})
276
+ map.click(position={"x": 100, "y": 150})
277
+ map.click(position={"x": 100, "y": 100})
278
+ # Click again to finish
279
+ map.click(position={"x": 100, "y": 100})
280
+ expect(polygons).to_have_count(1)
281
+ extract_button = page.get_by_role("link", name="Extract shape to separate feature")
282
+ polygons.first.click(position={"x": 20, "y": 20}, button="right")
283
+ expect(extract_button).to_be_hidden()
284
+ page.get_by_title("Draw a polyline").click()
285
+ map.click(position={"x": 200, "y": 250})
286
+ map.click(position={"x": 200, "y": 200})
287
+ # Click again to finish
288
+ map.click(position={"x": 200, "y": 200})
289
+ expect(polygons).to_have_count(2)
290
+ polygons.first.click(position={"x": 20, "y": 20}, button="right")
291
+ expect(extract_button).to_be_hidden()
292
+
293
+
294
+ def test_cannot_transfer_shape_to_marker(live_server, page, tilelayer):
295
+ page.goto(f"{live_server.url}/en/map/new/")
296
+ polygons = page.locator(".leaflet-overlay-pane path")
297
+ expect(polygons).to_have_count(0)
298
+ page.get_by_title("Draw a polygon").click()
299
+ map = page.locator("#map")
300
+ map.click(position={"x": 150, "y": 100})
301
+ map.click(position={"x": 150, "y": 150})
302
+ map.click(position={"x": 100, "y": 150})
303
+ map.click(position={"x": 100, "y": 100})
304
+ # Click again to finish
305
+ map.click(position={"x": 100, "y": 100})
306
+ expect(polygons).to_have_count(1)
307
+ extract_button = page.get_by_role("link", name="Extract shape to separate feature")
308
+ polygons.first.click(position={"x": 20, "y": 20}, button="right")
309
+ expect(extract_button).to_be_hidden()
310
+ page.get_by_title("Draw a marker").click()
311
+ map.click(position={"x": 250, "y": 200})
312
+ expect(polygons).to_have_count(1)
313
+ polygons.first.click(position={"x": 20, "y": 20}, button="right")
314
+ expect(extract_button).to_be_hidden()
315
+
316
+
317
+ def test_can_clone_polygon(live_server, page, tilelayer, settings):
318
+ settings.UMAP_ALLOW_ANONYMOUS = True
319
+ page.goto(f"{live_server.url}/en/map/new/")
320
+ polygons = page.locator(".leaflet-overlay-pane path")
321
+ expect(polygons).to_have_count(0)
322
+ page.get_by_title("Draw a polygon").click()
323
+ map = page.locator("#map")
324
+ map.click(position={"x": 200, "y": 100})
325
+ map.click(position={"x": 200, "y": 200})
326
+ map.click(position={"x": 100, "y": 200})
327
+ map.click(position={"x": 100, "y": 100})
328
+ # Click again to finish
329
+ map.click(position={"x": 100, "y": 100})
330
+ expect(polygons).to_have_count(1)
331
+ polygons.first.click(button="right")
332
+ page.get_by_role("link", name="Clone this feature").click()
333
+ expect(polygons).to_have_count(2)
334
+ data = save_and_get_json(page)
335
+ assert len(data["features"]) == 2
336
+ assert data["features"][0]["geometry"]["type"] == "Polygon"
337
+ assert data["features"][0]["geometry"] == data["features"][1]["geometry"]
338
+
339
+
340
+ def test_can_transform_polygon_to_line(live_server, page, tilelayer, settings):
341
+ settings.UMAP_ALLOW_ANONYMOUS = True
342
+ page.goto(f"{live_server.url}/en/map/new/")
343
+ paths = page.locator(".leaflet-overlay-pane path")
344
+ polygons = page.locator(".leaflet-overlay-pane path[fill='DarkBlue']")
345
+ expect(polygons).to_have_count(0)
346
+ page.get_by_title("Draw a polygon").click()
347
+ map = page.locator("#map")
348
+ map.click(position={"x": 200, "y": 100})
349
+ map.click(position={"x": 200, "y": 200})
350
+ map.click(position={"x": 100, "y": 200})
351
+ map.click(position={"x": 100, "y": 100})
352
+ # Click again to finish
353
+ map.click(position={"x": 100, "y": 100})
354
+ expect(polygons).to_have_count(1)
355
+ expect(paths).to_have_count(1)
356
+ polygons.first.click(button="right")
357
+ page.get_by_role("link", name="Transform to lines").click()
358
+ # No more polygons (will fill), but one path, it must be a line
359
+ expect(polygons).to_have_count(0)
360
+ expect(paths).to_have_count(1)
361
+ data = save_and_get_json(page)
362
+ assert len(data["features"]) == 1
363
+ assert data["features"][0]["geometry"]["type"] == "LineString"
@@ -0,0 +1,325 @@
1
+ import json
2
+ import re
3
+ from pathlib import Path
4
+
5
+ import pytest
6
+ from playwright.sync_api import expect
7
+
8
+ from umap.models import DataLayer
9
+
10
+ pytestmark = pytest.mark.django_db
11
+
12
+
13
+ def save_and_get_json(page):
14
+ with page.expect_response(re.compile(r".*/datalayer/create/.*")):
15
+ page.get_by_role("button", name="Save").click()
16
+ datalayer = DataLayer.objects.last()
17
+ return json.loads(Path(datalayer.geojson.path).read_text())
18
+
19
+
20
+ def test_draw_polyline(page, live_server, tilelayer):
21
+ page.goto(f"{live_server.url}/en/map/new/")
22
+
23
+ # Click on the Draw a line button on a new map.
24
+ create_line = page.locator(".leaflet-control-toolbar ").get_by_title(
25
+ "Draw a polyline"
26
+ )
27
+ create_line.click()
28
+
29
+ # Check no line is present by default.
30
+ # We target with the color, because there is also the drawing line guide (dash-array)
31
+ # around
32
+ lines = page.locator(".leaflet-overlay-pane path[stroke='DarkBlue']")
33
+ guide = page.locator(".leaflet-overlay-pane > svg > g > path")
34
+ expect(lines).to_have_count(0)
35
+ expect(guide).to_have_count(0)
36
+
37
+ # Click on the map, it will create a line.
38
+ map = page.locator("#map")
39
+ map.click(position={"x": 200, "y": 200})
40
+ expect(lines).to_have_count(1)
41
+ expect(guide).to_have_count(1)
42
+ map.click(position={"x": 100, "y": 200})
43
+ expect(lines).to_have_count(1)
44
+ expect(guide).to_have_count(1)
45
+ map.click(position={"x": 100, "y": 100})
46
+ expect(lines).to_have_count(1)
47
+ expect(guide).to_have_count(1)
48
+ # Click again to finish
49
+ map.click(position={"x": 100, "y": 100})
50
+ expect(lines).to_have_count(1)
51
+ expect(guide).to_have_count(0)
52
+
53
+
54
+ def test_clicking_esc_should_finish_line(page, live_server, tilelayer):
55
+ page.goto(f"{live_server.url}/en/map/new/")
56
+
57
+ # Click on the Draw a line button on a new map.
58
+ create_line = page.locator(".leaflet-control-toolbar ").get_by_title(
59
+ "Draw a polyline"
60
+ )
61
+ create_line.click()
62
+
63
+ # Check no line is present by default.
64
+ # We target with the color, because there is also the drawing line guide (dash-array)
65
+ # around
66
+ lines = page.locator(".leaflet-overlay-pane path[stroke='DarkBlue']")
67
+ guide = page.locator(".leaflet-overlay-pane > svg > g > path")
68
+ expect(lines).to_have_count(0)
69
+ expect(guide).to_have_count(0)
70
+
71
+ # Click on the map, it will create a line.
72
+ map = page.locator("#map")
73
+ map.click(position={"x": 200, "y": 200})
74
+ expect(lines).to_have_count(1)
75
+ expect(guide).to_have_count(1)
76
+ map.click(position={"x": 100, "y": 200})
77
+ expect(lines).to_have_count(1)
78
+ expect(guide).to_have_count(1)
79
+ map.click(position={"x": 100, "y": 100})
80
+ expect(lines).to_have_count(1)
81
+ expect(guide).to_have_count(1)
82
+ # Click ESC to finish
83
+ page.keyboard.press("Escape")
84
+ expect(lines).to_have_count(1)
85
+ expect(guide).to_have_count(0)
86
+
87
+
88
+ def test_clicking_esc_should_delete_line_if_empty(page, live_server, tilelayer):
89
+ page.goto(f"{live_server.url}/en/map/new/")
90
+
91
+ # Click on the Draw a line button on a new map.
92
+ create_line = page.locator(".leaflet-control-toolbar ").get_by_title(
93
+ "Draw a polyline"
94
+ )
95
+ create_line.click()
96
+
97
+ # Check no line is present by default.
98
+ # We target with the color, because there is also the drawing line guide (dash-array)
99
+ # around
100
+ lines = page.locator(".leaflet-overlay-pane path[stroke='DarkBlue']")
101
+ guide = page.locator(".leaflet-overlay-pane > svg > g > path")
102
+ expect(lines).to_have_count(0)
103
+ expect(guide).to_have_count(0)
104
+
105
+ map = page.locator("#map")
106
+ map.click(position={"x": 200, "y": 200})
107
+ # At this stage, the line as one element, it should not be created
108
+ # on pressing esc, as invalid
109
+ # Click ESC to finish
110
+ page.keyboard.press("Escape")
111
+ expect(lines).to_have_count(0)
112
+ expect(guide).to_have_count(0)
113
+
114
+
115
+ def test_clicking_esc_should_delete_line_if_invalid(page, live_server, tilelayer):
116
+ page.goto(f"{live_server.url}/en/map/new/")
117
+
118
+ # Click on the Draw a line button on a new map.
119
+ create_line = page.locator(".leaflet-control-toolbar ").get_by_title(
120
+ "Draw a polyline"
121
+ )
122
+ create_line.click()
123
+
124
+ # Check no line is present by default.
125
+ # We target with the color, because there is also the drawing line guide (dash-array)
126
+ # around
127
+ lines = page.locator(".leaflet-overlay-pane path[stroke='DarkBlue']")
128
+ guide = page.locator(".leaflet-overlay-pane > svg > g > path")
129
+ expect(lines).to_have_count(0)
130
+ expect(guide).to_have_count(0)
131
+
132
+ # At this stage, the line as no element, it should not be created
133
+ # on pressing esc
134
+ # Click ESC to finish
135
+ page.keyboard.press("Escape")
136
+ expect(lines).to_have_count(0)
137
+ expect(guide).to_have_count(0)
138
+
139
+
140
+ def test_can_draw_multi(live_server, page, tilelayer):
141
+ page.goto(f"{live_server.url}/en/map/new/")
142
+ lines = page.locator(".leaflet-overlay-pane path")
143
+ expect(lines).to_have_count(0)
144
+ add_shape = page.get_by_title("Add a line to the current multi")
145
+ expect(add_shape).to_be_hidden()
146
+ page.get_by_title("Draw a polyline").click()
147
+ map = page.locator("#map")
148
+ map.click(position={"x": 200, "y": 100})
149
+ map.click(position={"x": 100, "y": 100})
150
+ map.click(position={"x": 100, "y": 200})
151
+ # Click again to finish
152
+ map.click(position={"x": 100, "y": 200})
153
+ expect(add_shape).to_be_visible()
154
+ expect(lines).to_have_count(1)
155
+ add_shape.click()
156
+ map.click(position={"x": 250, "y": 250})
157
+ map.click(position={"x": 200, "y": 250})
158
+ map.click(position={"x": 200, "y": 200})
159
+ # Click again to finish
160
+ map.click(position={"x": 200, "y": 200})
161
+ expect(lines).to_have_count(1)
162
+ page.keyboard.press("Escape")
163
+ expect(add_shape).to_be_hidden()
164
+ lines.first.click(button="right", position={"x": 10, "y": 1})
165
+ expect(page.get_by_role("link", name="Transform to polygon")).to_be_hidden()
166
+ expect(page.get_by_role("link", name="Remove shape from the multi")).to_be_visible()
167
+
168
+
169
+ def test_can_transfer_shape_from_simple_polyline(live_server, page, tilelayer):
170
+ page.goto(f"{live_server.url}/en/map/new/")
171
+ lines = page.locator(".leaflet-overlay-pane path")
172
+ expect(lines).to_have_count(0)
173
+ page.get_by_title("Draw a polyline").click()
174
+ map = page.locator("#map")
175
+
176
+ # Draw a first line
177
+ map.click(position={"x": 200, "y": 100})
178
+ map.click(position={"x": 100, "y": 100})
179
+ map.click(position={"x": 100, "y": 200})
180
+ # Click again to finish
181
+ map.click(position={"x": 100, "y": 200})
182
+ expect(lines).to_have_count(1)
183
+
184
+ # Draw another polygon
185
+ page.get_by_title("Draw a polyline").click()
186
+ map.click(position={"x": 250, "y": 250})
187
+ map.click(position={"x": 200, "y": 250})
188
+ map.click(position={"x": 200, "y": 200})
189
+ # Click again to finish
190
+ map.click(position={"x": 200, "y": 200})
191
+ expect(lines).to_have_count(2)
192
+
193
+ # Now that polygon 2 is selected, right click on first one
194
+ # and transfer shape
195
+ lines.first.click(position={"x": 10, "y": 1}, button="right")
196
+ page.get_by_role("link", name="Transfer shape to edited feature").click()
197
+ expect(lines).to_have_count(1)
198
+
199
+
200
+ def test_can_transfer_shape_from_multi(live_server, page, tilelayer, settings):
201
+ settings.UMAP_ALLOW_ANONYMOUS = True
202
+ page.goto(f"{live_server.url}/en/map/new/")
203
+ lines = page.locator(".leaflet-overlay-pane path")
204
+ expect(lines).to_have_count(0)
205
+ page.get_by_title("Draw a polyline").click()
206
+ map = page.locator("#map")
207
+
208
+ # Draw a multi line
209
+ map.click(position={"x": 200, "y": 100})
210
+ map.click(position={"x": 100, "y": 100})
211
+ map.click(position={"x": 100, "y": 200})
212
+ # Click again to finish
213
+ map.click(position={"x": 100, "y": 200})
214
+ expect(lines).to_have_count(1)
215
+ page.get_by_title("Add a line to the current multi").click()
216
+ map.click(position={"x": 250, "y": 250})
217
+ map.click(position={"x": 200, "y": 250})
218
+ map.click(position={"x": 200, "y": 200})
219
+ # Click again to finish
220
+ map.click(position={"x": 200, "y": 200})
221
+ expect(lines).to_have_count(1)
222
+
223
+ # Draw another line
224
+ page.get_by_title("Draw a polyline").click()
225
+ map.click(position={"x": 350, "y": 350})
226
+ map.click(position={"x": 300, "y": 350})
227
+ map.click(position={"x": 300, "y": 300})
228
+ # Click again to finish
229
+ map.click(position={"x": 300, "y": 300})
230
+ expect(lines).to_have_count(2)
231
+
232
+ # Now that polygon 2 is selected, right click on first one
233
+ # and transfer shape
234
+ lines.first.click(position={"x": 10, "y": 1}, button="right")
235
+ page.get_by_role("link", name="Transfer shape to edited feature").click()
236
+ expect(lines).to_have_count(2)
237
+ data = save_and_get_json(page)
238
+ # FIXME this should be a LineString, not MultiLineString
239
+ assert data["features"][0]["geometry"] == {
240
+ "coordinates": [
241
+ [[-6.569824, 52.49616], [-7.668457, 52.49616], [-7.668457, 53.159947]]
242
+ ],
243
+ "type": "MultiLineString",
244
+ }
245
+ assert data["features"][1]["geometry"] == {
246
+ "coordinates": [
247
+ [[-4.372559, 51.138001], [-5.471191, 51.138001], [-5.471191, 51.822198]],
248
+ [[-7.668457, 54.457267], [-9.865723, 54.457267], [-9.865723, 53.159947]],
249
+ ],
250
+ "type": "MultiLineString",
251
+ }
252
+
253
+
254
+ def test_can_extract_shape(live_server, page, tilelayer):
255
+ page.goto(f"{live_server.url}/en/map/new/")
256
+ lines = page.locator(".leaflet-overlay-pane path")
257
+ expect(lines).to_have_count(0)
258
+ page.get_by_title("Draw a polylin").click()
259
+ map = page.locator("#map")
260
+ map.click(position={"x": 200, "y": 100})
261
+ map.click(position={"x": 100, "y": 100})
262
+ map.click(position={"x": 100, "y": 200})
263
+ # Click again to finish
264
+ map.click(position={"x": 100, "y": 200})
265
+ expect(lines).to_have_count(1)
266
+ extract_button = page.get_by_role("link", name="Extract shape to separate feature")
267
+ expect(extract_button).to_be_hidden()
268
+ page.get_by_title("Add a line to the current multi").click()
269
+ map.click(position={"x": 250, "y": 250})
270
+ map.click(position={"x": 200, "y": 250})
271
+ map.click(position={"x": 200, "y": 200})
272
+ # Click again to finish
273
+ map.click(position={"x": 200, "y": 200})
274
+ expect(lines).to_have_count(1)
275
+ lines.first.click(position={"x": 10, "y": 1}, button="right")
276
+ extract_button.click()
277
+ expect(lines).to_have_count(2)
278
+
279
+
280
+ def test_can_clone_polyline(live_server, page, tilelayer, settings):
281
+ settings.UMAP_ALLOW_ANONYMOUS = True
282
+ page.goto(f"{live_server.url}/en/map/new/")
283
+ lines = page.locator(".leaflet-overlay-pane path")
284
+ expect(lines).to_have_count(0)
285
+ page.get_by_title("Draw a polyline").click()
286
+ map = page.locator("#map")
287
+ map.click(position={"x": 200, "y": 100})
288
+ map.click(position={"x": 100, "y": 100})
289
+ map.click(position={"x": 100, "y": 200})
290
+ # Click again to finish
291
+ map.click(position={"x": 100, "y": 200})
292
+ expect(lines).to_have_count(1)
293
+ lines.first.click(position={"x": 10, "y": 1}, button="right")
294
+ page.get_by_role("link", name="Clone this feature").click()
295
+ expect(lines).to_have_count(2)
296
+ data = save_and_get_json(page)
297
+ assert len(data["features"]) == 2
298
+ assert data["features"][0]["geometry"]["type"] == "LineString"
299
+ assert data["features"][0]["geometry"] == data["features"][1]["geometry"]
300
+ assert data["features"][0]["properties"] == data["features"][1]["properties"]
301
+
302
+
303
+ def test_can_transform_polyline_to_polygon(live_server, page, tilelayer, settings):
304
+ settings.UMAP_ALLOW_ANONYMOUS = True
305
+ page.goto(f"{live_server.url}/en/map/new/")
306
+ paths = page.locator(".leaflet-overlay-pane path")
307
+ # Paths with fill
308
+ polygons = page.locator(".leaflet-overlay-pane path[fill='DarkBlue']")
309
+ expect(paths).to_have_count(0)
310
+ page.get_by_title("Draw a polyline").click()
311
+ map = page.locator("#map")
312
+ map.click(position={"x": 200, "y": 100})
313
+ map.click(position={"x": 100, "y": 100})
314
+ map.click(position={"x": 100, "y": 200})
315
+ # Click again to finish
316
+ map.click(position={"x": 100, "y": 200})
317
+ expect(paths).to_have_count(1)
318
+ expect(polygons).to_have_count(0)
319
+ paths.first.click(position={"x": 10, "y": 1}, button="right")
320
+ page.get_by_role("link", name="Transform to polygon").click()
321
+ expect(polygons).to_have_count(1)
322
+ expect(paths).to_have_count(1)
323
+ data = save_and_get_json(page)
324
+ assert len(data["features"]) == 1
325
+ assert data["features"][0]["geometry"]["type"] == "Polygon"