umap-project 2.5.1__py3-none-any.whl → 2.6.0b0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of umap-project might be problematic. Click here for more details.
- umap/__init__.py +1 -1
- umap/admin.py +6 -1
- umap/context_processors.py +2 -1
- umap/decorators.py +13 -2
- umap/forms.py +26 -2
- umap/locale/br/LC_MESSAGES/django.mo +0 -0
- umap/locale/br/LC_MESSAGES/django.po +252 -146
- umap/locale/ca/LC_MESSAGES/django.mo +0 -0
- umap/locale/ca/LC_MESSAGES/django.po +274 -162
- umap/locale/cs_CZ/LC_MESSAGES/django.mo +0 -0
- umap/locale/cs_CZ/LC_MESSAGES/django.po +261 -150
- umap/locale/de/LC_MESSAGES/django.mo +0 -0
- umap/locale/de/LC_MESSAGES/django.po +299 -187
- umap/locale/el/LC_MESSAGES/django.mo +0 -0
- umap/locale/el/LC_MESSAGES/django.po +215 -159
- umap/locale/en/LC_MESSAGES/django.po +211 -155
- umap/locale/es/LC_MESSAGES/django.mo +0 -0
- umap/locale/es/LC_MESSAGES/django.po +255 -144
- umap/locale/eu/LC_MESSAGES/django.mo +0 -0
- umap/locale/eu/LC_MESSAGES/django.po +254 -198
- umap/locale/fa_IR/LC_MESSAGES/django.mo +0 -0
- umap/locale/fa_IR/LC_MESSAGES/django.po +346 -234
- umap/locale/fr/LC_MESSAGES/django.mo +0 -0
- umap/locale/fr/LC_MESSAGES/django.po +216 -160
- umap/locale/hu/LC_MESSAGES/django.mo +0 -0
- umap/locale/hu/LC_MESSAGES/django.po +215 -159
- umap/locale/it/LC_MESSAGES/django.mo +0 -0
- umap/locale/it/LC_MESSAGES/django.po +252 -146
- umap/locale/ms/LC_MESSAGES/django.mo +0 -0
- umap/locale/ms/LC_MESSAGES/django.po +252 -146
- umap/locale/pl/LC_MESSAGES/django.mo +0 -0
- umap/locale/pl/LC_MESSAGES/django.po +254 -148
- umap/locale/pt/LC_MESSAGES/django.mo +0 -0
- umap/locale/pt/LC_MESSAGES/django.po +215 -159
- umap/locale/sv/LC_MESSAGES/django.mo +0 -0
- umap/locale/sv/LC_MESSAGES/django.po +254 -143
- umap/locale/th_TH/LC_MESSAGES/django.mo +0 -0
- umap/locale/th_TH/LC_MESSAGES/django.po +125 -70
- umap/locale/zh_TW/LC_MESSAGES/django.mo +0 -0
- umap/locale/zh_TW/LC_MESSAGES/django.po +256 -145
- umap/migrations/0022_add_team.py +94 -0
- umap/models.py +45 -10
- umap/settings/__init__.py +2 -0
- umap/settings/base.py +3 -2
- umap/static/umap/base.css +32 -41
- umap/static/umap/content.css +19 -25
- umap/static/umap/css/icon.css +63 -37
- umap/static/umap/css/importers.css +1 -1
- umap/static/umap/css/slideshow.css +7 -5
- umap/static/umap/css/tableeditor.css +4 -3
- umap/static/umap/img/16-white.svg +1 -4
- umap/static/umap/img/16.svg +2 -6
- umap/static/umap/img/24-white.svg +4 -4
- umap/static/umap/img/24.svg +6 -6
- umap/static/umap/img/source/16-white.svg +2 -5
- umap/static/umap/img/source/16.svg +3 -7
- umap/static/umap/img/source/24-white.svg +7 -14
- umap/static/umap/img/source/24.svg +10 -17
- umap/static/umap/js/components/alerts/alert.css +20 -8
- umap/static/umap/js/modules/autocomplete.js +3 -3
- umap/static/umap/js/modules/browser.js +4 -3
- umap/static/umap/js/modules/caption.js +9 -11
- umap/static/umap/js/modules/data/features.js +994 -0
- umap/static/umap/js/modules/data/layer.js +1210 -0
- umap/static/umap/js/modules/formatter.js +12 -3
- umap/static/umap/js/modules/global.js +21 -5
- umap/static/umap/js/modules/permissions.js +280 -0
- umap/static/umap/js/{umap.icon.js → modules/rendering/icon.js} +77 -56
- umap/static/umap/js/modules/rendering/layers/base.js +105 -0
- umap/static/umap/js/modules/rendering/layers/classified.js +484 -0
- umap/static/umap/js/modules/rendering/layers/cluster.js +103 -0
- umap/static/umap/js/modules/rendering/layers/heat.js +182 -0
- umap/static/umap/js/modules/rendering/popup.js +99 -0
- umap/static/umap/js/modules/rendering/template.js +217 -0
- umap/static/umap/js/modules/rendering/ui.js +573 -0
- umap/static/umap/js/modules/schema.js +24 -0
- umap/static/umap/js/modules/share.js +66 -45
- umap/static/umap/js/modules/sync/updaters.js +9 -10
- umap/static/umap/js/modules/tableeditor.js +7 -7
- umap/static/umap/js/modules/ui/dialog.js +8 -4
- umap/static/umap/js/modules/utils.js +22 -13
- umap/static/umap/js/umap.controls.js +79 -146
- umap/static/umap/js/umap.core.js +9 -9
- umap/static/umap/js/umap.forms.js +32 -12
- umap/static/umap/js/umap.js +65 -63
- umap/static/umap/locale/br.js +35 -35
- umap/static/umap/locale/br.json +35 -35
- umap/static/umap/locale/ca.js +50 -50
- umap/static/umap/locale/ca.json +50 -50
- umap/static/umap/locale/de.js +136 -136
- umap/static/umap/locale/de.json +136 -136
- umap/static/umap/locale/el.js +47 -47
- umap/static/umap/locale/el.json +47 -47
- umap/static/umap/locale/en.js +7 -1
- umap/static/umap/locale/en.json +7 -1
- umap/static/umap/locale/fa_IR.js +44 -44
- umap/static/umap/locale/fa_IR.json +44 -44
- umap/static/umap/locale/fr.js +8 -2
- umap/static/umap/locale/fr.json +8 -2
- umap/static/umap/locale/pt.js +17 -17
- umap/static/umap/locale/pt.json +17 -17
- umap/static/umap/locale/pt_PT.js +207 -207
- umap/static/umap/locale/pt_PT.json +207 -207
- umap/static/umap/locale/th_TH.js +25 -25
- umap/static/umap/locale/th_TH.json +25 -25
- umap/static/umap/map.css +107 -104
- umap/static/umap/nav.css +19 -10
- umap/static/umap/unittests/utils.js +230 -107
- umap/static/umap/vendors/csv2geojson/csv2geojson.js +62 -40
- umap/static/umap/vendors/markercluster/MarkerCluster.Default.css +1 -1
- umap/storage.py +1 -0
- umap/templates/404.html +5 -1
- umap/templates/500.html +3 -1
- umap/templates/auth/user_detail.html +8 -2
- umap/templates/auth/user_form.html +19 -10
- umap/templates/auth/user_stars.html +8 -2
- umap/templates/base.html +1 -0
- umap/templates/registration/login.html +18 -3
- umap/templates/umap/about.html +1 -0
- umap/templates/umap/about_summary.html +22 -7
- umap/templates/umap/components/alerts/alert.html +42 -21
- umap/templates/umap/content.html +2 -0
- umap/templates/umap/content_footer.html +6 -2
- umap/templates/umap/css.html +1 -0
- umap/templates/umap/dashboard_menu.html +15 -0
- umap/templates/umap/home.html +14 -4
- umap/templates/umap/js.html +4 -9
- umap/templates/umap/login_popup_end.html +10 -4
- umap/templates/umap/map_detail.html +8 -2
- umap/templates/umap/map_fragment.html +3 -1
- umap/templates/umap/map_init.html +2 -1
- umap/templates/umap/map_list.html +4 -3
- umap/templates/umap/map_table.html +36 -12
- umap/templates/umap/messages.html +0 -1
- umap/templates/umap/navigation.html +2 -1
- umap/templates/umap/password_change.html +5 -1
- umap/templates/umap/password_change_done.html +8 -2
- umap/templates/umap/search.html +8 -2
- umap/templates/umap/search_bar.html +1 -0
- umap/templates/umap/team_confirm_delete.html +19 -0
- umap/templates/umap/team_detail.html +27 -0
- umap/templates/umap/team_form.html +60 -0
- umap/templates/umap/user_dashboard.html +7 -9
- umap/templates/umap/user_teams.html +51 -0
- umap/tests/base.py +8 -1
- umap/tests/conftest.py +6 -0
- umap/tests/fixtures/test_circles_layer.geojson +219 -0
- umap/tests/fixtures/test_upload_georss.xml +20 -0
- umap/tests/integration/conftest.py +18 -4
- umap/tests/integration/helpers.py +12 -0
- umap/tests/integration/test_anonymous_owned_map.py +23 -0
- umap/tests/integration/test_basics.py +29 -0
- umap/tests/integration/test_caption.py +20 -0
- umap/tests/integration/test_circles_layer.py +69 -0
- umap/tests/integration/test_draw_polygon.py +110 -13
- umap/tests/integration/test_draw_polyline.py +8 -18
- umap/tests/integration/test_edit_datalayer.py +1 -1
- umap/tests/integration/test_import.py +64 -5
- umap/tests/integration/test_owned_map.py +21 -13
- umap/tests/integration/test_team.py +47 -0
- umap/tests/integration/test_tilelayer.py +19 -2
- umap/tests/integration/test_view_marker.py +28 -1
- umap/tests/integration/test_websocket_sync.py +5 -5
- umap/tests/test_datalayer.py +32 -7
- umap/tests/test_datalayer_views.py +1 -1
- umap/tests/test_map.py +30 -4
- umap/tests/test_map_views.py +2 -2
- umap/tests/test_statics.py +40 -0
- umap/tests/test_team_views.py +131 -0
- umap/tests/test_views.py +15 -1
- umap/urls.py +23 -13
- umap/views.py +116 -10
- {umap_project-2.5.1.dist-info → umap_project-2.6.0b0.dist-info}/METADATA +9 -9
- {umap_project-2.5.1.dist-info → umap_project-2.6.0b0.dist-info}/RECORD +177 -170
- umap/static/umap/js/umap.datalayer.permissions.js +0 -70
- umap/static/umap/js/umap.features.js +0 -1290
- umap/static/umap/js/umap.layer.js +0 -1837
- umap/static/umap/js/umap.permissions.js +0 -208
- umap/static/umap/js/umap.popup.js +0 -341
- umap/static/umap/test/TableEditor.js +0 -104
- umap/static/umap/vendors/leaflet/leaflet-src.js +0 -14512
- umap/static/umap/vendors/leaflet/leaflet-src.js.map +0 -1
- umap/static/umap/vendors/leaflet/leaflet.js +0 -6
- umap/static/umap/vendors/leaflet/leaflet.js.map +0 -1
- umap/static/umap/vendors/markercluster/WhereAreTheJavascriptFiles.txt +0 -5
- umap/static/umap/vendors/markercluster/leaflet.markercluster-src.js +0 -2718
- umap/static/umap/vendors/markercluster/leaflet.markercluster-src.js.map +0 -1
- umap/static/umap/vendors/toolbar/leaflet.toolbar-src.css +0 -117
- umap/static/umap/vendors/toolbar/leaflet.toolbar-src.js +0 -365
- umap/tests/integration/test_statics.py +0 -47
- {umap_project-2.5.1.dist-info → umap_project-2.6.0b0.dist-info}/WHEEL +0 -0
- {umap_project-2.5.1.dist-info → umap_project-2.6.0b0.dist-info}/entry_points.txt +0 -0
- {umap_project-2.5.1.dist-info → umap_project-2.6.0b0.dist-info}/licenses/LICENSE +0 -0
|
@@ -9,6 +9,8 @@ from playwright.sync_api import expect
|
|
|
9
9
|
|
|
10
10
|
from umap.models import DataLayer
|
|
11
11
|
|
|
12
|
+
from .helpers import save_and_get_json
|
|
13
|
+
|
|
12
14
|
pytestmark = pytest.mark.django_db
|
|
13
15
|
|
|
14
16
|
|
|
@@ -142,7 +144,8 @@ def test_import_kml_from_textarea(tilelayer, live_server, page):
|
|
|
142
144
|
expect(paths).to_have_count(2)
|
|
143
145
|
|
|
144
146
|
|
|
145
|
-
def test_import_gpx_from_textarea(tilelayer, live_server, page):
|
|
147
|
+
def test_import_gpx_from_textarea(tilelayer, live_server, page, settings):
|
|
148
|
+
settings.UMAP_ALLOW_ANONYMOUS = True
|
|
146
149
|
page.goto(f"{live_server.url}/map/new/")
|
|
147
150
|
page.get_by_title("Open browser").click()
|
|
148
151
|
layers = page.locator(".umap-browser .datalayer")
|
|
@@ -163,6 +166,42 @@ def test_import_gpx_from_textarea(tilelayer, live_server, page):
|
|
|
163
166
|
expect(layers).to_have_count(1)
|
|
164
167
|
expect(markers).to_have_count(1)
|
|
165
168
|
expect(paths).to_have_count(1)
|
|
169
|
+
data = save_and_get_json(page)
|
|
170
|
+
assert data["features"][0]["geometry"] == {
|
|
171
|
+
"coordinates": [
|
|
172
|
+
[
|
|
173
|
+
-121.7295456,
|
|
174
|
+
45.4431641,
|
|
175
|
+
],
|
|
176
|
+
[
|
|
177
|
+
-121.72908,
|
|
178
|
+
45.4428615,
|
|
179
|
+
],
|
|
180
|
+
[
|
|
181
|
+
-121.7279085,
|
|
182
|
+
45.4425697,
|
|
183
|
+
],
|
|
184
|
+
],
|
|
185
|
+
"type": "LineString",
|
|
186
|
+
}
|
|
187
|
+
assert data["features"][0]["properties"] == {
|
|
188
|
+
"description": "Simple description",
|
|
189
|
+
"desc": "Simple description",
|
|
190
|
+
"name": "Simple path",
|
|
191
|
+
}
|
|
192
|
+
assert data["features"][1]["geometry"] == {
|
|
193
|
+
"coordinates": [
|
|
194
|
+
-121.72904,
|
|
195
|
+
45.44283,
|
|
196
|
+
1374,
|
|
197
|
+
],
|
|
198
|
+
"type": "Point",
|
|
199
|
+
}
|
|
200
|
+
assert data["features"][1]["properties"] == {
|
|
201
|
+
"description": "Simple description",
|
|
202
|
+
"desc": "Simple description",
|
|
203
|
+
"name": "Simple Point",
|
|
204
|
+
}
|
|
166
205
|
|
|
167
206
|
|
|
168
207
|
def test_import_osm_from_textarea(tilelayer, live_server, page):
|
|
@@ -476,7 +515,7 @@ def test_create_remote_data(page, live_server, tilelayer):
|
|
|
476
515
|
page.route("*/**/ajax-proxy/**", handle)
|
|
477
516
|
page.goto(f"{live_server.url}/map/new/")
|
|
478
517
|
expect(page.locator(".leaflet-marker-icon")).to_be_hidden()
|
|
479
|
-
page.get_by_role("link", name="Import data
|
|
518
|
+
page.get_by_role("link", name="Import data").click()
|
|
480
519
|
page.get_by_placeholder("Provide an URL here").click()
|
|
481
520
|
page.get_by_placeholder("Provide an URL here").fill("https://remote.org/data.json")
|
|
482
521
|
page.locator("[name=format]").select_option("geojson")
|
|
@@ -513,7 +552,7 @@ def test_import_geojson_from_url(page, live_server, tilelayer):
|
|
|
513
552
|
page.route("https://remote.org/data.json", handle)
|
|
514
553
|
page.goto(f"{live_server.url}/map/new/")
|
|
515
554
|
expect(page.locator(".leaflet-marker-icon")).to_be_hidden()
|
|
516
|
-
page.get_by_role("link", name="Import data
|
|
555
|
+
page.get_by_role("link", name="Import data").click()
|
|
517
556
|
page.get_by_placeholder("Provide an URL here").click()
|
|
518
557
|
page.get_by_placeholder("Provide an URL here").fill("https://remote.org/data.json")
|
|
519
558
|
page.locator("[name=format]").select_option("geojson")
|
|
@@ -531,7 +570,7 @@ def test_overpass_import_with_bbox(page, live_server, tilelayer, settings):
|
|
|
531
570
|
"overpass": {"url": "https://my.overpass.io/interpreter"}
|
|
532
571
|
}
|
|
533
572
|
page.goto(f"{live_server.url}/map/new/")
|
|
534
|
-
page.get_by_role("link", name="Import data
|
|
573
|
+
page.get_by_role("link", name="Import data").click()
|
|
535
574
|
page.get_by_role("button", name="Overpass").click()
|
|
536
575
|
page.get_by_placeholder("amenity=drinking_water").fill("building")
|
|
537
576
|
page.get_by_role("button", name="Choose this data").click()
|
|
@@ -574,7 +613,7 @@ def test_import_from_datasets(page, live_server, tilelayer, settings):
|
|
|
574
613
|
page.route("https://remote.org/data.json", handle)
|
|
575
614
|
page.goto(f"{live_server.url}/map/new/")
|
|
576
615
|
expect(page.locator(".leaflet-marker-icon")).to_be_hidden()
|
|
577
|
-
page.get_by_role("link", name="Import data
|
|
616
|
+
page.get_by_role("link", name="Import data").click()
|
|
578
617
|
page.get_by_role("button", name="Datasets").click()
|
|
579
618
|
page.get_by_role("dialog").get_by_role("combobox").select_option(
|
|
580
619
|
"https://remote.org/data.json"
|
|
@@ -607,3 +646,23 @@ def test_import_osm_relation(tilelayer, live_server, page):
|
|
|
607
646
|
# A layer and one path has been created
|
|
608
647
|
expect(layers).to_have_count(1)
|
|
609
648
|
expect(paths).to_have_count(1)
|
|
649
|
+
|
|
650
|
+
|
|
651
|
+
def test_import_georss_from_textarea(tilelayer, live_server, page):
|
|
652
|
+
page.goto(f"{live_server.url}/map/new/")
|
|
653
|
+
page.get_by_title("Open browser").click()
|
|
654
|
+
layers = page.locator(".umap-browser .datalayer")
|
|
655
|
+
markers = page.locator(".leaflet-marker-icon")
|
|
656
|
+
expect(markers).to_have_count(0)
|
|
657
|
+
expect(layers).to_have_count(0)
|
|
658
|
+
button = page.get_by_title("Import data")
|
|
659
|
+
expect(button).to_be_visible()
|
|
660
|
+
button.click()
|
|
661
|
+
textarea = page.locator(".umap-upload textarea")
|
|
662
|
+
path = Path(__file__).parent.parent / "fixtures/test_upload_georss.xml"
|
|
663
|
+
textarea.fill(path.read_text())
|
|
664
|
+
page.locator('select[name="format"]').select_option("georss")
|
|
665
|
+
page.get_by_role("button", name="Import data", exact=True).click()
|
|
666
|
+
# A layer has been created
|
|
667
|
+
expect(layers).to_have_count(1)
|
|
668
|
+
expect(markers).to_have_count(1)
|
|
@@ -81,7 +81,7 @@ def test_owner_permissions_form(map, datalayer, live_server, login):
|
|
|
81
81
|
|
|
82
82
|
|
|
83
83
|
def test_map_update_with_editor(map, live_server, login, user):
|
|
84
|
-
map.edit_status = Map.
|
|
84
|
+
map.edit_status = Map.COLLABORATORS
|
|
85
85
|
map.editors.add(user)
|
|
86
86
|
map.save()
|
|
87
87
|
page = login(user)
|
|
@@ -104,7 +104,7 @@ def test_map_update_with_editor(map, live_server, login, user):
|
|
|
104
104
|
|
|
105
105
|
|
|
106
106
|
def test_permissions_form_with_editor(map, datalayer, live_server, login, user):
|
|
107
|
-
map.edit_status = Map.
|
|
107
|
+
map.edit_status = Map.COLLABORATORS
|
|
108
108
|
map.editors.add(user)
|
|
109
109
|
map.save()
|
|
110
110
|
page = login(user)
|
|
@@ -134,22 +134,14 @@ def test_owner_has_delete_map_button(map, live_server, login):
|
|
|
134
134
|
advanced.click()
|
|
135
135
|
delete = page.get_by_role("button", name="Delete", exact=True)
|
|
136
136
|
expect(delete).to_be_visible()
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
def handle_dialog(dialog):
|
|
140
|
-
dialog.accept()
|
|
141
|
-
nonlocal dialog_shown
|
|
142
|
-
dialog_shown = True
|
|
143
|
-
|
|
144
|
-
page.on("dialog", handle_dialog)
|
|
137
|
+
delete.click()
|
|
145
138
|
with page.expect_navigation():
|
|
146
|
-
|
|
147
|
-
assert dialog_shown
|
|
139
|
+
page.get_by_role("button", name="OK").click()
|
|
148
140
|
assert Map.objects.all().count() == 0
|
|
149
141
|
|
|
150
142
|
|
|
151
143
|
def test_editor_do_not_have_delete_map_button(map, live_server, login, user):
|
|
152
|
-
map.edit_status = Map.
|
|
144
|
+
map.edit_status = Map.COLLABORATORS
|
|
153
145
|
map.editors.add(user)
|
|
154
146
|
map.save()
|
|
155
147
|
page = login(user)
|
|
@@ -249,3 +241,19 @@ def test_can_delete_datalayer(live_server, map, login, datalayer):
|
|
|
249
241
|
expect(markers).to_have_count(0)
|
|
250
242
|
# FIXME does not work, resolve to 1 element, even if this command is empty:
|
|
251
243
|
expect(layers).to_have_count(0)
|
|
244
|
+
|
|
245
|
+
|
|
246
|
+
def test_can_set_team(map, live_server, login, team):
|
|
247
|
+
map.owner.teams.add(team)
|
|
248
|
+
map.owner.save()
|
|
249
|
+
page = login(map.owner)
|
|
250
|
+
page.goto(f"{live_server.url}{map.get_absolute_url()}?edit")
|
|
251
|
+
edit_permissions = page.get_by_title("Update permissions and editors")
|
|
252
|
+
edit_permissions.click()
|
|
253
|
+
page.locator("select[name=team]").select_option(str(team.pk))
|
|
254
|
+
save = page.get_by_role("button", name="Save")
|
|
255
|
+
expect(save).to_be_visible()
|
|
256
|
+
with page.expect_response(re.compile(r".*/update/permissions/.*")):
|
|
257
|
+
save.click()
|
|
258
|
+
modified = Map.objects.get(pk=map.pk)
|
|
259
|
+
assert modified.team == team
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import re
|
|
2
|
+
|
|
3
|
+
import pytest
|
|
4
|
+
|
|
5
|
+
from umap.models import Team
|
|
6
|
+
|
|
7
|
+
pytestmark = pytest.mark.django_db
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
def test_can_add_user_to_team(live_server, map, user, team, login):
|
|
11
|
+
map.owner.teams.add(team)
|
|
12
|
+
map.owner.save()
|
|
13
|
+
assert Team.objects.count() == 1
|
|
14
|
+
page = login(map.owner)
|
|
15
|
+
with page.expect_navigation():
|
|
16
|
+
page.get_by_role("link", name="My teams").click()
|
|
17
|
+
with page.expect_navigation():
|
|
18
|
+
page.get_by_role("link", name="Edit").click()
|
|
19
|
+
page.get_by_placeholder("Add user").click()
|
|
20
|
+
with page.expect_response(re.compile(r".*/agnocomplete/.*")):
|
|
21
|
+
page.get_by_placeholder("Add user").press_sequentially("joe")
|
|
22
|
+
page.get_by_text("Joe").click()
|
|
23
|
+
page.get_by_role("button", name="Save").click()
|
|
24
|
+
assert Team.objects.count() == 1
|
|
25
|
+
modified = Team.objects.first()
|
|
26
|
+
assert user in modified.users.all()
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
def test_can_remove_user_from_team(live_server, map, user, user2, team, login):
|
|
30
|
+
map.owner.teams.add(team)
|
|
31
|
+
map.owner.save()
|
|
32
|
+
user.teams.add(team)
|
|
33
|
+
user.save()
|
|
34
|
+
user2.teams.add(team)
|
|
35
|
+
user2.save()
|
|
36
|
+
assert Team.objects.count() == 1
|
|
37
|
+
page = login(map.owner)
|
|
38
|
+
with page.expect_navigation():
|
|
39
|
+
page.get_by_role("link", name="My teams").click()
|
|
40
|
+
with page.expect_navigation():
|
|
41
|
+
page.get_by_role("link", name="Edit").click()
|
|
42
|
+
page.locator("li").filter(has_text="Averell").locator(".close").click()
|
|
43
|
+
page.get_by_role("button", name="Save").click()
|
|
44
|
+
assert Team.objects.count() == 1
|
|
45
|
+
modified = Team.objects.first()
|
|
46
|
+
assert user in modified.users.all()
|
|
47
|
+
assert user2 not in modified.users.all()
|
|
@@ -16,7 +16,7 @@ def tilelayers():
|
|
|
16
16
|
TileLayerFactory(
|
|
17
17
|
rank=1,
|
|
18
18
|
name="OpenStreetMap",
|
|
19
|
-
url_template="https://
|
|
19
|
+
url_template="https://tile.openstreetmap.org/{z}/{x}/{y}.png",
|
|
20
20
|
)
|
|
21
21
|
TileLayerFactory(
|
|
22
22
|
rank=2,
|
|
@@ -76,7 +76,7 @@ def test_map_should_display_first_tilelayer_by_default(
|
|
|
76
76
|
page.goto(f"{live_server.url}/map/new")
|
|
77
77
|
tiles = page.locator(".leaflet-tile-pane img")
|
|
78
78
|
expect(tiles.first).to_have_attribute(
|
|
79
|
-
"src", re.compile(r"https://
|
|
79
|
+
"src", re.compile(r"https://tile.openstreetmap.org/\d+/\d+/\d+.png")
|
|
80
80
|
)
|
|
81
81
|
|
|
82
82
|
|
|
@@ -122,3 +122,20 @@ def test_can_have_smart_text_in_attribution(tilelayer, map, live_server, page):
|
|
|
122
122
|
page.goto(f"{live_server.url}{map.get_absolute_url()}")
|
|
123
123
|
expect(page.get_by_text("© OpenStreetMap contributors")).to_be_visible()
|
|
124
124
|
expect(page.get_by_role("link", name="OpenStreetMap")).to_be_visible()
|
|
125
|
+
|
|
126
|
+
|
|
127
|
+
def test_map_should_display_a_more_button(map, live_server, tilelayers, page):
|
|
128
|
+
map.settings["properties"]["tilelayersControl"] = True
|
|
129
|
+
map.save()
|
|
130
|
+
page.goto(f"{live_server.url}{map.get_absolute_url()}")
|
|
131
|
+
page.locator(".leaflet-iconLayers").hover()
|
|
132
|
+
page.get_by_role("button", name="+").click()
|
|
133
|
+
panel = page.locator(".panel.left.on")
|
|
134
|
+
expect(panel).to_be_visible()
|
|
135
|
+
expect(panel.get_by_text("Forte")).to_be_visible()
|
|
136
|
+
panel.get_by_text("Forte").click()
|
|
137
|
+
tiles = page.locator(".leaflet-tile-pane img")
|
|
138
|
+
url_pattern = re.compile(
|
|
139
|
+
r"https://[abc]{1}.forte.tiles.quaidorsay.fr/fr/\d+/\d+/\d+.png"
|
|
140
|
+
)
|
|
141
|
+
expect(tiles.first).to_have_attribute("src", url_pattern)
|
|
@@ -19,7 +19,7 @@ DATALAYER_DATA = {
|
|
|
19
19
|
},
|
|
20
20
|
"geometry": {
|
|
21
21
|
"type": "Point",
|
|
22
|
-
"coordinates": [14.6889, 48.5529],
|
|
22
|
+
"coordinates": [14.6889, 48.5529, 241],
|
|
23
23
|
},
|
|
24
24
|
},
|
|
25
25
|
],
|
|
@@ -79,3 +79,30 @@ def test_should_open_popup_panel_on_click(live_server, map, page, bootstrap):
|
|
|
79
79
|
# Close popup
|
|
80
80
|
page.locator("#map").click()
|
|
81
81
|
expect(panel).to_be_hidden()
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
def test_extended_properties_in_popup(live_server, map, page, bootstrap):
|
|
85
|
+
map.settings["properties"]["popupContentTemplate"] = """
|
|
86
|
+
Rank: {rank}
|
|
87
|
+
Locale: {locale}
|
|
88
|
+
Lang: {lang}
|
|
89
|
+
Lat: {lat}
|
|
90
|
+
Lon: {lon}
|
|
91
|
+
Alt: {alt}
|
|
92
|
+
Zoom: {zoom}
|
|
93
|
+
Layer: {layer}
|
|
94
|
+
"""
|
|
95
|
+
map.save()
|
|
96
|
+
page.goto(f"{live_server.url}{map.get_absolute_url()}")
|
|
97
|
+
expect(page.locator(".umap-icon-active")).to_be_hidden()
|
|
98
|
+
page.locator(".leaflet-marker-icon").click()
|
|
99
|
+
expect(page.locator(".umap-icon-active")).to_be_visible()
|
|
100
|
+
expect(page.locator(".leaflet-popup-content-wrapper")).to_be_visible()
|
|
101
|
+
expect(page.get_by_text("Rank: 1")).to_be_visible()
|
|
102
|
+
expect(page.get_by_text("Locale: en")).to_be_visible()
|
|
103
|
+
expect(page.get_by_text("Lang: en")).to_be_visible()
|
|
104
|
+
expect(page.get_by_text("Lat: 48.5529")).to_be_visible()
|
|
105
|
+
expect(page.get_by_text("Lon: 14.6889")).to_be_visible()
|
|
106
|
+
expect(page.get_by_text("Alt: 241")).to_be_visible()
|
|
107
|
+
expect(page.get_by_text("Zoom: 7")).to_be_visible()
|
|
108
|
+
expect(page.get_by_text("Layer: test datalayer")).to_be_visible()
|
|
@@ -12,7 +12,7 @@ DATALAYER_UPDATE = re.compile(r".*/datalayer/update/.*")
|
|
|
12
12
|
|
|
13
13
|
@pytest.mark.xdist_group(name="websockets")
|
|
14
14
|
def test_websocket_connection_can_sync_markers(
|
|
15
|
-
|
|
15
|
+
new_page, live_server, websocket_server, tilelayer
|
|
16
16
|
):
|
|
17
17
|
map = MapFactory(name="sync", edit_status=Map.ANONYMOUS)
|
|
18
18
|
map.settings["properties"]["syncEnabled"] = True
|
|
@@ -20,9 +20,9 @@ def test_websocket_connection_can_sync_markers(
|
|
|
20
20
|
DataLayerFactory(map=map, data={})
|
|
21
21
|
|
|
22
22
|
# Create two tabs
|
|
23
|
-
peerA =
|
|
23
|
+
peerA = new_page("Page A")
|
|
24
24
|
peerA.goto(f"{live_server.url}{map.get_absolute_url()}?edit")
|
|
25
|
-
peerB =
|
|
25
|
+
peerB = new_page("Page B")
|
|
26
26
|
peerB.goto(f"{live_server.url}{map.get_absolute_url()}?edit")
|
|
27
27
|
|
|
28
28
|
a_marker_pane = peerA.locator(".leaflet-marker-pane > div")
|
|
@@ -60,12 +60,12 @@ def test_websocket_connection_can_sync_markers(
|
|
|
60
60
|
expect(b_marker_pane).to_have_count(2)
|
|
61
61
|
|
|
62
62
|
# Drag a marker on peer B and check that it moved on peer A
|
|
63
|
-
a_first_marker.bounding_box() == b_first_marker.bounding_box()
|
|
63
|
+
assert a_first_marker.bounding_box() == b_first_marker.bounding_box()
|
|
64
64
|
b_old_bbox = b_first_marker.bounding_box()
|
|
65
65
|
b_first_marker.drag_to(b_map_el, target_position={"x": 250, "y": 250})
|
|
66
66
|
|
|
67
67
|
assert b_old_bbox is not b_first_marker.bounding_box()
|
|
68
|
-
a_first_marker.bounding_box() == b_first_marker.bounding_box()
|
|
68
|
+
assert a_first_marker.bounding_box() == b_first_marker.bounding_box()
|
|
69
69
|
|
|
70
70
|
# Delete a marker from peer A and check it's been deleted on peer B
|
|
71
71
|
a_first_marker.click(button="right")
|
umap/tests/test_datalayer.py
CHANGED
|
@@ -101,22 +101,33 @@ def test_should_remove_old_versions_on_save(map, settings):
|
|
|
101
101
|
|
|
102
102
|
|
|
103
103
|
def test_anonymous_cannot_edit_in_editors_mode(datalayer):
|
|
104
|
-
datalayer.edit_status = DataLayer.
|
|
104
|
+
datalayer.edit_status = DataLayer.COLLABORATORS
|
|
105
105
|
datalayer.save()
|
|
106
106
|
assert not datalayer.can_edit()
|
|
107
107
|
|
|
108
108
|
|
|
109
109
|
def test_owner_can_edit_in_editors_mode(datalayer, user):
|
|
110
|
-
datalayer.edit_status = DataLayer.
|
|
110
|
+
datalayer.edit_status = DataLayer.COLLABORATORS
|
|
111
111
|
datalayer.save()
|
|
112
112
|
assert datalayer.can_edit(datalayer.map.owner)
|
|
113
113
|
|
|
114
114
|
|
|
115
|
-
def
|
|
115
|
+
def test_editor_can_edit_in_collaborators_mode(datalayer, user):
|
|
116
116
|
map = datalayer.map
|
|
117
117
|
map.editors.add(user)
|
|
118
118
|
map.save()
|
|
119
|
-
datalayer.edit_status = DataLayer.
|
|
119
|
+
datalayer.edit_status = DataLayer.COLLABORATORS
|
|
120
|
+
datalayer.save()
|
|
121
|
+
assert datalayer.can_edit(user)
|
|
122
|
+
|
|
123
|
+
|
|
124
|
+
def test_team_members_can_edit_in_collaborators_mode(datalayer, user, team):
|
|
125
|
+
user.teams.add(team)
|
|
126
|
+
user.save()
|
|
127
|
+
map = datalayer.map
|
|
128
|
+
map.team = team
|
|
129
|
+
map.save()
|
|
130
|
+
datalayer.edit_status = DataLayer.COLLABORATORS
|
|
120
131
|
datalayer.save()
|
|
121
132
|
assert datalayer.can_edit(user)
|
|
122
133
|
|
|
@@ -170,6 +181,20 @@ def test_editors_cannot_edit_in_inherit_mode_and_map_in_owner_mode(datalayer, us
|
|
|
170
181
|
assert not datalayer.can_edit(user)
|
|
171
182
|
|
|
172
183
|
|
|
184
|
+
def test_team_members_cannot_edit_in_inherit_mode_and_map_in_owner_mode(
|
|
185
|
+
datalayer, user, team
|
|
186
|
+
):
|
|
187
|
+
datalayer.edit_status = DataLayer.INHERIT
|
|
188
|
+
datalayer.save()
|
|
189
|
+
user.teams.add(team)
|
|
190
|
+
team.save()
|
|
191
|
+
map = datalayer.map
|
|
192
|
+
map.team = team
|
|
193
|
+
map.edit_status = Map.OWNER
|
|
194
|
+
map.save()
|
|
195
|
+
assert not datalayer.can_edit(user)
|
|
196
|
+
|
|
197
|
+
|
|
173
198
|
def test_anonymous_cannot_edit_in_inherit_mode_and_map_in_owner_mode(datalayer):
|
|
174
199
|
datalayer.edit_status = DataLayer.INHERIT
|
|
175
200
|
datalayer.save()
|
|
@@ -183,7 +208,7 @@ def test_owner_can_edit_in_inherit_mode_and_map_in_editors_mode(datalayer):
|
|
|
183
208
|
datalayer.edit_status = DataLayer.INHERIT
|
|
184
209
|
datalayer.save()
|
|
185
210
|
map = datalayer.map
|
|
186
|
-
map.edit_status = Map.
|
|
211
|
+
map.edit_status = Map.COLLABORATORS
|
|
187
212
|
map.save()
|
|
188
213
|
assert datalayer.can_edit(map.owner)
|
|
189
214
|
|
|
@@ -193,7 +218,7 @@ def test_editors_can_edit_in_inherit_mode_and_map_in_editors_mode(datalayer, use
|
|
|
193
218
|
datalayer.save()
|
|
194
219
|
map = datalayer.map
|
|
195
220
|
map.editors.add(user)
|
|
196
|
-
map.edit_status = Map.
|
|
221
|
+
map.edit_status = Map.COLLABORATORS
|
|
197
222
|
map.save()
|
|
198
223
|
assert datalayer.can_edit(user)
|
|
199
224
|
|
|
@@ -202,7 +227,7 @@ def test_anonymous_cannot_edit_in_inherit_mode_and_map_in_editors_mode(datalayer
|
|
|
202
227
|
datalayer.edit_status = DataLayer.INHERIT
|
|
203
228
|
datalayer.save()
|
|
204
229
|
map = datalayer.map
|
|
205
|
-
map.edit_status = Map.
|
|
230
|
+
map.edit_status = Map.COLLABORATORS
|
|
206
231
|
map.save()
|
|
207
232
|
assert not datalayer.can_edit()
|
|
208
233
|
|
|
@@ -379,7 +379,7 @@ def test_owner_can_edit_in_owner_mode(datalayer, client, map, post_data):
|
|
|
379
379
|
|
|
380
380
|
def test_editor_can_edit_in_editors_mode(datalayer, client, map, post_data):
|
|
381
381
|
client.login(username=map.owner.username, password="123123")
|
|
382
|
-
datalayer.edit_status = DataLayer.
|
|
382
|
+
datalayer.edit_status = DataLayer.COLLABORATORS
|
|
383
383
|
datalayer.save()
|
|
384
384
|
url = reverse("datalayer_update", args=(map.pk, datalayer.pk))
|
|
385
385
|
name = "new name"
|
umap/tests/test_map.py
CHANGED
|
@@ -43,13 +43,31 @@ def test_editors_cannot_edit_if_status_owner(map, user):
|
|
|
43
43
|
assert not map.can_edit(user)
|
|
44
44
|
|
|
45
45
|
|
|
46
|
-
def
|
|
47
|
-
map.edit_status = map.
|
|
46
|
+
def test_editors_can_edit_if_status_collaborators(map, user):
|
|
47
|
+
map.edit_status = map.COLLABORATORS
|
|
48
48
|
map.editors.add(user)
|
|
49
49
|
map.save()
|
|
50
50
|
assert map.can_edit(user)
|
|
51
51
|
|
|
52
52
|
|
|
53
|
+
def test_team_members_cannot_edit_if_status_owner(map, user, team):
|
|
54
|
+
user.teams.add(team)
|
|
55
|
+
user.save()
|
|
56
|
+
map.edit_status = map.OWNER
|
|
57
|
+
map.team = team
|
|
58
|
+
map.save()
|
|
59
|
+
assert not map.can_edit(user)
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
def test_team_members_can_edit_if_status_collaborators(map, user, team):
|
|
63
|
+
user.teams.add(team)
|
|
64
|
+
user.save()
|
|
65
|
+
map.edit_status = map.COLLABORATORS
|
|
66
|
+
map.team = team
|
|
67
|
+
map.save()
|
|
68
|
+
assert map.can_edit(user)
|
|
69
|
+
|
|
70
|
+
|
|
53
71
|
def test_logged_in_user_should_be_allowed_for_anonymous_map_with_anonymous_edit_status(
|
|
54
72
|
map, user, rf
|
|
55
73
|
): # noqa
|
|
@@ -87,6 +105,14 @@ def test_clone_should_keep_editors(map, user):
|
|
|
87
105
|
assert user in clone.editors.all()
|
|
88
106
|
|
|
89
107
|
|
|
108
|
+
def test_clone_should_keep_team(map, user, team):
|
|
109
|
+
map.team = team
|
|
110
|
+
map.save()
|
|
111
|
+
clone = map.clone()
|
|
112
|
+
assert map.pk != clone.pk
|
|
113
|
+
assert clone.team == team
|
|
114
|
+
|
|
115
|
+
|
|
90
116
|
def test_clone_should_update_owner_if_passed(map, user):
|
|
91
117
|
clone = map.clone(owner=user)
|
|
92
118
|
assert map.pk != clone.pk
|
|
@@ -119,9 +145,9 @@ def test_publicmanager_should_get_only_public_maps(map, user, licence):
|
|
|
119
145
|
def test_can_change_default_edit_status(user, settings):
|
|
120
146
|
map = MapFactory(owner=user)
|
|
121
147
|
assert map.edit_status == Map.OWNER
|
|
122
|
-
settings.UMAP_DEFAULT_EDIT_STATUS = Map.
|
|
148
|
+
settings.UMAP_DEFAULT_EDIT_STATUS = Map.COLLABORATORS
|
|
123
149
|
map = MapFactory(owner=user)
|
|
124
|
-
assert map.edit_status == Map.
|
|
150
|
+
assert map.edit_status == Map.COLLABORATORS
|
|
125
151
|
|
|
126
152
|
|
|
127
153
|
def test_can_change_default_share_status(user, settings):
|
umap/tests/test_map_views.py
CHANGED
|
@@ -210,7 +210,7 @@ def test_user_not_allowed_should_not_clone_map(client, map, user, settings):
|
|
|
210
210
|
|
|
211
211
|
def test_clone_should_set_cloner_as_owner(client, map, user):
|
|
212
212
|
url = reverse("map_clone", kwargs={"map_id": map.pk})
|
|
213
|
-
map.edit_status = map.
|
|
213
|
+
map.edit_status = map.COLLABORATORS
|
|
214
214
|
map.editors.add(user)
|
|
215
215
|
map.save()
|
|
216
216
|
client.login(username=user.username, password="123123")
|
|
@@ -330,7 +330,7 @@ def test_only_owner_can_delete(client, map, user):
|
|
|
330
330
|
|
|
331
331
|
def test_map_editors_do_not_see_owner_change_input(client, map, user):
|
|
332
332
|
map.editors.add(user)
|
|
333
|
-
map.edit_status = map.
|
|
333
|
+
map.edit_status = map.COLLABORATORS
|
|
334
334
|
map.save()
|
|
335
335
|
url = reverse("map_update_permissions", kwargs={"map_id": map.pk})
|
|
336
336
|
client.login(username=user.username, password="123123")
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import json
|
|
2
|
+
import shutil
|
|
3
|
+
import tempfile
|
|
4
|
+
from copy import deepcopy
|
|
5
|
+
from pathlib import Path
|
|
6
|
+
|
|
7
|
+
import pytest
|
|
8
|
+
from django.core.management import call_command
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
@pytest.fixture
|
|
12
|
+
def staticfiles(settings):
|
|
13
|
+
static_root = tempfile.mkdtemp(prefix="test_static")
|
|
14
|
+
settings.STATIC_ROOT = static_root
|
|
15
|
+
# Make sure settings are properly reset after the test
|
|
16
|
+
settings.STORAGES = deepcopy(settings.STORAGES)
|
|
17
|
+
settings.STORAGES["staticfiles"]["BACKEND"] = (
|
|
18
|
+
"umap.storage.UmapManifestStaticFilesStorage"
|
|
19
|
+
)
|
|
20
|
+
try:
|
|
21
|
+
call_command("collectstatic", "--noinput")
|
|
22
|
+
yield
|
|
23
|
+
finally:
|
|
24
|
+
shutil.rmtree(static_root)
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
def test_collectstatic_ran_successfully_with_hashes(settings, staticfiles):
|
|
28
|
+
static_root = settings.STATIC_ROOT
|
|
29
|
+
manifest = Path(static_root) / "staticfiles.json"
|
|
30
|
+
assert manifest.exists()
|
|
31
|
+
json_manifest = json.loads(manifest.read_text())
|
|
32
|
+
assert "hash" in json_manifest.keys()
|
|
33
|
+
assert "umap/base.css" in json_manifest["paths"]
|
|
34
|
+
# Hash + the dot ("umap/base.<hash>.css").
|
|
35
|
+
md5_hash_lenght = 12 + 1
|
|
36
|
+
# The value of the manifest must contain the hash (length).
|
|
37
|
+
assert (
|
|
38
|
+
len(json_manifest["paths"]["umap/base.css"])
|
|
39
|
+
== len("umap/base.css") + md5_hash_lenght
|
|
40
|
+
)
|