umap-project 2.7.2__py3-none-any.whl → 2.8.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- umap/__init__.py +1 -1
- umap/forms.py +4 -14
- umap/locale/am_ET/LC_MESSAGES/django.mo +0 -0
- umap/locale/am_ET/LC_MESSAGES/django.po +278 -151
- umap/locale/ar/LC_MESSAGES/django.mo +0 -0
- umap/locale/ar/LC_MESSAGES/django.po +335 -141
- umap/locale/bg/LC_MESSAGES/django.mo +0 -0
- umap/locale/bg/LC_MESSAGES/django.po +279 -152
- umap/locale/br/LC_MESSAGES/django.mo +0 -0
- umap/locale/br/LC_MESSAGES/django.po +95 -79
- umap/locale/ca/LC_MESSAGES/django.mo +0 -0
- umap/locale/ca/LC_MESSAGES/django.po +85 -68
- umap/locale/cs_CZ/LC_MESSAGES/django.mo +0 -0
- umap/locale/cs_CZ/LC_MESSAGES/django.po +78 -66
- umap/locale/da/LC_MESSAGES/django.mo +0 -0
- umap/locale/da/LC_MESSAGES/django.po +280 -153
- umap/locale/de/LC_MESSAGES/django.mo +0 -0
- umap/locale/de/LC_MESSAGES/django.po +80 -64
- umap/locale/el/LC_MESSAGES/django.mo +0 -0
- umap/locale/el/LC_MESSAGES/django.po +82 -66
- umap/locale/en/LC_MESSAGES/django.po +73 -61
- umap/locale/es/LC_MESSAGES/django.mo +0 -0
- umap/locale/es/LC_MESSAGES/django.po +75 -63
- umap/locale/et/LC_MESSAGES/django.mo +0 -0
- umap/locale/et/LC_MESSAGES/django.po +280 -153
- umap/locale/eu/LC_MESSAGES/django.mo +0 -0
- umap/locale/eu/LC_MESSAGES/django.po +82 -66
- umap/locale/fa_IR/LC_MESSAGES/django.mo +0 -0
- umap/locale/fa_IR/LC_MESSAGES/django.po +80 -64
- umap/locale/fi/LC_MESSAGES/django.mo +0 -0
- umap/locale/fi/LC_MESSAGES/django.po +278 -151
- umap/locale/fr/LC_MESSAGES/django.mo +0 -0
- umap/locale/fr/LC_MESSAGES/django.po +75 -63
- umap/locale/gl/LC_MESSAGES/django.mo +0 -0
- umap/locale/gl/LC_MESSAGES/django.po +280 -153
- umap/locale/he/LC_MESSAGES/django.mo +0 -0
- umap/locale/he/LC_MESSAGES/django.po +281 -154
- umap/locale/hu/LC_MESSAGES/django.mo +0 -0
- umap/locale/hu/LC_MESSAGES/django.po +80 -64
- umap/locale/is/LC_MESSAGES/django.mo +0 -0
- umap/locale/is/LC_MESSAGES/django.po +280 -153
- umap/locale/it/LC_MESSAGES/django.mo +0 -0
- umap/locale/it/LC_MESSAGES/django.po +82 -66
- umap/locale/ja/LC_MESSAGES/django.mo +0 -0
- umap/locale/ja/LC_MESSAGES/django.po +280 -153
- umap/locale/ko/LC_MESSAGES/django.mo +0 -0
- umap/locale/ko/LC_MESSAGES/django.po +280 -153
- umap/locale/lt/LC_MESSAGES/django.mo +0 -0
- umap/locale/lt/LC_MESSAGES/django.po +280 -153
- umap/locale/ms/LC_MESSAGES/django.mo +0 -0
- umap/locale/ms/LC_MESSAGES/django.po +82 -66
- umap/locale/nl/LC_MESSAGES/django.mo +0 -0
- umap/locale/nl/LC_MESSAGES/django.po +280 -153
- umap/locale/pl/LC_MESSAGES/django.mo +0 -0
- umap/locale/pl/LC_MESSAGES/django.po +82 -66
- umap/locale/pt/LC_MESSAGES/django.mo +0 -0
- umap/locale/pt/LC_MESSAGES/django.po +75 -63
- umap/locale/pt_BR/LC_MESSAGES/django.mo +0 -0
- umap/locale/pt_BR/LC_MESSAGES/django.po +280 -153
- umap/locale/pt_PT/LC_MESSAGES/django.mo +0 -0
- umap/locale/pt_PT/LC_MESSAGES/django.po +280 -153
- umap/locale/ru/LC_MESSAGES/django.mo +0 -0
- umap/locale/ru/LC_MESSAGES/django.po +280 -153
- umap/locale/sk_SK/LC_MESSAGES/django.mo +0 -0
- umap/locale/sk_SK/LC_MESSAGES/django.po +280 -153
- umap/locale/sl/LC_MESSAGES/django.mo +0 -0
- umap/locale/sl/LC_MESSAGES/django.po +280 -153
- umap/locale/sr/LC_MESSAGES/django.mo +0 -0
- umap/locale/sr/LC_MESSAGES/django.po +280 -153
- umap/locale/sv/LC_MESSAGES/django.mo +0 -0
- umap/locale/sv/LC_MESSAGES/django.po +81 -65
- umap/locale/th_TH/LC_MESSAGES/django.mo +0 -0
- umap/locale/th_TH/LC_MESSAGES/django.po +257 -185
- umap/locale/tr/LC_MESSAGES/django.mo +0 -0
- umap/locale/tr/LC_MESSAGES/django.po +280 -153
- umap/locale/uk_UA/LC_MESSAGES/django.mo +0 -0
- umap/locale/uk_UA/LC_MESSAGES/django.po +280 -153
- umap/locale/vi/LC_MESSAGES/django.mo +0 -0
- umap/locale/vi/LC_MESSAGES/django.po +278 -151
- umap/locale/zh/LC_MESSAGES/django.mo +0 -0
- umap/locale/zh/LC_MESSAGES/django.po +278 -151
- umap/locale/zh_TW/LC_MESSAGES/django.mo +0 -0
- umap/locale/zh_TW/LC_MESSAGES/django.po +97 -81
- umap/management/commands/empty_trash.py +35 -0
- umap/management/commands/migrate_to_S3.py +29 -0
- umap/migrations/0023_alter_datalayer_uuid.py +19 -0
- umap/migrations/0024_alter_map_share_status.py +30 -0
- umap/migrations/0025_alter_datalayer_geojson.py +24 -0
- umap/models.py +68 -116
- umap/settings/base.py +23 -3
- umap/settings/local_s3.py +45 -0
- umap/static/umap/base.css +3 -603
- umap/static/umap/content.css +5 -3
- umap/static/umap/css/bar.css +202 -0
- umap/static/umap/css/form.css +620 -0
- umap/static/umap/css/icon.css +21 -1
- umap/static/umap/css/popup.css +125 -0
- umap/static/umap/img/16-white.svg +16 -4
- umap/static/umap/img/16.svg +1 -1
- umap/static/umap/img/source/16-white.svg +46 -45
- umap/static/umap/img/source/16.svg +1 -753
- umap/static/umap/js/components/fragment.js +3 -1
- umap/static/umap/js/modules/browser.js +20 -19
- umap/static/umap/js/modules/caption.js +21 -22
- umap/static/umap/js/modules/data/features.js +120 -78
- umap/static/umap/js/modules/data/layer.js +195 -153
- umap/static/umap/js/modules/facets.js +9 -9
- umap/static/umap/js/modules/formatter.js +5 -5
- umap/static/umap/js/modules/global.js +4 -52
- umap/static/umap/js/modules/help.js +18 -21
- umap/static/umap/js/modules/importer.js +133 -56
- umap/static/umap/js/modules/importers/cadastrefr.js +4 -0
- umap/static/umap/js/modules/importers/geodatamine.js +3 -3
- umap/static/umap/js/modules/importers/overpass.js +5 -0
- umap/static/umap/js/modules/permissions.js +85 -87
- umap/static/umap/js/modules/rendering/icon.js +2 -1
- umap/static/umap/js/modules/rendering/layers/base.js +15 -15
- umap/static/umap/js/modules/rendering/layers/classified.js +1 -1
- umap/static/umap/js/modules/rendering/layers/cluster.js +1 -1
- umap/static/umap/js/modules/rendering/layers/heat.js +1 -1
- umap/static/umap/js/modules/rendering/map.js +390 -0
- umap/static/umap/js/modules/rendering/popup.js +19 -19
- umap/static/umap/js/modules/rendering/template.js +88 -21
- umap/static/umap/js/modules/rendering/ui.js +63 -14
- umap/static/umap/js/modules/request.js +2 -2
- umap/static/umap/js/modules/rules.js +22 -25
- umap/static/umap/js/modules/saving.js +47 -0
- umap/static/umap/js/modules/schema.js +6 -0
- umap/static/umap/js/modules/share.js +21 -24
- umap/static/umap/js/modules/slideshow.js +24 -20
- umap/static/umap/js/modules/sync/updaters.js +7 -9
- umap/static/umap/js/modules/tableeditor.js +20 -19
- umap/static/umap/js/modules/ui/bar.js +196 -0
- umap/static/umap/js/modules/ui/dialog.js +6 -1
- umap/static/umap/js/modules/ui/panel.js +10 -9
- umap/static/umap/js/modules/umap.js +1691 -0
- umap/static/umap/js/modules/urls.js +2 -2
- umap/static/umap/js/modules/utils.js +22 -6
- umap/static/umap/js/umap.controls.js +81 -305
- umap/static/umap/js/umap.core.js +29 -50
- umap/static/umap/js/umap.forms.js +78 -27
- umap/static/umap/keycloak.png +0 -0
- umap/static/umap/locale/am_ET.js +26 -10
- umap/static/umap/locale/am_ET.json +26 -10
- umap/static/umap/locale/ar.js +26 -10
- umap/static/umap/locale/ar.json +26 -10
- umap/static/umap/locale/ast.js +26 -10
- umap/static/umap/locale/ast.json +26 -10
- umap/static/umap/locale/bg.js +26 -10
- umap/static/umap/locale/bg.json +26 -10
- umap/static/umap/locale/br.js +27 -20
- umap/static/umap/locale/br.json +27 -20
- umap/static/umap/locale/ca.js +32 -29
- umap/static/umap/locale/ca.json +32 -29
- umap/static/umap/locale/cs_CZ.js +24 -17
- umap/static/umap/locale/cs_CZ.json +24 -17
- umap/static/umap/locale/da.js +26 -10
- umap/static/umap/locale/da.json +26 -10
- umap/static/umap/locale/de.js +21 -14
- umap/static/umap/locale/de.json +21 -14
- umap/static/umap/locale/el.js +28 -12
- umap/static/umap/locale/el.json +28 -12
- umap/static/umap/locale/en.js +14 -9
- umap/static/umap/locale/en.json +14 -9
- umap/static/umap/locale/en_US.json +26 -10
- umap/static/umap/locale/es.js +16 -13
- umap/static/umap/locale/es.json +16 -13
- umap/static/umap/locale/et.js +26 -10
- umap/static/umap/locale/et.json +26 -10
- umap/static/umap/locale/eu.js +16 -9
- umap/static/umap/locale/eu.json +16 -9
- umap/static/umap/locale/fa_IR.js +16 -9
- umap/static/umap/locale/fa_IR.json +16 -9
- umap/static/umap/locale/fi.js +26 -10
- umap/static/umap/locale/fi.json +26 -10
- umap/static/umap/locale/fr.js +14 -9
- umap/static/umap/locale/fr.json +14 -9
- umap/static/umap/locale/gl.js +26 -10
- umap/static/umap/locale/gl.json +26 -10
- umap/static/umap/locale/he.js +26 -10
- umap/static/umap/locale/he.json +26 -10
- umap/static/umap/locale/hr.js +26 -10
- umap/static/umap/locale/hr.json +26 -10
- umap/static/umap/locale/hu.js +16 -9
- umap/static/umap/locale/hu.json +16 -9
- umap/static/umap/locale/id.js +26 -10
- umap/static/umap/locale/id.json +26 -10
- umap/static/umap/locale/is.js +26 -10
- umap/static/umap/locale/is.json +26 -10
- umap/static/umap/locale/it.js +26 -10
- umap/static/umap/locale/it.json +26 -10
- umap/static/umap/locale/ja.js +26 -10
- umap/static/umap/locale/ja.json +26 -10
- umap/static/umap/locale/ko.js +26 -10
- umap/static/umap/locale/ko.json +26 -10
- umap/static/umap/locale/lt.js +26 -10
- umap/static/umap/locale/lt.json +26 -10
- umap/static/umap/locale/ms.js +28 -12
- umap/static/umap/locale/ms.json +28 -12
- umap/static/umap/locale/nl.js +28 -12
- umap/static/umap/locale/nl.json +28 -12
- umap/static/umap/locale/no.js +26 -10
- umap/static/umap/locale/no.json +26 -10
- umap/static/umap/locale/pl.js +28 -12
- umap/static/umap/locale/pl.json +28 -12
- umap/static/umap/locale/pl_PL.json +26 -10
- umap/static/umap/locale/pt.js +16 -9
- umap/static/umap/locale/pt.json +16 -9
- umap/static/umap/locale/pt_BR.js +26 -10
- umap/static/umap/locale/pt_BR.json +26 -10
- umap/static/umap/locale/pt_PT.js +16 -9
- umap/static/umap/locale/pt_PT.json +16 -9
- umap/static/umap/locale/ro.js +26 -10
- umap/static/umap/locale/ro.json +26 -10
- umap/static/umap/locale/ru.js +26 -10
- umap/static/umap/locale/ru.json +26 -10
- umap/static/umap/locale/si.js +7 -7
- umap/static/umap/locale/si.json +7 -7
- umap/static/umap/locale/sk_SK.js +26 -10
- umap/static/umap/locale/sk_SK.json +26 -10
- umap/static/umap/locale/sl.js +26 -10
- umap/static/umap/locale/sl.json +26 -10
- umap/static/umap/locale/sr.js +26 -10
- umap/static/umap/locale/sr.json +26 -10
- umap/static/umap/locale/sv.js +27 -11
- umap/static/umap/locale/sv.json +27 -11
- umap/static/umap/locale/th_TH.js +28 -12
- umap/static/umap/locale/th_TH.json +28 -12
- umap/static/umap/locale/tr.js +26 -10
- umap/static/umap/locale/tr.json +26 -10
- umap/static/umap/locale/uk_UA.js +26 -10
- umap/static/umap/locale/uk_UA.json +26 -10
- umap/static/umap/locale/vi.js +26 -10
- umap/static/umap/locale/vi.json +26 -10
- umap/static/umap/locale/vi_VN.json +26 -10
- umap/static/umap/locale/zh.js +26 -10
- umap/static/umap/locale/zh.json +26 -10
- umap/static/umap/locale/zh_CN.json +26 -10
- umap/static/umap/locale/zh_TW.Big5.json +26 -10
- umap/static/umap/locale/zh_TW.js +34 -27
- umap/static/umap/locale/zh_TW.json +34 -27
- umap/static/umap/map.css +39 -530
- umap/static/umap/unittests/URLs.js +15 -15
- umap/static/umap/unittests/utils.js +23 -1
- umap/static/umap/vars.css +2 -1
- umap/static/umap/vendors/formbuilder/Leaflet.FormBuilder.js +5 -1
- umap/storage/__init__.py +3 -0
- umap/storage/fs.py +101 -0
- umap/storage/s3.py +61 -0
- umap/templates/base.html +2 -0
- umap/templates/registration/login.html +7 -6
- umap/templates/umap/components/alerts/alert.html +4 -0
- umap/templates/umap/css.html +6 -0
- umap/templates/umap/js.html +3 -2
- umap/templates/umap/map_init.html +6 -5
- umap/templates/umap/user_dashboard.html +20 -19
- umap/tests/base.py +11 -1
- umap/tests/fixtures/empty_tile.png +0 -0
- umap/tests/fixtures/test_upload_simple_marker.json +19 -0
- umap/tests/integration/conftest.py +4 -1
- umap/tests/integration/test_anonymous_owned_map.py +18 -10
- umap/tests/integration/test_browser.py +16 -1
- umap/tests/integration/test_dashboard.py +1 -1
- umap/tests/integration/test_edit_datalayer.py +29 -7
- umap/tests/integration/test_import.py +28 -4
- umap/tests/integration/test_optimistic_merge.py +31 -8
- umap/tests/integration/test_owned_map.py +22 -16
- umap/tests/integration/test_popup.py +44 -0
- umap/tests/integration/test_save.py +35 -0
- umap/tests/integration/test_view_marker.py +12 -0
- umap/tests/integration/test_view_polyline.py +257 -0
- umap/tests/integration/test_websocket_sync.py +81 -9
- umap/tests/test_dashboard.py +82 -0
- umap/tests/test_datalayer.py +6 -7
- umap/tests/test_datalayer_s3.py +135 -0
- umap/tests/test_datalayer_views.py +28 -10
- umap/tests/test_empty_trash.py +34 -0
- umap/tests/test_map.py +12 -3
- umap/tests/test_map_views.py +69 -37
- umap/tests/test_statics.py +1 -1
- umap/tests/test_team_views.py +35 -1
- umap/tests/test_views.py +31 -52
- umap/urls.py +3 -3
- umap/views.py +126 -90
- {umap_project-2.7.2.dist-info → umap_project-2.8.0.dist-info}/METADATA +16 -14
- {umap_project-2.7.2.dist-info → umap_project-2.8.0.dist-info}/RECORD +290 -269
- {umap_project-2.7.2.dist-info → umap_project-2.8.0.dist-info}/WHEEL +1 -1
- umap/management/commands/purge_purgatory.py +0 -28
- umap/static/umap/js/umap.js +0 -1903
- umap/tests/test_purge_purgatory.py +0 -25
- /umap/{storage.py → storage/staticfiles.py} +0 -0
- {umap_project-2.7.2.dist-info → umap_project-2.8.0.dist-info}/entry_points.txt +0 -0
- {umap_project-2.7.2.dist-info → umap_project-2.8.0.dist-info}/licenses/LICENSE +0 -0
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
from pathlib import Path
|
|
2
|
+
|
|
1
3
|
import pytest
|
|
2
4
|
from playwright.sync_api import expect
|
|
3
5
|
|
|
@@ -49,3 +51,258 @@ def test_should_open_popup_on_click(live_server, map, page, bootstrap):
|
|
|
49
51
|
# Close popup
|
|
50
52
|
page.locator("#map").click()
|
|
51
53
|
expect(line).to_have_attribute("stroke-opacity", "0.5")
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
def test_can_use_measure_on_name(live_server, map, page):
|
|
57
|
+
data = {
|
|
58
|
+
"type": "FeatureCollection",
|
|
59
|
+
"features": [
|
|
60
|
+
{
|
|
61
|
+
"type": "Feature",
|
|
62
|
+
"properties": {"name": "linestring"},
|
|
63
|
+
"geometry": {
|
|
64
|
+
"type": "LineString",
|
|
65
|
+
"coordinates": [
|
|
66
|
+
[11.25, 53.585984],
|
|
67
|
+
[10.151367, 52.975108],
|
|
68
|
+
],
|
|
69
|
+
},
|
|
70
|
+
},
|
|
71
|
+
{
|
|
72
|
+
"type": "Feature",
|
|
73
|
+
"properties": {"name": "multilinestring"},
|
|
74
|
+
"geometry": {
|
|
75
|
+
"type": "MultiLineString",
|
|
76
|
+
"coordinates": [[[8, 53], [13, 52]], [[12, 51], [15, 52]]],
|
|
77
|
+
},
|
|
78
|
+
},
|
|
79
|
+
],
|
|
80
|
+
}
|
|
81
|
+
map.settings["properties"]["labelKey"] = "{name} ({measure})"
|
|
82
|
+
map.settings["properties"]["onLoadPanel"] = "databrowser"
|
|
83
|
+
map.save()
|
|
84
|
+
DataLayerFactory(map=map, data=data)
|
|
85
|
+
page.goto(f"{live_server.url}{map.get_absolute_url()}#6/10/50")
|
|
86
|
+
expect(page.get_by_text("linestring (99.7 km)")).to_be_visible()
|
|
87
|
+
expect(page.get_by_text("multilinestring (592 km)")).to_be_visible()
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
def test_can_use_gain_and_loss(live_server, map, page):
|
|
91
|
+
data = {
|
|
92
|
+
"type": "FeatureCollection",
|
|
93
|
+
"features": [
|
|
94
|
+
{
|
|
95
|
+
"type": "Feature",
|
|
96
|
+
"geometry": {
|
|
97
|
+
"type": "LineString",
|
|
98
|
+
"coordinates": [
|
|
99
|
+
[8.420888, 39.327819, 12.1],
|
|
100
|
+
[8.420915, 39.327745, 12.9],
|
|
101
|
+
[8.420906, 39.327543, 14.8],
|
|
102
|
+
[8.420876, 39.327312, 17],
|
|
103
|
+
[8.420754, 39.327023, 16.8],
|
|
104
|
+
[8.420609, 39.326776, 16.6],
|
|
105
|
+
[8.42051, 39.326467, 16.4],
|
|
106
|
+
[8.420409, 39.326254, 16.3],
|
|
107
|
+
[8.420367, 39.326108, 16.2],
|
|
108
|
+
[8.420287, 39.326044, 16.2],
|
|
109
|
+
[8.420294, 39.325794, 15.1],
|
|
110
|
+
[8.419974, 39.325549, 12.5],
|
|
111
|
+
[8.419887, 39.325508, 11.9],
|
|
112
|
+
[8.419702, 39.325343, 10.3],
|
|
113
|
+
[8.419574, 39.325289, 9.4],
|
|
114
|
+
[8.41943, 39.325183, 8.2],
|
|
115
|
+
[8.419393, 39.325127, 7.8],
|
|
116
|
+
[8.419297, 39.325108, 7.2],
|
|
117
|
+
[8.419179, 39.325014, 6.2],
|
|
118
|
+
[8.419179, 39.324979, 6.1],
|
|
119
|
+
[8.419179, 39.324979, 6.1],
|
|
120
|
+
[8.419182, 39.324653, 6],
|
|
121
|
+
[8.419129, 39.324508, 5.9],
|
|
122
|
+
[8.419074, 39.324482, 5.9],
|
|
123
|
+
[8.419007, 39.324362, 5.8],
|
|
124
|
+
[8.418957, 39.324324, 5.8],
|
|
125
|
+
[8.418944, 39.324291, 5.8],
|
|
126
|
+
[8.418947, 39.324233, 5.8],
|
|
127
|
+
[8.418967, 39.324196, 5.7],
|
|
128
|
+
[8.41895, 39.324126, 5.6],
|
|
129
|
+
[8.418838, 39.323996, 5.4],
|
|
130
|
+
[8.418814, 39.323774, 5],
|
|
131
|
+
[8.418931, 39.323546, 10.1],
|
|
132
|
+
[8.41896, 39.323444, 12.3],
|
|
133
|
+
[8.418971, 39.323232, 16.9],
|
|
134
|
+
[8.419068, 39.322974, 13.5],
|
|
135
|
+
[8.41914, 39.322946, 12.7],
|
|
136
|
+
[8.419245, 39.322895, 12.3],
|
|
137
|
+
[8.419342, 39.322857, 11.9],
|
|
138
|
+
[8.419492, 39.322855, 11.3],
|
|
139
|
+
[8.419591, 39.322768, 11.1],
|
|
140
|
+
[8.419672, 39.322724, 11],
|
|
141
|
+
[8.419776, 39.322704, 10.9],
|
|
142
|
+
[8.419823, 39.322711, 10.8],
|
|
143
|
+
[8.41971, 39.322631, 8.5],
|
|
144
|
+
[8.419668, 39.322581, 7.3],
|
|
145
|
+
[8.419653, 39.322537, 6.3],
|
|
146
|
+
[8.419628, 39.32243, 5.3],
|
|
147
|
+
[8.419629, 39.322384, 5.4],
|
|
148
|
+
[8.419656, 39.322346, 5.5],
|
|
149
|
+
[8.419703, 39.322304, 5.6],
|
|
150
|
+
[8.419802, 39.322305, 5.7],
|
|
151
|
+
[8.419868, 39.32228, 5.8],
|
|
152
|
+
[8.419994, 39.322223, 6.1],
|
|
153
|
+
[8.420066, 39.322174, 6.2],
|
|
154
|
+
[8.42013, 39.32211, 6.4],
|
|
155
|
+
[8.420142, 39.322013, 6.5],
|
|
156
|
+
[8.420167, 39.321924, 6.7],
|
|
157
|
+
[8.420188, 39.321788, 7],
|
|
158
|
+
[8.420269, 39.32165, 7.3],
|
|
159
|
+
[8.420342, 39.321625, 7.4],
|
|
160
|
+
[8.420427, 39.321609, 7.5],
|
|
161
|
+
[8.420645, 39.321582, 7.8],
|
|
162
|
+
[8.420753, 39.321699, 8.1],
|
|
163
|
+
[8.420881, 39.321801, 8.4],
|
|
164
|
+
[8.421082, 39.321898, 8.7],
|
|
165
|
+
[8.421184, 39.321868, 8.9],
|
|
166
|
+
[8.421351, 39.321877, 9.1],
|
|
167
|
+
[8.421451, 39.321834, 8.2],
|
|
168
|
+
[8.421545, 39.321811, 7.5],
|
|
169
|
+
[8.421815, 39.321691, 5.1],
|
|
170
|
+
[8.421877, 39.321632, 4.3],
|
|
171
|
+
[8.42196, 39.321602, 3.7],
|
|
172
|
+
[8.422083, 39.321621, 4.5],
|
|
173
|
+
[8.422462, 39.321579, 8.7],
|
|
174
|
+
[8.422875, 39.321691, 13.5],
|
|
175
|
+
[8.423069, 39.321732, 15.7],
|
|
176
|
+
[8.423231, 39.321687, 17.6],
|
|
177
|
+
[8.423405, 39.321726, 19.6],
|
|
178
|
+
[8.423626, 39.321719, 22.1],
|
|
179
|
+
[8.424103, 39.321776, 27.4],
|
|
180
|
+
[8.424214, 39.321746, 28.7],
|
|
181
|
+
[8.424402, 39.321632, 27.5],
|
|
182
|
+
[8.424486, 39.321559, 26.8],
|
|
183
|
+
[8.424524, 39.321501, 26.3],
|
|
184
|
+
[8.424916, 39.321097, 22.6],
|
|
185
|
+
[8.424969, 39.321007, 21.9],
|
|
186
|
+
[8.425387, 39.320766, 19],
|
|
187
|
+
[8.425489, 39.320645, 20.4],
|
|
188
|
+
[8.425621, 39.320556, 22.1],
|
|
189
|
+
[8.425699, 39.320574, 22.8],
|
|
190
|
+
[8.425774, 39.320511, 23.9],
|
|
191
|
+
[8.425831, 39.320336, 19.6],
|
|
192
|
+
[8.425822, 39.32021, 16.1],
|
|
193
|
+
[8.42575, 39.320086, 12.4],
|
|
194
|
+
[8.425788, 39.320004, 10],
|
|
195
|
+
[8.425946, 39.319822, 10.7],
|
|
196
|
+
[8.426039, 39.319781, 11],
|
|
197
|
+
[8.426264, 39.319776, 11.8],
|
|
198
|
+
[8.426305, 39.319718, 12],
|
|
199
|
+
[8.426362, 39.319433, 6.8],
|
|
200
|
+
[8.426414, 39.31936, 5.3],
|
|
201
|
+
[8.426422, 39.319161, 1.6],
|
|
202
|
+
[8.426449, 39.319085, 0.2],
|
|
203
|
+
[8.426568, 39.31904, 0.4],
|
|
204
|
+
[8.426608, 39.318981, 1.8],
|
|
205
|
+
[8.426714, 39.318923, 3.8],
|
|
206
|
+
[8.427072, 39.318862, 9.6],
|
|
207
|
+
[8.427204, 39.31886, 11.7],
|
|
208
|
+
[8.427359, 39.318896, 14.3],
|
|
209
|
+
[8.427434, 39.31895, 15.9],
|
|
210
|
+
[8.427519, 39.318968, 17.3],
|
|
211
|
+
[8.427558, 39.318972, 18.4],
|
|
212
|
+
[8.427616, 39.318991, 19.2],
|
|
213
|
+
[8.427685, 39.319082, 21.3],
|
|
214
|
+
[8.42773, 39.31921, 25.1],
|
|
215
|
+
[8.427914, 39.319306, 29.9],
|
|
216
|
+
[8.42849, 39.319358, 46.7],
|
|
217
|
+
[8.429645, 39.319309, 79.8],
|
|
218
|
+
[8.430532, 39.319314, 85],
|
|
219
|
+
[8.430582, 39.319297, 85.2],
|
|
220
|
+
[8.430808, 39.319195, 84.8],
|
|
221
|
+
[8.43098, 39.319076, 84.5],
|
|
222
|
+
[8.431138, 39.318999, 84.2],
|
|
223
|
+
[8.431283, 39.318985, 84],
|
|
224
|
+
[8.431288, 39.318946, 84.8],
|
|
225
|
+
[8.431373, 39.318825, 87.6],
|
|
226
|
+
[8.431411, 39.318796, 87.9],
|
|
227
|
+
[8.431678, 39.318827, 87.1],
|
|
228
|
+
[8.431773, 39.318752, 88.3],
|
|
229
|
+
[8.431854, 39.318552, 90.7],
|
|
230
|
+
[8.431832, 39.31847, 91.7],
|
|
231
|
+
[8.431959, 39.318284, 94.1],
|
|
232
|
+
[8.431968, 39.318034, 97],
|
|
233
|
+
[8.43207, 39.31791, 98.7],
|
|
234
|
+
[8.432118, 39.317736, 100.8],
|
|
235
|
+
[8.432263, 39.317582, 103],
|
|
236
|
+
[8.432291, 39.317263, 106.7],
|
|
237
|
+
[8.432279, 39.316848, 111.5],
|
|
238
|
+
[8.432358, 39.31652, 115.3],
|
|
239
|
+
[8.432327, 39.316486, 115.8],
|
|
240
|
+
[8.432336, 39.316437, 116.4],
|
|
241
|
+
[8.432287, 39.316409, 116.4],
|
|
242
|
+
[8.432257, 39.316391, 116.2],
|
|
243
|
+
[8.432179, 39.316251, 115.4],
|
|
244
|
+
[8.432156, 39.316183, 115.6],
|
|
245
|
+
[8.43223, 39.316138, 116.5],
|
|
246
|
+
[8.43223, 39.316043, 117.7],
|
|
247
|
+
[8.432274, 39.315918, 119.4],
|
|
248
|
+
[8.432254, 39.315799, 121],
|
|
249
|
+
[8.432377, 39.315713, 122.6],
|
|
250
|
+
[8.43248, 39.315542, 125.1],
|
|
251
|
+
[8.43257, 39.315451, 126],
|
|
252
|
+
[8.432652, 39.315352, 127],
|
|
253
|
+
[8.432724, 39.315291, 127.7],
|
|
254
|
+
[8.432779, 39.315208, 128.5],
|
|
255
|
+
[8.432863, 39.315109, 129.5],
|
|
256
|
+
[8.432945, 39.315038, 130.3],
|
|
257
|
+
[8.433002, 39.315014, 130.7],
|
|
258
|
+
[8.433092, 39.315007, 131.3],
|
|
259
|
+
[8.43318, 39.315012, 131.9],
|
|
260
|
+
[8.433295, 39.315111, 133],
|
|
261
|
+
[8.433346, 39.315126, 133.4],
|
|
262
|
+
[8.43338, 39.315113, 133.6],
|
|
263
|
+
[8.433404, 39.31509, 133.8],
|
|
264
|
+
[8.433408, 39.315058, 132.4],
|
|
265
|
+
[8.433422, 39.31498, 131.6],
|
|
266
|
+
[8.43347, 39.314876, 130.3],
|
|
267
|
+
[8.433562, 39.314771, 128.2],
|
|
268
|
+
[8.433817, 39.314543, 123],
|
|
269
|
+
[8.434004, 39.314434, 119.9],
|
|
270
|
+
[8.434262, 39.314344, 121.2],
|
|
271
|
+
[8.434729, 39.314236, 123.9],
|
|
272
|
+
[8.435085, 39.31388, 127.2],
|
|
273
|
+
[8.435254, 39.313808, 128.4],
|
|
274
|
+
[8.435388, 39.313779, 128.4],
|
|
275
|
+
[8.435547, 39.313774, 129.9],
|
|
276
|
+
[8.4357, 39.313825, 131.6],
|
|
277
|
+
[8.435802, 39.313882, 132.8],
|
|
278
|
+
[8.435866, 39.313979, 134.1],
|
|
279
|
+
[8.435902, 39.314064, 135.2],
|
|
280
|
+
[8.435973, 39.314103, 136],
|
|
281
|
+
[8.436062, 39.314107, 136.9],
|
|
282
|
+
[8.436143, 39.314101, 137.7],
|
|
283
|
+
[8.436215, 39.313989, 137.7],
|
|
284
|
+
[8.436162, 39.313752, 137.5],
|
|
285
|
+
[8.436209, 39.313402, 137.2],
|
|
286
|
+
[8.436413, 39.313182, 137],
|
|
287
|
+
[8.436559, 39.313127, 136.9],
|
|
288
|
+
[8.43664, 39.313115, 136.8],
|
|
289
|
+
[8.436682, 39.313058, 137.7],
|
|
290
|
+
[8.436798, 39.312789, 139.1],
|
|
291
|
+
[8.436706, 39.312486, 140.7],
|
|
292
|
+
[8.436703, 39.312448, 141],
|
|
293
|
+
],
|
|
294
|
+
},
|
|
295
|
+
"properties": {"name": "some track"},
|
|
296
|
+
"id": "MzMTI",
|
|
297
|
+
}
|
|
298
|
+
],
|
|
299
|
+
"_umap_options": {"popupContentTemplate": "{name}\n⭧ {gain} m\n⭨ {loss} m"},
|
|
300
|
+
}
|
|
301
|
+
DataLayerFactory(map=map, data=data)
|
|
302
|
+
page.goto(
|
|
303
|
+
f"{live_server.url}{map.get_absolute_url()}?onLoadPanel=databrowser#16/39.3201/8.4278"
|
|
304
|
+
)
|
|
305
|
+
# We can't make PW to click on the path, so let's use the browser for that
|
|
306
|
+
page.get_by_text("some track").click()
|
|
307
|
+
expect(page.get_by_text("⭧ 211 m")).to_be_visible()
|
|
308
|
+
expect(page.get_by_text("⭨ 82 m")).to_be_visible()
|
|
@@ -3,7 +3,7 @@ import re
|
|
|
3
3
|
import pytest
|
|
4
4
|
from playwright.sync_api import expect
|
|
5
5
|
|
|
6
|
-
from umap.models import Map
|
|
6
|
+
from umap.models import DataLayer, Map
|
|
7
7
|
|
|
8
8
|
from ..base import DataLayerFactory, MapFactory
|
|
9
9
|
|
|
@@ -161,7 +161,7 @@ def test_websocket_connection_can_sync_polygons(
|
|
|
161
161
|
|
|
162
162
|
@pytest.mark.xdist_group(name="websockets")
|
|
163
163
|
def test_websocket_connection_can_sync_map_properties(
|
|
164
|
-
|
|
164
|
+
new_page, live_server, websocket_server, tilelayer
|
|
165
165
|
):
|
|
166
166
|
map = MapFactory(name="sync", edit_status=Map.ANONYMOUS)
|
|
167
167
|
map.settings["properties"]["syncEnabled"] = True
|
|
@@ -169,9 +169,9 @@ def test_websocket_connection_can_sync_map_properties(
|
|
|
169
169
|
DataLayerFactory(map=map, data={})
|
|
170
170
|
|
|
171
171
|
# Create two tabs
|
|
172
|
-
peerA =
|
|
172
|
+
peerA = new_page()
|
|
173
173
|
peerA.goto(f"{live_server.url}{map.get_absolute_url()}?edit")
|
|
174
|
-
peerB =
|
|
174
|
+
peerB = new_page()
|
|
175
175
|
peerB.goto(f"{live_server.url}{map.get_absolute_url()}?edit")
|
|
176
176
|
|
|
177
177
|
# Name change is synced
|
|
@@ -193,7 +193,7 @@ def test_websocket_connection_can_sync_map_properties(
|
|
|
193
193
|
|
|
194
194
|
@pytest.mark.xdist_group(name="websockets")
|
|
195
195
|
def test_websocket_connection_can_sync_datalayer_properties(
|
|
196
|
-
|
|
196
|
+
new_page, live_server, websocket_server, tilelayer
|
|
197
197
|
):
|
|
198
198
|
map = MapFactory(name="sync", edit_status=Map.ANONYMOUS)
|
|
199
199
|
map.settings["properties"]["syncEnabled"] = True
|
|
@@ -201,9 +201,9 @@ def test_websocket_connection_can_sync_datalayer_properties(
|
|
|
201
201
|
DataLayerFactory(map=map, data={})
|
|
202
202
|
|
|
203
203
|
# Create two tabs
|
|
204
|
-
peerA =
|
|
204
|
+
peerA = new_page()
|
|
205
205
|
peerA.goto(f"{live_server.url}{map.get_absolute_url()}?edit")
|
|
206
|
-
peerB =
|
|
206
|
+
peerB = new_page()
|
|
207
207
|
peerB.goto(f"{live_server.url}{map.get_absolute_url()}?edit")
|
|
208
208
|
|
|
209
209
|
# Layer addition, name and type are synced
|
|
@@ -215,7 +215,7 @@ def test_websocket_connection_can_sync_datalayer_properties(
|
|
|
215
215
|
peerA.locator("body").press("Escape")
|
|
216
216
|
|
|
217
217
|
peerB.get_by_role("link", name="Manage layers").click()
|
|
218
|
-
peerB.get_by_role("button", name="Edit").first.click()
|
|
218
|
+
peerB.locator(".panel.right").get_by_role("button", name="Edit").first.click()
|
|
219
219
|
expect(peerB.locator('input[name="name"]')).to_have_value("synced layer!")
|
|
220
220
|
expect(peerB.get_by_role("combobox")).to_have_value("Choropleth")
|
|
221
221
|
|
|
@@ -267,7 +267,7 @@ def test_websocket_connection_can_sync_cloned_polygons(
|
|
|
267
267
|
b_polygon = peerB.locator("path")
|
|
268
268
|
|
|
269
269
|
# Clone on peer B and save
|
|
270
|
-
b_polygon.click(button="right")
|
|
270
|
+
b_polygon.click(button="right", delay=200)
|
|
271
271
|
peerB.get_by_role("button", name="Clone this feature").click()
|
|
272
272
|
|
|
273
273
|
expect(peerB.locator("path")).to_have_count(2)
|
|
@@ -343,3 +343,75 @@ def test_websocket_connection_can_sync_late_joining_peer(
|
|
|
343
343
|
|
|
344
344
|
# Clean up: close edit mode
|
|
345
345
|
peerB.locator("body").press("Escape")
|
|
346
|
+
|
|
347
|
+
|
|
348
|
+
@pytest.mark.xdist_group(name="websockets")
|
|
349
|
+
def test_should_sync_datalayers(new_page, live_server, websocket_server, tilelayer):
|
|
350
|
+
map = MapFactory(name="sync", edit_status=Map.ANONYMOUS)
|
|
351
|
+
map.settings["properties"]["syncEnabled"] = True
|
|
352
|
+
map.save()
|
|
353
|
+
|
|
354
|
+
assert not DataLayer.objects.count()
|
|
355
|
+
|
|
356
|
+
# Create two tabs
|
|
357
|
+
peerA = new_page("Page A")
|
|
358
|
+
peerA.goto(f"{live_server.url}{map.get_absolute_url()}?edit")
|
|
359
|
+
peerB = new_page("Page B")
|
|
360
|
+
peerB.goto(f"{live_server.url}{map.get_absolute_url()}?edit")
|
|
361
|
+
|
|
362
|
+
# Create a new layer from peerA
|
|
363
|
+
peerA.get_by_role("link", name="Manage layers").click()
|
|
364
|
+
peerA.get_by_role("button", name="Add a layer").click()
|
|
365
|
+
|
|
366
|
+
# Check layer has been sync to peerB
|
|
367
|
+
peerB.get_by_role("button", name="Open browser").click()
|
|
368
|
+
expect(peerB.get_by_text("Layer 1")).to_be_visible()
|
|
369
|
+
|
|
370
|
+
# Draw a marker in layer 1 from peerA
|
|
371
|
+
peerA.get_by_role("link", name="Draw a marker (Ctrl+M)").click()
|
|
372
|
+
peerA.locator("#map").click()
|
|
373
|
+
|
|
374
|
+
# Check marker is visible from peerB
|
|
375
|
+
expect(peerB.locator(".leaflet-marker-icon")).to_be_visible()
|
|
376
|
+
|
|
377
|
+
# Save layer to the server
|
|
378
|
+
with peerA.expect_response(re.compile(".*/datalayer/create/.*")):
|
|
379
|
+
peerA.get_by_role("button", name="Save").click()
|
|
380
|
+
|
|
381
|
+
assert DataLayer.objects.count() == 1
|
|
382
|
+
|
|
383
|
+
# Create another layer from peerA and draw a marker on it (without saving to server)
|
|
384
|
+
peerA.get_by_role("link", name="Manage layers").click()
|
|
385
|
+
peerA.get_by_role("button", name="Add a layer").click()
|
|
386
|
+
peerA.get_by_role("link", name="Draw a marker (Ctrl+M)").click()
|
|
387
|
+
peerA.locator("#map").click()
|
|
388
|
+
|
|
389
|
+
# Make sure this new marker is in Layer 2 for peerB
|
|
390
|
+
expect(peerB.get_by_text("Layer 2")).to_be_visible()
|
|
391
|
+
peerB.locator(".panel.left").get_by_role("button", name="Show/hide layer").nth(
|
|
392
|
+
1
|
|
393
|
+
).click()
|
|
394
|
+
expect(peerB.locator(".leaflet-marker-icon")).to_be_visible()
|
|
395
|
+
|
|
396
|
+
# Now draw a marker from peerB
|
|
397
|
+
peerB.get_by_role("link", name="Draw a marker (Ctrl+M)").click()
|
|
398
|
+
peerB.locator("#map").click()
|
|
399
|
+
peerB.locator('input[name="name"]').fill("marker from peerB")
|
|
400
|
+
|
|
401
|
+
# Save from peer B
|
|
402
|
+
with peerB.expect_response(re.compile(".*/datalayer/create/.*")):
|
|
403
|
+
peerB.get_by_role("button", name="Save").click()
|
|
404
|
+
|
|
405
|
+
assert DataLayer.objects.count() == 2
|
|
406
|
+
|
|
407
|
+
# Check this new marker is visible from peerA
|
|
408
|
+
peerA.get_by_role("button", name="Open browser").click()
|
|
409
|
+
peerA.locator(".panel.left").get_by_role("button", name="Show/hide layer").nth(
|
|
410
|
+
1
|
|
411
|
+
).click()
|
|
412
|
+
|
|
413
|
+
# Now peerA saves the layer 2 to the server
|
|
414
|
+
with peerA.expect_response(re.compile(".*/datalayer/update/.*")):
|
|
415
|
+
peerA.get_by_role("button", name="Save").click()
|
|
416
|
+
|
|
417
|
+
assert DataLayer.objects.count() == 2
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import pytest
|
|
2
|
+
from django.contrib.auth import get_user_model
|
|
3
|
+
from django.urls import reverse
|
|
4
|
+
|
|
5
|
+
from umap.models import Map
|
|
6
|
+
|
|
7
|
+
from .base import MapFactory, UserFactory
|
|
8
|
+
|
|
9
|
+
User = get_user_model()
|
|
10
|
+
|
|
11
|
+
pytestmark = pytest.mark.django_db
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
def test_user_dashboard_is_restricted_to_logged_in(client):
|
|
15
|
+
response = client.get(reverse("user_dashboard"))
|
|
16
|
+
assert response.status_code == 302
|
|
17
|
+
assert response["Location"] == "/en/login/?next=/en/me"
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
def test_user_dashboard_display_user_maps(client, map):
|
|
21
|
+
client.login(username=map.owner.username, password="123123")
|
|
22
|
+
response = client.get(reverse("user_dashboard"))
|
|
23
|
+
assert response.status_code == 200
|
|
24
|
+
body = response.content.decode()
|
|
25
|
+
assert map.name in body
|
|
26
|
+
assert f"{map.get_absolute_url()}?edit" in body
|
|
27
|
+
assert f"{map.get_absolute_url()}?share" in body
|
|
28
|
+
assert f"/map/{map.pk}/download" in body
|
|
29
|
+
assert "Everyone (public)" in body
|
|
30
|
+
assert "Owner only" in body
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
def test_user_dashboard_do_not_display_blocked_user_maps(client, map):
|
|
34
|
+
map.share_status = Map.BLOCKED
|
|
35
|
+
map.save()
|
|
36
|
+
client.login(username=map.owner.username, password="123123")
|
|
37
|
+
response = client.get(reverse("user_dashboard"))
|
|
38
|
+
assert response.status_code == 200
|
|
39
|
+
body = response.content.decode()
|
|
40
|
+
assert map.name not in body
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
def test_user_dashboard_do_not_display_deleted_user_maps(client, map):
|
|
44
|
+
map.share_status = Map.DELETED
|
|
45
|
+
map.save()
|
|
46
|
+
client.login(username=map.owner.username, password="123123")
|
|
47
|
+
response = client.get(reverse("user_dashboard"))
|
|
48
|
+
assert response.status_code == 200
|
|
49
|
+
body = response.content.decode()
|
|
50
|
+
assert map.name not in body
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
@pytest.mark.parametrize("share_status", [Map.DRAFT, Map.PRIVATE, Map.PUBLIC, Map.OPEN])
|
|
54
|
+
def test_user_dashboard_display_user_team_maps(client, map, team, user, share_status):
|
|
55
|
+
user.teams.add(team)
|
|
56
|
+
user.save()
|
|
57
|
+
map.team = team
|
|
58
|
+
map.share_status = share_status
|
|
59
|
+
map.save()
|
|
60
|
+
assert map.owner != user
|
|
61
|
+
client.login(username=user.username, password="123123")
|
|
62
|
+
response = client.get(reverse("user_dashboard"))
|
|
63
|
+
assert response.status_code == 200
|
|
64
|
+
body = response.content.decode()
|
|
65
|
+
assert map.name in body
|
|
66
|
+
assert map.get_absolute_url() in body
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
def test_user_dashboard_display_user_maps_distinct(client, map):
|
|
70
|
+
# cf https://github.com/umap-project/umap/issues/1325
|
|
71
|
+
anonymap = MapFactory(name="Map witout owner should not appear")
|
|
72
|
+
user1 = UserFactory(username="user1")
|
|
73
|
+
user2 = UserFactory(username="user2")
|
|
74
|
+
map.editors.add(user1)
|
|
75
|
+
map.editors.add(user2)
|
|
76
|
+
map.save()
|
|
77
|
+
client.login(username=map.owner.username, password="123123")
|
|
78
|
+
response = client.get(reverse("user_dashboard"))
|
|
79
|
+
assert response.status_code == 200
|
|
80
|
+
body = response.content.decode()
|
|
81
|
+
assert body.count(f'<a href="/en/map/test-map_{map.pk}">test map</a>') == 1
|
|
82
|
+
assert body.count(anonymap.name) == 0
|
umap/tests/test_datalayer.py
CHANGED
|
@@ -22,10 +22,11 @@ def test_datalayers_should_be_ordered_by_rank(map, datalayer):
|
|
|
22
22
|
assert list(map.datalayer_set.all()) == [c1, c2, c3, c4, datalayer]
|
|
23
23
|
|
|
24
24
|
|
|
25
|
-
def test_upload_to(map
|
|
25
|
+
def test_upload_to(map):
|
|
26
26
|
map.pk = 302
|
|
27
|
-
|
|
28
|
-
|
|
27
|
+
map.save()
|
|
28
|
+
datalayer = DataLayerFactory(map=map)
|
|
29
|
+
assert datalayer.geojson.name.startswith(f"datalayer/2/0/302/{datalayer.pk}_")
|
|
29
30
|
|
|
30
31
|
|
|
31
32
|
def test_save_should_use_pk_as_name(map, datalayer):
|
|
@@ -65,7 +66,7 @@ def test_clone_should_clone_geojson_too(datalayer):
|
|
|
65
66
|
def test_should_remove_old_versions_on_save(map, settings):
|
|
66
67
|
datalayer = DataLayerFactory(uuid="0f1161c0-c07f-4ba4-86c5-8d8981d8a813", old_id=17)
|
|
67
68
|
settings.UMAP_KEEP_VERSIONS = 3
|
|
68
|
-
root = Path(datalayer.
|
|
69
|
+
root = Path(datalayer.geojson.storage._base_path(datalayer))
|
|
69
70
|
before = len(datalayer.geojson.storage.listdir(root)[1])
|
|
70
71
|
newer = f"{datalayer.pk}_1440924889.geojson"
|
|
71
72
|
medium = f"{datalayer.pk}_1440923687.geojson"
|
|
@@ -273,9 +274,8 @@ def test_anonymous_can_edit_in_inherit_mode_and_map_in_public_mode(
|
|
|
273
274
|
|
|
274
275
|
|
|
275
276
|
def test_should_remove_all_versions_on_delete(map, settings):
|
|
276
|
-
settings.UMAP_PURGATORY_ROOT = tempfile.mkdtemp()
|
|
277
277
|
datalayer = DataLayerFactory(uuid="0f1161c0-c07f-4ba4-86c5-8d8981d8a813", old_id=17)
|
|
278
|
-
root = Path(datalayer.
|
|
278
|
+
root = Path(datalayer.geojson.storage._base_path(datalayer))
|
|
279
279
|
before = len(datalayer.geojson.storage.listdir(root)[1])
|
|
280
280
|
other = "123456_1440918637.geojson"
|
|
281
281
|
files = [
|
|
@@ -292,4 +292,3 @@ def test_should_remove_all_versions_on_delete(map, settings):
|
|
|
292
292
|
datalayer.delete()
|
|
293
293
|
found = datalayer.geojson.storage.listdir(root)[1]
|
|
294
294
|
assert found == [other, f"{other}.gz"]
|
|
295
|
-
assert len(list(Path(settings.UMAP_PURGATORY_ROOT).iterdir())) == 4 + before
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
import json
|
|
2
|
+
import os
|
|
3
|
+
|
|
4
|
+
import boto3
|
|
5
|
+
import pytest
|
|
6
|
+
from botocore.errorfactory import ClientError
|
|
7
|
+
from django.core.files.base import ContentFile
|
|
8
|
+
from django.core.files.storage import storages
|
|
9
|
+
from moto import mock_aws
|
|
10
|
+
|
|
11
|
+
from umap.models import DataLayer
|
|
12
|
+
|
|
13
|
+
from .base import DataLayerFactory
|
|
14
|
+
|
|
15
|
+
pytestmark = pytest.mark.django_db
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
@pytest.fixture(scope="module", autouse=True)
|
|
19
|
+
def patch_storage():
|
|
20
|
+
"""Mocked AWS Credentials for moto."""
|
|
21
|
+
os.environ["AWS_ACCESS_KEY_ID"] = "testing"
|
|
22
|
+
os.environ["AWS_SECRET_ACCESS_KEY"] = "testing"
|
|
23
|
+
os.environ["AWS_SECURITY_TOKEN"] = "testing"
|
|
24
|
+
os.environ["AWS_SESSION_TOKEN"] = "testing"
|
|
25
|
+
os.environ["AWS_DEFAULT_REGION"] = "us-east-1"
|
|
26
|
+
before = DataLayer.geojson.field.storage
|
|
27
|
+
|
|
28
|
+
DataLayer.geojson.field.storage = storages.create_storage(
|
|
29
|
+
{
|
|
30
|
+
"BACKEND": "umap.storage.s3.S3DataStorage",
|
|
31
|
+
"OPTIONS": {
|
|
32
|
+
"access_key": "testing",
|
|
33
|
+
"secret_key": "testing",
|
|
34
|
+
"bucket_name": "umap",
|
|
35
|
+
"region_name": "us-east-1",
|
|
36
|
+
},
|
|
37
|
+
}
|
|
38
|
+
)
|
|
39
|
+
yield
|
|
40
|
+
DataLayer.geojson.field.storage = before
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
@pytest.fixture(scope="module", autouse=True)
|
|
44
|
+
def mocked_aws():
|
|
45
|
+
"""
|
|
46
|
+
Mock all AWS interactions
|
|
47
|
+
Requires you to create your own boto3 clients
|
|
48
|
+
"""
|
|
49
|
+
with mock_aws():
|
|
50
|
+
client = boto3.client("s3", region_name="us-east-1")
|
|
51
|
+
client.create_bucket(Bucket="umap")
|
|
52
|
+
client.put_bucket_versioning(
|
|
53
|
+
Bucket="umap", VersioningConfiguration={"Status": "Enabled"}
|
|
54
|
+
)
|
|
55
|
+
yield
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
def test_can_create_datalayer(map, datalayer):
|
|
59
|
+
other = DataLayerFactory(map=map)
|
|
60
|
+
assert datalayer.geojson.name == f"{datalayer.pk}.geojson"
|
|
61
|
+
assert other.geojson.name == f"{other.pk}.geojson"
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
def test_clone_should_return_new_instance(map, datalayer):
|
|
65
|
+
clone = datalayer.clone()
|
|
66
|
+
assert datalayer.pk != clone.pk
|
|
67
|
+
assert datalayer.name == clone.name
|
|
68
|
+
assert datalayer.map == clone.map
|
|
69
|
+
assert datalayer.geojson != clone.geojson
|
|
70
|
+
assert datalayer.geojson.name != clone.geojson.name
|
|
71
|
+
assert clone.geojson.name == f"{clone.pk}.geojson"
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
def test_update_should_add_version(map, datalayer):
|
|
75
|
+
assert len(datalayer.versions) == 1
|
|
76
|
+
datalayer.geojson = ContentFile("{}", "foo.json")
|
|
77
|
+
datalayer.save()
|
|
78
|
+
assert len(datalayer.versions) == 2
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
def test_get_version(map, datalayer):
|
|
82
|
+
assert len(datalayer.versions) == 1
|
|
83
|
+
datalayer.geojson = ContentFile(b'{"foo": "bar"}', "foo.json")
|
|
84
|
+
datalayer.save()
|
|
85
|
+
assert len(datalayer.versions) == 2
|
|
86
|
+
latest = datalayer.versions[0]["ref"]
|
|
87
|
+
version = datalayer.get_version(latest)
|
|
88
|
+
assert json.loads(version) == {"foo": "bar"}
|
|
89
|
+
older = datalayer.versions[1]["ref"]
|
|
90
|
+
version = datalayer.get_version(older)
|
|
91
|
+
assert json.loads(version) == {
|
|
92
|
+
"_umap_options": {
|
|
93
|
+
"browsable": True,
|
|
94
|
+
"displayOnLoad": True,
|
|
95
|
+
"name": "test datalayer",
|
|
96
|
+
},
|
|
97
|
+
"features": [
|
|
98
|
+
{
|
|
99
|
+
"geometry": {
|
|
100
|
+
"coordinates": [
|
|
101
|
+
14.68896484375,
|
|
102
|
+
48.55297816440071,
|
|
103
|
+
],
|
|
104
|
+
"type": "Point",
|
|
105
|
+
},
|
|
106
|
+
"properties": {
|
|
107
|
+
"_umap_options": {
|
|
108
|
+
"color": "DarkCyan",
|
|
109
|
+
"iconClass": "Ball",
|
|
110
|
+
},
|
|
111
|
+
"description": "Da place anonymous again 755",
|
|
112
|
+
"name": "Here",
|
|
113
|
+
},
|
|
114
|
+
"type": "Feature",
|
|
115
|
+
},
|
|
116
|
+
],
|
|
117
|
+
"type": "FeatureCollection",
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
latest = datalayer.reference_version
|
|
121
|
+
version = datalayer.get_version(latest)
|
|
122
|
+
assert json.loads(version) == {"foo": "bar"}
|
|
123
|
+
|
|
124
|
+
|
|
125
|
+
def test_delete_datalayer_should_delete_all_versions(datalayer):
|
|
126
|
+
# create a new version
|
|
127
|
+
datalayer.geojson = ContentFile('{"foo": "bar"}', "foo.json")
|
|
128
|
+
datalayer.save()
|
|
129
|
+
s3_key = datalayer.geojson.name
|
|
130
|
+
datalayer.delete()
|
|
131
|
+
with pytest.raises(ClientError):
|
|
132
|
+
datalayer.geojson.storage.connection.meta.client.get_object(
|
|
133
|
+
Bucket="umap",
|
|
134
|
+
Key=s3_key,
|
|
135
|
+
)
|