umap-project 1.14.0a5__py3-none-any.whl → 2.0.0a1__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/decorators.py +0 -14
- umap/locale/br/LC_MESSAGES/django.mo +0 -0
- umap/locale/br/LC_MESSAGES/django.po +137 -85
- umap/locale/cs_CZ/LC_MESSAGES/django.mo +0 -0
- umap/locale/cs_CZ/LC_MESSAGES/django.po +136 -84
- umap/locale/el/LC_MESSAGES/django.mo +0 -0
- umap/locale/el/LC_MESSAGES/django.po +136 -84
- umap/locale/en/LC_MESSAGES/django.po +128 -88
- umap/locale/es/LC_MESSAGES/django.mo +0 -0
- umap/locale/es/LC_MESSAGES/django.po +136 -84
- umap/locale/fr/LC_MESSAGES/django.mo +0 -0
- umap/locale/fr/LC_MESSAGES/django.po +131 -91
- umap/locale/hu/LC_MESSAGES/django.mo +0 -0
- umap/locale/hu/LC_MESSAGES/django.po +137 -85
- umap/locale/it/LC_MESSAGES/django.mo +0 -0
- umap/locale/it/LC_MESSAGES/django.po +136 -84
- umap/locale/ms/LC_MESSAGES/django.mo +0 -0
- umap/locale/ms/LC_MESSAGES/django.po +136 -84
- umap/locale/pl/LC_MESSAGES/django.mo +0 -0
- umap/locale/pl/LC_MESSAGES/django.po +136 -84
- umap/locale/sv/LC_MESSAGES/django.mo +0 -0
- umap/locale/sv/LC_MESSAGES/django.po +135 -83
- umap/locale/zh_TW/LC_MESSAGES/django.mo +0 -0
- umap/locale/zh_TW/LC_MESSAGES/django.po +143 -91
- umap/models.py +23 -1
- umap/settings/__init__.py +1 -4
- umap/settings/base.py +1 -0
- umap/static/umap/base.css +5 -0
- umap/static/umap/content.css +185 -13
- umap/static/umap/favicons/icon.svg +2 -2
- umap/static/umap/img/edit.svg +3 -3
- umap/static/umap/img/icon-delete.svg +4 -0
- umap/static/umap/img/icon-download.svg +13 -0
- umap/static/umap/img/icon-duplicate.svg +5 -0
- umap/static/umap/img/icon-edit.svg +12 -0
- umap/static/umap/img/icon-share.svg +11 -0
- umap/static/umap/img/icon-view.svg +12 -0
- umap/static/umap/img/logo.svg +2 -2
- umap/static/umap/img/logo_small.svg +2 -2
- umap/static/umap/img/marker.svg +4 -0
- umap/static/umap/img/opensource.svg +2 -2
- umap/static/umap/img/osm.svg +2 -2
- umap/static/umap/js/components/fragment.js +1 -1
- umap/static/umap/js/modules/browser.js +159 -0
- umap/static/umap/js/modules/global.js +3 -1
- umap/static/umap/js/modules/request.js +155 -0
- umap/static/umap/js/umap.autocomplete.js +28 -38
- umap/static/umap/js/umap.controls.js +73 -58
- umap/static/umap/js/umap.core.js +4 -9
- umap/static/umap/js/umap.datalayer.permissions.js +13 -12
- umap/static/umap/js/umap.features.js +51 -49
- umap/static/umap/js/umap.forms.js +19 -19
- umap/static/umap/js/umap.icon.js +17 -17
- umap/static/umap/js/umap.importer.js +2 -1
- umap/static/umap/js/umap.js +242 -291
- umap/static/umap/js/umap.layer.js +173 -141
- umap/static/umap/js/umap.permissions.js +24 -25
- umap/static/umap/js/umap.popup.js +14 -14
- umap/static/umap/js/umap.share.js +4 -4
- umap/static/umap/js/umap.slideshow.js +4 -4
- umap/static/umap/js/umap.tableeditor.js +2 -2
- umap/static/umap/js/umap.ui.js +1 -1
- umap/static/umap/locale/am_ET.js +1 -11
- umap/static/umap/locale/am_ET.json +1 -11
- umap/static/umap/locale/ar.js +1 -11
- umap/static/umap/locale/ar.json +1 -11
- umap/static/umap/locale/ast.js +1 -11
- umap/static/umap/locale/ast.json +1 -11
- umap/static/umap/locale/bg.js +1 -11
- umap/static/umap/locale/bg.json +1 -11
- umap/static/umap/locale/br.js +1 -11
- umap/static/umap/locale/br.json +1 -11
- umap/static/umap/locale/ca.js +1 -11
- umap/static/umap/locale/ca.json +1 -11
- umap/static/umap/locale/cs_CZ.js +1 -11
- umap/static/umap/locale/cs_CZ.json +1 -11
- umap/static/umap/locale/da.js +1 -11
- umap/static/umap/locale/da.json +1 -11
- umap/static/umap/locale/de.js +1 -11
- umap/static/umap/locale/de.json +1 -11
- umap/static/umap/locale/el.js +1 -11
- umap/static/umap/locale/el.json +1 -11
- umap/static/umap/locale/en.js +1 -11
- umap/static/umap/locale/en.json +1 -11
- umap/static/umap/locale/en_US.json +1 -11
- umap/static/umap/locale/es.js +1 -11
- umap/static/umap/locale/es.json +1 -11
- umap/static/umap/locale/et.js +1 -11
- umap/static/umap/locale/et.json +1 -11
- umap/static/umap/locale/fa_IR.js +6 -16
- umap/static/umap/locale/fa_IR.json +6 -16
- umap/static/umap/locale/fi.js +1 -11
- umap/static/umap/locale/fi.json +1 -11
- umap/static/umap/locale/fr.js +1 -11
- umap/static/umap/locale/fr.json +1 -11
- umap/static/umap/locale/gl.js +1 -11
- umap/static/umap/locale/gl.json +1 -11
- umap/static/umap/locale/he.js +1 -11
- umap/static/umap/locale/he.json +1 -11
- umap/static/umap/locale/hr.js +1 -11
- umap/static/umap/locale/hr.json +1 -11
- umap/static/umap/locale/hu.js +1 -11
- umap/static/umap/locale/hu.json +1 -11
- umap/static/umap/locale/id.js +1 -11
- umap/static/umap/locale/id.json +1 -11
- umap/static/umap/locale/is.js +1 -11
- umap/static/umap/locale/is.json +1 -11
- umap/static/umap/locale/it.js +1 -11
- umap/static/umap/locale/it.json +1 -11
- umap/static/umap/locale/ja.js +1 -11
- umap/static/umap/locale/ja.json +1 -11
- umap/static/umap/locale/ko.js +1 -11
- umap/static/umap/locale/ko.json +1 -11
- umap/static/umap/locale/lt.js +1 -11
- umap/static/umap/locale/lt.json +1 -11
- umap/static/umap/locale/ms.js +1 -11
- umap/static/umap/locale/ms.json +1 -11
- umap/static/umap/locale/nl.js +1 -11
- umap/static/umap/locale/nl.json +1 -11
- umap/static/umap/locale/no.js +1 -11
- umap/static/umap/locale/no.json +1 -11
- umap/static/umap/locale/pl.js +1 -11
- umap/static/umap/locale/pl.json +1 -11
- umap/static/umap/locale/pl_PL.json +1 -11
- umap/static/umap/locale/pt.js +1 -11
- umap/static/umap/locale/pt.json +1 -11
- umap/static/umap/locale/pt_BR.js +1 -11
- umap/static/umap/locale/pt_BR.json +1 -11
- umap/static/umap/locale/pt_PT.js +1 -11
- umap/static/umap/locale/pt_PT.json +1 -11
- umap/static/umap/locale/ro.js +1 -11
- umap/static/umap/locale/ro.json +1 -11
- umap/static/umap/locale/ru.js +1 -11
- umap/static/umap/locale/ru.json +1 -11
- umap/static/umap/locale/sk_SK.js +1 -11
- umap/static/umap/locale/sk_SK.json +1 -11
- umap/static/umap/locale/sl.js +1 -11
- umap/static/umap/locale/sl.json +1 -11
- umap/static/umap/locale/sr.js +1 -11
- umap/static/umap/locale/sr.json +1 -11
- umap/static/umap/locale/sv.js +1 -11
- umap/static/umap/locale/sv.json +1 -11
- umap/static/umap/locale/th_TH.js +1 -11
- umap/static/umap/locale/th_TH.json +1 -11
- umap/static/umap/locale/tr.js +1 -11
- umap/static/umap/locale/tr.json +1 -11
- umap/static/umap/locale/uk_UA.js +1 -11
- umap/static/umap/locale/uk_UA.json +1 -11
- umap/static/umap/locale/vi.js +1 -11
- umap/static/umap/locale/vi.json +1 -11
- umap/static/umap/locale/vi_VN.json +1 -11
- umap/static/umap/locale/zh.js +1 -11
- umap/static/umap/locale/zh.json +1 -11
- umap/static/umap/locale/zh_CN.json +1 -11
- umap/static/umap/locale/zh_TW.Big5.json +1 -11
- umap/static/umap/locale/zh_TW.js +17 -27
- umap/static/umap/locale/zh_TW.json +17 -27
- umap/static/umap/map.css +2 -2
- umap/static/umap/nav.css +2 -1
- umap/static/umap/test/.eslintrc +0 -1
- umap/static/umap/test/Choropleth.js +29 -27
- umap/static/umap/test/DataLayer.js +207 -239
- umap/static/umap/test/Feature.js +33 -58
- umap/static/umap/test/Map.Export.js +11 -11
- umap/static/umap/test/Map.js +66 -67
- umap/static/umap/test/Marker.js +36 -32
- umap/static/umap/test/Polygon.js +95 -95
- umap/static/umap/test/Polyline.js +31 -31
- umap/static/umap/test/TableEditor.js +29 -25
- umap/static/umap/test/_pre.js +2 -7
- umap/static/umap/test/index.html +4 -4
- umap/storage.py +2 -0
- umap/templates/auth/user_form.html +3 -2
- umap/templates/base.html +1 -0
- umap/templates/registration/login.html +51 -36
- umap/templates/umap/about_summary.html +1 -1
- umap/templates/umap/branding.html +3 -0
- umap/templates/umap/content.html +15 -39
- umap/templates/umap/header.html +0 -0
- umap/templates/umap/home.html +4 -2
- umap/templates/umap/js.html +0 -2
- umap/templates/umap/map_detail.html +9 -0
- umap/templates/umap/map_init.html +1 -1
- umap/templates/umap/map_messages.html +4 -2
- umap/templates/umap/map_table.html +130 -69
- umap/templates/umap/navigation.html +2 -4
- umap/templates/umap/user_dashboard.html +29 -6
- umap/tests/base.py +1 -1
- umap/tests/integration/conftest.py +18 -0
- umap/tests/integration/test_anonymous_owned_map.py +6 -3
- umap/tests/integration/test_browser.py +166 -6
- umap/tests/integration/test_collaborative_editing.py +23 -5
- umap/tests/integration/test_dashboard.py +17 -0
- umap/tests/integration/test_edit_datalayer.py +4 -3
- umap/tests/integration/test_export_map.py +1 -1
- umap/tests/integration/test_import.py +9 -4
- umap/tests/integration/test_map.py +64 -0
- umap/tests/integration/test_map_preview.py +75 -0
- umap/tests/integration/test_owned_map.py +11 -25
- umap/tests/integration/test_picto.py +3 -3
- umap/tests/integration/test_querystring.py +52 -0
- umap/tests/integration/test_share.py +22 -0
- umap/tests/test_map_views.py +157 -14
- umap/tests/test_views.py +50 -11
- umap/urls.py +6 -12
- umap/views.py +170 -47
- {umap_project-1.14.0a5.dist-info → umap_project-2.0.0a1.dist-info}/METADATA +13 -15
- {umap_project-1.14.0a5.dist-info → umap_project-2.0.0a1.dist-info}/RECORD +212 -200
- umap/static/umap/js/umap.browser.js +0 -148
- umap/static/umap/js/umap.xhr.js +0 -304
- umap/static/umap/test/Controls.js +0 -100
- umap/static/umap/test/Map.Init.js +0 -46
- {umap_project-1.14.0a5.dist-info → umap_project-2.0.0a1.dist-info}/WHEEL +0 -0
- {umap_project-1.14.0a5.dist-info → umap_project-2.0.0a1.dist-info}/entry_points.txt +0 -0
- {umap_project-1.14.0a5.dist-info → umap_project-2.0.0a1.dist-info}/licenses/LICENSE +0 -0
umap/tests/test_map_views.py
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import json
|
|
2
|
+
import zipfile
|
|
3
|
+
from io import BytesIO
|
|
2
4
|
|
|
3
5
|
import pytest
|
|
4
6
|
from django.contrib.auth import get_user_model
|
|
@@ -8,7 +10,7 @@ from django.urls import reverse
|
|
|
8
10
|
|
|
9
11
|
from umap.models import DataLayer, Map, Star
|
|
10
12
|
|
|
11
|
-
from .base import login_required
|
|
13
|
+
from .base import MapFactory, UserFactory, login_required
|
|
12
14
|
|
|
13
15
|
pytestmark = pytest.mark.django_db
|
|
14
16
|
User = get_user_model()
|
|
@@ -19,7 +21,7 @@ def post_data():
|
|
|
19
21
|
return {
|
|
20
22
|
"name": "name",
|
|
21
23
|
"center": '{"type":"Point","coordinates":[13.447265624999998,48.94415123418794]}', # noqa
|
|
22
|
-
"settings": '{"type":"Feature","geometry":{"type":"Point","coordinates":[5.0592041015625,52.05924589011585]},"properties":{"tilelayer":{"maxZoom":20,"url_template":"http://
|
|
24
|
+
"settings": '{"type":"Feature","geometry":{"type":"Point","coordinates":[5.0592041015625,52.05924589011585]},"properties":{"tilelayer":{"maxZoom":20,"url_template":"http://a.tile.openstreetmap.fr/hot/{z}/{x}/{y}.png","minZoom":0,"attribution":"HOT and friends"},"licence":"","description":"","name":"test enrhûmé","tilelayersControl":true,"displayDataBrowserOnLoad":false,"displayPopupFooter":true,"displayCaptionOnLoad":false,"miniMap":true,"moreControl":true,"scaleControl":true,"zoomControl":true,"datalayersControl":true,"zoom":8}}', # noqa
|
|
23
25
|
}
|
|
24
26
|
|
|
25
27
|
|
|
@@ -107,7 +109,9 @@ def test_update(client, map, post_data):
|
|
|
107
109
|
def test_delete(client, map, datalayer):
|
|
108
110
|
url = reverse("map_delete", args=(map.pk,))
|
|
109
111
|
client.login(username=map.owner.username, password="123123")
|
|
110
|
-
response = client.post(
|
|
112
|
+
response = client.post(
|
|
113
|
+
url, headers={"X-Requested-With": "XMLHttpRequest"}, follow=True
|
|
114
|
+
)
|
|
111
115
|
assert response.status_code == 200
|
|
112
116
|
assert not Map.objects.filter(pk=map.pk).exists()
|
|
113
117
|
assert not DataLayer.objects.filter(pk=datalayer.pk).exists()
|
|
@@ -156,9 +160,23 @@ def test_clone_map_should_create_a_new_instance(client, map):
|
|
|
156
160
|
url = reverse("map_clone", kwargs={"map_id": map.pk})
|
|
157
161
|
client.login(username=map.owner.username, password="123123")
|
|
158
162
|
response = client.post(url)
|
|
163
|
+
assert response.status_code == 302
|
|
164
|
+
assert Map.objects.count() == 2
|
|
165
|
+
clone = Map.objects.latest("pk")
|
|
166
|
+
assert response["Location"] == clone.get_absolute_url()
|
|
167
|
+
assert clone.pk != map.pk
|
|
168
|
+
assert clone.name == "Clone of " + map.name
|
|
169
|
+
|
|
170
|
+
|
|
171
|
+
def test_clone_map_should_be_possible_via_ajax(client, map):
|
|
172
|
+
assert Map.objects.count() == 1
|
|
173
|
+
url = reverse("map_clone", kwargs={"map_id": map.pk})
|
|
174
|
+
client.login(username=map.owner.username, password="123123")
|
|
175
|
+
response = client.post(url, headers={"X-Requested-With": "XMLHttpRequest"})
|
|
159
176
|
assert response.status_code == 200
|
|
160
177
|
assert Map.objects.count() == 2
|
|
161
178
|
clone = Map.objects.latest("pk")
|
|
179
|
+
assert response.json() == {"redirect": clone.get_absolute_url()}
|
|
162
180
|
assert clone.pk != map.pk
|
|
163
181
|
assert clone.name == "Clone of " + map.name
|
|
164
182
|
|
|
@@ -189,7 +207,7 @@ def test_clone_should_set_cloner_as_owner(client, map, user):
|
|
|
189
207
|
map.save()
|
|
190
208
|
client.login(username=user.username, password="123123")
|
|
191
209
|
response = client.post(url)
|
|
192
|
-
assert response.status_code ==
|
|
210
|
+
assert response.status_code == 302
|
|
193
211
|
assert Map.objects.count() == 2
|
|
194
212
|
clone = Map.objects.latest("pk")
|
|
195
213
|
assert clone.pk != map.pk
|
|
@@ -275,7 +293,7 @@ def test_owner_cannot_access_map_with_share_status_blocked(client, map):
|
|
|
275
293
|
assert response.status_code == 403
|
|
276
294
|
|
|
277
295
|
|
|
278
|
-
def test_non_editor_cannot_access_map_if_share_status_private(client, map, user):
|
|
296
|
+
def test_non_editor_cannot_access_map_if_share_status_private(client, map, user):
|
|
279
297
|
url = reverse("map", args=(map.slug, map.pk))
|
|
280
298
|
map.share_status = map.PRIVATE
|
|
281
299
|
map.save()
|
|
@@ -296,7 +314,9 @@ def test_only_owner_can_delete(client, map, user):
|
|
|
296
314
|
map.editors.add(user)
|
|
297
315
|
url = reverse("map_delete", kwargs={"map_id": map.pk})
|
|
298
316
|
client.login(username=user.username, password="123123")
|
|
299
|
-
response = client.post(
|
|
317
|
+
response = client.post(
|
|
318
|
+
url, headers={"X-Requested-With": "XMLHttpRequest"}, follow=True
|
|
319
|
+
)
|
|
300
320
|
assert response.status_code == 403
|
|
301
321
|
|
|
302
322
|
|
|
@@ -346,14 +366,14 @@ def test_anonymous_create(cookieclient, post_data):
|
|
|
346
366
|
|
|
347
367
|
|
|
348
368
|
@pytest.mark.usefixtures("allow_anonymous")
|
|
349
|
-
def test_anonymous_update_without_cookie_fails(client, anonymap, post_data):
|
|
369
|
+
def test_anonymous_update_without_cookie_fails(client, anonymap, post_data):
|
|
350
370
|
url = reverse("map_update", kwargs={"map_id": anonymap.pk})
|
|
351
371
|
response = client.post(url, post_data)
|
|
352
372
|
assert response.status_code == 403
|
|
353
373
|
|
|
354
374
|
|
|
355
375
|
@pytest.mark.usefixtures("allow_anonymous")
|
|
356
|
-
def test_anonymous_update_with_cookie_should_work(cookieclient, anonymap, post_data):
|
|
376
|
+
def test_anonymous_update_with_cookie_should_work(cookieclient, anonymap, post_data):
|
|
357
377
|
url = reverse("map_update", kwargs={"map_id": anonymap.pk})
|
|
358
378
|
# POST only mendatory fields
|
|
359
379
|
name = "new map name"
|
|
@@ -368,7 +388,9 @@ def test_anonymous_update_with_cookie_should_work(cookieclient, anonymap, post_d
|
|
|
368
388
|
@pytest.mark.usefixtures("allow_anonymous")
|
|
369
389
|
def test_anonymous_delete(cookieclient, anonymap):
|
|
370
390
|
url = reverse("map_delete", args=(anonymap.pk,))
|
|
371
|
-
response = cookieclient.post(
|
|
391
|
+
response = cookieclient.post(
|
|
392
|
+
url, headers={"X-Requested-With": "XMLHttpRequest"}, follow=True
|
|
393
|
+
)
|
|
372
394
|
assert response.status_code == 200
|
|
373
395
|
assert not Map.objects.filter(pk=anonymap.pk).count()
|
|
374
396
|
# Test response is a json
|
|
@@ -379,7 +401,9 @@ def test_anonymous_delete(cookieclient, anonymap):
|
|
|
379
401
|
@pytest.mark.usefixtures("allow_anonymous")
|
|
380
402
|
def test_no_cookie_cant_delete(client, anonymap):
|
|
381
403
|
url = reverse("map_delete", args=(anonymap.pk,))
|
|
382
|
-
response = client.post(
|
|
404
|
+
response = client.post(
|
|
405
|
+
url, headers={"X-Requested-With": "XMLHttpRequest"}, follow=True
|
|
406
|
+
)
|
|
383
407
|
assert response.status_code == 403
|
|
384
408
|
|
|
385
409
|
|
|
@@ -420,7 +444,7 @@ def test_bad_anonymous_edit_url_should_return_403(cookieclient, anonymap):
|
|
|
420
444
|
@pytest.mark.usefixtures("allow_anonymous")
|
|
421
445
|
def test_clone_anonymous_map_should_not_be_possible_if_user_is_not_allowed(
|
|
422
446
|
client, anonymap, user
|
|
423
|
-
):
|
|
447
|
+
):
|
|
424
448
|
assert Map.objects.count() == 1
|
|
425
449
|
url = reverse("map_clone", kwargs={"map_id": anonymap.pk})
|
|
426
450
|
anonymap.edit_status = anonymap.OWNER
|
|
@@ -434,15 +458,16 @@ def test_clone_anonymous_map_should_not_be_possible_if_user_is_not_allowed(
|
|
|
434
458
|
|
|
435
459
|
|
|
436
460
|
@pytest.mark.usefixtures("allow_anonymous")
|
|
437
|
-
def test_clone_map_should_be_possible_if_edit_status_is_anonymous(client, anonymap):
|
|
461
|
+
def test_clone_map_should_be_possible_if_edit_status_is_anonymous(client, anonymap):
|
|
438
462
|
assert Map.objects.count() == 1
|
|
439
463
|
url = reverse("map_clone", kwargs={"map_id": anonymap.pk})
|
|
440
464
|
anonymap.edit_status = anonymap.ANONYMOUS
|
|
441
465
|
anonymap.save()
|
|
442
466
|
response = client.post(url)
|
|
443
|
-
assert response.status_code ==
|
|
467
|
+
assert response.status_code == 302
|
|
444
468
|
assert Map.objects.count() == 2
|
|
445
469
|
clone = Map.objects.latest("pk")
|
|
470
|
+
assert response["Location"] == clone.get_absolute_url()
|
|
446
471
|
assert clone.pk != anonymap.pk
|
|
447
472
|
assert clone.name == "Clone of " + anonymap.name
|
|
448
473
|
assert clone.owner is None
|
|
@@ -624,7 +649,7 @@ def test_download(client, map, datalayer):
|
|
|
624
649
|
"attribution": "© OSM Contributors",
|
|
625
650
|
"maxZoom": 18,
|
|
626
651
|
"minZoom": 0,
|
|
627
|
-
"url_template": "https://
|
|
652
|
+
"url_template": "https://a.tile.openstreetmap.fr/osmfr/{z}/{x}/{y}.png",
|
|
628
653
|
},
|
|
629
654
|
"tilelayersControl": True,
|
|
630
655
|
"zoom": 7,
|
|
@@ -656,6 +681,64 @@ def test_download(client, map, datalayer):
|
|
|
656
681
|
]
|
|
657
682
|
|
|
658
683
|
|
|
684
|
+
def test_download_multiple_maps(client, map, datalayer):
|
|
685
|
+
map.share_status = Map.PRIVATE
|
|
686
|
+
map.save()
|
|
687
|
+
another_map = MapFactory(
|
|
688
|
+
owner=map.owner, name="Another map", share_status=Map.PUBLIC
|
|
689
|
+
)
|
|
690
|
+
client.login(username=map.owner.username, password="123123")
|
|
691
|
+
url = reverse("user_download")
|
|
692
|
+
response = client.get(f"{url}?map_id={map.id}&map_id={another_map.id}")
|
|
693
|
+
assert response.status_code == 200
|
|
694
|
+
with zipfile.ZipFile(file=BytesIO(response.content), mode="r") as f:
|
|
695
|
+
assert len(f.infolist()) == 2
|
|
696
|
+
assert f.infolist()[0].filename == f"umap_backup_test-map_{another_map.id}.umap"
|
|
697
|
+
assert f.infolist()[1].filename == f"umap_backup_test-map_{map.id}.umap"
|
|
698
|
+
with f.open(f.infolist()[1]) as umap_file:
|
|
699
|
+
umapjson = json.loads(umap_file.read().decode())
|
|
700
|
+
assert list(umapjson.keys()) == [
|
|
701
|
+
"type",
|
|
702
|
+
"geometry",
|
|
703
|
+
"properties",
|
|
704
|
+
"uri",
|
|
705
|
+
"layers",
|
|
706
|
+
]
|
|
707
|
+
assert umapjson["type"] == "umap"
|
|
708
|
+
assert umapjson["uri"] == f"http://testserver/en/map/test-map_{map.id}"
|
|
709
|
+
|
|
710
|
+
|
|
711
|
+
def test_download_multiple_maps_unauthorized(client, map, datalayer):
|
|
712
|
+
map.share_status = Map.PRIVATE
|
|
713
|
+
map.save()
|
|
714
|
+
user1 = UserFactory(username="user1")
|
|
715
|
+
another_map = MapFactory(owner=user1, name="Another map", share_status=Map.PUBLIC)
|
|
716
|
+
client.login(username=map.owner.username, password="123123")
|
|
717
|
+
url = reverse("user_download")
|
|
718
|
+
response = client.get(f"{url}?map_id={map.id}&map_id={another_map.id}")
|
|
719
|
+
assert response.status_code == 200
|
|
720
|
+
with zipfile.ZipFile(file=BytesIO(response.content), mode="r") as f:
|
|
721
|
+
assert len(f.infolist()) == 1
|
|
722
|
+
assert f.infolist()[0].filename == f"umap_backup_test-map_{map.id}.umap"
|
|
723
|
+
|
|
724
|
+
|
|
725
|
+
def test_download_multiple_maps_editor(client, map, datalayer):
|
|
726
|
+
map.share_status = Map.PRIVATE
|
|
727
|
+
map.save()
|
|
728
|
+
user1 = UserFactory(username="user1")
|
|
729
|
+
another_map = MapFactory(owner=user1, name="Another map", share_status=Map.PUBLIC)
|
|
730
|
+
another_map.editors.add(map.owner)
|
|
731
|
+
another_map.save()
|
|
732
|
+
client.login(username=map.owner.username, password="123123")
|
|
733
|
+
url = reverse("user_download")
|
|
734
|
+
response = client.get(f"{url}?map_id={map.id}&map_id={another_map.id}")
|
|
735
|
+
assert response.status_code == 200
|
|
736
|
+
with zipfile.ZipFile(file=BytesIO(response.content), mode="r") as f:
|
|
737
|
+
assert len(f.infolist()) == 2
|
|
738
|
+
assert f.infolist()[0].filename == f"umap_backup_test-map_{another_map.id}.umap"
|
|
739
|
+
assert f.infolist()[1].filename == f"umap_backup_test-map_{map.id}.umap"
|
|
740
|
+
|
|
741
|
+
|
|
659
742
|
@pytest.mark.parametrize("share_status", [Map.PRIVATE, Map.BLOCKED])
|
|
660
743
|
def test_download_shared_status_map(client, map, datalayer, share_status):
|
|
661
744
|
map.share_status = share_status
|
|
@@ -675,3 +758,63 @@ def test_download_my_map(client, map, datalayer):
|
|
|
675
758
|
# Test response is a json
|
|
676
759
|
j = json.loads(response.content.decode())
|
|
677
760
|
assert j["type"] == "umap"
|
|
761
|
+
|
|
762
|
+
|
|
763
|
+
@pytest.mark.parametrize("share_status", [Map.PRIVATE, Map.BLOCKED, Map.OPEN])
|
|
764
|
+
def test_oembed_shared_status_map(client, map, datalayer, share_status):
|
|
765
|
+
map.share_status = share_status
|
|
766
|
+
map.save()
|
|
767
|
+
url = f"{reverse('map_oembed')}?url=http://testserver{map.get_absolute_url()}"
|
|
768
|
+
response = client.get(url)
|
|
769
|
+
assert response.status_code == 403
|
|
770
|
+
|
|
771
|
+
|
|
772
|
+
def test_oembed_no_url_map(client, map, datalayer):
|
|
773
|
+
url = reverse("map_oembed")
|
|
774
|
+
response = client.get(url)
|
|
775
|
+
assert response.status_code == 404
|
|
776
|
+
|
|
777
|
+
|
|
778
|
+
def test_oembed_wrong_format_map(client, map, datalayer):
|
|
779
|
+
url = (
|
|
780
|
+
f"{reverse('map_oembed')}"
|
|
781
|
+
f"?url=http://testserver{map.get_absolute_url()}&format=xml"
|
|
782
|
+
)
|
|
783
|
+
response = client.get(url)
|
|
784
|
+
assert response.status_code == 501
|
|
785
|
+
|
|
786
|
+
|
|
787
|
+
def test_oembed_wrong_domain_map(client, map, datalayer):
|
|
788
|
+
url = f"{reverse('map_oembed')}?url=http://BADserver{map.get_absolute_url()}"
|
|
789
|
+
response = client.get(url)
|
|
790
|
+
assert response.status_code == 404
|
|
791
|
+
|
|
792
|
+
|
|
793
|
+
def test_oembed_map(client, map, datalayer):
|
|
794
|
+
url = f"{reverse('map_oembed')}?url=http://testserver{map.get_absolute_url()}"
|
|
795
|
+
response = client.get(url)
|
|
796
|
+
assert response.status_code == 200
|
|
797
|
+
j = json.loads(response.content.decode())
|
|
798
|
+
assert j["type"] == "rich"
|
|
799
|
+
assert j["version"] == "1.0"
|
|
800
|
+
assert j["width"] == 800
|
|
801
|
+
assert j["height"] == 300
|
|
802
|
+
assert j["html"] == (
|
|
803
|
+
'<iframe width="100%" height="300px" frameborder="0" allowfullscreen '
|
|
804
|
+
f'allow="geolocation" src="//testserver/en/map/test-map_{map.id}"></iframe>'
|
|
805
|
+
f'<p><a href="//testserver/en/map/test-map_{map.id}">See full screen</a></p>'
|
|
806
|
+
)
|
|
807
|
+
|
|
808
|
+
|
|
809
|
+
def test_oembed_link(client, map, datalayer):
|
|
810
|
+
response = client.get(map.get_absolute_url())
|
|
811
|
+
assert response.status_code == 200
|
|
812
|
+
assert (
|
|
813
|
+
'<link rel="alternate" type="application/json+oembed"'
|
|
814
|
+
in response.content.decode()
|
|
815
|
+
)
|
|
816
|
+
assert (
|
|
817
|
+
'href="http://testserver/map/oembed/'
|
|
818
|
+
f'?url=http%3A//testserver/en/map/test-map_{map.id}&format=json"'
|
|
819
|
+
) in response.content.decode()
|
|
820
|
+
assert 'title="test map oEmbed URL" />' in response.content.decode()
|
umap/tests/test_views.py
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import json
|
|
2
2
|
import socket
|
|
3
|
-
from datetime import
|
|
3
|
+
from datetime import datetime, timedelta
|
|
4
4
|
|
|
5
5
|
import pytest
|
|
6
6
|
from django.conf import settings
|
|
@@ -10,6 +10,7 @@ from django.urls import reverse
|
|
|
10
10
|
from django.utils.timezone import make_aware
|
|
11
11
|
|
|
12
12
|
from umap import VERSION
|
|
13
|
+
from umap.models import Map, Star
|
|
13
14
|
from umap.views import validate_url
|
|
14
15
|
|
|
15
16
|
from .base import MapFactory, UserFactory
|
|
@@ -303,16 +304,6 @@ def test_user_dashboard_display_user_maps_distinct(client, map):
|
|
|
303
304
|
assert body.count(anonymap.name) == 0
|
|
304
305
|
|
|
305
306
|
|
|
306
|
-
@pytest.mark.django_db
|
|
307
|
-
def test_logout_should_return_json_in_ajax(client, user, settings):
|
|
308
|
-
client.login(username=user.username, password="123123")
|
|
309
|
-
response = client.get(
|
|
310
|
-
reverse("logout"), headers={"X_REQUESTED_WITH": "XMLHttpRequest"}
|
|
311
|
-
)
|
|
312
|
-
data = json.loads(response.content.decode())
|
|
313
|
-
assert data["redirect"] == "/"
|
|
314
|
-
|
|
315
|
-
|
|
316
307
|
@pytest.mark.django_db
|
|
317
308
|
def test_logout_should_return_redirect(client, user, settings):
|
|
318
309
|
client.login(username=user.username, password="123123")
|
|
@@ -391,3 +382,51 @@ def test_webmanifest(client):
|
|
|
391
382
|
},
|
|
392
383
|
]
|
|
393
384
|
}
|
|
385
|
+
|
|
386
|
+
|
|
387
|
+
@pytest.mark.django_db
|
|
388
|
+
def test_home_feed(client, settings, user, tilelayer):
|
|
389
|
+
settings.UMAP_HOME_FEED = "latest"
|
|
390
|
+
staff = UserFactory(username="Staff", is_staff=True)
|
|
391
|
+
starred = MapFactory(
|
|
392
|
+
owner=user, name="A public map starred by staff", share_status=Map.PUBLIC
|
|
393
|
+
)
|
|
394
|
+
MapFactory(
|
|
395
|
+
owner=user, name="A public map not starred by staff", share_status=Map.PUBLIC
|
|
396
|
+
)
|
|
397
|
+
non_staff = MapFactory(
|
|
398
|
+
owner=user, name="A public map starred by non staff", share_status=Map.PUBLIC
|
|
399
|
+
)
|
|
400
|
+
private = MapFactory(
|
|
401
|
+
owner=user, name="A private map starred by staff", share_status=Map.PRIVATE
|
|
402
|
+
)
|
|
403
|
+
reserved = MapFactory(
|
|
404
|
+
owner=user, name="A reserved map starred by staff", share_status=Map.OPEN
|
|
405
|
+
)
|
|
406
|
+
Star.objects.create(by=staff, map=starred)
|
|
407
|
+
Star.objects.create(by=staff, map=private)
|
|
408
|
+
Star.objects.create(by=staff, map=reserved)
|
|
409
|
+
Star.objects.create(by=user, map=non_staff)
|
|
410
|
+
response = client.get(reverse("home"))
|
|
411
|
+
content = response.content.decode()
|
|
412
|
+
assert "A public map starred by staff" in content
|
|
413
|
+
assert "A public map not starred by staff" in content
|
|
414
|
+
assert "A public map starred by non staff" in content
|
|
415
|
+
assert "A private map starred by staff" not in content
|
|
416
|
+
assert "A reserved map starred by staff" not in content
|
|
417
|
+
settings.UMAP_HOME_FEED = "highlighted"
|
|
418
|
+
response = client.get(reverse("home"))
|
|
419
|
+
content = response.content.decode()
|
|
420
|
+
assert "A public map starred by staff" in content
|
|
421
|
+
assert "A public map not starred by staff" not in content
|
|
422
|
+
assert "A public map starred by non staff" not in content
|
|
423
|
+
assert "A private map starred by staff" not in content
|
|
424
|
+
assert "A reserved map starred by staff" not in content
|
|
425
|
+
settings.UMAP_HOME_FEED = None
|
|
426
|
+
response = client.get(reverse("home"))
|
|
427
|
+
content = response.content.decode()
|
|
428
|
+
assert "A public map starred by staff" not in content
|
|
429
|
+
assert "A public map not starred by staff" not in content
|
|
430
|
+
assert "A public map starred by non staff" not in content
|
|
431
|
+
assert "A private map starred by staff" not in content
|
|
432
|
+
assert "A reserved map starred by staff" not in content
|
umap/urls.py
CHANGED
|
@@ -15,7 +15,6 @@ from . import views
|
|
|
15
15
|
from .decorators import (
|
|
16
16
|
can_edit_map,
|
|
17
17
|
can_view_map,
|
|
18
|
-
jsonize_view,
|
|
19
18
|
login_required_if_not_anonymous_allowed,
|
|
20
19
|
)
|
|
21
20
|
from .utils import decorated_patterns
|
|
@@ -41,6 +40,7 @@ urlpatterns = [
|
|
|
41
40
|
),
|
|
42
41
|
re_path(r"^i18n/", include("django.conf.urls.i18n")),
|
|
43
42
|
re_path(r"^agnocomplete/", include("agnocomplete.urls")),
|
|
43
|
+
re_path(r"^map/oembed/", views.MapOEmbed.as_view(), name="map_oembed"),
|
|
44
44
|
re_path(
|
|
45
45
|
r"^map/(?P<map_id>\d+)/download/",
|
|
46
46
|
can_view_map(views.MapDownload.as_view()),
|
|
@@ -49,7 +49,7 @@ urlpatterns = [
|
|
|
49
49
|
]
|
|
50
50
|
|
|
51
51
|
i18n_urls = [
|
|
52
|
-
re_path(r"^login/$",
|
|
52
|
+
re_path(r"^login/$", auth_views.LoginView.as_view(), name="login"),
|
|
53
53
|
re_path(
|
|
54
54
|
r"^login/popup/end/$", views.LoginPopupEnd.as_view(), name="login_popup_end"
|
|
55
55
|
),
|
|
@@ -96,6 +96,7 @@ i18n_urls += decorated_patterns(
|
|
|
96
96
|
)
|
|
97
97
|
i18n_urls += decorated_patterns(
|
|
98
98
|
[ensure_csrf_cookie],
|
|
99
|
+
re_path(r"^map/$", views.MapPreview.as_view(), name="map_preview"),
|
|
99
100
|
re_path(r"^map/new/$", views.MapNew.as_view(), name="map_new"),
|
|
100
101
|
)
|
|
101
102
|
i18n_urls += decorated_patterns(
|
|
@@ -109,16 +110,9 @@ i18n_urls += decorated_patterns(
|
|
|
109
110
|
views.ToggleMapStarStatus.as_view(),
|
|
110
111
|
name="map_star",
|
|
111
112
|
),
|
|
112
|
-
re_path(
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
name="user_dashboard",
|
|
116
|
-
),
|
|
117
|
-
re_path(
|
|
118
|
-
r"^me/profile$",
|
|
119
|
-
views.user_profile,
|
|
120
|
-
name="user_profile",
|
|
121
|
-
),
|
|
113
|
+
re_path(r"^me$", views.user_dashboard, name="user_dashboard"),
|
|
114
|
+
re_path(r"^me/profile$", views.user_profile, name="user_profile"),
|
|
115
|
+
re_path(r"^me/download$", views.user_download, name="user_download"),
|
|
122
116
|
)
|
|
123
117
|
map_urls = [
|
|
124
118
|
re_path(
|