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.
- umap/__init__.py +1 -1
- umap/admin.py +7 -3
- umap/autocomplete.py +3 -5
- umap/bin/__init__.py +2 -5
- umap/decorators.py +4 -5
- umap/forms.py +5 -5
- umap/locale/en/LC_MESSAGES/django.po +23 -23
- umap/locale/fr/LC_MESSAGES/django.mo +0 -0
- umap/locale/fr/LC_MESSAGES/django.po +28 -27
- umap/management/commands/generate_js_locale.py +9 -11
- umap/management/commands/import_pictograms.py +49 -28
- umap/managers.py +5 -3
- umap/middleware.py +2 -3
- umap/migrations/0001_initial.py +204 -56
- umap/migrations/0002_tilelayer_tms.py +3 -4
- umap/migrations/0003_add_tilelayer.py +13 -9
- umap/migrations/0004_add_licence.py +3 -6
- umap/migrations/0005_remove_map_tilelayer.py +3 -4
- umap/migrations/0006_auto_20190407_0719.py +6 -5
- umap/migrations/0007_auto_20190416_1757.py +13 -5
- umap/migrations/0008_alter_map_settings.py +0 -1
- umap/migrations/0009_star.py +27 -8
- umap/migrations/0010_alter_map_edit_status_alter_map_share_status.py +20 -8
- umap/migrations/0011_alter_map_edit_status_alter_map_share_status.py +21 -8
- umap/migrations/0014_map_created_at.py +1 -1
- umap/migrations/0015_alter_pictogram_pictogram.py +17 -0
- umap/migrations/0016_pictogram_category.py +17 -0
- umap/models.py +9 -7
- umap/settings/base.py +1 -4
- umap/static/umap/base.css +59 -20
- umap/static/umap/content.css +2 -13
- umap/static/umap/favicons/apple-touch-icon.png +0 -0
- umap/static/umap/favicons/favicon.ico +0 -0
- umap/static/umap/favicons/icon-192.png +0 -0
- umap/static/umap/favicons/icon-512.png +0 -0
- umap/static/umap/favicons/icon.svg +5 -0
- umap/static/umap/img/16-white.svg +20 -9
- umap/static/umap/img/24-white.svg +2 -2
- umap/static/umap/img/source/16-white.svg +25 -13
- umap/static/umap/img/source/24-white.svg +5 -5
- umap/static/umap/js/umap.controls.js +15 -23
- umap/static/umap/js/umap.core.js +33 -24
- umap/static/umap/js/umap.features.js +24 -2
- umap/static/umap/js/umap.forms.js +182 -84
- umap/static/umap/js/umap.icon.js +19 -14
- umap/static/umap/js/umap.js +14 -32
- umap/static/umap/js/umap.layer.js +13 -2
- umap/static/umap/js/umap.popup.js +21 -0
- umap/static/umap/locale/am_ET.js +9 -4
- umap/static/umap/locale/am_ET.json +9 -4
- umap/static/umap/locale/ar.js +9 -4
- umap/static/umap/locale/ar.json +9 -4
- umap/static/umap/locale/ast.js +9 -4
- umap/static/umap/locale/ast.json +9 -4
- umap/static/umap/locale/bg.js +9 -4
- umap/static/umap/locale/bg.json +9 -4
- umap/static/umap/locale/br.js +20 -15
- umap/static/umap/locale/br.json +20 -15
- umap/static/umap/locale/ca.js +9 -4
- umap/static/umap/locale/ca.json +9 -4
- umap/static/umap/locale/cs_CZ.js +9 -4
- umap/static/umap/locale/cs_CZ.json +9 -4
- umap/static/umap/locale/da.js +9 -4
- umap/static/umap/locale/da.json +9 -4
- umap/static/umap/locale/de.js +9 -4
- umap/static/umap/locale/de.json +9 -4
- umap/static/umap/locale/el.js +9 -4
- umap/static/umap/locale/el.json +9 -4
- umap/static/umap/locale/en.js +9 -4
- umap/static/umap/locale/en.json +9 -4
- umap/static/umap/locale/en_US.json +9 -4
- umap/static/umap/locale/es.js +15 -10
- umap/static/umap/locale/es.json +15 -10
- umap/static/umap/locale/et.js +9 -4
- umap/static/umap/locale/et.json +9 -4
- umap/static/umap/locale/fa_IR.js +9 -4
- umap/static/umap/locale/fa_IR.json +9 -4
- umap/static/umap/locale/fi.js +9 -4
- umap/static/umap/locale/fi.json +9 -4
- umap/static/umap/locale/fr.js +10 -5
- umap/static/umap/locale/fr.json +10 -5
- umap/static/umap/locale/gl.js +9 -4
- umap/static/umap/locale/gl.json +9 -4
- umap/static/umap/locale/he.js +9 -4
- umap/static/umap/locale/he.json +9 -4
- umap/static/umap/locale/hr.js +9 -4
- umap/static/umap/locale/hr.json +9 -4
- umap/static/umap/locale/hu.js +64 -59
- umap/static/umap/locale/hu.json +64 -59
- umap/static/umap/locale/id.js +9 -4
- umap/static/umap/locale/id.json +9 -4
- umap/static/umap/locale/is.js +9 -4
- umap/static/umap/locale/is.json +9 -4
- umap/static/umap/locale/it.js +9 -4
- umap/static/umap/locale/it.json +9 -4
- umap/static/umap/locale/ja.js +9 -4
- umap/static/umap/locale/ja.json +9 -4
- umap/static/umap/locale/ko.js +9 -4
- umap/static/umap/locale/ko.json +9 -4
- umap/static/umap/locale/lt.js +9 -4
- umap/static/umap/locale/lt.json +9 -4
- umap/static/umap/locale/ms.js +15 -10
- umap/static/umap/locale/ms.json +15 -10
- umap/static/umap/locale/nl.js +9 -4
- umap/static/umap/locale/nl.json +9 -4
- umap/static/umap/locale/no.js +9 -4
- umap/static/umap/locale/no.json +9 -4
- umap/static/umap/locale/pl.js +9 -4
- umap/static/umap/locale/pl.json +9 -4
- umap/static/umap/locale/pl_PL.json +9 -4
- umap/static/umap/locale/pt.js +9 -4
- umap/static/umap/locale/pt.json +9 -4
- umap/static/umap/locale/pt_BR.js +9 -4
- umap/static/umap/locale/pt_BR.json +9 -4
- umap/static/umap/locale/pt_PT.js +9 -4
- umap/static/umap/locale/pt_PT.json +9 -4
- umap/static/umap/locale/ro.js +9 -4
- umap/static/umap/locale/ro.json +9 -4
- umap/static/umap/locale/ru.js +9 -4
- umap/static/umap/locale/ru.json +9 -4
- umap/static/umap/locale/si.js +55 -20
- umap/static/umap/locale/si.json +55 -20
- umap/static/umap/locale/sk_SK.js +9 -4
- umap/static/umap/locale/sk_SK.json +9 -4
- umap/static/umap/locale/sl.js +9 -4
- umap/static/umap/locale/sl.json +9 -4
- umap/static/umap/locale/sr.js +9 -4
- umap/static/umap/locale/sr.json +9 -4
- umap/static/umap/locale/sv.js +9 -4
- umap/static/umap/locale/sv.json +9 -4
- umap/static/umap/locale/th_TH.js +9 -4
- umap/static/umap/locale/th_TH.json +9 -4
- umap/static/umap/locale/tr.js +9 -4
- umap/static/umap/locale/tr.json +9 -4
- umap/static/umap/locale/uk_UA.js +9 -4
- umap/static/umap/locale/uk_UA.json +9 -4
- umap/static/umap/locale/vi.js +9 -4
- umap/static/umap/locale/vi.json +9 -4
- umap/static/umap/locale/vi_VN.json +9 -4
- umap/static/umap/locale/zh.js +9 -4
- umap/static/umap/locale/zh.json +9 -4
- umap/static/umap/locale/zh_CN.json +9 -4
- umap/static/umap/locale/zh_TW.Big5.json +9 -4
- umap/static/umap/locale/zh_TW.js +9 -4
- umap/static/umap/locale/zh_TW.json +9 -4
- umap/static/umap/map.css +104 -21
- umap/static/umap/nav.css +0 -1
- umap/static/umap/test/Controls.js +0 -1
- umap/static/umap/test/Feature.js +29 -0
- umap/static/umap/test/Map.Export.js +2 -127
- umap/static/umap/test/Util.js +10 -0
- umap/static/umap/test/_pre.js +2 -3
- umap/static/umap/vendors/formbuilder/Leaflet.FormBuilder.js +13 -2
- umap/static/umap/vendors/leaflet/leaflet-src.js +7144 -7144
- umap/templates/auth/user_form.html +2 -2
- umap/templates/base.html +11 -0
- umap/templates/umap/map_table.html +3 -3
- umap/templatetags/umap_tags.py +32 -34
- umap/tests/base.py +4 -4
- umap/tests/conftest.py +3 -6
- umap/tests/fixtures/circle.svg +4 -0
- umap/tests/fixtures/star.svg +4 -0
- umap/tests/integration/test_export_map.py +5 -18
- umap/tests/integration/test_picto.py +217 -0
- umap/tests/integration/test_slideshow.py +70 -0
- umap/tests/settings.py +11 -5
- umap/tests/test_datalayer.py +7 -6
- umap/tests/test_map.py +6 -5
- umap/tests/test_map_views.py +82 -10
- umap/tests/test_tilelayer.py +17 -11
- umap/tests/test_views.py +36 -9
- umap/urls.py +27 -4
- umap/utils.py +1 -2
- umap/views.py +67 -35
- umap/wsgi.py +2 -2
- {umap_project-1.10.0.dist-info → umap_project-1.11.1.dist-info}/METADATA +11 -9
- {umap_project-1.10.0.dist-info → umap_project-1.11.1.dist-info}/RECORD +180 -170
- umap/static/favicon.ico +0 -0
- {umap_project-1.10.0.dist-info → umap_project-1.11.1.dist-info}/WHEEL +0 -0
- {umap_project-1.10.0.dist-info → umap_project-1.11.1.dist-info}/entry_points.txt +0 -0
- {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
|
|
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
|
|
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="{
|
|
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 %}
|
umap/templatetags/umap_tags.py
CHANGED
|
@@ -10,53 +10,50 @@ from ..views import _urls_for_js
|
|
|
10
10
|
register = template.Library()
|
|
11
11
|
|
|
12
12
|
|
|
13
|
-
@register.inclusion_tag(
|
|
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(
|
|
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(
|
|
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[
|
|
35
|
-
map_settings[
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
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(
|
|
73
|
+
return s.replace("<", "<")
|
|
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":
|
|
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
|
-
|
|
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
|
|
|
@@ -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
|
-
|
|
13
|
-
expect(
|
|
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
|
-
|
|
15
|
+
link.click()
|
|
16
16
|
download = download_info.value
|
|
17
|
-
assert download.suggested_filename == "
|
|
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.
|
|
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 =
|
|
8
|
+
EMAIL_BACKEND = "django.core.mail.backends.locmem.EmailBackend"
|
|
9
9
|
|
|
10
|
-
if "
|
|
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": "
|
|
15
|
-
"
|
|
16
|
-
"
|
|
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
|
+
]
|
umap/tests/test_datalayer.py
CHANGED
|
@@ -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
|
|
67
|
-
medium = f
|
|
68
|
-
older = f
|
|
69
|
-
other = f
|
|
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 +
|
|
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(
|
|
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(
|
|
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
|
|
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()
|