umap-project 3.3.2__py3-none-any.whl → 3.4.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (242) hide show
  1. umap/__init__.py +1 -1
  2. umap/context_processors.py +4 -1
  3. umap/locale/cs_CZ/LC_MESSAGES/django.mo +0 -0
  4. umap/locale/cs_CZ/LC_MESSAGES/django.po +43 -33
  5. umap/locale/da/LC_MESSAGES/django.mo +0 -0
  6. umap/locale/da/LC_MESSAGES/django.po +43 -33
  7. umap/locale/de/LC_MESSAGES/django.mo +0 -0
  8. umap/locale/de/LC_MESSAGES/django.po +64 -53
  9. umap/locale/el/LC_MESSAGES/django.mo +0 -0
  10. umap/locale/el/LC_MESSAGES/django.po +35 -29
  11. umap/locale/en/LC_MESSAGES/django.po +47 -41
  12. umap/locale/es/LC_MESSAGES/django.mo +0 -0
  13. umap/locale/es/LC_MESSAGES/django.po +43 -33
  14. umap/locale/et/LC_MESSAGES/django.mo +0 -0
  15. umap/locale/et/LC_MESSAGES/django.po +58 -54
  16. umap/locale/eu/LC_MESSAGES/django.mo +0 -0
  17. umap/locale/eu/LC_MESSAGES/django.po +43 -33
  18. umap/locale/fa_IR/LC_MESSAGES/django.mo +0 -0
  19. umap/locale/fa_IR/LC_MESSAGES/django.po +43 -33
  20. umap/locale/fr/LC_MESSAGES/django.mo +0 -0
  21. umap/locale/fr/LC_MESSAGES/django.po +36 -30
  22. umap/locale/gl/LC_MESSAGES/django.mo +0 -0
  23. umap/locale/gl/LC_MESSAGES/django.po +43 -33
  24. umap/locale/hu/LC_MESSAGES/django.mo +0 -0
  25. umap/locale/hu/LC_MESSAGES/django.po +35 -29
  26. umap/locale/is/LC_MESSAGES/django.mo +0 -0
  27. umap/locale/is/LC_MESSAGES/django.po +43 -33
  28. umap/locale/it/LC_MESSAGES/django.mo +0 -0
  29. umap/locale/it/LC_MESSAGES/django.po +43 -33
  30. umap/locale/nl/LC_MESSAGES/django.mo +0 -0
  31. umap/locale/nl/LC_MESSAGES/django.po +35 -29
  32. umap/locale/pl/LC_MESSAGES/django.mo +0 -0
  33. umap/locale/pl/LC_MESSAGES/django.po +114 -103
  34. umap/locale/pt/LC_MESSAGES/django.mo +0 -0
  35. umap/locale/pt/LC_MESSAGES/django.po +43 -33
  36. umap/locale/th_TH/LC_MESSAGES/django.mo +0 -0
  37. umap/locale/th_TH/LC_MESSAGES/django.po +310 -109
  38. umap/locale/zh_TW/LC_MESSAGES/django.mo +0 -0
  39. umap/locale/zh_TW/LC_MESSAGES/django.po +80 -70
  40. umap/management/commands/switch_user.py +2 -2
  41. umap/migrations/0018_datalayer_uuid.py +1 -1
  42. umap/models.py +7 -3
  43. umap/settings/local.py.sample +1 -1
  44. umap/static/umap/base.css +89 -32
  45. umap/static/umap/content.css +129 -33
  46. umap/static/umap/css/bar.css +82 -20
  47. umap/static/umap/css/browser.css +163 -0
  48. umap/static/umap/css/contextmenu.css +15 -0
  49. umap/static/umap/css/dialog.css +36 -16
  50. umap/static/umap/css/form.css +123 -33
  51. umap/static/umap/css/icon.css +46 -3
  52. umap/static/umap/css/panel.css +7 -3
  53. umap/static/umap/css/popup.css +34 -8
  54. umap/static/umap/css/tooltip.css +8 -4
  55. umap/static/umap/img/16-white.svg +26 -8
  56. umap/static/umap/img/16.svg +1 -1
  57. umap/static/umap/img/source/16-white.svg +36 -18
  58. umap/static/umap/img/source/16.svg +1 -1
  59. umap/static/umap/js/components/alerts/alert.css +69 -31
  60. umap/static/umap/js/components/alerts/alert.js +20 -2
  61. umap/static/umap/js/components/base.js +1 -1
  62. umap/static/umap/js/modules/browser.js +69 -61
  63. umap/static/umap/js/modules/caption.js +10 -7
  64. umap/static/umap/js/modules/data/features.js +89 -63
  65. umap/static/umap/js/modules/data/fields.js +446 -0
  66. umap/static/umap/js/modules/data/layer.js +116 -196
  67. umap/static/umap/js/modules/domutils.js +109 -0
  68. umap/static/umap/js/modules/filters.js +780 -0
  69. umap/static/umap/js/modules/form/builder.js +8 -5
  70. umap/static/umap/js/modules/form/fields.js +111 -221
  71. umap/static/umap/js/modules/formatter.js +24 -1
  72. umap/static/umap/js/modules/help.js +4 -3
  73. umap/static/umap/js/modules/i18n.js +1 -1
  74. umap/static/umap/js/modules/importer.js +1 -1
  75. umap/static/umap/js/modules/importers/opendata.js +15 -0
  76. umap/static/umap/js/modules/importers/openrouteservice.js +6 -1
  77. umap/static/umap/js/modules/managers.js +2 -1
  78. umap/static/umap/js/modules/permissions.js +39 -31
  79. umap/static/umap/js/modules/rendering/controls.js +11 -9
  80. umap/static/umap/js/modules/rendering/icon.js +3 -8
  81. umap/static/umap/js/modules/rendering/layers/base.js +3 -3
  82. umap/static/umap/js/modules/rendering/layers/classified.js +18 -11
  83. umap/static/umap/js/modules/rendering/layers/cluster.js +23 -11
  84. umap/static/umap/js/modules/rendering/layers/heat.js +27 -21
  85. umap/static/umap/js/modules/rendering/map.js +1 -0
  86. umap/static/umap/js/modules/rendering/template.js +50 -23
  87. umap/static/umap/js/modules/rendering/ui.js +33 -25
  88. umap/static/umap/js/modules/rules.js +38 -44
  89. umap/static/umap/js/modules/schema.js +3 -6
  90. umap/static/umap/js/modules/share.js +5 -4
  91. umap/static/umap/js/modules/tableeditor.js +50 -38
  92. umap/static/umap/js/modules/templates.js +2 -3
  93. umap/static/umap/js/modules/ui/bar.js +55 -23
  94. umap/static/umap/js/modules/ui/dialog.js +38 -27
  95. umap/static/umap/js/modules/ui/panel.js +23 -8
  96. umap/static/umap/js/modules/ui/tooltip.js +6 -5
  97. umap/static/umap/js/modules/umap.js +158 -51
  98. umap/static/umap/js/modules/utils.js +24 -2
  99. umap/static/umap/js/umap.core.js +1 -110
  100. umap/static/umap/locale/am_ET.js +52 -17
  101. umap/static/umap/locale/am_ET.json +52 -17
  102. umap/static/umap/locale/ar.js +52 -17
  103. umap/static/umap/locale/ar.json +52 -17
  104. umap/static/umap/locale/ast.js +52 -17
  105. umap/static/umap/locale/ast.json +52 -17
  106. umap/static/umap/locale/bg.js +52 -17
  107. umap/static/umap/locale/bg.json +52 -17
  108. umap/static/umap/locale/br.js +48 -22
  109. umap/static/umap/locale/br.json +48 -22
  110. umap/static/umap/locale/ca.js +52 -17
  111. umap/static/umap/locale/ca.json +52 -17
  112. umap/static/umap/locale/cs_CZ.js +52 -17
  113. umap/static/umap/locale/cs_CZ.json +52 -17
  114. umap/static/umap/locale/da.js +54 -17
  115. umap/static/umap/locale/da.json +54 -17
  116. umap/static/umap/locale/de.js +102 -67
  117. umap/static/umap/locale/de.json +102 -67
  118. umap/static/umap/locale/el.js +52 -17
  119. umap/static/umap/locale/el.json +52 -17
  120. umap/static/umap/locale/en.js +54 -16
  121. umap/static/umap/locale/en.json +54 -16
  122. umap/static/umap/locale/en_US.json +52 -17
  123. umap/static/umap/locale/es.js +54 -17
  124. umap/static/umap/locale/es.json +54 -17
  125. umap/static/umap/locale/et.js +91 -56
  126. umap/static/umap/locale/et.json +91 -56
  127. umap/static/umap/locale/eu.js +84 -49
  128. umap/static/umap/locale/eu.json +84 -49
  129. umap/static/umap/locale/fa_IR.js +52 -17
  130. umap/static/umap/locale/fa_IR.json +52 -17
  131. umap/static/umap/locale/fi.js +52 -17
  132. umap/static/umap/locale/fi.json +52 -17
  133. umap/static/umap/locale/fr.js +54 -17
  134. umap/static/umap/locale/fr.json +54 -17
  135. umap/static/umap/locale/gl.js +52 -17
  136. umap/static/umap/locale/gl.json +52 -17
  137. umap/static/umap/locale/he.js +52 -17
  138. umap/static/umap/locale/he.json +52 -17
  139. umap/static/umap/locale/hr.js +52 -17
  140. umap/static/umap/locale/hr.json +52 -17
  141. umap/static/umap/locale/hu.js +59 -24
  142. umap/static/umap/locale/hu.json +59 -24
  143. umap/static/umap/locale/id.js +52 -17
  144. umap/static/umap/locale/id.json +52 -17
  145. umap/static/umap/locale/is.js +52 -17
  146. umap/static/umap/locale/is.json +52 -17
  147. umap/static/umap/locale/it.js +52 -17
  148. umap/static/umap/locale/it.json +52 -17
  149. umap/static/umap/locale/ja.js +52 -17
  150. umap/static/umap/locale/ja.json +52 -17
  151. umap/static/umap/locale/ko.js +52 -17
  152. umap/static/umap/locale/ko.json +52 -17
  153. umap/static/umap/locale/lt.js +52 -17
  154. umap/static/umap/locale/lt.json +52 -17
  155. umap/static/umap/locale/ms.js +52 -17
  156. umap/static/umap/locale/ms.json +52 -17
  157. umap/static/umap/locale/nl.js +52 -17
  158. umap/static/umap/locale/nl.json +52 -17
  159. umap/static/umap/locale/no.js +52 -17
  160. umap/static/umap/locale/no.json +52 -17
  161. umap/static/umap/locale/pl.js +53 -17
  162. umap/static/umap/locale/pl.json +53 -17
  163. umap/static/umap/locale/pl_PL.json +52 -17
  164. umap/static/umap/locale/pt.js +52 -17
  165. umap/static/umap/locale/pt.json +52 -17
  166. umap/static/umap/locale/pt_BR.js +52 -17
  167. umap/static/umap/locale/pt_BR.json +52 -17
  168. umap/static/umap/locale/pt_PT.js +52 -17
  169. umap/static/umap/locale/pt_PT.json +52 -17
  170. umap/static/umap/locale/ro.js +52 -17
  171. umap/static/umap/locale/ro.json +52 -17
  172. umap/static/umap/locale/ru.js +52 -17
  173. umap/static/umap/locale/ru.json +52 -17
  174. umap/static/umap/locale/si.js +1 -1
  175. umap/static/umap/locale/si.json +1 -1
  176. umap/static/umap/locale/sk_SK.js +52 -17
  177. umap/static/umap/locale/sk_SK.json +52 -17
  178. umap/static/umap/locale/sl.js +52 -17
  179. umap/static/umap/locale/sl.json +52 -17
  180. umap/static/umap/locale/sr.js +52 -17
  181. umap/static/umap/locale/sr.json +52 -17
  182. umap/static/umap/locale/sv.js +52 -17
  183. umap/static/umap/locale/sv.json +52 -17
  184. umap/static/umap/locale/th_TH.js +52 -17
  185. umap/static/umap/locale/th_TH.json +52 -17
  186. umap/static/umap/locale/tr.js +52 -17
  187. umap/static/umap/locale/tr.json +52 -17
  188. umap/static/umap/locale/uk_UA.js +52 -17
  189. umap/static/umap/locale/uk_UA.json +52 -17
  190. umap/static/umap/locale/vi.js +52 -17
  191. umap/static/umap/locale/vi.json +52 -17
  192. umap/static/umap/locale/vi_VN.json +52 -17
  193. umap/static/umap/locale/zh.js +52 -17
  194. umap/static/umap/locale/zh.json +52 -17
  195. umap/static/umap/locale/zh_CN.json +52 -17
  196. umap/static/umap/locale/zh_TW.Big5.json +52 -17
  197. umap/static/umap/locale/zh_TW.js +53 -17
  198. umap/static/umap/locale/zh_TW.json +53 -17
  199. umap/static/umap/map.css +63 -226
  200. umap/static/umap/unittests/utils.js +18 -0
  201. umap/static/umap/vars.css +23 -5
  202. umap/templates/umap/components/alerts/alert.html +32 -29
  203. umap/templates/umap/css.html +2 -1
  204. umap/templates/umap/login_popup_end.html +18 -9
  205. umap/templates/umap/user_map_table.html +7 -2
  206. umap/tests/integration/conftest.py +10 -6
  207. umap/tests/integration/test_anonymous_owned_map.py +90 -37
  208. umap/tests/integration/test_basics.py +25 -1
  209. umap/tests/integration/test_browser.py +37 -0
  210. umap/tests/integration/test_cluster.py +110 -0
  211. umap/tests/integration/test_conditional_rules.py +107 -52
  212. umap/tests/integration/test_datalayer.py +9 -16
  213. umap/tests/integration/test_draw_polygon.py +6 -0
  214. umap/tests/integration/test_draw_polyline.py +11 -0
  215. umap/tests/integration/test_edit_marker.py +12 -1
  216. umap/tests/integration/test_export_map.py +19 -0
  217. umap/tests/integration/test_fields.py +541 -0
  218. umap/tests/integration/test_filters.py +616 -0
  219. umap/tests/integration/test_iframe.py +1 -1
  220. umap/tests/integration/test_import.py +38 -42
  221. umap/tests/integration/test_map_preview.py +1 -1
  222. umap/tests/integration/test_picto.py +1 -1
  223. umap/tests/integration/test_popup.py +31 -0
  224. umap/tests/integration/test_remote_data.py +60 -4
  225. umap/tests/integration/test_save.py +1 -1
  226. umap/tests/integration/test_share.py +4 -4
  227. umap/tests/integration/test_tableeditor.py +31 -7
  228. umap/tests/integration/test_websocket_sync.py +71 -20
  229. umap/tests/test_dashboard.py +11 -1
  230. umap/tests/test_statics.py +2 -2
  231. umap/tests/test_utils.py +19 -2
  232. umap/tests/test_views.py +1 -1
  233. umap/urls.py +1 -0
  234. umap/utils.py +8 -1
  235. umap/views.py +5 -0
  236. {umap_project-3.3.2.dist-info → umap_project-3.4.0.dist-info}/METADATA +15 -15
  237. {umap_project-3.3.2.dist-info → umap_project-3.4.0.dist-info}/RECORD +240 -236
  238. umap/static/umap/js/modules/facets.js +0 -164
  239. umap/tests/integration/test_facets_browser.py +0 -279
  240. {umap_project-3.3.2.dist-info → umap_project-3.4.0.dist-info}/WHEEL +0 -0
  241. {umap_project-3.3.2.dist-info → umap_project-3.4.0.dist-info}/entry_points.txt +0 -0
  242. {umap_project-3.3.2.dist-info → umap_project-3.4.0.dist-info}/licenses/LICENSE +0 -0
@@ -18,25 +18,24 @@ def owner_session(anonymap, context, live_server):
18
18
  key, value = anonymap.signed_cookie_elements
19
19
  signed = get_cookie_signer(salt=key).sign(value)
20
20
  context.add_cookies([{"name": key, "value": signed, "url": live_server.url}])
21
- return context.new_page()
22
21
 
23
22
 
24
- def test_map_load_with_owner(anonymap, live_server, owner_session):
25
- owner_session.goto(f"{live_server.url}{anonymap.get_absolute_url()}")
26
- map_el = owner_session.locator("#map")
23
+ def test_map_load_with_owner(anonymap, live_server, owner_session, page):
24
+ page.goto(f"{live_server.url}{anonymap.get_absolute_url()}")
25
+ map_el = page.locator("#map")
27
26
  expect(map_el).to_be_visible()
28
- enable = owner_session.get_by_role("button", name="Edit")
27
+ enable = page.get_by_role("button", name="Edit")
29
28
  expect(enable).to_be_visible()
30
29
  enable.click()
31
- disable = owner_session.get_by_role("button", name="View")
30
+ disable = page.get_by_role("button", name="View")
32
31
  expect(disable).to_be_visible()
33
- save = owner_session.get_by_role("button", name="Save")
32
+ save = page.get_by_role("button", name="Save")
34
33
  expect(save).to_be_visible()
35
- add_marker = owner_session.get_by_title("Draw a marker")
34
+ add_marker = page.get_by_title("Draw a marker")
36
35
  expect(add_marker).to_be_visible()
37
- edit_settings = owner_session.get_by_title("Map advanced properties")
36
+ edit_settings = page.get_by_title("Map advanced properties")
38
37
  expect(edit_settings).to_be_visible()
39
- edit_permissions = owner_session.get_by_title("Update permissions and editors")
38
+ edit_permissions = page.get_by_title("Update permissions and editors")
40
39
  expect(edit_permissions).to_be_visible()
41
40
 
42
41
 
@@ -71,35 +70,31 @@ def test_map_load_with_anonymous_but_editable_layer(
71
70
  expect(edit_permissions).to_be_hidden()
72
71
 
73
72
 
74
- def test_owner_permissions_form(map, datalayer, live_server, owner_session):
75
- owner_session.goto(f"{live_server.url}{map.get_absolute_url()}?edit")
76
- edit_permissions = owner_session.get_by_title("Update permissions and editors")
73
+ def test_owner_permissions_form(map, datalayer, live_server, owner_session, page):
74
+ page.goto(f"{live_server.url}{map.get_absolute_url()}?edit")
75
+ edit_permissions = page.get_by_title("Update permissions and editors")
77
76
  expect(edit_permissions).to_be_visible()
78
77
  edit_permissions.click()
79
- owner_field = owner_session.locator(".umap-field-owner")
78
+ owner_field = page.locator(".umap-field-owner")
80
79
  expect(owner_field).to_be_hidden()
81
- editors_field = owner_session.locator(".umap-field-editors input")
80
+ editors_field = page.locator(".umap-field-editors input")
82
81
  expect(editors_field).to_be_hidden()
83
- datalayer_label = owner_session.get_by_text('Who can edit "test datalayer"')
82
+ datalayer_label = page.get_by_text('Who can edit "test datalayer"')
84
83
  expect(datalayer_label).to_be_visible()
85
- options = owner_session.locator(
86
- ".datalayer-permissions select[name='edit_status'] option"
87
- )
84
+ options = page.locator(".datalayer-permissions select[name='edit_status'] option")
88
85
  expect(options).to_have_count(3)
89
- option = owner_session.locator(
86
+ option = page.locator(
90
87
  ".datalayer-permissions select[name='edit_status'] option:checked"
91
88
  )
92
89
  expect(option).to_have_text("Inherit")
93
- expect(owner_session.locator(".umap-field-share_status select")).to_be_visible()
90
+ expect(page.locator(".umap-field-share_status select")).to_be_visible()
94
91
  options = [
95
92
  int(option.get_attribute("value"))
96
- for option in owner_session.locator(
97
- ".umap-field-share_status select option"
98
- ).all()
93
+ for option in page.locator(".umap-field-share_status select option").all()
99
94
  ]
100
95
  assert options == [Map.DRAFT, Map.PUBLIC]
101
96
  # This field should not be present in anonymous maps
102
- expect(owner_session.locator(".umap-field-owner")).to_be_hidden()
97
+ expect(page.locator(".umap-field-owner")).to_be_hidden()
103
98
 
104
99
 
105
100
  def test_anonymous_can_add_marker_on_editable_layer(
@@ -180,7 +175,7 @@ def test_alert_message_after_create(
180
175
  new_map = Map.objects.last()
181
176
  expect(alert).to_be_visible()
182
177
  expect(
183
- alert.get_by_text("Your map has been created with an anonymous account!")
178
+ alert.get_by_text("Hey, you created a map without an account!")
184
179
  ).to_be_visible()
185
180
  expect(alert.get_by_role("button", name="Copy")).to_be_visible()
186
181
  expect(alert.get_by_role("button", name="Send me the link")).to_be_visible()
@@ -198,7 +193,7 @@ def test_alert_message_after_create(
198
193
  )
199
194
 
200
195
 
201
- def test_email_sending_error_are_catched(tilelayer, page, live_server):
196
+ def test_email_sending_error_are_caught(tilelayer, page, live_server):
202
197
  page.goto(f"{live_server.url}/en/map/new")
203
198
  alert_creation = page.locator('umap-alert-creation div[role="dialog"]')
204
199
  with page.expect_response(re.compile(r".*/map/create/")):
@@ -224,22 +219,22 @@ def test_alert_message_after_create_show_link_even_without_mail(
224
219
  alert = page.locator('umap-alert-creation div[role="dialog"]')
225
220
  expect(alert).to_be_visible()
226
221
  expect(
227
- alert.get_by_text("Your map has been created with an anonymous account!")
222
+ alert.get_by_text("Hey, you created a map without an account!")
228
223
  ).to_be_visible()
229
224
  expect(alert.get_by_role("button", name="Copy")).to_be_visible()
230
225
  expect(alert.get_by_role("button", name="Send me the link")).to_be_hidden()
231
226
 
232
227
 
233
- def test_anonymous_owner_can_delete_the_map(anonymap, live_server, owner_session):
228
+ def test_anonymous_owner_can_delete_the_map(anonymap, live_server, owner_session, page):
234
229
  assert Map.objects.count() == 1
235
- owner_session.goto(f"{live_server.url}{anonymap.get_absolute_url()}")
236
- owner_session.get_by_role("button", name="Edit").click()
237
- owner_session.get_by_role("button", name="Map advanced properties").click()
238
- owner_session.get_by_text("Advanced actions").click()
239
- expect(owner_session.get_by_role("button", name="Delete")).to_be_visible()
240
- owner_session.get_by_role("button", name="Delete").click()
241
- with owner_session.expect_response(re.compile(r".*/update/delete/.*")):
242
- owner_session.get_by_role("button", name="OK").click()
230
+ page.goto(f"{live_server.url}{anonymap.get_absolute_url()}")
231
+ page.get_by_role("button", name="Edit").click()
232
+ page.get_by_role("button", name="Map advanced properties").click()
233
+ page.get_by_text("Advanced actions").click()
234
+ expect(page.get_by_role("button", name="Delete")).to_be_visible()
235
+ page.get_by_role("button", name="Delete").click()
236
+ with page.expect_response(re.compile(r".*/update/delete/.*")):
237
+ page.get_by_role("button", name="OK").click()
243
238
  assert Map.objects.get(pk=anonymap.pk).share_status == Map.DELETED
244
239
 
245
240
 
@@ -251,3 +246,61 @@ def test_non_owner_cannot_see_delete_button(anonymap, live_server, page):
251
246
  page.get_by_role("button", name="Map advanced properties").click()
252
247
  page.get_by_text("Advanced actions").click()
253
248
  expect(page.get_by_role("button", name="Delete")).to_be_hidden()
249
+
250
+
251
+ def test_logged_in_user_should_have_a_message_to_attach_map(
252
+ anonymap, live_server, login, user, page, owner_session
253
+ ):
254
+ page.goto(f"{live_server.url}{anonymap.get_absolute_url()}")
255
+ page.get_by_role("button", name="Edit").click()
256
+ expect(
257
+ page.get_by_text(
258
+ "This map is anonymous, do you want to attach it to your account?"
259
+ )
260
+ ).to_be_hidden()
261
+
262
+ page = login(user)
263
+ page.goto(f"{live_server.url}{anonymap.get_absolute_url()}")
264
+ page.get_by_role("button", name="Edit").click()
265
+ expect(
266
+ page.get_by_text(
267
+ "This map is anonymous, do you want to attach it to your account?"
268
+ )
269
+ ).to_be_visible()
270
+ with page.expect_response(re.compile(r".*/update/owner/.*")):
271
+ page.get_by_role("button", name="OK").click()
272
+ saved = Map.objects.get(pk=anonymap.pk)
273
+ assert saved.owner
274
+
275
+
276
+ def test_can_attach_map_after_save(
277
+ live_server, user, page, tilelayer, context, settings
278
+ ):
279
+ settings.ENABLE_ACCOUNT_LOGIN = True
280
+ page.goto(f"{live_server.url}/en/map/new")
281
+ expect(page.get_by_role("button", name="Anonymous")).to_be_visible()
282
+ expect(page.get_by_role("button", name="Visibility: Draft")).to_have_class(
283
+ re.compile(r".*anonymous.*")
284
+ )
285
+ assert not Map.objects.count()
286
+ with page.expect_response(re.compile(r".*/map/create/")):
287
+ page.get_by_role("button", name="Save draft", exact=True).click()
288
+ assert Map.objects.count() == 1
289
+ saved = Map.objects.last()
290
+ assert not saved.owner
291
+ with context.expect_page() as login_page_info:
292
+ page.get_by_role("link", name="log in").click()
293
+ login_page = login_page_info.value
294
+ expect(login_page).to_have_title("Login - Online map creator")
295
+ login_page.get_by_placeholder("Username").fill(user.username)
296
+ login_page.get_by_placeholder("Password").fill("123123")
297
+ with page.expect_response(re.compile(r".*/update/owner/")):
298
+ login_page.locator('#login_form input[type="submit"]').click()
299
+ expect(page.get_by_text("Map has been attached to your account")).to_be_visible()
300
+ saved = Map.objects.last()
301
+ assert saved.owner == user
302
+ expect(page.get_by_role("button", name="Anonymous")).to_be_hidden()
303
+ expect(page.get_by_role("button", name=user.username)).to_be_visible()
304
+ expect(page.get_by_role("button", name="Visibility: Draft")).not_to_have_class(
305
+ re.compile(r".*anonymous.*")
306
+ )
@@ -79,7 +79,9 @@ def test_cannot_put_script_tag_in_datalayer_name_or_description(
79
79
  expect(page.get_by_text("before after")).to_be_visible()
80
80
 
81
81
 
82
- def test_login_from_map_page(live_server, page, tilelayer, settings, user, context):
82
+ def test_login_from_map_page_after_save(
83
+ live_server, page, tilelayer, settings, user, context
84
+ ):
83
85
  settings.ENABLE_ACCOUNT_LOGIN = True
84
86
  assert Map.objects.count() == 0
85
87
  page.goto(f"{live_server.url}/en/map/new/")
@@ -102,3 +104,25 @@ def test_login_from_map_page(live_server, page, tilelayer, settings, user, conte
102
104
  assert Map.objects.count() == 1
103
105
  # Use name should now appear on the header toolbar
104
106
  expect(page.get_by_role("button", name="Joe")).to_be_visible()
107
+
108
+
109
+ def test_login_from_unsaved_map_page(
110
+ live_server, page, tilelayer, settings, user, context
111
+ ):
112
+ settings.ENABLE_ACCOUNT_LOGIN = True
113
+ assert Map.objects.count() == 0
114
+ page.goto(f"{live_server.url}/en/map/new/")
115
+ page.locator('[data-ref="user"]').click()
116
+ with context.expect_page() as login_page_info:
117
+ page.get_by_role("button", name="Login").click()
118
+ login_page = login_page_info.value
119
+ expect(login_page).to_have_title("Login - Online map creator")
120
+ login_page.get_by_placeholder("Username").fill(user.username)
121
+ login_page.get_by_placeholder("Password").fill("123123")
122
+ login_page.locator('#login_form input[type="submit"]').click()
123
+ # Login page should be closed
124
+ page.wait_for_timeout(500) # Seems needed from time to time…
125
+ assert len(context.pages) == 1
126
+ # Save should have proceed
127
+ # Use name should now appear on the header toolbar
128
+ expect(page.get_by_role("button", name="Joe")).to_be_visible()
@@ -353,6 +353,43 @@ def test_should_redraw_list_on_feature_delete(live_server, openmap, page, bootst
353
353
  expect(buttons).to_have_count(3)
354
354
 
355
355
 
356
+ def test_should_change_feature_title_and_color_on_edit(
357
+ live_server, openmap, page, bootstrap
358
+ ):
359
+ page.goto(f"{live_server.url}{openmap.get_absolute_url()}?edit#2/19/-2")
360
+ expect(page.locator(".umap-browser .feature.marker")).to_contain_text(
361
+ "one point in france"
362
+ )
363
+ page.locator(".leaflet-marker-icon").click(modifiers=["Shift"])
364
+ page.locator('input[name="name"]').fill("changed name")
365
+ expect(page.locator(".umap-browser .feature.marker")).to_contain_text(
366
+ "changed name"
367
+ )
368
+
369
+ # Change color
370
+ expect(
371
+ page.get_by_role("listitem").filter(has_text="changed name").locator("i")
372
+ ).to_have_css("background-color", "rgb(0, 0, 139)")
373
+ page.get_by_role("heading", name="Shape properties").click()
374
+ page.locator(".umap-field-color").get_by_role("button", name="define").first.click()
375
+ page.get_by_title("Crimson").click()
376
+ expect(
377
+ page.get_by_role("listitem").filter(has_text="changed name").locator("i")
378
+ ).to_have_css("background-color", "rgb(220, 20, 60)")
379
+
380
+ # Undo color
381
+ page.locator(".edit-undo").click()
382
+ expect(
383
+ page.get_by_role("listitem").filter(has_text="changed name").locator("i")
384
+ ).to_have_css("background-color", "rgb(0, 0, 139)")
385
+
386
+ # Undo title change
387
+ page.locator(".edit-undo").click()
388
+ expect(page.locator(".umap-browser .feature.marker")).to_contain_text(
389
+ "one point in france"
390
+ )
391
+
392
+
356
393
  def test_should_show_header_for_display_on_load_false(
357
394
  live_server, page, bootstrap, map, datalayer
358
395
  ):
@@ -51,3 +51,113 @@ def test_can_open_feature_on_browser_click(live_server, page, map):
51
51
  expect(page.get_by_text("can you see me ?")).to_be_visible()
52
52
  page.get_by_text("again one another point").click()
53
53
  expect(page.get_by_text("and me ?")).to_be_visible()
54
+
55
+
56
+ def test_can_drag_single_marker_in_cluster_layer(live_server, page, tilelayer, openmap):
57
+ DataLayerFactory(map=openmap, data=DATALAYER_DATA)
58
+ page.goto(f"{live_server.url}{openmap.get_absolute_url()}?edit#7/46.920/3.340")
59
+
60
+ marker = page.locator(".umap-div-icon")
61
+ map = page.locator("#map")
62
+
63
+ expect(page.locator(".edit-undo")).to_be_disabled()
64
+ # Drag marker
65
+ old_bbox = marker.bounding_box()
66
+ marker.first.drag_to(map, target_position={"x": 250, "y": 250})
67
+ assert marker.bounding_box() != old_bbox
68
+ expect(page.locator(".edit-undo")).to_be_enabled()
69
+ # Make sure edit stays panel
70
+ page.wait_for_timeout(1000)
71
+ expect(page.locator(".panel.right")).to_be_visible()
72
+
73
+
74
+ def test_can_drag_marker_in_cluster(live_server, page, tilelayer, openmap):
75
+ DataLayerFactory(map=openmap, data=DATALAYER_DATA)
76
+ page.goto(f"{live_server.url}{openmap.get_absolute_url()}?edit#18/46.92/3.34")
77
+
78
+ marker = page.locator(".umap-div-icon")
79
+ cluster = page.locator(".umap-cluster-icon")
80
+ map = page.locator("#map")
81
+ expect(marker).to_have_count(0)
82
+
83
+ expect(page.locator(".edit-undo")).to_be_disabled()
84
+ cluster.click()
85
+ marker.first.drag_to(map, target_position={"x": 250, "y": 250})
86
+ expect(page.locator(".edit-undo")).to_be_enabled()
87
+ # There is no more cluster
88
+ expect(marker).to_have_count(2)
89
+
90
+
91
+ def test_can_change_datalayer_of_marker_in_cluster(
92
+ live_server, page, datalayer, openmap, tilelayer
93
+ ):
94
+ DataLayerFactory(map=openmap, data=DATALAYER_DATA)
95
+ datalayer.settings["iconClass"] = "Ball"
96
+ datalayer.save()
97
+ page.goto(f"{live_server.url}{openmap.get_absolute_url()}?edit#7/46.920/3.340")
98
+
99
+ expect(page.locator(".umap-ball-icon")).to_have_count(0)
100
+ page.locator(".umap-div-icon").click(modifiers=["Shift"])
101
+ page.get_by_role("combobox").select_option(str(datalayer.pk))
102
+ expect(page.locator(".umap-ball-icon")).to_have_count(1)
103
+
104
+
105
+ def test_can_combine_cluster_with_remote_data_and_fromZoom(
106
+ page, live_server, tilelayer, map
107
+ ):
108
+ settings = {
109
+ "fromZoom": "7",
110
+ "type": "Cluster",
111
+ "showLabel": True,
112
+ "remoteData": {
113
+ "url": "https://remote.org/data.json",
114
+ "format": "geojson",
115
+ "dynamic": True,
116
+ },
117
+ }
118
+ DataLayerFactory(map=map, settings=settings)
119
+ data = [
120
+ {
121
+ "type": "FeatureCollection",
122
+ "features": [
123
+ {
124
+ "type": "Feature",
125
+ "properties": {"name": "Point 2"},
126
+ "geometry": {
127
+ "type": "Point",
128
+ "coordinates": [4.3375, 11.2707],
129
+ },
130
+ }
131
+ ],
132
+ },
133
+ {
134
+ "type": "FeatureCollection",
135
+ "features": [
136
+ {
137
+ "type": "Feature",
138
+ "properties": {"name": "Point 1"},
139
+ "geometry": {
140
+ "type": "Point",
141
+ "coordinates": [4.3375, 12.2707],
142
+ },
143
+ }
144
+ ],
145
+ },
146
+ ]
147
+
148
+ def handle(route):
149
+ route.fulfill(json=data.pop())
150
+
151
+ page.route("https://remote.org/data.json", handle)
152
+ page.goto(f"{live_server.url}{map.get_absolute_url()}#7/12.271/4.338")
153
+ expect(page.locator(".umap-div-icon")).to_have_count(1)
154
+ expect(page.get_by_role("tooltip", name="Point 1")).to_be_visible()
155
+ page.get_by_role("button", name="Zoom out").click()
156
+
157
+ # We are above fromZoom
158
+ expect(page.locator(".umap-div-icon")).to_have_count(0)
159
+
160
+ page.get_by_role("button", name="Zoom in").click()
161
+
162
+ expect(page.locator(".umap-div-icon")).to_have_count(1)
163
+ expect(page.get_by_role("tooltip", name="Point 2")).to_be_visible()