umap-project 1.10.0__py3-none-any.whl → 1.11.1__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 (181) hide show
  1. umap/__init__.py +1 -1
  2. umap/admin.py +7 -3
  3. umap/autocomplete.py +3 -5
  4. umap/bin/__init__.py +2 -5
  5. umap/decorators.py +4 -5
  6. umap/forms.py +5 -5
  7. umap/locale/en/LC_MESSAGES/django.po +23 -23
  8. umap/locale/fr/LC_MESSAGES/django.mo +0 -0
  9. umap/locale/fr/LC_MESSAGES/django.po +28 -27
  10. umap/management/commands/generate_js_locale.py +9 -11
  11. umap/management/commands/import_pictograms.py +49 -28
  12. umap/managers.py +5 -3
  13. umap/middleware.py +2 -3
  14. umap/migrations/0001_initial.py +204 -56
  15. umap/migrations/0002_tilelayer_tms.py +3 -4
  16. umap/migrations/0003_add_tilelayer.py +13 -9
  17. umap/migrations/0004_add_licence.py +3 -6
  18. umap/migrations/0005_remove_map_tilelayer.py +3 -4
  19. umap/migrations/0006_auto_20190407_0719.py +6 -5
  20. umap/migrations/0007_auto_20190416_1757.py +13 -5
  21. umap/migrations/0008_alter_map_settings.py +0 -1
  22. umap/migrations/0009_star.py +27 -8
  23. umap/migrations/0010_alter_map_edit_status_alter_map_share_status.py +20 -8
  24. umap/migrations/0011_alter_map_edit_status_alter_map_share_status.py +21 -8
  25. umap/migrations/0014_map_created_at.py +1 -1
  26. umap/migrations/0015_alter_pictogram_pictogram.py +17 -0
  27. umap/migrations/0016_pictogram_category.py +17 -0
  28. umap/models.py +9 -7
  29. umap/settings/base.py +1 -4
  30. umap/static/umap/base.css +59 -20
  31. umap/static/umap/content.css +2 -13
  32. umap/static/umap/favicons/apple-touch-icon.png +0 -0
  33. umap/static/umap/favicons/favicon.ico +0 -0
  34. umap/static/umap/favicons/icon-192.png +0 -0
  35. umap/static/umap/favicons/icon-512.png +0 -0
  36. umap/static/umap/favicons/icon.svg +5 -0
  37. umap/static/umap/img/16-white.svg +20 -9
  38. umap/static/umap/img/24-white.svg +2 -2
  39. umap/static/umap/img/source/16-white.svg +25 -13
  40. umap/static/umap/img/source/24-white.svg +5 -5
  41. umap/static/umap/js/umap.controls.js +15 -23
  42. umap/static/umap/js/umap.core.js +33 -24
  43. umap/static/umap/js/umap.features.js +24 -2
  44. umap/static/umap/js/umap.forms.js +182 -84
  45. umap/static/umap/js/umap.icon.js +19 -14
  46. umap/static/umap/js/umap.js +14 -32
  47. umap/static/umap/js/umap.layer.js +13 -2
  48. umap/static/umap/js/umap.popup.js +21 -0
  49. umap/static/umap/locale/am_ET.js +9 -4
  50. umap/static/umap/locale/am_ET.json +9 -4
  51. umap/static/umap/locale/ar.js +9 -4
  52. umap/static/umap/locale/ar.json +9 -4
  53. umap/static/umap/locale/ast.js +9 -4
  54. umap/static/umap/locale/ast.json +9 -4
  55. umap/static/umap/locale/bg.js +9 -4
  56. umap/static/umap/locale/bg.json +9 -4
  57. umap/static/umap/locale/br.js +20 -15
  58. umap/static/umap/locale/br.json +20 -15
  59. umap/static/umap/locale/ca.js +9 -4
  60. umap/static/umap/locale/ca.json +9 -4
  61. umap/static/umap/locale/cs_CZ.js +9 -4
  62. umap/static/umap/locale/cs_CZ.json +9 -4
  63. umap/static/umap/locale/da.js +9 -4
  64. umap/static/umap/locale/da.json +9 -4
  65. umap/static/umap/locale/de.js +9 -4
  66. umap/static/umap/locale/de.json +9 -4
  67. umap/static/umap/locale/el.js +9 -4
  68. umap/static/umap/locale/el.json +9 -4
  69. umap/static/umap/locale/en.js +9 -4
  70. umap/static/umap/locale/en.json +9 -4
  71. umap/static/umap/locale/en_US.json +9 -4
  72. umap/static/umap/locale/es.js +15 -10
  73. umap/static/umap/locale/es.json +15 -10
  74. umap/static/umap/locale/et.js +9 -4
  75. umap/static/umap/locale/et.json +9 -4
  76. umap/static/umap/locale/fa_IR.js +9 -4
  77. umap/static/umap/locale/fa_IR.json +9 -4
  78. umap/static/umap/locale/fi.js +9 -4
  79. umap/static/umap/locale/fi.json +9 -4
  80. umap/static/umap/locale/fr.js +10 -5
  81. umap/static/umap/locale/fr.json +10 -5
  82. umap/static/umap/locale/gl.js +9 -4
  83. umap/static/umap/locale/gl.json +9 -4
  84. umap/static/umap/locale/he.js +9 -4
  85. umap/static/umap/locale/he.json +9 -4
  86. umap/static/umap/locale/hr.js +9 -4
  87. umap/static/umap/locale/hr.json +9 -4
  88. umap/static/umap/locale/hu.js +64 -59
  89. umap/static/umap/locale/hu.json +64 -59
  90. umap/static/umap/locale/id.js +9 -4
  91. umap/static/umap/locale/id.json +9 -4
  92. umap/static/umap/locale/is.js +9 -4
  93. umap/static/umap/locale/is.json +9 -4
  94. umap/static/umap/locale/it.js +9 -4
  95. umap/static/umap/locale/it.json +9 -4
  96. umap/static/umap/locale/ja.js +9 -4
  97. umap/static/umap/locale/ja.json +9 -4
  98. umap/static/umap/locale/ko.js +9 -4
  99. umap/static/umap/locale/ko.json +9 -4
  100. umap/static/umap/locale/lt.js +9 -4
  101. umap/static/umap/locale/lt.json +9 -4
  102. umap/static/umap/locale/ms.js +15 -10
  103. umap/static/umap/locale/ms.json +15 -10
  104. umap/static/umap/locale/nl.js +9 -4
  105. umap/static/umap/locale/nl.json +9 -4
  106. umap/static/umap/locale/no.js +9 -4
  107. umap/static/umap/locale/no.json +9 -4
  108. umap/static/umap/locale/pl.js +9 -4
  109. umap/static/umap/locale/pl.json +9 -4
  110. umap/static/umap/locale/pl_PL.json +9 -4
  111. umap/static/umap/locale/pt.js +9 -4
  112. umap/static/umap/locale/pt.json +9 -4
  113. umap/static/umap/locale/pt_BR.js +9 -4
  114. umap/static/umap/locale/pt_BR.json +9 -4
  115. umap/static/umap/locale/pt_PT.js +9 -4
  116. umap/static/umap/locale/pt_PT.json +9 -4
  117. umap/static/umap/locale/ro.js +9 -4
  118. umap/static/umap/locale/ro.json +9 -4
  119. umap/static/umap/locale/ru.js +9 -4
  120. umap/static/umap/locale/ru.json +9 -4
  121. umap/static/umap/locale/si.js +55 -20
  122. umap/static/umap/locale/si.json +55 -20
  123. umap/static/umap/locale/sk_SK.js +9 -4
  124. umap/static/umap/locale/sk_SK.json +9 -4
  125. umap/static/umap/locale/sl.js +9 -4
  126. umap/static/umap/locale/sl.json +9 -4
  127. umap/static/umap/locale/sr.js +9 -4
  128. umap/static/umap/locale/sr.json +9 -4
  129. umap/static/umap/locale/sv.js +9 -4
  130. umap/static/umap/locale/sv.json +9 -4
  131. umap/static/umap/locale/th_TH.js +9 -4
  132. umap/static/umap/locale/th_TH.json +9 -4
  133. umap/static/umap/locale/tr.js +9 -4
  134. umap/static/umap/locale/tr.json +9 -4
  135. umap/static/umap/locale/uk_UA.js +9 -4
  136. umap/static/umap/locale/uk_UA.json +9 -4
  137. umap/static/umap/locale/vi.js +9 -4
  138. umap/static/umap/locale/vi.json +9 -4
  139. umap/static/umap/locale/vi_VN.json +9 -4
  140. umap/static/umap/locale/zh.js +9 -4
  141. umap/static/umap/locale/zh.json +9 -4
  142. umap/static/umap/locale/zh_CN.json +9 -4
  143. umap/static/umap/locale/zh_TW.Big5.json +9 -4
  144. umap/static/umap/locale/zh_TW.js +9 -4
  145. umap/static/umap/locale/zh_TW.json +9 -4
  146. umap/static/umap/map.css +104 -21
  147. umap/static/umap/nav.css +0 -1
  148. umap/static/umap/test/Controls.js +0 -1
  149. umap/static/umap/test/Feature.js +29 -0
  150. umap/static/umap/test/Map.Export.js +2 -127
  151. umap/static/umap/test/Util.js +10 -0
  152. umap/static/umap/test/_pre.js +2 -3
  153. umap/static/umap/vendors/formbuilder/Leaflet.FormBuilder.js +13 -2
  154. umap/static/umap/vendors/leaflet/leaflet-src.js +7144 -7144
  155. umap/templates/auth/user_form.html +2 -2
  156. umap/templates/base.html +11 -0
  157. umap/templates/umap/map_table.html +3 -3
  158. umap/templatetags/umap_tags.py +32 -34
  159. umap/tests/base.py +4 -4
  160. umap/tests/conftest.py +3 -6
  161. umap/tests/fixtures/circle.svg +4 -0
  162. umap/tests/fixtures/star.svg +4 -0
  163. umap/tests/integration/test_export_map.py +5 -18
  164. umap/tests/integration/test_picto.py +217 -0
  165. umap/tests/integration/test_slideshow.py +70 -0
  166. umap/tests/settings.py +11 -5
  167. umap/tests/test_datalayer.py +7 -6
  168. umap/tests/test_map.py +6 -5
  169. umap/tests/test_map_views.py +82 -10
  170. umap/tests/test_tilelayer.py +17 -11
  171. umap/tests/test_views.py +36 -9
  172. umap/urls.py +27 -4
  173. umap/utils.py +1 -2
  174. umap/views.py +67 -35
  175. umap/wsgi.py +2 -2
  176. {umap_project-1.10.0.dist-info → umap_project-1.11.1.dist-info}/METADATA +11 -9
  177. {umap_project-1.10.0.dist-info → umap_project-1.11.1.dist-info}/RECORD +180 -170
  178. umap/static/favicon.ico +0 -0
  179. {umap_project-1.10.0.dist-info → umap_project-1.11.1.dist-info}/WHEEL +0 -0
  180. {umap_project-1.10.0.dist-info → umap_project-1.11.1.dist-info}/entry_points.txt +0 -0
  181. {umap_project-1.10.0.dist-info → umap_project-1.11.1.dist-info}/licenses/LICENSE +0 -0
@@ -3,7 +3,7 @@
3
3
  {% block maincontent %}
4
4
  <div class="col wide">
5
5
  <h2 class="section tabs">
6
- <a href="{% url 'user_dashboard' %}">{% trans "My Dashboard" %}</a> | {% trans "My Profile" %}
6
+ <a href="{% url "user_dashboard" %}">{% trans "My Dashboard" %}</a> | {% trans "My Profile" %}
7
7
  </h2>
8
8
  </div>
9
9
  <div class="wrapper">
@@ -16,7 +16,7 @@
16
16
  <form id="user_form" method="post">
17
17
  {% csrf_token %}
18
18
  {{ form }}
19
- <input type="submit" value="{% trans 'Save' %}" />
19
+ <input type="submit" value="{% trans "Save" %}" />
20
20
  </form>
21
21
  </div>
22
22
  {% if backends.backends|length %}
umap/templates/base.html CHANGED
@@ -15,6 +15,17 @@
15
15
  {% endblock extra_head %}
16
16
  <meta name="viewport"
17
17
  content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />
18
+ {# See https://evilmartians.com/chronicles/how-to-favicon-in-2021-six-files-that-fit-most-needs #}
19
+ <link rel="icon"
20
+ href="{{ STATIC_URL }}umap/favicons/favicon.ico"
21
+ sizes="32x32">
22
+ <link rel="icon"
23
+ href="{{ STATIC_URL }}umap/favicons/icon.svg"
24
+ type="image/svg+xml">
25
+ <link rel="apple-touch-icon"
26
+ href="{{ STATIC_URL }}umap/favicons/apple-touch-icon.png">
27
+ <!-- 180×180 -->
28
+ <link rel="manifest" href="/manifest.webmanifest">
18
29
  </head>
19
30
  <body class="{% block body_class %}{% endblock body_class %}">
20
31
  {% block header %}
@@ -25,9 +25,9 @@
25
25
  <a href="{{ map_inst.owner.get_url }}">{{ map_inst.owner }}</a>
26
26
  </td>
27
27
  <td>
28
- <a href="{{ map_inst.get_absolute_url }}?share">{% translate "Share" %}</a>
29
- <a href="{{ map_inst.get_absolute_url }}?edit">{% translate "Edit" %}</a>
30
- <a href="{{ map_inst.get_absolute_url }}?download">{% translate "Download" %}</a>
28
+ <a href="{{ map_inst.get_absolute_url }}?share">{% translate "Share" %}</a> |
29
+ <a href="{{ map_inst.get_absolute_url }}?edit">{% translate "Edit" %}</a> |
30
+ <a href="{% url 'map_download' map_inst.pk %}">{% translate "Download" %}</a>
31
31
  </td>
32
32
  </tr>
33
33
  {% endfor %}
@@ -10,53 +10,50 @@ from ..views import _urls_for_js
10
10
  register = template.Library()
11
11
 
12
12
 
13
- @register.inclusion_tag('umap/css.html')
13
+ @register.inclusion_tag("umap/css.html")
14
14
  def umap_css():
15
- return {
16
- "STATIC_URL": settings.STATIC_URL
17
- }
15
+ return {"STATIC_URL": settings.STATIC_URL}
18
16
 
19
17
 
20
- @register.inclusion_tag('umap/js.html')
18
+ @register.inclusion_tag("umap/js.html")
21
19
  def umap_js(locale=None):
22
- return {
23
- "STATIC_URL": settings.STATIC_URL,
24
- "locale": locale
25
- }
20
+ return {"STATIC_URL": settings.STATIC_URL, "locale": locale}
26
21
 
27
22
 
28
- @register.inclusion_tag('umap/map_fragment.html')
23
+ @register.inclusion_tag("umap/map_fragment.html")
29
24
  def map_fragment(map_instance, **kwargs):
30
25
  layers = DataLayer.objects.filter(map=map_instance)
31
26
  datalayer_data = [c.metadata() for c in layers]
32
27
  map_settings = map_instance.settings
33
28
  if "properties" not in map_settings:
34
- map_settings['properties'] = {}
35
- map_settings['properties'].update({
36
- 'tilelayers': [TileLayer.get_default().json],
37
- 'datalayers': datalayer_data,
38
- 'urls': _urls_for_js(),
39
- 'STATIC_URL': settings.STATIC_URL,
40
- "editMode": 'disabled',
41
- 'hash': False,
42
- 'attributionControl': False,
43
- 'scrollWheelZoom': False,
44
- 'umapAttributionControl': False,
45
- 'noControl': True,
46
- 'umap_id': map_instance.pk,
47
- 'onLoadPanel': "none",
48
- 'captionBar': False,
49
- 'default_iconUrl': "%sumap/img/marker.png" % settings.STATIC_URL,
50
- 'slideshow': {}
51
- })
52
- map_settings['properties'].update(kwargs)
53
- prefix = kwargs.pop('prefix', None) or 'map'
54
- page = kwargs.pop('page', None) or ''
29
+ map_settings["properties"] = {}
30
+ map_settings["properties"].update(
31
+ {
32
+ "tilelayers": [TileLayer.get_default().json],
33
+ "datalayers": datalayer_data,
34
+ "urls": _urls_for_js(),
35
+ "STATIC_URL": settings.STATIC_URL,
36
+ "editMode": "disabled",
37
+ "hash": False,
38
+ "attributionControl": False,
39
+ "scrollWheelZoom": False,
40
+ "umapAttributionControl": False,
41
+ "noControl": True,
42
+ "umap_id": map_instance.pk,
43
+ "onLoadPanel": "none",
44
+ "captionBar": False,
45
+ "default_iconUrl": "%sumap/img/marker.png" % settings.STATIC_URL,
46
+ "slideshow": {},
47
+ }
48
+ )
49
+ map_settings["properties"].update(kwargs)
50
+ prefix = kwargs.pop("prefix", None) or "map"
51
+ page = kwargs.pop("page", None) or ""
55
52
  unique_id = prefix + str(page) + "_" + str(map_instance.pk)
56
53
  return {
57
54
  "map_settings": json.dumps(map_settings),
58
55
  "map": map_instance,
59
- "unique_id": unique_id
56
+ "unique_id": unique_id,
60
57
  }
61
58
 
62
59
 
@@ -73,7 +70,7 @@ def tilelayer_preview(tilelayer):
73
70
 
74
71
  @register.filter
75
72
  def notag(s):
76
- return s.replace('<', '&lt;')
73
+ return s.replace("<", "&lt;")
77
74
 
78
75
 
79
76
  @register.simple_tag(takes_context=True)
@@ -86,5 +83,6 @@ def paginate_querystring(context, page):
86
83
  @register.filter
87
84
  def ipdb(what):
88
85
  import ipdb
86
+
89
87
  ipdb.set_trace()
90
- return ''
88
+ return ""
umap/tests/base.py CHANGED
@@ -1,5 +1,5 @@
1
- import json
2
1
  import copy
2
+ import json
3
3
 
4
4
  import factory
5
5
  from django.contrib.auth import get_user_model
@@ -71,13 +71,11 @@ class MapFactory(factory.django.DjangoModelFactory):
71
71
  "properties": {
72
72
  "datalayersControl": True,
73
73
  "description": "Which is just the Danube, at the end",
74
- "displayCaptionOnLoad": False,
75
- "displayDataBrowserOnLoad": False,
76
74
  "displayPopupFooter": False,
77
75
  "licence": "",
78
76
  "miniMap": False,
79
77
  "moreControl": True,
80
- "name": "Cruising on the Donau",
78
+ "name": name,
81
79
  "scaleControl": True,
82
80
  "tilelayer": {
83
81
  "attribution": "\xa9 OSM Contributors",
@@ -100,6 +98,7 @@ class MapFactory(factory.django.DjangoModelFactory):
100
98
  def _adjust_kwargs(cls, **kwargs):
101
99
  # Make sure there is no persistency
102
100
  kwargs["settings"] = copy.deepcopy(kwargs["settings"])
101
+ kwargs["settings"]["properties"]["name"] = kwargs["name"]
103
102
  return kwargs
104
103
 
105
104
  class Meta:
@@ -125,6 +124,7 @@ class DataLayerFactory(factory.django.DjangoModelFactory):
125
124
  **DataLayerFactory.settings._defaults,
126
125
  **kwargs["settings"],
127
126
  }
127
+ data.setdefault("_umap_options", {})
128
128
  data["_umap_options"]["name"] = kwargs["name"]
129
129
  kwargs["geojson"] = ContentFile(json.dumps(data), "foo.json")
130
130
  return kwargs
umap/tests/conftest.py CHANGED
@@ -9,10 +9,10 @@ from umap.models import Map
9
9
 
10
10
  from .base import (
11
11
  DataLayerFactory,
12
+ LicenceFactory,
12
13
  MapFactory,
13
- UserFactory,
14
14
  TileLayerFactory,
15
- LicenceFactory,
15
+ UserFactory,
16
16
  )
17
17
 
18
18
  TMP_ROOT = tempfile.mkdtemp()
@@ -24,11 +24,8 @@ def pytest_configure(config):
24
24
  settings.MEDIA_ROOT = TMP_ROOT
25
25
 
26
26
 
27
- def pytest_unconfigure(config):
28
- shutil.rmtree(TMP_ROOT, ignore_errors=True)
29
-
30
-
31
27
  def pytest_runtest_teardown():
28
+ shutil.rmtree(TMP_ROOT, ignore_errors=True)
32
29
  cache.clear()
33
30
 
34
31
 
@@ -0,0 +1,4 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <svg version="1.1" id="circle" xmlns="http://www.w3.org/2000/svg" width="15" height="15" viewBox="0 0 15 15">
3
+ <path d="M14,7.5c0,3.5899-2.9101,6.5-6.5,6.5S1,11.0899,1,7.5S3.9101,1,7.5,1S14,3.9101,14,7.5z"/>
4
+ </svg>
@@ -0,0 +1,4 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <svg version="1.1" id="star" xmlns="http://www.w3.org/2000/svg" width="15" height="15" viewBox="0 0 15 15">
3
+ <path id="path4749-2-8-2" d="M7.5,0l-2,5h-5l4,3.5l-2,6l5-3.5&#xA;&#x9;l5,3.5l-2-6l4-3.5h-5L7.5,0z"/>
4
+ </svg>
@@ -9,12 +9,12 @@ pytestmark = pytest.mark.django_db
9
9
 
10
10
  def test_umap_export(map, live_server, datalayer, page):
11
11
  page.goto(f"{live_server.url}{map.get_absolute_url()}?share")
12
- button = page.get_by_role("button", name="Download data")
13
- expect(button).to_be_visible()
12
+ link = page.get_by_role("link", name="Download full data")
13
+ expect(link).to_be_visible()
14
14
  with page.expect_download() as download_info:
15
- button.click()
15
+ link.click()
16
16
  download = download_info.value
17
- assert download.suggested_filename == "test_map.umap"
17
+ assert download.suggested_filename == "umap_backup_test-map.umap"
18
18
  path = Path("/tmp/") / download.suggested_filename
19
19
  download.save_as(path)
20
20
  downloaded = json.loads(path.read_text())
@@ -29,14 +29,12 @@ def test_umap_export(map, live_server, datalayer, page):
29
29
  "_umap_options": {
30
30
  "browsable": True,
31
31
  "displayOnLoad": True,
32
- "editMode": "disabled",
33
- "inCaption": True,
34
32
  "name": "test datalayer",
35
33
  },
36
34
  "features": [
37
35
  {
38
36
  "geometry": {
39
- "coordinates": [13.688965, 48.552978],
37
+ "coordinates": [13.68896484375, 48.55297816440071],
40
38
  "type": "Point",
41
39
  },
42
40
  "properties": {
@@ -51,25 +49,14 @@ def test_umap_export(map, live_server, datalayer, page):
51
49
  }
52
50
  ],
53
51
  "properties": {
54
- "captionBar": False,
55
- "captionMenus": True,
56
52
  "datalayersControl": True,
57
53
  "description": "Which is just the Danube, at the end",
58
54
  "displayPopupFooter": False,
59
- "easing": False,
60
- "embedControl": True,
61
- "fullscreenControl": True,
62
55
  "licence": "",
63
- "limitBounds": {},
64
56
  "miniMap": False,
65
57
  "moreControl": True,
66
58
  "name": "test map",
67
- "overlay": None,
68
- "permanentCreditBackground": True,
69
59
  "scaleControl": True,
70
- "scrollWheelZoom": True,
71
- "searchControl": True,
72
- "slideshow": {},
73
60
  "tilelayer": {
74
61
  "attribution": "© OSM Contributors",
75
62
  "maxZoom": 18,
@@ -0,0 +1,217 @@
1
+ from pathlib import Path
2
+
3
+ import pytest
4
+ from django.core.files.base import ContentFile
5
+ from playwright.sync_api import expect
6
+
7
+ from umap.models import Map, Pictogram
8
+
9
+ from ..base import DataLayerFactory
10
+
11
+ pytestmark = pytest.mark.django_db
12
+
13
+
14
+ DATALAYER_DATA = {
15
+ "type": "FeatureCollection",
16
+ "features": [
17
+ {
18
+ "type": "Feature",
19
+ "geometry": {
20
+ "type": "Point",
21
+ "coordinates": [13.68896484375, 48.55297816440071],
22
+ },
23
+ "properties": {"_umap_options": {"color": "DarkCyan"}, "name": "Here"},
24
+ }
25
+ ],
26
+ "_umap_options": {"displayOnLoad": True, "name": "FooBarFoo"},
27
+ }
28
+ FIXTURES = Path(__file__).parent.parent / "fixtures"
29
+
30
+
31
+ @pytest.fixture
32
+ def pictos():
33
+ path = FIXTURES / "star.svg"
34
+ Pictogram(name="star", pictogram=ContentFile(path.read_text(), path.name)).save()
35
+ path = FIXTURES / "circle.svg"
36
+ Pictogram(name="circle", pictogram=ContentFile(path.read_text(), path.name)).save()
37
+
38
+
39
+ def test_can_change_picto_at_map_level(map, live_server, page, pictos):
40
+ # Faster than doing a login
41
+ map.edit_status = Map.ANONYMOUS
42
+ map.save()
43
+ DataLayerFactory(map=map, data=DATALAYER_DATA)
44
+ page.goto(f"{live_server.url}{map.get_absolute_url()}?edit")
45
+ marker = page.locator(".umap-div-icon img")
46
+ expect(marker).to_have_count(1)
47
+ # Should have default img
48
+ expect(marker).to_have_attribute("src", "/static/umap/img/marker.png")
49
+ edit_settings = page.get_by_title("Edit map settings")
50
+ expect(edit_settings).to_be_visible()
51
+ edit_settings.click()
52
+ shape_settings = page.get_by_text("Default shape properties")
53
+ expect(shape_settings).to_be_visible()
54
+ shape_settings.click()
55
+ define = page.locator(".umap-field-iconUrl .define")
56
+ undefine = page.locator(".umap-field-iconUrl .undefine")
57
+ expect(define).to_be_visible()
58
+ expect(undefine).to_be_hidden()
59
+ define.click()
60
+ symbols = page.locator(".umap-pictogram-choice")
61
+ expect(symbols).to_have_count(2)
62
+ search = page.locator(".umap-pictogram-body input")
63
+ search.type("star")
64
+ expect(symbols).to_have_count(1)
65
+ symbols.click()
66
+ expect(marker).to_have_attribute("src", "/uploads/pictogram/star.svg")
67
+ undefine.click()
68
+ expect(marker).to_have_attribute("src", "/static/umap/img/marker.png")
69
+
70
+
71
+ def test_can_change_picto_at_datalayer_level(map, live_server, page, pictos):
72
+ # Faster than doing a login
73
+ map.edit_status = Map.ANONYMOUS
74
+ map.settings["properties"]["iconUrl"] = "/uploads/pictogram/star.svg"
75
+ map.save()
76
+ DataLayerFactory(map=map, data=DATALAYER_DATA)
77
+ page.goto(f"{live_server.url}{map.get_absolute_url()}?edit")
78
+ marker = page.locator(".umap-div-icon img")
79
+ expect(marker).to_have_count(1)
80
+ # Should have default img
81
+ expect(marker).to_have_attribute("src", "/uploads/pictogram/star.svg")
82
+ # Edit datalayer
83
+ marker.click(modifiers=["Control", "Shift"])
84
+ settings = page.get_by_text("Layer properties")
85
+ expect(settings).to_be_visible()
86
+ shape_settings = page.get_by_text("Shape properties")
87
+ expect(shape_settings).to_be_visible()
88
+ shape_settings.click()
89
+ define = page.locator(".umap-field-iconUrl .define")
90
+ undefine = page.locator(".umap-field-iconUrl .undefine")
91
+ expect(define).to_be_visible()
92
+ expect(undefine).to_be_hidden()
93
+ define.click()
94
+ symbols = page.locator(".umap-pictogram-choice")
95
+ expect(symbols).to_have_count(2)
96
+ search = page.locator(".umap-pictogram-body input")
97
+ search.type("circle")
98
+ expect(symbols).to_have_count(1)
99
+ symbols.click()
100
+ expect(marker).to_have_attribute("src", "/uploads/pictogram/circle.svg")
101
+ undefine.click()
102
+ expect(marker).to_have_attribute("src", "/uploads/pictogram/star.svg")
103
+
104
+
105
+ def test_can_change_picto_at_marker_level(map, live_server, page, pictos):
106
+ # Faster than doing a login
107
+ map.edit_status = Map.ANONYMOUS
108
+ map.settings["properties"]["iconUrl"] = "/uploads/pictogram/star.svg"
109
+ map.save()
110
+ DataLayerFactory(map=map, data=DATALAYER_DATA)
111
+ page.goto(f"{live_server.url}{map.get_absolute_url()}?edit")
112
+ marker = page.locator(".umap-div-icon img")
113
+ expect(marker).to_have_count(1)
114
+ # Should have default img
115
+ expect(marker).to_have_attribute("src", "/uploads/pictogram/star.svg")
116
+ # Edit marker
117
+ marker.click(modifiers=["Shift"])
118
+ settings = page.get_by_text("Feature properties")
119
+ expect(settings).to_be_visible()
120
+ shape_settings = page.get_by_text("Shape properties")
121
+ expect(shape_settings).to_be_visible()
122
+ shape_settings.click()
123
+ define = page.locator(".umap-field-iconUrl .define")
124
+ undefine = page.locator(".umap-field-iconUrl .undefine")
125
+ expect(define).to_be_visible()
126
+ expect(undefine).to_be_hidden()
127
+ define.click()
128
+ symbols = page.locator(".umap-pictogram-choice")
129
+ expect(symbols).to_have_count(2)
130
+ search = page.locator(".umap-pictogram-body input")
131
+ search.type("circle")
132
+ expect(symbols).to_have_count(1)
133
+ symbols.click()
134
+ expect(marker).to_have_attribute("src", "/uploads/pictogram/circle.svg")
135
+ undefine.click()
136
+ expect(marker).to_have_attribute("src", "/uploads/pictogram/star.svg")
137
+
138
+
139
+ def test_can_use_remote_url_as_picto(map, live_server, page, pictos):
140
+ # Faster than doing a login
141
+ map.edit_status = Map.ANONYMOUS
142
+ map.save()
143
+ DataLayerFactory(map=map, data=DATALAYER_DATA)
144
+ page.goto(f"{live_server.url}{map.get_absolute_url()}?edit")
145
+ marker = page.locator(".umap-div-icon img")
146
+ expect(marker).to_have_count(1)
147
+ # Should have default img
148
+ expect(marker).to_have_attribute("src", "/static/umap/img/marker.png")
149
+ edit_settings = page.get_by_title("Edit map settings")
150
+ expect(edit_settings).to_be_visible()
151
+ edit_settings.click()
152
+ shape_settings = page.get_by_text("Default shape properties")
153
+ expect(shape_settings).to_be_visible()
154
+ shape_settings.click()
155
+ define = page.locator(".umap-field-iconUrl .define")
156
+ expect(define).to_be_visible()
157
+ define.click()
158
+ url_tab = page.get_by_role("button", name="URL")
159
+ input_el = page.get_by_placeholder("Add image URL")
160
+ expect(input_el).to_be_hidden()
161
+ expect(url_tab).to_be_visible()
162
+ url_tab.click()
163
+ expect(input_el).to_be_visible()
164
+ input_el.fill("https://foo.bar/img.jpg")
165
+ input_el.blur()
166
+ expect(marker).to_have_attribute("src", "https://foo.bar/img.jpg")
167
+ # Now close and reopen the form, it should still be the URL tab
168
+ close = page.locator("#umap-ui-container").get_by_title("Close")
169
+ expect(close).to_be_visible()
170
+ close.click()
171
+ edit_settings.click()
172
+ shape_settings.click()
173
+ modify = page.locator(".umap-field-iconUrl").get_by_text("Change")
174
+ expect(modify).to_be_visible()
175
+ modify.click()
176
+ # Should be on URL tab
177
+ expect(input_el).to_be_visible()
178
+
179
+
180
+ def test_can_use_char_as_picto(map, live_server, page, pictos):
181
+ # Faster than doing a login
182
+ map.edit_status = Map.ANONYMOUS
183
+ map.save()
184
+ DataLayerFactory(map=map, data=DATALAYER_DATA)
185
+ page.goto(f"{live_server.url}{map.get_absolute_url()}?edit")
186
+ marker = page.locator(".umap-div-icon span")
187
+ # Should have default img, so not a span
188
+ expect(marker).to_have_count(0)
189
+ edit_settings = page.get_by_title("Edit map settings")
190
+ expect(edit_settings).to_be_visible()
191
+ edit_settings.click()
192
+ shape_settings = page.get_by_text("Default shape properties")
193
+ expect(shape_settings).to_be_visible()
194
+ shape_settings.click()
195
+ define = page.locator(".umap-field-iconUrl .define")
196
+ define.click()
197
+ url_tab = page.get_by_role("button", name="Emoji & Character")
198
+ input_el = page.get_by_placeholder("Type char or paste emoji")
199
+ expect(input_el).to_be_hidden()
200
+ expect(url_tab).to_be_visible()
201
+ url_tab.click()
202
+ expect(input_el).to_be_visible()
203
+ input_el.fill("♩")
204
+ input_el.blur()
205
+ expect(marker).to_have_count(1)
206
+ expect(marker).to_have_text("♩")
207
+ # Now close and reopen the form, it should still be the URL tab
208
+ close = page.locator("#umap-ui-container").get_by_title("Close")
209
+ expect(close).to_be_visible()
210
+ close.click()
211
+ edit_settings.click()
212
+ shape_settings.click()
213
+ preview = page.locator(".umap-pictogram-choice")
214
+ expect(preview).to_be_visible()
215
+ preview.click()
216
+ # Should be on URL tab
217
+ expect(input_el).to_be_visible()
@@ -0,0 +1,70 @@
1
+ from pathlib import Path
2
+
3
+ import pytest
4
+ from django.core.files.base import ContentFile
5
+ from playwright.sync_api import expect
6
+
7
+ from umap.models import Map, Pictogram
8
+
9
+ from ..base import DataLayerFactory
10
+
11
+ pytestmark = pytest.mark.django_db
12
+
13
+
14
+ DATALAYER_DATA = {
15
+ "type": "FeatureCollection",
16
+ "features": [
17
+ {
18
+ "type": "Feature",
19
+ "geometry": {
20
+ "type": "Point",
21
+ "coordinates": [13.6, 48.5],
22
+ },
23
+ "properties": {"name": "1st Point"},
24
+ },
25
+ {
26
+ "type": "Feature",
27
+ "geometry": {
28
+ "type": "Point",
29
+ "coordinates": [13.7, 48.4],
30
+ },
31
+ "properties": {"name": "2d Point"},
32
+ },
33
+ {
34
+ "type": "Feature",
35
+ "geometry": {
36
+ "type": "Point",
37
+ "coordinates": [13.5, 48.6],
38
+ },
39
+ "properties": {"name": "3d Point"},
40
+ },
41
+ ],
42
+ }
43
+
44
+
45
+ def test_can_use_slideshow_manually(map, live_server, page):
46
+ map.settings["properties"]["slideshow"] = {"active": True, "delay": 5000}
47
+ map.save()
48
+ DataLayerFactory(map=map, data=DATALAYER_DATA)
49
+ page.goto(f"{live_server.url}{map.get_absolute_url()}")
50
+ first_point = page.get_by_text("1st Point")
51
+ second_point = page.get_by_text("2d Point")
52
+ third_point = page.get_by_text("3d Point")
53
+ expect(first_point).to_be_hidden()
54
+ expect(second_point).to_be_hidden()
55
+ expect(third_point).to_be_hidden()
56
+ next_ = page.get_by_title("Zoom to the next")
57
+ expect(next_).to_be_visible()
58
+ next_.click()
59
+ expect(first_point).to_be_visible()
60
+ next_.click()
61
+ expect(first_point).to_be_hidden()
62
+ expect(second_point).to_be_visible()
63
+ next_.click()
64
+ expect(first_point).to_be_hidden()
65
+ expect(second_point).to_be_hidden()
66
+ expect(third_point).to_be_visible()
67
+ next_.click()
68
+ expect(first_point).to_be_visible()
69
+ expect(second_point).to_be_hidden()
70
+ expect(third_point).to_be_hidden()
umap/tests/settings.py CHANGED
@@ -5,14 +5,20 @@ from umap.settings.base import * # pylint: disable=W0614,W0401
5
5
  SECRET_KEY = "justfortests"
6
6
  COMPRESS_ENABLED = False
7
7
  FROM_EMAIL = "test@test.org"
8
- EMAIL_BACKEND = 'django.core.mail.backends.locmem.EmailBackend'
8
+ EMAIL_BACKEND = "django.core.mail.backends.locmem.EmailBackend"
9
9
 
10
- if "TRAVIS" in os.environ:
10
+ if os.environ.get("GITHUB_ACTIONS", False) == "true":
11
11
  DATABASES = {
12
12
  "default": {
13
13
  "ENGINE": "django.contrib.gis.db.backends.postgis",
14
- "NAME": "umap",
15
- "PORT": 5433,
16
- "USER": "travis",
14
+ "NAME": "postgres",
15
+ "USER": "postgres",
16
+ "HOST": "localhost",
17
+ "PORT": 5432,
18
+ "PASSWORD": "postgres",
17
19
  }
18
20
  }
21
+
22
+ PASSWORD_HASHERS = [
23
+ "django.contrib.auth.hashers.MD5PasswordHasher",
24
+ ]
@@ -3,9 +3,10 @@ import os
3
3
  import pytest
4
4
  from django.core.files.base import ContentFile
5
5
 
6
- from .base import DataLayerFactory, MapFactory
7
6
  from umap.models import DataLayer, Map
8
7
 
8
+ from .base import DataLayerFactory, MapFactory
9
+
9
10
  pytestmark = pytest.mark.django_db
10
11
 
11
12
 
@@ -63,13 +64,13 @@ def test_should_remove_old_versions_on_save(datalayer, map, settings):
63
64
  settings.UMAP_KEEP_VERSIONS = 3
64
65
  root = datalayer.storage_root()
65
66
  before = len(datalayer.geojson.storage.listdir(root)[1])
66
- newer = f'{root}/{datalayer.pk}_1440924889.geojson'
67
- medium = f'{root}/{datalayer.pk}_1440923687.geojson'
68
- older = f'{root}/{datalayer.pk}_1440918637.geojson'
69
- other = f'{root}/123456_1440918637.geojson'
67
+ newer = f"{root}/{datalayer.pk}_1440924889.geojson"
68
+ medium = f"{root}/{datalayer.pk}_1440923687.geojson"
69
+ older = f"{root}/{datalayer.pk}_1440918637.geojson"
70
+ other = f"{root}/123456_1440918637.geojson"
70
71
  for path in [medium, newer, older, other]:
71
72
  datalayer.geojson.storage.save(path, ContentFile("{}"))
72
- datalayer.geojson.storage.save(path + '.gz', ContentFile("{}"))
73
+ datalayer.geojson.storage.save(path + ".gz", ContentFile("{}"))
73
74
  assert len(datalayer.geojson.storage.listdir(root)[1]) == 8 + before
74
75
  datalayer.save()
75
76
  files = datalayer.geojson.storage.listdir(root)[1]
umap/tests/test_map.py CHANGED
@@ -50,11 +50,13 @@ def test_editors_can_edit_if_status_editors(map, user):
50
50
  assert map.can_edit(user)
51
51
 
52
52
 
53
- def test_logged_in_user_should_be_allowed_for_anonymous_map_with_anonymous_edit_status(map, user, rf): # noqa
53
+ def test_logged_in_user_should_be_allowed_for_anonymous_map_with_anonymous_edit_status(
54
+ map, user, rf
55
+ ): # noqa
54
56
  map.owner = None
55
57
  map.edit_status = map.ANONYMOUS
56
58
  map.save()
57
- url = reverse('map_update', kwargs={'map_id': map.pk})
59
+ url = reverse("map_update", kwargs={"map_id": map.pk})
58
60
  request = rf.get(url)
59
61
  request.user = user
60
62
  assert map.can_edit(user, request)
@@ -70,7 +72,7 @@ def test_anonymous_user_should_not_be_allowed_for_anonymous_map(map, user, rf):
70
72
  def test_clone_should_return_new_instance(map, user):
71
73
  clone = map.clone()
72
74
  assert map.pk != clone.pk
73
- assert u"Clone of " + map.name == clone.name
75
+ assert "Clone of " + map.name == clone.name
74
76
  assert map.settings == clone.settings
75
77
  assert map.center == clone.center
76
78
  assert map.zoom == clone.zoom
@@ -108,8 +110,7 @@ def test_clone_should_clone_datalayers_and_features_too(map, user, datalayer):
108
110
  def test_publicmanager_should_get_only_public_maps(map, user, licence):
109
111
  map.share_status = map.PUBLIC
110
112
  open_map = MapFactory(owner=user, licence=licence, share_status=Map.OPEN)
111
- private_map = MapFactory(owner=user, licence=licence,
112
- share_status=Map.PRIVATE)
113
+ private_map = MapFactory(owner=user, licence=licence, share_status=Map.PRIVATE)
113
114
  assert map in Map.public.all()
114
115
  assert open_map not in Map.public.all()
115
116
  assert private_map not in Map.public.all()