umap-project 2.8.2__py3-none-any.whl → 2.9.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 (157) hide show
  1. umap/__init__.py +1 -1
  2. umap/asgi.py +12 -7
  3. umap/context_processors.py +1 -0
  4. umap/locale/en/LC_MESSAGES/django.po +102 -59
  5. umap/locale/fr/LC_MESSAGES/django.mo +0 -0
  6. umap/locale/fr/LC_MESSAGES/django.po +105 -61
  7. umap/management/commands/empty_trash.py +12 -1
  8. umap/migrations/0026_datalayer_modified_at_datalayer_share_status.py +26 -0
  9. umap/models.py +23 -3
  10. umap/settings/base.py +4 -1
  11. umap/static/umap/base.css +1 -1
  12. umap/static/umap/content.css +2 -22
  13. umap/static/umap/css/bar.css +7 -10
  14. umap/static/umap/css/form.css +28 -29
  15. umap/static/umap/css/icon.css +8 -2
  16. umap/static/umap/css/panel.css +2 -1
  17. umap/static/umap/css/tooltip.css +33 -31
  18. umap/static/umap/img/16-white.svg +2 -0
  19. umap/static/umap/img/16.svg +1 -1
  20. umap/static/umap/img/providers/bitbucket.png +0 -0
  21. umap/static/umap/img/providers/github.png +0 -0
  22. umap/static/umap/img/providers/keycloak.png +0 -0
  23. umap/static/umap/img/providers/openstreetmap-oauth2.png +0 -0
  24. umap/static/umap/img/providers/twitter-oauth2.png +0 -0
  25. umap/static/umap/img/source/16-white.svg +3 -1
  26. umap/static/umap/img/source/16.svg +1 -1
  27. umap/static/umap/js/components/alerts/alert.js +4 -1
  28. umap/static/umap/js/modules/browser.js +6 -6
  29. umap/static/umap/js/modules/caption.js +30 -7
  30. umap/static/umap/js/modules/data/features.js +21 -24
  31. umap/static/umap/js/modules/data/layer.js +71 -33
  32. umap/static/umap/js/modules/form/builder.js +241 -0
  33. umap/static/umap/js/modules/form/fields.js +1338 -0
  34. umap/static/umap/js/modules/formatter.js +5 -8
  35. umap/static/umap/js/modules/help.js +3 -1
  36. umap/static/umap/js/modules/importer.js +1 -1
  37. umap/static/umap/js/modules/permissions.js +5 -4
  38. umap/static/umap/js/modules/rendering/icon.js +5 -1
  39. umap/static/umap/js/modules/rendering/layers/classified.js +11 -7
  40. umap/static/umap/js/modules/rendering/layers/cluster.js +11 -1
  41. umap/static/umap/js/modules/rendering/map.js +0 -2
  42. umap/static/umap/js/modules/rules.js +2 -1
  43. umap/static/umap/js/modules/schema.js +5 -6
  44. umap/static/umap/js/modules/share.js +3 -3
  45. umap/static/umap/js/modules/sync/engine.js +18 -13
  46. umap/static/umap/js/modules/sync/updaters.js +8 -0
  47. umap/static/umap/js/modules/sync/websocket.js +10 -5
  48. umap/static/umap/js/modules/tableeditor.js +3 -2
  49. umap/static/umap/js/modules/ui/bar.js +17 -9
  50. umap/static/umap/js/modules/ui/base.js +7 -24
  51. umap/static/umap/js/modules/ui/tooltip.js +19 -11
  52. umap/static/umap/js/modules/umap.js +36 -24
  53. umap/static/umap/js/modules/utils.js +196 -12
  54. umap/static/umap/js/umap.controls.js +0 -12
  55. umap/static/umap/locale/br.js +21 -13
  56. umap/static/umap/locale/br.json +21 -13
  57. umap/static/umap/locale/ca.js +12 -4
  58. umap/static/umap/locale/ca.json +12 -4
  59. umap/static/umap/locale/cs_CZ.js +10 -4
  60. umap/static/umap/locale/cs_CZ.json +10 -4
  61. umap/static/umap/locale/de.js +12 -4
  62. umap/static/umap/locale/de.json +12 -4
  63. umap/static/umap/locale/el.js +12 -4
  64. umap/static/umap/locale/el.json +12 -4
  65. umap/static/umap/locale/en.js +9 -4
  66. umap/static/umap/locale/en.json +9 -4
  67. umap/static/umap/locale/es.js +20 -12
  68. umap/static/umap/locale/es.json +20 -12
  69. umap/static/umap/locale/eu.js +12 -4
  70. umap/static/umap/locale/eu.json +12 -4
  71. umap/static/umap/locale/fa_IR.js +12 -4
  72. umap/static/umap/locale/fa_IR.json +12 -4
  73. umap/static/umap/locale/fr.js +10 -5
  74. umap/static/umap/locale/fr.json +10 -5
  75. umap/static/umap/locale/gl.js +353 -345
  76. umap/static/umap/locale/gl.json +353 -345
  77. umap/static/umap/locale/hu.js +9 -4
  78. umap/static/umap/locale/hu.json +9 -4
  79. umap/static/umap/locale/it.js +100 -92
  80. umap/static/umap/locale/it.json +100 -92
  81. umap/static/umap/locale/ms.js +12 -4
  82. umap/static/umap/locale/ms.json +12 -4
  83. umap/static/umap/locale/nl.js +12 -4
  84. umap/static/umap/locale/nl.json +12 -4
  85. umap/static/umap/locale/pl.js +12 -4
  86. umap/static/umap/locale/pl.json +12 -4
  87. umap/static/umap/locale/pt.js +12 -4
  88. umap/static/umap/locale/pt.json +12 -4
  89. umap/static/umap/locale/pt_PT.js +12 -4
  90. umap/static/umap/locale/pt_PT.json +12 -4
  91. umap/static/umap/locale/th_TH.js +12 -4
  92. umap/static/umap/locale/th_TH.json +12 -4
  93. umap/static/umap/locale/zh_TW.js +10 -4
  94. umap/static/umap/locale/zh_TW.json +10 -4
  95. umap/static/umap/map.css +12 -8
  96. umap/static/umap/nav.css +2 -3
  97. umap/static/umap/unittests/utils.js +14 -0
  98. umap/static/umap/vars.css +2 -0
  99. umap/sync/__init__.py +0 -0
  100. umap/sync/app.py +181 -0
  101. umap/sync/payloads.py +49 -0
  102. umap/templates/auth/user_detail.html +4 -0
  103. umap/templates/auth/user_form.html +9 -6
  104. umap/templates/auth/user_stars.html +4 -0
  105. umap/templates/base.html +1 -1
  106. umap/templates/registration/login.html +2 -5
  107. umap/templates/umap/about.html +5 -0
  108. umap/templates/umap/about_summary.html +2 -2
  109. umap/templates/umap/components/provider.html +8 -0
  110. umap/templates/umap/js.html +0 -3
  111. umap/templates/umap/map_detail.html +1 -1
  112. umap/templates/umap/password_change.html +4 -0
  113. umap/templates/umap/password_change_done.html +4 -0
  114. umap/templates/umap/search.html +4 -0
  115. umap/templates/umap/team_confirm_delete.html +4 -0
  116. umap/templates/umap/team_detail.html +4 -0
  117. umap/templates/umap/team_form.html +4 -0
  118. umap/templates/umap/user_dashboard.html +1 -1
  119. umap/templates/umap/user_teams.html +4 -0
  120. umap/tests/base.py +3 -1
  121. umap/tests/integration/conftest.py +16 -23
  122. umap/tests/integration/test_basics.py +2 -2
  123. umap/tests/integration/test_caption.py +1 -0
  124. umap/tests/integration/test_draw_polygon.py +3 -3
  125. umap/tests/integration/test_edit_datalayer.py +1 -1
  126. umap/tests/integration/test_edit_map.py +3 -3
  127. umap/tests/integration/test_edit_polygon.py +1 -1
  128. umap/tests/integration/test_import.py +23 -1
  129. umap/tests/integration/test_optimistic_merge.py +1 -0
  130. umap/tests/integration/test_picto.py +8 -8
  131. umap/tests/integration/test_save.py +1 -0
  132. umap/tests/integration/test_star.py +13 -9
  133. umap/tests/integration/test_tableeditor.py +1 -0
  134. umap/tests/integration/test_websocket_sync.py +112 -33
  135. umap/tests/settings.py +2 -0
  136. umap/tests/test_datalayer.py +2 -3
  137. umap/tests/test_datalayer_views.py +20 -1
  138. umap/tests/test_empty_trash.py +10 -3
  139. umap/tests/test_map_views.py +11 -0
  140. umap/utils.py +24 -11
  141. umap/views.py +37 -6
  142. {umap_project-2.8.2.dist-info → umap_project-2.9.0b0.dist-info}/METADATA +15 -15
  143. {umap_project-2.8.2.dist-info → umap_project-2.9.0b0.dist-info}/RECORD +146 -145
  144. {umap_project-2.8.2.dist-info → umap_project-2.9.0b0.dist-info}/WHEEL +1 -1
  145. umap/management/commands/run_websocket_server.py +0 -23
  146. umap/settings/local_s3.py +0 -45
  147. umap/static/umap/bitbucket.png +0 -0
  148. umap/static/umap/github.png +0 -0
  149. umap/static/umap/js/umap.forms.js +0 -1242
  150. umap/static/umap/keycloak.png +0 -0
  151. umap/static/umap/openstreetmap.png +0 -0
  152. umap/static/umap/twitter.png +0 -0
  153. umap/static/umap/vendors/formbuilder/Leaflet.FormBuilder.js +0 -468
  154. umap/tests/test_websocket_server.py +0 -22
  155. umap/websocket_server.py +0 -202
  156. {umap_project-2.8.2.dist-info → umap_project-2.9.0b0.dist-info}/entry_points.txt +0 -0
  157. {umap_project-2.8.2.dist-info → umap_project-2.9.0b0.dist-info}/licenses/LICENSE +0 -0
@@ -3,7 +3,7 @@
3
3
  {% load i18n %}
4
4
 
5
5
  {% block head_title %}
6
- {% trans "Login" %}
6
+ {% trans "Login" %} - {{ SITE_DESCRIPTION }}
7
7
  {% endblock head_title %}
8
8
  {% load umap_tags i18n %}
9
9
 
@@ -55,10 +55,7 @@
55
55
  <ul class="login-grid block-grid">
56
56
  {% for name in backends.backends %}
57
57
  <li>
58
- <a rel="nofollow"
59
- href="{% url "social:begin" name %}"
60
- class="umap-login-popup login-{{ name }}"
61
- title="{{ name|title }}"></a>
58
+ {% include "umap/components/provider.html" with name=name %}
62
59
  </li>
63
60
  {% endfor %}
64
61
  </ul>
@@ -1,4 +1,9 @@
1
1
  {% extends "umap/content.html" %}
2
+ {% load i18n %}
3
+
4
+ {% block head_title %}
5
+ {% translate "About" %} - {{ SITE_DESCRIPTION }}
6
+ {% endblock head_title %}
2
7
 
3
8
  {% block maincontent %}
4
9
  {% include "umap/about_summary.html" %}
@@ -60,10 +60,10 @@
60
60
  {% spaceless %}
61
61
  <div class="button-bar {% if demo_map %}half{% endif %}">
62
62
  {% if not UMAP_READONLY %}
63
- <a href="{% url 'map_new' %}" class="button button-primary half">{% trans "Create a map" %}</a>
63
+ <a href="{% url 'map_new' %}" class="button button-primary">{% trans "Create a map" %}</a>
64
64
  {% endif %}
65
65
  {% if demo_map %}
66
- <a href="{{ demo_map.get_absolute_url }}" class="button half neutral">{% trans "Play with the demo" %}</a>
66
+ <a href="{{ demo_map.get_absolute_url }}" class="button neutral">{% trans "Play with the demo" %}</a>
67
67
  {% endif %}
68
68
  </div>
69
69
  {% endspaceless %}
@@ -0,0 +1,8 @@
1
+ {% load static %}
2
+ <a href="{% url "social:begin" name %}"
3
+ class="umap-login-popup"
4
+ title="{{ name|title }}">
5
+ {% with "umap/img/providers/"|add:name|add:".png" as path %}
6
+ <img src="{% static path %}" width="92px" height="92px" alt="{{ name }}" />
7
+ {% endwith %}
8
+ </a>
@@ -30,8 +30,6 @@
30
30
  <script src="{% static 'umap/vendors/fullscreen/Leaflet.fullscreen.min.js' %}"
31
31
  defer></script>
32
32
  <script src="{% static 'umap/vendors/toolbar/leaflet.toolbar.js' %}" defer></script>
33
- <script src="{% static 'umap/vendors/formbuilder/Leaflet.FormBuilder.js' %}"
34
- defer></script>
35
33
  <script src="{% static 'umap/vendors/measurable/Leaflet.Measurable.js' %}"
36
34
  defer></script>
37
35
  <script src="{% static 'umap/vendors/iconlayers/iconLayers.js' %}" defer></script>
@@ -40,7 +38,6 @@
40
38
  <script src="{% static 'umap/vendors/simple-statistics/simple-statistics.min.js' %}"
41
39
  defer></script>
42
40
  <script src="{% static 'umap/js/umap.core.js' %}" defer></script>
43
- <script src="{% static 'umap/js/umap.forms.js' %}" defer></script>
44
41
  <script src="{% static 'umap/js/umap.controls.js' %}" defer></script>
45
42
  <script type="module" src="{% static 'umap/js/components/fragment.js' %}" defer></script>
46
43
  {% endautoescape %}
@@ -3,7 +3,7 @@
3
3
  {% load umap_tags i18n %}
4
4
 
5
5
  {% block head_title %}
6
- {{ map.name }} - {{ SITE_NAME }}
6
+ {{ map.name }} - {{ SITE_NAME }} - {{ SITE_DESCRIPTION }}
7
7
  {% endblock head_title %}
8
8
  {% block body_class %}
9
9
  map_detail
@@ -2,6 +2,10 @@
2
2
 
3
3
  {% load i18n %}
4
4
 
5
+ {% block head_title %}
6
+ {% translate "Password change" %} - {{ SITE_DESCRIPTION }}
7
+ {% endblock head_title %}
8
+
5
9
  {% block content %}
6
10
  <h2 class="section">
7
11
  {% trans "Password change" %}
@@ -2,6 +2,10 @@
2
2
 
3
3
  {% load i18n %}
4
4
 
5
+ {% block head_title %}
6
+ {% translate "Password change successful" %} - {{ SITE_DESCRIPTION }}
7
+ {% endblock head_title %}
8
+
5
9
  {% block content %}
6
10
  <h2 class="section">
7
11
  {% trans "Password change successful" %}
@@ -2,6 +2,10 @@
2
2
 
3
3
  {% load i18n %}
4
4
 
5
+ {% block head_title %}
6
+ {% translate "Explore maps" %} - {{ SITE_DESCRIPTION }}
7
+ {% endblock head_title %}
8
+
5
9
  {% block messages %}
6
10
  {# We don't want maps from the results list to display errors in the main page. #}
7
11
  {% endblock messages %}
@@ -2,6 +2,10 @@
2
2
 
3
3
  {% load i18n %}
4
4
 
5
+ {% block head_title %}
6
+ {% translate "Team deletion" %} - {{ SITE_DESCRIPTION }}
7
+ {% endblock head_title %}
8
+
5
9
  {% block maincontent %}
6
10
  {% include "umap/dashboard_menu.html" with selected="teams" %}
7
11
  <div class="wrapper">
@@ -2,6 +2,10 @@
2
2
 
3
3
  {% load i18n %}
4
4
 
5
+ {% block head_title %}
6
+ {% blocktranslate %}{{ current_team }}’s maps{% endblocktranslate %} - {{ SITE_DESCRIPTION }}
7
+ {% endblock head_title %}
8
+
5
9
  {% block maincontent %}
6
10
  <div class="wrapper">
7
11
  <div class="row">
@@ -2,6 +2,10 @@
2
2
 
3
3
  {% load i18n %}
4
4
 
5
+ {% block head_title %}
6
+ {% translate "Create or edit a team" %} - {{ SITE_DESCRIPTION }}
7
+ {% endblock head_title %}
8
+
5
9
  {% block maincontent %}
6
10
  {% include "umap/dashboard_menu.html" with selected="teams" %}
7
11
  <div class="wrapper">
@@ -3,7 +3,7 @@
3
3
  {% load i18n static %}
4
4
 
5
5
  {% block head_title %}
6
- {{ SITE_NAME }} - {% trans "My Dashboard" %}
6
+ {% translate "My Dashboard" %} - {{ SITE_DESCRIPTION }}
7
7
  {% endblock head_title %}
8
8
  {% block maincontent %}
9
9
  {% trans "Search my maps" as placeholder %}
@@ -2,6 +2,10 @@
2
2
 
3
3
  {% load i18n %}
4
4
 
5
+ {% block head_title %}
6
+ {% translate "My Teams" %} - {{ SITE_DESCRIPTION }}
7
+ {% endblock head_title %}
8
+
5
9
  {% block maincontent %}
6
10
  {% include "umap/dashboard_menu.html" with selected="teams" %}
7
11
  <div class="wrapper">
umap/tests/base.py CHANGED
@@ -127,6 +127,9 @@ class DataLayerFactory(factory.django.DjangoModelFactory):
127
127
  def _adjust_kwargs(cls, **kwargs):
128
128
  if "data" in kwargs:
129
129
  data = copy.deepcopy(kwargs.pop("data"))
130
+ data.setdefault("_umap_options", {})
131
+ if "name" in data["_umap_options"] and kwargs["name"] == cls.name:
132
+ kwargs["name"] = data["_umap_options"]["name"]
130
133
  if "settings" not in kwargs:
131
134
  kwargs["settings"] = data.get("_umap_options", {})
132
135
  else:
@@ -135,7 +138,6 @@ class DataLayerFactory(factory.django.DjangoModelFactory):
135
138
  **DataLayerFactory.settings._defaults,
136
139
  **kwargs["settings"],
137
140
  }
138
- data.setdefault("_umap_options", {})
139
141
  kwargs["settings"]["name"] = kwargs["name"]
140
142
  data["_umap_options"]["name"] = kwargs["name"]
141
143
  data.setdefault("type", "FeatureCollection")
@@ -1,12 +1,13 @@
1
1
  import os
2
2
  import re
3
- import subprocess
4
- import time
5
- from pathlib import Path
6
3
 
7
4
  import pytest
5
+ from daphne.testing import DaphneProcess
6
+ from django.contrib.staticfiles.handlers import ASGIStaticFilesHandler
8
7
  from playwright.sync_api import expect
9
8
 
9
+ from umap.asgi import application
10
+
10
11
  from ..base import mock_tiles
11
12
 
12
13
 
@@ -67,23 +68,15 @@ def login(new_page, settings, live_server):
67
68
  return do_login
68
69
 
69
70
 
70
- @pytest.fixture
71
- def websocket_server():
72
- # Find the test-settings, and put them in the current environment
73
- settings_path = (Path(__file__).parent.parent / "settings.py").absolute().as_posix()
74
- os.environ["UMAP_SETTINGS"] = settings_path
75
-
76
- ds_proc = subprocess.Popen(
77
- [
78
- "umap",
79
- "run_websocket_server",
80
- ],
81
- stdout=subprocess.PIPE,
82
- stderr=subprocess.STDOUT,
83
- )
84
- time.sleep(2)
85
- # Ensure it started properly before yielding
86
- assert not ds_proc.poll(), ds_proc.stdout.read().decode("utf-8")
87
- yield ds_proc
88
- # Shut it down at the end of the pytest session
89
- ds_proc.terminate()
71
+ @pytest.fixture(scope="function")
72
+ def asgi_live_server(request, live_server):
73
+ server = DaphneProcess("localhost", lambda: ASGIStaticFilesHandler(application))
74
+ server.start()
75
+ server.ready.wait()
76
+ port = server.port.value
77
+ server.url = f"http://localhost:{port}"
78
+
79
+ yield server
80
+
81
+ server.terminate()
82
+ server.join()
@@ -8,7 +8,7 @@ from umap.models import Map
8
8
 
9
9
  def test_page_title(page, live_server):
10
10
  page.goto(live_server.url)
11
- expect(page).to_have_title("uMap")
11
+ expect(page).to_have_title("uMap - Online map creator")
12
12
 
13
13
 
14
14
  @pytest.mark.parametrize(
@@ -83,7 +83,7 @@ def test_login_from_map_page(live_server, page, tilelayer, settings, user, conte
83
83
  page.get_by_role("button", name="Save").click()
84
84
  assert Map.objects.count() == 0
85
85
  login_page = login_page_info.value
86
- expect(login_page).to_have_title("Login")
86
+ expect(login_page).to_have_title("Login - Online map creator")
87
87
  login_page.get_by_placeholder("Username").fill(user.username)
88
88
  login_page.get_by_placeholder("Password").fill("123123")
89
89
  with page.expect_response(re.compile(r".*/map/create/")):
@@ -25,6 +25,7 @@ def test_caption(live_server, page, map):
25
25
  panel.locator(".caption-item .off").get_by_text(non_loaded.name)
26
26
  ).to_be_visible()
27
27
  expect(panel.locator(".caption-item").get_by_text(hidden.name)).to_be_hidden()
28
+ expect(panel.get_by_text("Created at")).to_be_visible()
28
29
 
29
30
 
30
31
  def test_caption_should_display_owner_as_author(live_server, page, map):
@@ -484,12 +484,12 @@ def test_vertexmarker_not_shown_if_too_many(live_server, map, page, settings):
484
484
  page.get_by_role("button", name="Import data", exact=True).click()
485
485
  page.locator("path").click()
486
486
  page.get_by_role("link", name="Toggle edit mode (⇧+Click)").click()
487
- expect(page.locator("#umap-tooltip-container")).to_contain_text(
487
+ expect(page.locator(".umap-tooltip-container")).to_contain_text(
488
488
  "Please zoom in to edit the geometry"
489
489
  )
490
490
  expect(page.locator(".leaflet-vertex-icon")).to_be_hidden()
491
491
  page.get_by_label("Zoom in").click()
492
- expect(page.locator("#umap-tooltip-container")).to_contain_text(
492
+ expect(page.locator(".umap-tooltip-container")).to_contain_text(
493
493
  "Please zoom in to edit the geometry"
494
494
  )
495
495
  page.get_by_label("Zoom in").click()
@@ -497,6 +497,6 @@ def test_vertexmarker_not_shown_if_too_many(live_server, map, page, settings):
497
497
  page.get_by_label("Zoom out").click()
498
498
  page.wait_for_timeout(500)
499
499
  expect(page.locator(".leaflet-vertex-icon")).to_be_hidden()
500
- expect(page.locator("#umap-tooltip-container")).to_contain_text(
500
+ expect(page.locator(".umap-tooltip-container")).to_contain_text(
501
501
  "Please zoom in to edit the geometry"
502
502
  )
@@ -103,7 +103,7 @@ def test_can_change_icon_class(live_server, openmap, page):
103
103
  expect(page.locator(".umap-circle-icon")).to_be_hidden()
104
104
  page.locator(".panel.right").get_by_title("Edit", exact=True).click()
105
105
  page.get_by_text("Shape properties").click()
106
- page.locator(".umap-field-iconClass a.define").click()
106
+ page.locator(".umap-field-iconClass button.define").click()
107
107
  page.get_by_text("Circle", exact=True).click()
108
108
  expect(page.locator(".umap-circle-icon")).to_be_visible()
109
109
  expect(page.locator(".umap-div-icon")).to_be_hidden()
@@ -60,8 +60,8 @@ def test_zoomcontrol_impacts_ui(live_server, page, tilelayer):
60
60
  # Hide them
61
61
  page.get_by_text("User interface options").click()
62
62
  hide_zoom_controls = (
63
- page.locator("div")
64
- .filter(has_text=re.compile(r"^Display the zoom control"))
63
+ page.locator(".panel")
64
+ .filter(has_text=re.compile("Display the zoom control"))
65
65
  .locator("label")
66
66
  .nth(2)
67
67
  )
@@ -191,7 +191,7 @@ def test_sortkey_impacts_datalayerindex(map, live_server, page):
191
191
  page.locator('input[name="sortKey"]').fill("key")
192
192
 
193
193
  # Click the checkmark to apply the changes
194
- page.locator(".panel .umap-field-sortKey .blur-button").click()
194
+ page.locator(".panel .umap-field-sortKey .blur-container button").click()
195
195
 
196
196
  # Features should be sorted by key (First, Second, Third)
197
197
  first_listed_feature = page.locator(".umap-browser .datalayer ul > li").nth(0)
@@ -101,7 +101,7 @@ def test_can_remove_stroke(live_server, openmap, page, bootstrap):
101
101
  page.get_by_role("link", name="Toggle edit mode").click()
102
102
  page.get_by_text("Shape properties").click()
103
103
  page.locator(".umap-field-stroke .define").first.click()
104
- page.locator(".umap-field-stroke label").first.click()
104
+ page.locator(".umap-field-stroke .show-on-defined label").first.click()
105
105
  expect(page.locator(".leaflet-overlay-pane path[stroke='DarkBlue']")).to_have_count(
106
106
  0
107
107
  )
@@ -24,6 +24,7 @@ def test_layers_list_is_updated(live_server, tilelayer, page):
24
24
  page.get_by_role("button", name="Add a layer").click()
25
25
  page.locator('input[name="name"]').click()
26
26
  page.locator('input[name="name"]').fill("foobar")
27
+ page.wait_for_timeout(300) # Time for the input debounce.
27
28
  page.get_by_role("link", name=f"Import data ({modifier}+I)").click()
28
29
  # Should still work
29
30
  page.locator("[name=layer-id]").select_option(label="Import in a new layer")
@@ -70,7 +71,6 @@ def test_umap_import_from_file(live_server, tilelayer, page):
70
71
  expect(nonloaded).to_have_count(1)
71
72
 
72
73
 
73
- @pytest.mark.skip
74
74
  def test_umap_import_from_textarea(live_server, tilelayer, page, settings):
75
75
  settings.UMAP_ALLOW_ANONYMOUS = True
76
76
  page.goto(f"{live_server.url}/map/new/")
@@ -122,6 +122,28 @@ def test_import_geojson_from_textarea(tilelayer, live_server, page):
122
122
  expect(paths).to_have_count(3)
123
123
 
124
124
 
125
+ def test_import_invalid_data(tilelayer, live_server, page):
126
+ uncaught_errors = []
127
+ page.on("pageerror", lambda exc: uncaught_errors.append(exc))
128
+ page.goto(f"{live_server.url}/map/new/")
129
+ page.get_by_title("Open browser").click()
130
+ layers = page.locator(".umap-browser .datalayer")
131
+ markers = page.locator(".leaflet-marker-icon")
132
+ paths = page.locator("path")
133
+ expect(markers).to_have_count(0)
134
+ expect(paths).to_have_count(0)
135
+ expect(layers).to_have_count(0)
136
+ button = page.get_by_title("Import data")
137
+ expect(button).to_be_visible()
138
+ button.click()
139
+ textarea = page.locator(".umap-upload textarea")
140
+ textarea.fill("invalid data")
141
+ for format in ["geojson", "csv", "gpx", "kml", "georss", "osm", "umap"]:
142
+ page.locator('select[name="format"]').select_option(format)
143
+ page.get_by_role("button", name="Import data", exact=True).click()
144
+ assert not uncaught_errors, f"Error with format {format}"
145
+
146
+
125
147
  def test_import_kml_from_textarea(tilelayer, live_server, page):
126
148
  page.goto(f"{live_server.url}/map/new/")
127
149
  page.get_by_title("Open browser").click()
@@ -285,6 +285,7 @@ def test_should_display_alert_on_conflict(context, live_server, datalayer, openm
285
285
  # Change name on page one and save
286
286
  page_one.locator(".leaflet-marker-icon").click(modifiers=["Shift"])
287
287
  page_one.locator('input[name="name"]').fill("name from page one")
288
+ page_one.wait_for_timeout(300) # Time for the input debounce.
288
289
  with page_one.expect_response(re.compile(r".*/datalayer/update/.*")):
289
290
  page_one.get_by_role("button", name="Save").click()
290
291
 
@@ -57,7 +57,7 @@ def test_can_change_picto_at_map_level(openmap, live_server, page, pictos):
57
57
  define.click()
58
58
  # No picto defined yet, so recent should not be visible
59
59
  expect(page.get_by_text("Recent")).to_be_hidden()
60
- symbols = page.locator(".umap-pictogram-choice")
60
+ symbols = page.locator(".umap-pictogram-body .umap-pictogram-choice")
61
61
  expect(symbols).to_have_count(2)
62
62
  search = page.locator(".umap-pictogram-body input")
63
63
  search.type("star")
@@ -90,8 +90,8 @@ def test_can_change_picto_at_datalayer_level(openmap, live_server, page, pictos)
90
90
  expect(define).to_be_visible()
91
91
  expect(undefine).to_be_hidden()
92
92
  define.click()
93
- # Map has an icon defined, so it shold open on Recent tab
94
- symbols = page.locator(".umap-pictogram-choice")
93
+ # Map has an icon defined, so it should open on Recent tab
94
+ symbols = page.locator(".umap-pictogram-body .umap-pictogram-choice")
95
95
  expect(page.get_by_text("Recent")).to_be_visible()
96
96
  expect(symbols).to_have_count(1)
97
97
  symbol_tab = page.get_by_role("button", name="Symbol")
@@ -128,8 +128,8 @@ def test_can_change_picto_at_marker_level(openmap, live_server, page, pictos):
128
128
  expect(define).to_be_visible()
129
129
  expect(undefine).to_be_hidden()
130
130
  define.click()
131
- # Map has an icon defined, so it shold open on Recent tab
132
- symbols = page.locator(".umap-pictogram-choice")
131
+ # Map has an icon defined, so it shuold open on Recent tab
132
+ symbols = page.locator(".umap-pictogram-body .umap-pictogram-choice")
133
133
  expect(page.get_by_text("Recent")).to_be_visible()
134
134
  expect(symbols).to_have_count(1)
135
135
  symbol_tab = page.get_by_role("button", name="Symbol")
@@ -180,7 +180,7 @@ def test_can_use_remote_url_as_picto(openmap, live_server, page, pictos):
180
180
  expect(modify).to_be_visible()
181
181
  modify.click()
182
182
  # Should be on Recent tab
183
- symbols = page.locator(".umap-pictogram-choice")
183
+ symbols = page.locator(".umap-pictogram-body .umap-pictogram-choice")
184
184
  expect(page.get_by_text("Recent")).to_be_visible()
185
185
  expect(symbols).to_have_count(1)
186
186
 
@@ -215,10 +215,10 @@ def test_can_use_char_as_picto(openmap, live_server, page, pictos):
215
215
  close.click()
216
216
  edit_settings.click()
217
217
  shape_settings.click()
218
- preview = page.locator(".umap-pictogram-choice")
218
+ preview = page.locator(".header .umap-pictogram-choice")
219
219
  expect(preview).to_be_visible()
220
220
  preview.click()
221
221
  # Should be on URL tab
222
- symbols = page.locator(".umap-pictogram-choice")
222
+ symbols = page.locator(".umap-pictogram-body .umap-pictogram-choice")
223
223
  expect(page.get_by_text("Recent")).to_be_visible()
224
224
  expect(symbols).to_have_count(1)
@@ -24,6 +24,7 @@ def test_reseting_map_would_remove_from_save_queue(
24
24
  page.get_by_role("button", name="Edit", exact=True).click()
25
25
  page.locator('input[name="name"]').click()
26
26
  page.locator('input[name="name"]').fill("new datalayer name")
27
+ page.wait_for_timeout(300) # Time of the Input debounce
27
28
  with page.expect_response(re.compile(".*/datalayer/update/.*")):
28
29
  page.get_by_role("button", name="Save").click()
29
30
  assert len(requests) == 1
@@ -8,20 +8,24 @@ from umap.models import Star
8
8
  pytestmark = pytest.mark.django_db
9
9
 
10
10
 
11
- def test_star_control_is_visible_if_logged_in(map, live_server, page, login, user):
11
+ def test_star_button_is_active_if_logged_in(map, live_server, page, login, user):
12
12
  login(user)
13
13
  assert not Star.objects.count()
14
14
  page.goto(f"{live_server.url}{map.get_absolute_url()}")
15
- page.get_by_title("More controls").click()
16
- control = page.locator(".leaflet-control-star")
17
- expect(control).to_be_visible()
15
+ page.get_by_title("About").click()
16
+ button = page.locator(".icon-star")
17
+ expect(button).to_be_visible()
18
18
  with page.expect_response(re.compile(".*/star/")):
19
- control.click()
19
+ button.click()
20
+ expect(button).to_be_hidden()
21
+ # Button has changed
22
+ expect(page.locator(".icon-starred")).to_be_visible()
20
23
  assert Star.objects.count() == 1
21
24
 
22
25
 
23
- def test_no_star_control_if_not_logged_in(map, live_server, page):
26
+ def test_star_button_inctive_if_not_logged_in(map, live_server, page):
24
27
  page.goto(f"{live_server.url}{map.get_absolute_url()}")
25
- page.get_by_title("More controls").click()
26
- control = page.locator(".leaflet-control-star")
27
- expect(control).to_be_hidden()
28
+ page.get_by_title("About").click()
29
+ button = page.locator(".icon-star")
30
+ button.click()
31
+ expect(page.get_by_text("You must be logged in")).to_be_visible()
@@ -74,6 +74,7 @@ def test_table_editor(live_server, openmap, datalayer, page):
74
74
  page.locator("dialog").get_by_role("button", name="OK").click()
75
75
  page.locator("td").nth(2).dblclick()
76
76
  page.locator('input[name="newprop"]').fill("newvalue")
77
+ page.wait_for_timeout(300) # Time for the input debounce.
77
78
  page.keyboard.press("Enter")
78
79
  page.locator("thead button[data-property=name]").click()
79
80
  page.get_by_role("button", name="Delete this column").click()