umap-project 2.1.3__py3-none-any.whl → 2.2.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.

Potentially problematic release.


This version of umap-project might be problematic. Click here for more details.

Files changed (196) 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 +8 -6
  11. umap/settings/base.py +1 -0
  12. umap/static/umap/base.css +29 -151
  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 +82 -73
  25. umap/static/umap/js/modules/dompurify.js +12 -0
  26. umap/static/umap/js/modules/facets.js +148 -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.controls.js +183 -330
  36. umap/static/umap/js/umap.core.js +60 -364
  37. umap/static/umap/js/umap.datalayer.permissions.js +1 -1
  38. umap/static/umap/js/umap.features.js +60 -40
  39. umap/static/umap/js/umap.forms.js +111 -25
  40. umap/static/umap/js/umap.icon.js +11 -4
  41. umap/static/umap/js/umap.importer.js +24 -17
  42. umap/static/umap/js/umap.js +170 -145
  43. umap/static/umap/js/umap.layer.js +71 -40
  44. umap/static/umap/js/umap.permissions.js +9 -11
  45. umap/static/umap/js/umap.popup.js +10 -21
  46. umap/static/umap/js/umap.share.js +11 -8
  47. umap/static/umap/js/umap.tableeditor.js +4 -6
  48. umap/static/umap/js/umap.ui.js +0 -51
  49. umap/static/umap/locale/am_ET.js +242 -227
  50. umap/static/umap/locale/am_ET.json +18 -7
  51. umap/static/umap/locale/ar.js +242 -227
  52. umap/static/umap/locale/ar.json +18 -7
  53. umap/static/umap/locale/ast.js +242 -227
  54. umap/static/umap/locale/ast.json +18 -7
  55. umap/static/umap/locale/bg.js +242 -227
  56. umap/static/umap/locale/bg.json +18 -7
  57. umap/static/umap/locale/br.js +252 -237
  58. umap/static/umap/locale/br.json +22 -11
  59. umap/static/umap/locale/ca.js +242 -227
  60. umap/static/umap/locale/ca.json +18 -7
  61. umap/static/umap/locale/cs_CZ.js +242 -227
  62. umap/static/umap/locale/cs_CZ.json +18 -7
  63. umap/static/umap/locale/da.js +242 -227
  64. umap/static/umap/locale/da.json +18 -7
  65. umap/static/umap/locale/de.js +242 -227
  66. umap/static/umap/locale/de.json +18 -7
  67. umap/static/umap/locale/el.js +242 -227
  68. umap/static/umap/locale/el.json +18 -7
  69. umap/static/umap/locale/en.js +242 -234
  70. umap/static/umap/locale/en.json +19 -8
  71. umap/static/umap/locale/en_US.json +18 -7
  72. umap/static/umap/locale/es.js +242 -227
  73. umap/static/umap/locale/es.json +18 -7
  74. umap/static/umap/locale/et.js +242 -227
  75. umap/static/umap/locale/et.json +18 -7
  76. umap/static/umap/locale/eu.js +227 -199
  77. umap/static/umap/locale/eu.json +1 -1
  78. umap/static/umap/locale/fa_IR.js +242 -227
  79. umap/static/umap/locale/fa_IR.json +18 -7
  80. umap/static/umap/locale/fi.js +242 -227
  81. umap/static/umap/locale/fi.json +18 -7
  82. umap/static/umap/locale/fr.js +242 -234
  83. umap/static/umap/locale/fr.json +18 -7
  84. umap/static/umap/locale/gl.js +242 -227
  85. umap/static/umap/locale/gl.json +18 -7
  86. umap/static/umap/locale/he.js +242 -227
  87. umap/static/umap/locale/he.json +18 -7
  88. umap/static/umap/locale/hr.js +242 -227
  89. umap/static/umap/locale/hr.json +18 -7
  90. umap/static/umap/locale/hu.js +242 -234
  91. umap/static/umap/locale/hu.json +18 -7
  92. umap/static/umap/locale/id.js +242 -227
  93. umap/static/umap/locale/id.json +18 -7
  94. umap/static/umap/locale/is.js +242 -227
  95. umap/static/umap/locale/is.json +18 -7
  96. umap/static/umap/locale/it.js +242 -234
  97. umap/static/umap/locale/it.json +18 -7
  98. umap/static/umap/locale/ja.js +242 -227
  99. umap/static/umap/locale/ja.json +18 -7
  100. umap/static/umap/locale/ko.js +242 -227
  101. umap/static/umap/locale/ko.json +18 -7
  102. umap/static/umap/locale/lt.js +242 -227
  103. umap/static/umap/locale/lt.json +18 -7
  104. umap/static/umap/locale/ms.js +242 -234
  105. umap/static/umap/locale/ms.json +19 -8
  106. umap/static/umap/locale/nl.js +245 -230
  107. umap/static/umap/locale/nl.json +18 -7
  108. umap/static/umap/locale/no.js +242 -227
  109. umap/static/umap/locale/no.json +18 -7
  110. umap/static/umap/locale/pl.js +242 -227
  111. umap/static/umap/locale/pl.json +18 -7
  112. umap/static/umap/locale/pl_PL.json +18 -7
  113. umap/static/umap/locale/pt.js +242 -227
  114. umap/static/umap/locale/pt.json +18 -7
  115. umap/static/umap/locale/pt_BR.js +242 -227
  116. umap/static/umap/locale/pt_BR.json +18 -7
  117. umap/static/umap/locale/pt_PT.js +242 -227
  118. umap/static/umap/locale/pt_PT.json +18 -7
  119. umap/static/umap/locale/ro.js +242 -227
  120. umap/static/umap/locale/ro.json +18 -7
  121. umap/static/umap/locale/ru.js +242 -227
  122. umap/static/umap/locale/ru.json +18 -7
  123. umap/static/umap/locale/si.js +1 -1
  124. umap/static/umap/locale/si.json +1 -1
  125. umap/static/umap/locale/sk_SK.js +242 -227
  126. umap/static/umap/locale/sk_SK.json +18 -7
  127. umap/static/umap/locale/sl.js +242 -227
  128. umap/static/umap/locale/sl.json +18 -7
  129. umap/static/umap/locale/sr.js +242 -227
  130. umap/static/umap/locale/sr.json +18 -7
  131. umap/static/umap/locale/sv.js +242 -227
  132. umap/static/umap/locale/sv.json +18 -7
  133. umap/static/umap/locale/th_TH.js +242 -227
  134. umap/static/umap/locale/th_TH.json +18 -7
  135. umap/static/umap/locale/tr.js +242 -227
  136. umap/static/umap/locale/tr.json +18 -7
  137. umap/static/umap/locale/uk_UA.js +242 -227
  138. umap/static/umap/locale/uk_UA.json +18 -7
  139. umap/static/umap/locale/vi.js +242 -227
  140. umap/static/umap/locale/vi.json +18 -7
  141. umap/static/umap/locale/vi_VN.json +18 -7
  142. umap/static/umap/locale/zh.js +242 -227
  143. umap/static/umap/locale/zh.json +18 -7
  144. umap/static/umap/locale/zh_CN.json +18 -7
  145. umap/static/umap/locale/zh_TW.Big5.json +18 -7
  146. umap/static/umap/locale/zh_TW.js +242 -234
  147. umap/static/umap/locale/zh_TW.json +18 -7
  148. umap/static/umap/map.css +114 -265
  149. umap/static/umap/test/DataLayer.js +463 -0
  150. umap/static/umap/test/Feature.js +0 -226
  151. umap/static/umap/test/TableEditor.js +104 -0
  152. umap/static/umap/test/Util.js +0 -521
  153. umap/static/umap/test/index.html +0 -1
  154. umap/static/umap/unittests/URLs.js +1 -1
  155. umap/static/umap/unittests/utils.js +610 -0
  156. umap/static/umap/vars.css +9 -0
  157. umap/static/umap/vendors/dompurify/purify.es.mjs +1525 -0
  158. umap/static/umap/vendors/iconlayers/iconLayers.js +1 -1
  159. umap/templates/umap/css.html +2 -0
  160. umap/templates/umap/js.html +0 -1
  161. umap/templates/umap/map_detail.html +4 -0
  162. umap/templates/umap/map_table.html +12 -10
  163. umap/templatetags/umap_tags.py +5 -0
  164. umap/tests/integration/conftest.py +12 -1
  165. umap/tests/integration/test_anonymous_owned_map.py +6 -5
  166. umap/tests/integration/test_browser.py +12 -25
  167. umap/tests/integration/test_choropleth.py +1 -1
  168. umap/tests/integration/test_dashboard.py +10 -0
  169. umap/tests/integration/test_datalayer.py +8 -6
  170. umap/tests/integration/test_edit_datalayer.py +24 -19
  171. umap/tests/integration/test_edit_map.py +182 -2
  172. umap/tests/integration/test_edit_marker.py +120 -0
  173. umap/tests/integration/test_edit_polygon.py +122 -0
  174. umap/tests/integration/test_facets_browser.py +104 -14
  175. umap/tests/integration/test_import.py +70 -20
  176. umap/tests/integration/test_map.py +19 -17
  177. umap/tests/integration/test_map_list.py +28 -0
  178. umap/tests/integration/test_owned_map.py +10 -10
  179. umap/tests/integration/test_picto.py +5 -5
  180. umap/tests/integration/test_querystring.py +9 -15
  181. umap/tests/integration/test_slideshow.py +0 -5
  182. umap/tests/integration/test_statics.py +3 -2
  183. umap/tests/integration/test_tableeditor.py +1 -5
  184. umap/tests/integration/test_view_marker.py +64 -0
  185. umap/tests/integration/test_view_polygon.py +59 -0
  186. umap/tests/integration/test_view_polyline.py +51 -0
  187. umap/tests/test_map_views.py +13 -0
  188. {umap_project-2.1.3.dist-info → umap_project-2.2.0b0.dist-info}/METADATA +8 -8
  189. {umap_project-2.1.3.dist-info → umap_project-2.2.0b0.dist-info}/RECORD +194 -178
  190. umap/static/umap/vendors/dompurify/purify.min.js +0 -3
  191. umap/static/umap/vendors/dompurify/purify.min.js.map +0 -1
  192. /umap/tests/integration/{test_polygon.py → test_draw_polygon.py} +0 -0
  193. /umap/tests/integration/{test_polyline.py → test_draw_polyline.py} +0 -0
  194. {umap_project-2.1.3.dist-info → umap_project-2.2.0b0.dist-info}/WHEEL +0 -0
  195. {umap_project-2.1.3.dist-info → umap_project-2.2.0b0.dist-info}/entry_points.txt +0 -0
  196. {umap_project-2.1.3.dist-info → umap_project-2.2.0b0.dist-info}/licenses/LICENSE +0 -0
@@ -0,0 +1,120 @@
1
+ import platform
2
+ from copy import deepcopy
3
+
4
+ import pytest
5
+ from playwright.sync_api import expect
6
+
7
+ from ..base import DataLayerFactory
8
+
9
+ pytestmark = pytest.mark.django_db
10
+
11
+ DATALAYER_DATA = {
12
+ "type": "FeatureCollection",
13
+ "features": [
14
+ {
15
+ "type": "Feature",
16
+ "properties": {
17
+ "name": "test marker",
18
+ "description": "Some description",
19
+ },
20
+ "id": "QwNjg",
21
+ "geometry": {
22
+ "type": "Point",
23
+ "coordinates": [14.6889, 48.5529],
24
+ },
25
+ },
26
+ ],
27
+ }
28
+
29
+
30
+ @pytest.fixture
31
+ def bootstrap(map, live_server):
32
+ DataLayerFactory(map=map, data=DATALAYER_DATA)
33
+
34
+
35
+ def test_can_edit_on_shift_click(live_server, openmap, page, datalayer):
36
+ modifier = "Meta" if platform.system() == "Darwin" else "Control"
37
+ page.goto(f"{live_server.url}{openmap.get_absolute_url()}?edit")
38
+ page.locator(".leaflet-marker-icon").click(modifiers=[modifier, "Shift"])
39
+ expect(page.get_by_role("heading", name="Layer properties")).to_be_visible()
40
+
41
+
42
+ def test_marker_style_should_have_precedence(live_server, openmap, page, bootstrap):
43
+ page.goto(f"{live_server.url}{openmap.get_absolute_url()}?edit")
44
+
45
+ # Change colour at layer level
46
+ page.get_by_role("link", name="Manage layers").click()
47
+ page.locator(".panel").get_by_title("Edit", exact=True).click()
48
+ page.get_by_role("heading", name="Shape properties").click()
49
+ page.locator(".umap-field-color .define").click()
50
+ expect(page.locator(".leaflet-marker-icon .icon_container")).to_have_css(
51
+ "background-color", "rgb(0, 0, 139)"
52
+ )
53
+ page.get_by_title("DarkRed").first.click()
54
+ expect(page.locator(".leaflet-marker-icon .icon_container")).to_have_css(
55
+ "background-color", "rgb(139, 0, 0)"
56
+ )
57
+
58
+ # Now change at marker level, it should take precedence
59
+ page.locator(".leaflet-marker-icon").click(modifiers=["Shift"])
60
+ page.get_by_role("heading", name="Shape properties").click()
61
+ page.locator("#umap-feature-shape-properties").get_by_text("define").first.click()
62
+ page.get_by_title("GoldenRod", exact=True).click()
63
+ expect(page.locator(".leaflet-marker-icon .icon_container")).to_have_css(
64
+ "background-color", "rgb(218, 165, 32)"
65
+ )
66
+
67
+ # Now change again at layer level again, it should not change the marker color
68
+ page.get_by_role("link", name="Manage layers").click()
69
+ page.locator(".panel").get_by_title("Edit", exact=True).click()
70
+ page.get_by_role("heading", name="Shape properties").click()
71
+ page.locator(".umap-field-color input").click()
72
+ page.get_by_title("DarkViolet").first.click()
73
+ expect(page.locator(".leaflet-marker-icon .icon_container")).to_have_css(
74
+ "background-color", "rgb(218, 165, 32)"
75
+ )
76
+
77
+
78
+ def test_should_open_an_edit_toolbar_on_click(live_server, openmap, page, bootstrap):
79
+ page.goto(f"{live_server.url}{openmap.get_absolute_url()}?edit")
80
+ page.locator(".leaflet-marker-icon").click()
81
+ expect(page.get_by_role("link", name="Toggle edit mode")).to_be_visible()
82
+ expect(page.get_by_role("link", name="Delete this feature")).to_be_visible()
83
+
84
+
85
+ def test_should_update_open_popup_on_edit(live_server, openmap, page, bootstrap):
86
+ page.goto(f"{live_server.url}{openmap.get_absolute_url()}")
87
+ expect(page.locator(".umap-icon-active")).to_be_hidden()
88
+ page.locator(".leaflet-marker-icon").click()
89
+ expect(page.locator(".leaflet-popup-content-wrapper")).to_be_visible()
90
+ expect(page.get_by_role("heading", name="test marker")).to_be_visible()
91
+ expect(page.get_by_text("Some description")).to_be_visible()
92
+ page.get_by_role("button", name="Edit").click()
93
+ page.locator(".leaflet-marker-icon").click(modifiers=["Shift"])
94
+ page.locator('input[name="name"]').fill("test marker edited")
95
+ expect(page.get_by_role("heading", name="test marker edited")).to_be_visible()
96
+
97
+
98
+ def test_should_follow_datalayer_style_when_changing_datalayer(
99
+ live_server, openmap, page
100
+ ):
101
+ data = deepcopy(DATALAYER_DATA)
102
+ data["_umap_options"] = {"color": "DarkCyan"}
103
+ DataLayerFactory(map=openmap, data=data)
104
+ DataLayerFactory(
105
+ map=openmap,
106
+ name="other datalayer",
107
+ data={
108
+ "type": "FeatureCollection",
109
+ "features": [],
110
+ "_umap_options": {"color": "DarkViolet"},
111
+ },
112
+ )
113
+ page.goto(f"{live_server.url}{openmap.get_absolute_url()}?edit")
114
+ marker = page.locator(".leaflet-marker-icon .icon_container")
115
+ expect(marker).to_have_css("background-color", "rgb(0, 139, 139)")
116
+ # Change datalayer
117
+ marker.click()
118
+ page.get_by_role("link", name="Toggle edit mode (⇧+Click)").click()
119
+ page.locator(".umap-field-datalayer select").select_option(label="other datalayer")
120
+ expect(marker).to_have_css("background-color", "rgb(148, 0, 211)")
@@ -0,0 +1,122 @@
1
+ import platform
2
+
3
+ import pytest
4
+ from playwright.sync_api import expect
5
+
6
+ from ..base import DataLayerFactory
7
+
8
+ pytestmark = pytest.mark.django_db
9
+
10
+ DATALAYER_DATA = {
11
+ "type": "FeatureCollection",
12
+ "features": [
13
+ {
14
+ "type": "Feature",
15
+ "properties": {
16
+ "name": "name poly",
17
+ },
18
+ "id": "gyNzM",
19
+ "geometry": {
20
+ "type": "Polygon",
21
+ "coordinates": [
22
+ [
23
+ [11.25, 53.585984],
24
+ [10.151367, 52.975108],
25
+ [12.689209, 52.167194],
26
+ [14.084473, 53.199452],
27
+ [12.634277, 53.618579],
28
+ [11.25, 53.585984],
29
+ [11.25, 53.585984],
30
+ ],
31
+ ],
32
+ },
33
+ },
34
+ ],
35
+ }
36
+
37
+
38
+ @pytest.fixture
39
+ def bootstrap(map, live_server):
40
+ map.settings["properties"]["zoom"] = 6
41
+ map.settings["geometry"] = {
42
+ "type": "Point",
43
+ "coordinates": [8.429, 53.239],
44
+ }
45
+ map.save()
46
+ DataLayerFactory(map=map, data=DATALAYER_DATA)
47
+
48
+
49
+ def test_can_edit_on_shift_click(live_server, openmap, page, datalayer):
50
+ modifier = "Meta" if platform.system() == "Darwin" else "Control"
51
+ page.goto(f"{live_server.url}{openmap.get_absolute_url()}?edit")
52
+ page.locator(".leaflet-marker-icon").click(modifiers=[modifier, "Shift"])
53
+ expect(page.get_by_role("heading", name="Layer properties")).to_be_visible()
54
+
55
+
56
+ def test_marker_style_should_have_precedence(live_server, openmap, page, bootstrap):
57
+ page.goto(f"{live_server.url}{openmap.get_absolute_url()}?edit")
58
+
59
+ # Change colour at layer level
60
+ page.get_by_role("link", name="Manage layers").click()
61
+ page.locator(".panel").get_by_title("Edit", exact=True).click()
62
+ page.get_by_role("heading", name="Shape properties").click()
63
+ page.locator(".umap-field-color .define").click()
64
+ expect(page.locator(".leaflet-overlay-pane path[fill='DarkBlue']")).to_have_count(1)
65
+ page.get_by_title("DarkRed").first.click()
66
+ expect(page.locator(".leaflet-overlay-pane path[fill='DarkRed']")).to_have_count(1)
67
+
68
+ # Now change at polygon level, it should take precedence
69
+ page.locator("path").click(modifiers=["Shift"])
70
+ page.get_by_role("heading", name="Shape properties").click()
71
+ page.locator("#umap-feature-shape-properties").get_by_text("define").first.click()
72
+ page.get_by_title("GoldenRod", exact=True).first.click()
73
+ expect(page.locator(".leaflet-overlay-pane path[fill='GoldenRod']")).to_have_count(
74
+ 1
75
+ )
76
+
77
+ # Now change again at layer level again, it should not change the marker color
78
+ page.get_by_role("link", name="Manage layers").click()
79
+ page.locator(".panel").get_by_title("Edit", exact=True).click()
80
+ page.get_by_role("heading", name="Shape properties").click()
81
+ page.locator(".umap-field-color input").click()
82
+ page.get_by_title("DarkViolet").first.click()
83
+ expect(page.locator(".leaflet-overlay-pane path[fill='GoldenRod']")).to_have_count(
84
+ 1
85
+ )
86
+
87
+
88
+ def test_should_open_an_edit_toolbar_on_click(live_server, openmap, page, bootstrap):
89
+ page.goto(f"{live_server.url}{openmap.get_absolute_url()}?edit")
90
+ page.locator("path").click()
91
+ expect(page.get_by_role("link", name="Toggle edit mode")).to_be_visible()
92
+ expect(page.get_by_role("link", name="Delete this feature")).to_be_visible()
93
+
94
+
95
+ def test_can_remove_stroke(live_server, openmap, page, bootstrap):
96
+ page.goto(f"{live_server.url}{openmap.get_absolute_url()}?edit")
97
+ expect(page.locator(".leaflet-overlay-pane path[stroke='DarkBlue']")).to_have_count(
98
+ 1
99
+ )
100
+ page.locator("path").click()
101
+ page.get_by_role("link", name="Toggle edit mode").click()
102
+ page.get_by_role("heading", name="Shape properties").click()
103
+ page.locator(".umap-field-stroke .define").first.click()
104
+ page.locator(".umap-field-stroke label").first.click()
105
+ expect(page.locator(".leaflet-overlay-pane path[stroke='DarkBlue']")).to_have_count(
106
+ 0
107
+ )
108
+ expect(page.locator(".leaflet-overlay-pane path[stroke='none']")).to_have_count(1)
109
+
110
+
111
+ def test_should_reset_style_on_cancel(live_server, openmap, page, bootstrap):
112
+ page.goto(f"{live_server.url}{openmap.get_absolute_url()}?edit")
113
+ page.locator("path").click(modifiers=["Shift"])
114
+ page.get_by_role("heading", name="Shape properties").click()
115
+ page.locator("#umap-feature-shape-properties").get_by_text("define").first.click()
116
+ page.get_by_title("GoldenRod", exact=True).first.click()
117
+ expect(page.locator(".leaflet-overlay-pane path[fill='GoldenRod']")).to_have_count(
118
+ 1
119
+ )
120
+ page.once("dialog", lambda dialog: dialog.accept())
121
+ page.get_by_role("button", name="Cancel edits").click()
122
+ expect(page.locator(".leaflet-overlay-pane path[fill='DarkBlue']")).to_have_count(1)
@@ -1,3 +1,5 @@
1
+ import copy
2
+
1
3
  import pytest
2
4
  from playwright.sync_api import expect
3
5
 
@@ -11,12 +13,22 @@ DATALAYER_DATA1 = {
11
13
  "features": [
12
14
  {
13
15
  "type": "Feature",
14
- "properties": {"mytype": "even", "name": "Point 2"},
16
+ "properties": {
17
+ "mytype": "even",
18
+ "name": "Point 2",
19
+ "mynumber": 10,
20
+ "mydate": "2024/04/14 12:19:17",
21
+ },
15
22
  "geometry": {"type": "Point", "coordinates": [0.065918, 48.385442]},
16
23
  },
17
24
  {
18
25
  "type": "Feature",
19
- "properties": {"mytype": "odd", "name": "Point 1"},
26
+ "properties": {
27
+ "mytype": "odd",
28
+ "name": "Point 1",
29
+ "mynumber": 12,
30
+ "mydate": "2024/03/13 12:20:20",
31
+ },
20
32
  "geometry": {"type": "Point", "coordinates": [3.55957, 49.767074]},
21
33
  },
22
34
  ],
@@ -31,12 +43,22 @@ DATALAYER_DATA2 = {
31
43
  "features": [
32
44
  {
33
45
  "type": "Feature",
34
- "properties": {"mytype": "even", "name": "Point 4"},
46
+ "properties": {
47
+ "mytype": "even",
48
+ "name": "Point 4",
49
+ "mynumber": 10,
50
+ "mydate": "2024/08/18 13:14:15",
51
+ },
35
52
  "geometry": {"type": "Point", "coordinates": [0.856934, 45.290347]},
36
53
  },
37
54
  {
38
55
  "type": "Feature",
39
- "properties": {"mytype": "odd", "name": "Point 3"},
56
+ "properties": {
57
+ "mytype": "odd",
58
+ "name": "Point 3",
59
+ "mynumber": 14,
60
+ "mydate": "2024-04-14T10:19:17.000Z",
61
+ },
40
62
  "geometry": {"type": "Point", "coordinates": [4.372559, 47.945786]},
41
63
  },
42
64
  ],
@@ -70,23 +92,19 @@ DATALAYER_DATA3 = {
70
92
  }
71
93
 
72
94
 
73
- @pytest.fixture
74
- def bootstrap(map, live_server):
95
+ def test_simple_facet_search(live_server, page, map):
75
96
  map.settings["properties"]["onLoadPanel"] = "facet"
76
- map.settings["properties"]["facetKey"] = "mytype|My type"
97
+ map.settings["properties"]["facetKey"] = "mytype|My type,mynumber|My Number|number"
77
98
  map.settings["properties"]["showLabel"] = True
78
99
  map.save()
79
100
  DataLayerFactory(map=map, data=DATALAYER_DATA1)
80
101
  DataLayerFactory(map=map, data=DATALAYER_DATA2)
81
102
  DataLayerFactory(map=map, data=DATALAYER_DATA3)
82
-
83
-
84
- def test_simple_facet_search(live_server, page, bootstrap, map):
85
- page.goto(f"{live_server.url}{map.get_absolute_url()}")
103
+ page.goto(f"{live_server.url}{map.get_absolute_url()}#6/48.948/1.670")
86
104
  panel = page.locator(".umap-facet-search")
87
105
  # From a non browsable datalayer, should not be impacted
88
106
  paths = page.locator(".leaflet-overlay-pane path")
89
- expect(paths).to_be_visible
107
+ expect(paths).to_be_visible()
90
108
  expect(panel).to_be_visible()
91
109
  # Facet name
92
110
  expect(page.get_by_text("My type")).to_be_visible()
@@ -95,7 +113,7 @@ def test_simple_facet_search(live_server, page, bootstrap, map):
95
113
  odd = page.get_by_text("odd")
96
114
  expect(oven).to_be_visible()
97
115
  expect(odd).to_be_visible()
98
- expect(paths).to_be_visible
116
+ expect(paths).to_be_visible()
99
117
  markers = page.locator(".leaflet-marker-icon")
100
118
  expect(markers).to_have_count(4)
101
119
  # Tooltips
@@ -114,4 +132,76 @@ def test_simple_facet_search(live_server, page, bootstrap, map):
114
132
  # Now let's filter
115
133
  odd.click()
116
134
  expect(markers).to_have_count(4)
117
- expect(paths).to_be_visible
135
+ expect(paths).to_be_visible()
136
+
137
+ # Let's filter using the number facet
138
+ expect(page.get_by_text("My Number")).to_be_visible()
139
+ expect(page.get_by_label("Min")).to_have_value("10")
140
+ expect(page.get_by_label("Max")).to_have_value("14")
141
+ page.get_by_label("Min").fill("11")
142
+ page.keyboard.press("Tab") # Move out of the input, so the "change" event is sent
143
+ expect(markers).to_have_count(2)
144
+ expect(paths).to_be_visible()
145
+ page.get_by_label("Max").fill("13")
146
+ page.keyboard.press("Tab")
147
+ expect(markers).to_have_count(1)
148
+
149
+ # Now let's combine
150
+ page.get_by_label("Min").fill("10")
151
+ page.keyboard.press("Tab")
152
+ expect(markers).to_have_count(3)
153
+ odd.click()
154
+ expect(markers).to_have_count(1)
155
+ expect(paths).to_be_visible()
156
+
157
+
158
+ def test_date_facet_search(live_server, page, map):
159
+ map.settings["properties"]["onLoadPanel"] = "facet"
160
+ map.settings["properties"]["facetKey"] = "mydate|Date filter|date"
161
+ map.save()
162
+ DataLayerFactory(map=map, data=DATALAYER_DATA1)
163
+ DataLayerFactory(map=map, data=DATALAYER_DATA2)
164
+ page.goto(f"{live_server.url}{map.get_absolute_url()}")
165
+ markers = page.locator(".leaflet-marker-icon")
166
+ expect(markers).to_have_count(4)
167
+ expect(page.get_by_text("Date Filter")).to_be_visible()
168
+ expect(page.get_by_label("From")).to_have_value("2024-03-13")
169
+ expect(page.get_by_label("Until")).to_have_value("2024-08-18")
170
+ page.get_by_label("From").fill("2024-03-14")
171
+ expect(markers).to_have_count(3)
172
+ page.get_by_label("Until").fill("2024-08-17")
173
+ expect(markers).to_have_count(2)
174
+
175
+
176
+ def test_choice_with_empty_value(live_server, page, map):
177
+ map.settings["properties"]["onLoadPanel"] = "facet"
178
+ map.settings["properties"]["facetKey"] = "mytype|My type"
179
+ map.save()
180
+ data = copy.deepcopy(DATALAYER_DATA1)
181
+ data["features"][0]["properties"]["mytype"] = ""
182
+ del data["features"][1]["properties"]["mytype"]
183
+ DataLayerFactory(map=map, data=data)
184
+ DataLayerFactory(map=map, data=DATALAYER_DATA2)
185
+ page.goto(f"{live_server.url}{map.get_absolute_url()}")
186
+ expect(page.get_by_text("<empty value>")).to_be_visible()
187
+ markers = page.locator(".leaflet-marker-icon")
188
+ expect(markers).to_have_count(4)
189
+ page.get_by_text("<empty value>").click()
190
+ expect(markers).to_have_count(2)
191
+
192
+
193
+ def test_number_with_zero_value(live_server, page, map):
194
+ map.settings["properties"]["onLoadPanel"] = "facet"
195
+ map.settings["properties"]["facetKey"] = "mynumber|Filter|number"
196
+ map.save()
197
+ data = copy.deepcopy(DATALAYER_DATA1)
198
+ data["features"][0]["properties"]["mynumber"] = 0
199
+ DataLayerFactory(map=map, data=data)
200
+ DataLayerFactory(map=map, data=DATALAYER_DATA2)
201
+ page.goto(f"{live_server.url}{map.get_absolute_url()}")
202
+ expect(page.get_by_label("Min")).to_have_value("0")
203
+ expect(page.get_by_label("Max")).to_have_value("14")
204
+ page.get_by_label("Min").fill("1")
205
+ page.keyboard.press("Tab") # Move out of the input, so the "change" event is sent
206
+ markers = page.locator(".leaflet-marker-icon")
207
+ expect(markers).to_have_count(3)
@@ -1,6 +1,7 @@
1
1
  import json
2
2
  import re
3
3
  from pathlib import Path
4
+ from time import sleep
4
5
 
5
6
  import pytest
6
7
  from playwright.sync_api import expect
@@ -10,11 +11,29 @@ from umap.models import DataLayer
10
11
  pytestmark = pytest.mark.django_db
11
12
 
12
13
 
14
+ def test_layers_list_is_updated(live_server, tilelayer, page):
15
+ page.goto(f"{live_server.url}/map/new/")
16
+ page.get_by_role("link", name="Import data (Ctrl+I)").click()
17
+ # Should work
18
+ page.get_by_label("Choose the layer to import").select_option(
19
+ label="Import in a new layer"
20
+ )
21
+ page.get_by_role("link", name="Manage layers").click()
22
+ page.get_by_role("button", name="Add a layer").click()
23
+ page.locator('input[name="name"]').click()
24
+ page.locator('input[name="name"]').fill("foobar")
25
+ page.get_by_role("link", name="Import data (Ctrl+I)").click()
26
+ # Should still work
27
+ page.get_by_label("Choose the layer to import").select_option(
28
+ label="Import in a new layer"
29
+ )
30
+ # Now layer should be visible in the options
31
+ page.get_by_label("Choose the layer to import").select_option(label="foobar")
32
+
33
+
13
34
  def test_umap_import_from_file(live_server, tilelayer, page):
14
35
  page.goto(f"{live_server.url}/map/new/")
15
- button = page.get_by_title("Import data")
16
- expect(button).to_be_visible()
17
- button.click()
36
+ page.get_by_title("Import data").click()
18
37
  file_input = page.locator("input[type='file']")
19
38
  with page.expect_file_chooser() as fc_info:
20
39
  file_input.click()
@@ -24,34 +43,38 @@ def test_umap_import_from_file(live_server, tilelayer, page):
24
43
  button = page.get_by_role("button", name="Import", exact=True)
25
44
  expect(button).to_be_visible()
26
45
  button.click()
27
- layers = page.locator(".umap-browse-datalayers li")
28
- expect(layers).to_have_count(2)
29
- nonloaded = page.locator(".umap-browse-datalayers li.off")
30
- expect(nonloaded).to_have_count(1)
31
46
  assert file_input.input_value()
32
47
  # Close the import panel
33
48
  page.keyboard.press("Escape")
49
+ # Reopen
50
+ page.get_by_title("Import data").click()
51
+ sleep(1) # Wait for CSS transition to happen
34
52
  assert not file_input.input_value()
35
53
  expect(page.locator(".umap-main-edit-toolbox .map-name")).to_have_text(
36
54
  "Carte sans nom"
37
55
  )
56
+ page.get_by_title("See layers").click()
57
+ layers = page.locator(".umap-browser .datalayer")
58
+ expect(layers).to_have_count(2)
59
+ nonloaded = page.locator(".umap-browser .datalayer.off")
60
+ expect(nonloaded).to_have_count(1)
38
61
 
39
62
 
40
63
  def test_umap_import_from_textarea(live_server, tilelayer, page, settings):
41
64
  settings.UMAP_ALLOW_ANONYMOUS = True
42
65
  page.goto(f"{live_server.url}/map/new/")
66
+ page.get_by_role("button", name="See layers").click()
43
67
  page.get_by_title("Import data").click()
44
68
  textarea = page.locator(".umap-upload textarea")
45
69
  path = Path(__file__).parent.parent / "fixtures/test_upload_data.umap"
46
70
  textarea.fill(path.read_text())
47
71
  page.locator('select[name="format"]').select_option("umap")
48
72
  page.get_by_role("button", name="Import", exact=True).click()
49
- layers = page.locator(".umap-browse-datalayers li")
73
+ layers = page.locator(".umap-browser .datalayer")
50
74
  expect(layers).to_have_count(2)
51
75
  expect(page.locator(".umap-main-edit-toolbox .map-name")).to_have_text(
52
76
  "Imported map"
53
77
  )
54
- page.get_by_role("button", name="See data layers").click()
55
78
  expect(page.get_by_text("Tunnels")).to_be_visible()
56
79
  expect(page.get_by_text("Cities")).to_be_visible()
57
80
  expect(page.locator(".leaflet-control-minimap")).to_be_visible()
@@ -67,7 +90,8 @@ def test_umap_import_from_textarea(live_server, tilelayer, page, settings):
67
90
 
68
91
  def test_import_geojson_from_textarea(tilelayer, live_server, page):
69
92
  page.goto(f"{live_server.url}/map/new/")
70
- layers = page.locator(".umap-browse-datalayers li")
93
+ page.get_by_title("See layers").click()
94
+ layers = page.locator(".umap-browser .datalayer")
71
95
  markers = page.locator(".leaflet-marker-icon")
72
96
  paths = page.locator("path")
73
97
  expect(markers).to_have_count(0)
@@ -91,7 +115,8 @@ def test_import_geojson_from_textarea(tilelayer, live_server, page):
91
115
 
92
116
  def test_import_kml_from_textarea(tilelayer, live_server, page):
93
117
  page.goto(f"{live_server.url}/map/new/")
94
- layers = page.locator(".umap-browse-datalayers li")
118
+ page.get_by_title("See layers").click()
119
+ layers = page.locator(".umap-browser .datalayer")
95
120
  markers = page.locator(".leaflet-marker-icon")
96
121
  paths = page.locator("path")
97
122
  expect(markers).to_have_count(0)
@@ -115,7 +140,8 @@ def test_import_kml_from_textarea(tilelayer, live_server, page):
115
140
 
116
141
  def test_import_gpx_from_textarea(tilelayer, live_server, page):
117
142
  page.goto(f"{live_server.url}/map/new/")
118
- layers = page.locator(".umap-browse-datalayers li")
143
+ page.get_by_title("See layers").click()
144
+ layers = page.locator(".umap-browser .datalayer")
119
145
  markers = page.locator(".leaflet-marker-icon")
120
146
  paths = page.locator("path")
121
147
  expect(markers).to_have_count(0)
@@ -139,7 +165,8 @@ def test_import_gpx_from_textarea(tilelayer, live_server, page):
139
165
 
140
166
  def test_import_osm_from_textarea(tilelayer, live_server, page):
141
167
  page.goto(f"{live_server.url}/map/new/")
142
- layers = page.locator(".umap-browse-datalayers li")
168
+ page.get_by_title("See layers").click()
169
+ layers = page.locator(".umap-browser .datalayer")
143
170
  markers = page.locator(".leaflet-marker-icon")
144
171
  expect(markers).to_have_count(0)
145
172
  expect(layers).to_have_count(0)
@@ -158,7 +185,8 @@ def test_import_osm_from_textarea(tilelayer, live_server, page):
158
185
 
159
186
  def test_import_csv_from_textarea(tilelayer, live_server, page):
160
187
  page.goto(f"{live_server.url}/map/new/")
161
- layers = page.locator(".umap-browse-datalayers li")
188
+ page.get_by_title("See layers").click()
189
+ layers = page.locator(".umap-browser .datalayer")
162
190
  markers = page.locator(".leaflet-marker-icon")
163
191
  expect(markers).to_have_count(0)
164
192
  expect(layers).to_have_count(0)
@@ -177,7 +205,8 @@ def test_import_csv_from_textarea(tilelayer, live_server, page):
177
205
 
178
206
  def test_can_import_in_existing_datalayer(live_server, datalayer, page, openmap):
179
207
  page.goto(f"{live_server.url}{openmap.get_absolute_url()}")
180
- layers = page.locator(".umap-browse-datalayers li")
208
+ page.get_by_title("See layers").click()
209
+ layers = page.locator(".umap-browser .datalayer")
181
210
  markers = page.locator(".leaflet-marker-icon")
182
211
  expect(markers).to_have_count(1)
183
212
  expect(layers).to_have_count(1)
@@ -195,7 +224,8 @@ def test_can_import_in_existing_datalayer(live_server, datalayer, page, openmap)
195
224
 
196
225
  def test_can_replace_datalayer_data(live_server, datalayer, page, openmap):
197
226
  page.goto(f"{live_server.url}{openmap.get_absolute_url()}")
198
- layers = page.locator(".umap-browse-datalayers li")
227
+ page.get_by_title("See layers").click()
228
+ layers = page.locator(".umap-browser .datalayer")
199
229
  markers = page.locator(".leaflet-marker-icon")
200
230
  expect(markers).to_have_count(1)
201
231
  expect(layers).to_have_count(1)
@@ -214,7 +244,8 @@ def test_can_replace_datalayer_data(live_server, datalayer, page, openmap):
214
244
 
215
245
  def test_can_import_in_new_datalayer(live_server, datalayer, page, openmap):
216
246
  page.goto(f"{live_server.url}{openmap.get_absolute_url()}")
217
- layers = page.locator(".umap-browse-datalayers li")
247
+ page.get_by_title("See layers").click()
248
+ layers = page.locator(".umap-browser .datalayer")
218
249
  markers = page.locator(".leaflet-marker-icon")
219
250
  expect(markers).to_have_count(1)
220
251
  expect(layers).to_have_count(1)
@@ -317,7 +348,8 @@ def test_import_geometry_collection(live_server, page, tilelayer):
317
348
  ],
318
349
  }
319
350
  page.goto(f"{live_server.url}/map/new/")
320
- layers = page.locator(".umap-browse-datalayers li")
351
+ page.get_by_title("See layers").click()
352
+ layers = page.locator(".umap-browser .datalayer")
321
353
  markers = page.locator(".leaflet-marker-icon")
322
354
  paths = page.locator("path")
323
355
  expect(markers).to_have_count(0)
@@ -352,7 +384,8 @@ def test_import_multipolygon(live_server, page, tilelayer):
352
384
  },
353
385
  }
354
386
  page.goto(f"{live_server.url}/map/new/")
355
- layers = page.locator(".umap-browse-datalayers li")
387
+ page.get_by_title("See layers").click()
388
+ layers = page.locator(".umap-browser .datalayer")
356
389
  paths = page.locator("path")
357
390
  expect(paths).to_have_count(0)
358
391
  expect(layers).to_have_count(0)
@@ -383,7 +416,8 @@ def test_import_multipolyline(live_server, page, tilelayer):
383
416
  ],
384
417
  }
385
418
  page.goto(f"{live_server.url}/map/new/")
386
- layers = page.locator(".umap-browse-datalayers li")
419
+ page.get_by_title("See layers").click()
420
+ layers = page.locator(".umap-browser .datalayer")
387
421
  paths = page.locator("path")
388
422
  expect(paths).to_have_count(0)
389
423
  expect(layers).to_have_count(0)
@@ -397,3 +431,19 @@ def test_import_multipolyline(live_server, page, tilelayer):
397
431
  # A layer has been created
398
432
  expect(layers).to_have_count(1)
399
433
  expect(paths).to_have_count(1)
434
+
435
+
436
+ def test_import_csv_without_valid_latlon_headers(tilelayer, live_server, page):
437
+ page.goto(f"{live_server.url}/map/new/")
438
+ page.get_by_title("See layers").click()
439
+ layers = page.locator(".umap-browser .datalayer")
440
+ markers = page.locator(".leaflet-marker-icon")
441
+ page.get_by_title("Import data").click()
442
+ textarea = page.locator(".umap-upload textarea")
443
+ textarea.fill("a,b,c\n12.23,48.34,mypoint\n12.23,48.34,mypoint2")
444
+ page.locator('select[name="format"]').select_option("csv")
445
+ page.get_by_role("button", name="Import", exact=True).click()
446
+ # FIXME do not create a layer
447
+ expect(layers).to_have_count(1)
448
+ expect(markers).to_have_count(0)
449
+ expect(page.locator(".umap-alert")).to_be_visible()